--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/media/js/terrain2.js Sat Mar 05 21:26:30 2016 +0000
@@ -0,0 +1,783 @@
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+{
+ var _ns_ = {
+ id: 'demo',
+ doc: void 0
+ };
+ var ndarray = require('ndarray');
+}
+var width = exports.width = 610;
+var height = exports.height = 400;
+var wireframe = exports.wireframe = true;
+var wireframeWidth = exports.wireframeWidth = 1.2;
+var terrainHeight = exports.terrainHeight = 50;
+var terrainSize = exports.terrainSize = 100;
+void 0;
+void 0;
+void 0;
+var inc = exports.inc = function inc(x) {
+ return x + 1;
+};
+var dec = exports.dec = function dec(x) {
+ return x - 1;
+};
+void 0;
+void 0;
+void 0;
+void 0;
+void 0;
+void 0;
+void 0;
+void 0;
+var midpoint = exports.midpoint = function midpoint(a, b) {
+ return (a + b) / 2;
+};
+var average2 = exports.average2 = function average2(a, b) {
+ return (a + b) / 2;
+};
+var average4 = exports.average4 = function average4(a, b, c, d) {
+ return (a + b + c + d) / 4;
+};
+var safeAverage = exports.safeAverage = function safeAverage(a, b, c, d) {
+ return function () {
+ var totalø1 = 0;
+ var countø1 = 0;
+ a ? (function () {
+ totalø1 = totalø1 + a;
+ return countø1 = inc(countø1);
+ })() : void 0;
+ b ? (function () {
+ totalø1 = totalø1 + b;
+ return countø1 = inc(countø1);
+ })() : void 0;
+ c ? (function () {
+ totalø1 = totalø1 + c;
+ return countø1 = inc(countø1);
+ })() : void 0;
+ d ? (function () {
+ totalø1 = totalø1 + d;
+ return countø1 = inc(countø1);
+ })() : void 0;
+ return totalø1 / countø1;
+ }.call(this);
+};
+var rand = exports.rand = function rand() {
+ return Math.random();
+};
+var randAroundZero = exports.randAroundZero = function randAroundZero(spread) {
+ return spread * rand() * 2 - spread;
+};
+var jitter = exports.jitter = function jitter(value, spread) {
+ return value + randAroundZero(spread);
+};
+var heightmapResolution = exports.heightmapResolution = function heightmapResolution(heightmap) {
+ return heightmap.shape[0];
+};
+var heightmapLastIndex = exports.heightmapLastIndex = function heightmapLastIndex(heightmap) {
+ return dec(heightmapResolution(heightmap));
+};
+var heightmapCenterIndex = exports.heightmapCenterIndex = function heightmapCenterIndex(heightmap) {
+ return midpoint(0, heightmapLastIndex(heightmap));
+};
+var heightmapGet = exports.heightmapGet = function heightmapGet(heightmap, x, y) {
+ return heightmap.get(x, y);
+};
+var heightmapGetSafe = exports.heightmapGetSafe = function heightmapGetSafe(heightmap, x, y) {
+ return function () {
+ var lastø1 = heightmapLastIndex(heightmap);
+ return 0 <= x && x <= lastø1 && (0 <= y && y <= lastø1) ? (function () {
+ return heightmapGet(heightmap, x, y);
+ })() : void 0;
+ }.call(this);
+};
+var heightmapSet = exports.heightmapSet = function heightmapSet(heightmap, x, y, val) {
+ return heightmap.set(x, y, val);
+};
+var heightmapSetIfUnset = exports.heightmapSetIfUnset = function heightmapSetIfUnset(heightmap, x, y, val) {
+ return 0 == heightmapGet(heightmap, x, y) ? (function () {
+ return heightmapSet(heightmap, x, y, val);
+ })() : void 0;
+};
+var normalize = exports.normalize = function normalize(heightmap) {
+ return function () {
+ var maxø1 = 0 - Infinity;
+ var minø1 = Infinity;
+ (function () {
+ var array2ø1 = heightmap;
+ return function () {
+ var G__3ø1 = array2ø1.data.length;
+ return function loop() {
+ var recur = loop;
+ var index1ø1 = 0;
+ do {
+ recur = index1ø1 < G__3ø1 ? (function () {
+ (function () {
+ var elø1 = array2ø1.data[index1ø1];
+ maxø1 < elø1 ? (function () {
+ return maxø1 = elø1;
+ })() : void 0;
+ return minø1 > elø1 ? (function () {
+ return minø1 = elø1;
+ })() : void 0;
+ }.call(this));
+ return loop[0] = inc(index1ø1), loop;
+ })() : void 0;
+ } while (index1ø1 = loop[0], recur === loop);
+ return recur;
+ }.call(this);
+ }.call(this);
+ }.call(this));
+ return function () {
+ var spanø1 = maxø1 - minø1;
+ return function () {
+ var array4ø1 = heightmap;
+ return function () {
+ var G__5ø1 = array4ø1.shape[0];
+ return function loop() {
+ var recur = loop;
+ var xø1 = 0;
+ do {
+ recur = xø1 < G__5ø1 ? (function () {
+ (function () {
+ var G__6ø1 = array4ø1.shape[1];
+ return function loop() {
+ var recur = loop;
+ var yø1 = 0;
+ do {
+ recur = yø1 < G__6ø1 ? (function () {
+ (function () {
+ return heightmapSet(heightmap, xø1, yø1, (heightmapGet(heightmap, xø1, yø1) - minø1) / spanø1);
+ })();
+ return loop[0] = inc(yø1), loop;
+ })() : void 0;
+ } while (yø1 = loop[0], recur === loop);
+ return recur;
+ }.call(this);
+ }.call(this));
+ return loop[0] = inc(xø1), loop;
+ })() : void 0;
+ } while (xø1 = loop[0], recur === loop);
+ return recur;
+ }.call(this);
+ }.call(this);
+ }.call(this);
+ }.call(this);
+ }.call(this);
+};
+var makeHeightmap = exports.makeHeightmap = function makeHeightmap(exponent) {
+ return function () {
+ var resolutionø1 = Math.pow(2, exponent) + 1;
+ return function () {
+ var heightmapø1 = ndarray(new Float64Array(resolutionø1 * resolutionø1), [
+ resolutionø1,
+ resolutionø1
+ ]);
+ heightmapø1.exponent = exponent;
+ heightmapø1.resolution = resolutionø1;
+ heightmapø1.last = dec(resolutionø1);
+ return heightmapø1;
+ }.call(this);
+ }.call(this);
+};
+var topLeftCorner = exports.topLeftCorner = function topLeftCorner(heightmap) {
+ return function () {
+ var centerø1 = heightmapCenterIndex(heightmap);
+ return heightmap.lo(0, 0).hi(inc(centerø1), inc(centerø1));
+ }.call(this);
+};
+var topRightCorner = exports.topRightCorner = function topRightCorner(heightmap) {
+ return function () {
+ var centerø1 = heightmapCenterIndex(heightmap);
+ return heightmap.lo(centerø1, 0).hi(inc(centerø1), inc(centerø1));
+ }.call(this);
+};
+var bottomLeftCorner = exports.bottomLeftCorner = function bottomLeftCorner(heightmap) {
+ return function () {
+ var centerø1 = heightmapCenterIndex(heightmap);
+ return heightmap.lo(0, centerø1).hi(inc(centerø1), inc(centerø1));
+ }.call(this);
+};
+var bottomRightCorner = exports.bottomRightCorner = function bottomRightCorner(heightmap) {
+ return function () {
+ var centerø1 = heightmapCenterIndex(heightmap);
+ return heightmap.lo(centerø1, centerø1).hi(inc(centerø1), inc(centerø1));
+ }.call(this);
+};
+var mpdInitCorners = exports.mpdInitCorners = function mpdInitCorners(heightmap) {
+ return function () {
+ var lastø1 = heightmapLastIndex(heightmap);
+ heightmapSet(heightmap, 0, 0, rand());
+ heightmapSet(heightmap, 0, lastø1, rand());
+ heightmapSet(heightmap, lastø1, 0, rand());
+ return heightmapSet(heightmap, lastø1, lastø1, rand());
+ }.call(this);
+};
+var mpdDisplace = exports.mpdDisplace = function mpdDisplace(heightmap, spread, spreadReduction) {
+ return function () {
+ var lastø1 = heightmapLastIndex(heightmap);
+ var cø1 = midpoint(0, lastø1);
+ var bottomLeftø1 = heightmapGet(heightmap, 0, 0);
+ var bottomRightø1 = heightmapGet(heightmap, lastø1, 0);
+ var topLeftø1 = heightmapGet(heightmap, 0, lastø1);
+ var topRightø1 = heightmapGet(heightmap, lastø1, lastø1);
+ var topø1 = average2(topLeftø1, topRightø1);
+ var leftø1 = average2(bottomLeftø1, topLeftø1);
+ var bottomø1 = average2(bottomLeftø1, bottomRightø1);
+ var rightø1 = average2(bottomRightø1, topRightø1);
+ var centerø1 = average4(topø1, leftø1, bottomø1, rightø1);
+ var nextSpreadø1 = spread * spreadReduction;
+ heightmapSetIfUnset(heightmap, cø1, 0, jitter(bottomø1, spread));
+ heightmapSetIfUnset(heightmap, cø1, lastø1, jitter(topø1, spread));
+ heightmapSetIfUnset(heightmap, 0, cø1, jitter(leftø1, spread));
+ heightmapSetIfUnset(heightmap, lastø1, cø1, jitter(rightø1, spread));
+ heightmapSetIfUnset(heightmap, cø1, cø1, jitter(centerø1, spread));
+ return !(3 == heightmapResolution(heightmap)) ? (function () {
+ heightmapSetIfUnset(heightmap, cø1, 0, jitter(bottomø1, spread));
+ heightmapSetIfUnset(heightmap, cø1, lastø1, jitter(topø1, spread));
+ heightmapSetIfUnset(heightmap, 0, cø1, jitter(leftø1, spread));
+ heightmapSetIfUnset(heightmap, lastø1, cø1, jitter(rightø1, spread));
+ heightmapSetIfUnset(heightmap, cø1, cø1, jitter(centerø1, spread));
+ mpdDisplace(topLeftCorner(heightmap), nextSpreadø1, spreadReduction);
+ mpdDisplace(topRightCorner(heightmap), nextSpreadø1, spreadReduction);
+ mpdDisplace(bottomLeftCorner(heightmap), nextSpreadø1, spreadReduction);
+ return mpdDisplace(bottomRightCorner(heightmap), nextSpreadø1, spreadReduction);
+ })() : void 0;
+ }.call(this);
+};
+var midpointDisplacement = exports.midpointDisplacement = function midpointDisplacement(heightmap) {
+ return function () {
+ var initialSpreadø1 = 0.3;
+ var spreadReductionø1 = 0.55;
+ mpdInitCorners(heightmap);
+ mpdDisplace(heightmap, initialSpreadø1, spreadReductionø1);
+ return normalize(heightmap);
+ }.call(this);
+};
+var makeDirectionalLight = exports.makeDirectionalLight = function makeDirectionalLight() {
+ return function () {
+ var lightø1 = new THREE.DirectionalLight(16777215, 1);
+ lightø1.position.set(100, 0, 150);
+ return lightø1;
+ }.call(this);
+};
+var makeCamera = exports.makeCamera = function makeCamera() {
+ return function () {
+ var cameraø1 = new THREE.PerspectiveCamera(55, width / height, 0.1, 1000);
+ cameraø1.position.set(0, -100, 150);
+ return cameraø1;
+ }.call(this);
+};
+var makeRenderer = exports.makeRenderer = function makeRenderer() {
+ return function () {
+ var rendererø1 = new THREE.WebGLRenderer({ 'antialias': false });
+ rendererø1.setClearColor(16777215);
+ rendererø1.setSize(width, height);
+ rendererø1.setPixelRatio(2);
+ return rendererø1;
+ }.call(this);
+};
+var makeGeometry = exports.makeGeometry = function makeGeometry(heightmap) {
+ return function () {
+ var resolutionø1 = heightmap.shape[0];
+ var geometryø1 = new THREE.PlaneGeometry(terrainSize, terrainSize, resolutionø1 - 1, resolutionø1 - 1);
+ return geometryø1;
+ }.call(this);
+};
+var makeControls = exports.makeControls = function makeControls(camera, renderer) {
+ return function () {
+ var controlsø1 = new THREE.TrackballControls(camera, renderer.domElement);
+ controlsø1.rotateSpeed = 1.4;
+ controlsø1.zoomSpeed = 0.5;
+ controlsø1.staticMoving = true;
+ controlsø1.dynamicDampingFactor = 0.3;
+ return controlsø1;
+ }.call(this);
+};
+var makePlane = exports.makePlane = function makePlane(geometry) {
+ return function () {
+ var materialø1 = new THREE.MeshLambertMaterial({
+ 'wireframe': wireframe,
+ 'wireframeLinewidth': wireframeWidth,
+ 'color': 47872
+ });
+ return new THREE.Mesh(geometry, materialø1);
+ }.call(this);
+};
+var attachToDom = exports.attachToDom = function attachToDom(renderer, elName, refreshFn) {
+ return function () {
+ var containerø1 = document.getElementById(elName);
+ var settingsø1 = document.createElement('div');
+ var refreshButtonø1 = document.createElement('button');
+ var buttonTextø1 = document.createTextNode('Refresh');
+ var cancelScrollø1 = function (e) {
+ return e.preventDefault();
+ };
+ refreshButtonø1.onclick = refreshFn;
+ renderer.domElement.onmousewheel = cancelScrollø1;
+ renderer.domElement.addEventListener('MozMousePixelScroll', cancelScrollø1, false);
+ refreshButtonø1.appendChild(buttonTextø1);
+ containerø1.appendChild(renderer.domElement);
+ containerø1.appendChild(settingsø1);
+ return settingsø1.appendChild(refreshButtonø1);
+ }.call(this);
+};
+var updateGeometry = exports.updateGeometry = function updateGeometry(geometry, heightmap) {
+ (function loop() {
+ var recur = loop;
+ var iø1 = 0;
+ do {
+ recur = iø1 < geometry.vertices.length ? (function () {
+ geometry.vertices[iø1].z = terrainHeight * heightmap.data[iø1];
+ return loop[0] = iø1 + 1, loop;
+ })() : void 0;
+ } while (iø1 = loop[0], recur === loop);
+ return recur;
+ }.call(this));
+ geometry.computeVertexNormals();
+ return geometry;
+};
+var makeFinal = exports.makeFinal = function makeFinal(elementId) {
+ var scene = new THREE.Scene();
+ scene.add(new THREE.AxisHelper(100));
+ var clock = new THREE.Clock();
+ var camera = makeCamera();
+ var renderer = makeRenderer();
+ var geometry = void 0;
+ var plane = void 0;
+ scene.add(makeDirectionalLight());
+ scene.add(new THREE.AmbientLight(16777215, 0.05));
+ var refresh = function refresh() {
+ return function () {
+ var heightmapø1 = makeHeightmap(6);
+ console.log('Generating terrain...');
+ (function () {
+ var G__7ø1 = new Date().getTime();
+ var G__9ø1 = (function () {
+ return midpointDisplacement(heightmapø1);
+ })();
+ var G__8ø1 = new Date().getTime();
+ console.log('Elapsed time: ' + (G__8ø1 - G__7ø1) + 'ms.');
+ return G__9ø1;
+ }.call(this));
+ console.log('Rebuilding geometry...');
+ (function () {
+ var G__10ø1 = new Date().getTime();
+ var G__12ø1 = (function () {
+ geometry = makeGeometry(heightmapø1);
+ return updateGeometry(geometry, heightmapø1);
+ })();
+ var G__11ø1 = new Date().getTime();
+ console.log('Elapsed time: ' + (G__11ø1 - G__10ø1) + 'ms.');
+ return G__12ø1;
+ }.call(this));
+ console.log('Rebuilding plane...');
+ return function () {
+ var G__13ø1 = new Date().getTime();
+ var G__15ø1 = (function () {
+ scene.remove(plane);
+ plane = makePlane(geometry);
+ return scene.add(plane);
+ })();
+ var G__14ø1 = new Date().getTime();
+ console.log('Elapsed time: ' + (G__14ø1 - G__13ø1) + 'ms.');
+ return G__15ø1;
+ }.call(this);
+ }.call(this);
+ };
+ attachToDom(renderer, elementId, refresh);
+ var controls = makeControls(camera, renderer);
+ var render = function render() {
+ return function () {
+ var deltaø1 = clock.getDelta();
+ requestAnimationFrame(render);
+ controls.update(deltaø1);
+ return renderer.render(scene, camera);
+ }.call(this);
+ };
+ refresh();
+ render();
+ return void 0;
+};
+var run = exports.run = function run() {
+ return makeFinal('demo-final');
+};
+$(run);
+
+
+},{"ndarray":4}],2:[function(require,module,exports){
+"use strict"
+
+function iota(n) {
+ var result = new Array(n)
+ for(var i=0; i<n; ++i) {
+ result[i] = i
+ }
+ return result
+}
+
+module.exports = iota
+},{}],3:[function(require,module,exports){
+/**
+ * Determine if an object is Buffer
+ *
+ * Author: Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
+ * License: MIT
+ *
+ * `npm install is-buffer`
+ */
+
+module.exports = function (obj) {
+ return !!(obj != null &&
+ (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor)
+ (obj.constructor &&
+ typeof obj.constructor.isBuffer === 'function' &&
+ obj.constructor.isBuffer(obj))
+ ))
+}
+
+},{}],4:[function(require,module,exports){
+var iota = require("iota-array")
+var isBuffer = require("is-buffer")
+
+var hasTypedArrays = ((typeof Float64Array) !== "undefined")
+
+function compare1st(a, b) {
+ return a[0] - b[0]
+}
+
+function order() {
+ var stride = this.stride
+ var terms = new Array(stride.length)
+ var i
+ for(i=0; i<terms.length; ++i) {
+ terms[i] = [Math.abs(stride[i]), i]
+ }
+ terms.sort(compare1st)
+ var result = new Array(terms.length)
+ for(i=0; i<result.length; ++i) {
+ result[i] = terms[i][1]
+ }
+ return result
+}
+
+function compileConstructor(dtype, dimension) {
+ var className = ["View", dimension, "d", dtype].join("")
+ if(dimension < 0) {
+ className = "View_Nil" + dtype
+ }
+ var useGetters = (dtype === "generic")
+
+ if(dimension === -1) {
+ //Special case for trivial arrays
+ var code =
+ "function "+className+"(a){this.data=a;};\
+var proto="+className+".prototype;\
+proto.dtype='"+dtype+"';\
+proto.index=function(){return -1};\
+proto.size=0;\
+proto.dimension=-1;\
+proto.shape=proto.stride=proto.order=[];\
+proto.lo=proto.hi=proto.transpose=proto.step=\
+function(){return new "+className+"(this.data);};\
+proto.get=proto.set=function(){};\
+proto.pick=function(){return null};\
+return function construct_"+className+"(a){return new "+className+"(a);}"
+ var procedure = new Function(code)
+ return procedure()
+ } else if(dimension === 0) {
+ //Special case for 0d arrays
+ var code =
+ "function "+className+"(a,d) {\
+this.data = a;\
+this.offset = d\
+};\
+var proto="+className+".prototype;\
+proto.dtype='"+dtype+"';\
+proto.index=function(){return this.offset};\
+proto.dimension=0;\
+proto.size=1;\
+proto.shape=\
+proto.stride=\
+proto.order=[];\
+proto.lo=\
+proto.hi=\
+proto.transpose=\
+proto.step=function "+className+"_copy() {\
+return new "+className+"(this.data,this.offset)\
+};\
+proto.pick=function "+className+"_pick(){\
+return TrivialArray(this.data);\
+};\
+proto.valueOf=proto.get=function "+className+"_get(){\
+return "+(useGetters ? "this.data.get(this.offset)" : "this.data[this.offset]")+
+"};\
+proto.set=function "+className+"_set(v){\
+return "+(useGetters ? "this.data.set(this.offset,v)" : "this.data[this.offset]=v")+"\
+};\
+return function construct_"+className+"(a,b,c,d){return new "+className+"(a,d)}"
+ var procedure = new Function("TrivialArray", code)
+ return procedure(CACHED_CONSTRUCTORS[dtype][0])
+ }
+
+ var code = ["'use strict'"]
+
+ //Create constructor for view
+ var indices = iota(dimension)
+ var args = indices.map(function(i) { return "i"+i })
+ var index_str = "this.offset+" + indices.map(function(i) {
+ return "this.stride[" + i + "]*i" + i
+ }).join("+")
+ var shapeArg = indices.map(function(i) {
+ return "b"+i
+ }).join(",")
+ var strideArg = indices.map(function(i) {
+ return "c"+i
+ }).join(",")
+ code.push(
+ "function "+className+"(a," + shapeArg + "," + strideArg + ",d){this.data=a",
+ "this.shape=[" + shapeArg + "]",
+ "this.stride=[" + strideArg + "]",
+ "this.offset=d|0}",
+ "var proto="+className+".prototype",
+ "proto.dtype='"+dtype+"'",
+ "proto.dimension="+dimension)
+
+ //view.size:
+ code.push("Object.defineProperty(proto,'size',{get:function "+className+"_size(){\
+return "+indices.map(function(i) { return "this.shape["+i+"]" }).join("*"),
+"}})")
+
+ //view.order:
+ if(dimension === 1) {
+ code.push("proto.order=[0]")
+ } else {
+ code.push("Object.defineProperty(proto,'order',{get:")
+ if(dimension < 4) {
+ code.push("function "+className+"_order(){")
+ if(dimension === 2) {
+ code.push("return (Math.abs(this.stride[0])>Math.abs(this.stride[1]))?[1,0]:[0,1]}})")
+ } else if(dimension === 3) {
+ code.push(
+"var s0=Math.abs(this.stride[0]),s1=Math.abs(this.stride[1]),s2=Math.abs(this.stride[2]);\
+if(s0>s1){\
+if(s1>s2){\
+return [2,1,0];\
+}else if(s0>s2){\
+return [1,2,0];\
+}else{\
+return [1,0,2];\
+}\
+}else if(s0>s2){\
+return [2,0,1];\
+}else if(s2>s1){\
+return [0,1,2];\
+}else{\
+return [0,2,1];\
+}}})")
+ }
+ } else {
+ code.push("ORDER})")
+ }
+ }
+
+ //view.set(i0, ..., v):
+ code.push(
+"proto.set=function "+className+"_set("+args.join(",")+",v){")
+ if(useGetters) {
+ code.push("return this.data.set("+index_str+",v)}")
+ } else {
+ code.push("return this.data["+index_str+"]=v}")
+ }
+
+ //view.get(i0, ...):
+ code.push("proto.get=function "+className+"_get("+args.join(",")+"){")
+ if(useGetters) {
+ code.push("return this.data.get("+index_str+")}")
+ } else {
+ code.push("return this.data["+index_str+"]}")
+ }
+
+ //view.index:
+ code.push(
+ "proto.index=function "+className+"_index(", args.join(), "){return "+index_str+"}")
+
+ //view.hi():
+ code.push("proto.hi=function "+className+"_hi("+args.join(",")+"){return new "+className+"(this.data,"+
+ indices.map(function(i) {
+ return ["(typeof i",i,"!=='number'||i",i,"<0)?this.shape[", i, "]:i", i,"|0"].join("")
+ }).join(",")+","+
+ indices.map(function(i) {
+ return "this.stride["+i + "]"
+ }).join(",")+",this.offset)}")
+
+ //view.lo():
+ var a_vars = indices.map(function(i) { return "a"+i+"=this.shape["+i+"]" })
+ var c_vars = indices.map(function(i) { return "c"+i+"=this.stride["+i+"]" })
+ code.push("proto.lo=function "+className+"_lo("+args.join(",")+"){var b=this.offset,d=0,"+a_vars.join(",")+","+c_vars.join(","))
+ for(var i=0; i<dimension; ++i) {
+ code.push(
+"if(typeof i"+i+"==='number'&&i"+i+">=0){\
+d=i"+i+"|0;\
+b+=c"+i+"*d;\
+a"+i+"-=d}")
+ }
+ code.push("return new "+className+"(this.data,"+
+ indices.map(function(i) {
+ return "a"+i
+ }).join(",")+","+
+ indices.map(function(i) {
+ return "c"+i
+ }).join(",")+",b)}")
+
+ //view.step():
+ code.push("proto.step=function "+className+"_step("+args.join(",")+"){var "+
+ indices.map(function(i) {
+ return "a"+i+"=this.shape["+i+"]"
+ }).join(",")+","+
+ indices.map(function(i) {
+ return "b"+i+"=this.stride["+i+"]"
+ }).join(",")+",c=this.offset,d=0,ceil=Math.ceil")
+ for(var i=0; i<dimension; ++i) {
+ code.push(
+"if(typeof i"+i+"==='number'){\
+d=i"+i+"|0;\
+if(d<0){\
+c+=b"+i+"*(a"+i+"-1);\
+a"+i+"=ceil(-a"+i+"/d)\
+}else{\
+a"+i+"=ceil(a"+i+"/d)\
+}\
+b"+i+"*=d\
+}")
+ }
+ code.push("return new "+className+"(this.data,"+
+ indices.map(function(i) {
+ return "a" + i
+ }).join(",")+","+
+ indices.map(function(i) {
+ return "b" + i
+ }).join(",")+",c)}")
+
+ //view.transpose():
+ var tShape = new Array(dimension)
+ var tStride = new Array(dimension)
+ for(var i=0; i<dimension; ++i) {
+ tShape[i] = "a[i"+i+"]"
+ tStride[i] = "b[i"+i+"]"
+ }
+ code.push("proto.transpose=function "+className+"_transpose("+args+"){"+
+ args.map(function(n,idx) { return n + "=(" + n + "===undefined?" + idx + ":" + n + "|0)"}).join(";"),
+ "var a=this.shape,b=this.stride;return new "+className+"(this.data,"+tShape.join(",")+","+tStride.join(",")+",this.offset)}")
+
+ //view.pick():
+ code.push("proto.pick=function "+className+"_pick("+args+"){var a=[],b=[],c=this.offset")
+ for(var i=0; i<dimension; ++i) {
+ code.push("if(typeof i"+i+"==='number'&&i"+i+">=0){c=(c+this.stride["+i+"]*i"+i+")|0}else{a.push(this.shape["+i+"]);b.push(this.stride["+i+"])}")
+ }
+ code.push("var ctor=CTOR_LIST[a.length+1];return ctor(this.data,a,b,c)}")
+
+ //Add return statement
+ code.push("return function construct_"+className+"(data,shape,stride,offset){return new "+className+"(data,"+
+ indices.map(function(i) {
+ return "shape["+i+"]"
+ }).join(",")+","+
+ indices.map(function(i) {
+ return "stride["+i+"]"
+ }).join(",")+",offset)}")
+
+ //Compile procedure
+ var procedure = new Function("CTOR_LIST", "ORDER", code.join("\n"))
+ return procedure(CACHED_CONSTRUCTORS[dtype], order)
+}
+
+function arrayDType(data) {
+ if(isBuffer(data)) {
+ return "buffer"
+ }
+ if(hasTypedArrays) {
+ switch(Object.prototype.toString.call(data)) {
+ case "[object Float64Array]":
+ return "float64"
+ case "[object Float32Array]":
+ return "float32"
+ case "[object Int8Array]":
+ return "int8"
+ case "[object Int16Array]":
+ return "int16"
+ case "[object Int32Array]":
+ return "int32"
+ case "[object Uint8Array]":
+ return "uint8"
+ case "[object Uint16Array]":
+ return "uint16"
+ case "[object Uint32Array]":
+ return "uint32"
+ case "[object Uint8ClampedArray]":
+ return "uint8_clamped"
+ }
+ }
+ if(Array.isArray(data)) {
+ return "array"
+ }
+ return "generic"
+}
+
+var CACHED_CONSTRUCTORS = {
+ "float32":[],
+ "float64":[],
+ "int8":[],
+ "int16":[],
+ "int32":[],
+ "uint8":[],
+ "uint16":[],
+ "uint32":[],
+ "array":[],
+ "uint8_clamped":[],
+ "buffer":[],
+ "generic":[]
+}
+
+;(function() {
+ for(var id in CACHED_CONSTRUCTORS) {
+ CACHED_CONSTRUCTORS[id].push(compileConstructor(id, -1))
+ }
+});
+
+function wrappedNDArrayCtor(data, shape, stride, offset) {
+ if(data === undefined) {
+ var ctor = CACHED_CONSTRUCTORS.array[0]
+ return ctor([])
+ } else if(typeof data === "number") {
+ data = [data]
+ }
+ if(shape === undefined) {
+ shape = [ data.length ]
+ }
+ var d = shape.length
+ if(stride === undefined) {
+ stride = new Array(d)
+ for(var i=d-1, sz=1; i>=0; --i) {
+ stride[i] = sz
+ sz *= shape[i]
+ }
+ }
+ if(offset === undefined) {
+ offset = 0
+ for(var i=0; i<d; ++i) {
+ if(stride[i] < 0) {
+ offset -= (shape[i]-1)*stride[i]
+ }
+ }
+ }
+ var dtype = arrayDType(data)
+ var ctor_list = CACHED_CONSTRUCTORS[dtype]
+ while(ctor_list.length <= d+1) {
+ ctor_list.push(compileConstructor(dtype, ctor_list.length-1))
+ }
+ var ctor = ctor_list[d+1]
+ return ctor(data, shape, stride, offset)
+}
+
+module.exports = wrappedNDArrayCtor
+
+},{"iota-array":2,"is-buffer":3}]},{},[1]);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/media/js/wisp/terrain2.js Sat Mar 05 21:26:30 2016 +0000
@@ -0,0 +1,404 @@
+{
+ var _ns_ = {
+ id: 'demo',
+ doc: void 0
+ };
+ var ndarray = require('ndarray');
+}
+var width = exports.width = 610;
+var height = exports.height = 400;
+var wireframe = exports.wireframe = true;
+var wireframeWidth = exports.wireframeWidth = 1.2;
+var terrainHeight = exports.terrainHeight = 50;
+var terrainSize = exports.terrainSize = 100;
+void 0;
+void 0;
+void 0;
+var inc = exports.inc = function inc(x) {
+ return x + 1;
+};
+var dec = exports.dec = function dec(x) {
+ return x - 1;
+};
+void 0;
+void 0;
+void 0;
+void 0;
+void 0;
+void 0;
+void 0;
+void 0;
+var midpoint = exports.midpoint = function midpoint(a, b) {
+ return (a + b) / 2;
+};
+var average2 = exports.average2 = function average2(a, b) {
+ return (a + b) / 2;
+};
+var average4 = exports.average4 = function average4(a, b, c, d) {
+ return (a + b + c + d) / 4;
+};
+var safeAverage = exports.safeAverage = function safeAverage(a, b, c, d) {
+ return function () {
+ var totalø1 = 0;
+ var countø1 = 0;
+ a ? (function () {
+ totalø1 = totalø1 + a;
+ return countø1 = inc(countø1);
+ })() : void 0;
+ b ? (function () {
+ totalø1 = totalø1 + b;
+ return countø1 = inc(countø1);
+ })() : void 0;
+ c ? (function () {
+ totalø1 = totalø1 + c;
+ return countø1 = inc(countø1);
+ })() : void 0;
+ d ? (function () {
+ totalø1 = totalø1 + d;
+ return countø1 = inc(countø1);
+ })() : void 0;
+ return totalø1 / countø1;
+ }.call(this);
+};
+var rand = exports.rand = function rand() {
+ return Math.random();
+};
+var randAroundZero = exports.randAroundZero = function randAroundZero(spread) {
+ return spread * rand() * 2 - spread;
+};
+var jitter = exports.jitter = function jitter(value, spread) {
+ return value + randAroundZero(spread);
+};
+var heightmapResolution = exports.heightmapResolution = function heightmapResolution(heightmap) {
+ return heightmap.shape[0];
+};
+var heightmapLastIndex = exports.heightmapLastIndex = function heightmapLastIndex(heightmap) {
+ return dec(heightmapResolution(heightmap));
+};
+var heightmapCenterIndex = exports.heightmapCenterIndex = function heightmapCenterIndex(heightmap) {
+ return midpoint(0, heightmapLastIndex(heightmap));
+};
+var heightmapGet = exports.heightmapGet = function heightmapGet(heightmap, x, y) {
+ return heightmap.get(x, y);
+};
+var heightmapGetSafe = exports.heightmapGetSafe = function heightmapGetSafe(heightmap, x, y) {
+ return function () {
+ var lastø1 = heightmapLastIndex(heightmap);
+ return 0 <= x && x <= lastø1 && (0 <= y && y <= lastø1) ? (function () {
+ return heightmapGet(heightmap, x, y);
+ })() : void 0;
+ }.call(this);
+};
+var heightmapSet = exports.heightmapSet = function heightmapSet(heightmap, x, y, val) {
+ return heightmap.set(x, y, val);
+};
+var heightmapSetIfUnset = exports.heightmapSetIfUnset = function heightmapSetIfUnset(heightmap, x, y, val) {
+ return 0 == heightmapGet(heightmap, x, y) ? (function () {
+ return heightmapSet(heightmap, x, y, val);
+ })() : void 0;
+};
+var normalize = exports.normalize = function normalize(heightmap) {
+ return function () {
+ var maxø1 = 0 - Infinity;
+ var minø1 = Infinity;
+ (function () {
+ var array2ø1 = heightmap;
+ return function () {
+ var G__3ø1 = array2ø1.data.length;
+ return function loop() {
+ var recur = loop;
+ var index1ø1 = 0;
+ do {
+ recur = index1ø1 < G__3ø1 ? (function () {
+ (function () {
+ var elø1 = array2ø1.data[index1ø1];
+ maxø1 < elø1 ? (function () {
+ return maxø1 = elø1;
+ })() : void 0;
+ return minø1 > elø1 ? (function () {
+ return minø1 = elø1;
+ })() : void 0;
+ }.call(this));
+ return loop[0] = inc(index1ø1), loop;
+ })() : void 0;
+ } while (index1ø1 = loop[0], recur === loop);
+ return recur;
+ }.call(this);
+ }.call(this);
+ }.call(this));
+ return function () {
+ var spanø1 = maxø1 - minø1;
+ return function () {
+ var array4ø1 = heightmap;
+ return function () {
+ var G__5ø1 = array4ø1.shape[0];
+ return function loop() {
+ var recur = loop;
+ var xø1 = 0;
+ do {
+ recur = xø1 < G__5ø1 ? (function () {
+ (function () {
+ var G__6ø1 = array4ø1.shape[1];
+ return function loop() {
+ var recur = loop;
+ var yø1 = 0;
+ do {
+ recur = yø1 < G__6ø1 ? (function () {
+ (function () {
+ return heightmapSet(heightmap, xø1, yø1, (heightmapGet(heightmap, xø1, yø1) - minø1) / spanø1);
+ })();
+ return loop[0] = inc(yø1), loop;
+ })() : void 0;
+ } while (yø1 = loop[0], recur === loop);
+ return recur;
+ }.call(this);
+ }.call(this));
+ return loop[0] = inc(xø1), loop;
+ })() : void 0;
+ } while (xø1 = loop[0], recur === loop);
+ return recur;
+ }.call(this);
+ }.call(this);
+ }.call(this);
+ }.call(this);
+ }.call(this);
+};
+var makeHeightmap = exports.makeHeightmap = function makeHeightmap(exponent) {
+ return function () {
+ var resolutionø1 = Math.pow(2, exponent) + 1;
+ return function () {
+ var heightmapø1 = ndarray(new Float64Array(resolutionø1 * resolutionø1), [
+ resolutionø1,
+ resolutionø1
+ ]);
+ heightmapø1.exponent = exponent;
+ heightmapø1.resolution = resolutionø1;
+ heightmapø1.last = dec(resolutionø1);
+ return heightmapø1;
+ }.call(this);
+ }.call(this);
+};
+var topLeftCorner = exports.topLeftCorner = function topLeftCorner(heightmap) {
+ return function () {
+ var centerø1 = heightmapCenterIndex(heightmap);
+ return heightmap.lo(0, 0).hi(inc(centerø1), inc(centerø1));
+ }.call(this);
+};
+var topRightCorner = exports.topRightCorner = function topRightCorner(heightmap) {
+ return function () {
+ var centerø1 = heightmapCenterIndex(heightmap);
+ return heightmap.lo(centerø1, 0).hi(inc(centerø1), inc(centerø1));
+ }.call(this);
+};
+var bottomLeftCorner = exports.bottomLeftCorner = function bottomLeftCorner(heightmap) {
+ return function () {
+ var centerø1 = heightmapCenterIndex(heightmap);
+ return heightmap.lo(0, centerø1).hi(inc(centerø1), inc(centerø1));
+ }.call(this);
+};
+var bottomRightCorner = exports.bottomRightCorner = function bottomRightCorner(heightmap) {
+ return function () {
+ var centerø1 = heightmapCenterIndex(heightmap);
+ return heightmap.lo(centerø1, centerø1).hi(inc(centerø1), inc(centerø1));
+ }.call(this);
+};
+var mpdInitCorners = exports.mpdInitCorners = function mpdInitCorners(heightmap) {
+ return function () {
+ var lastø1 = heightmapLastIndex(heightmap);
+ heightmapSet(heightmap, 0, 0, rand());
+ heightmapSet(heightmap, 0, lastø1, rand());
+ heightmapSet(heightmap, lastø1, 0, rand());
+ return heightmapSet(heightmap, lastø1, lastø1, rand());
+ }.call(this);
+};
+var mpdDisplace = exports.mpdDisplace = function mpdDisplace(heightmap, spread, spreadReduction) {
+ return function () {
+ var lastø1 = heightmapLastIndex(heightmap);
+ var cø1 = midpoint(0, lastø1);
+ var bottomLeftø1 = heightmapGet(heightmap, 0, 0);
+ var bottomRightø1 = heightmapGet(heightmap, lastø1, 0);
+ var topLeftø1 = heightmapGet(heightmap, 0, lastø1);
+ var topRightø1 = heightmapGet(heightmap, lastø1, lastø1);
+ var topø1 = average2(topLeftø1, topRightø1);
+ var leftø1 = average2(bottomLeftø1, topLeftø1);
+ var bottomø1 = average2(bottomLeftø1, bottomRightø1);
+ var rightø1 = average2(bottomRightø1, topRightø1);
+ var centerø1 = average4(topø1, leftø1, bottomø1, rightø1);
+ var nextSpreadø1 = spread * spreadReduction;
+ heightmapSetIfUnset(heightmap, cø1, 0, jitter(bottomø1, spread));
+ heightmapSetIfUnset(heightmap, cø1, lastø1, jitter(topø1, spread));
+ heightmapSetIfUnset(heightmap, 0, cø1, jitter(leftø1, spread));
+ heightmapSetIfUnset(heightmap, lastø1, cø1, jitter(rightø1, spread));
+ heightmapSetIfUnset(heightmap, cø1, cø1, jitter(centerø1, spread));
+ return !(3 == heightmapResolution(heightmap)) ? (function () {
+ heightmapSetIfUnset(heightmap, cø1, 0, jitter(bottomø1, spread));
+ heightmapSetIfUnset(heightmap, cø1, lastø1, jitter(topø1, spread));
+ heightmapSetIfUnset(heightmap, 0, cø1, jitter(leftø1, spread));
+ heightmapSetIfUnset(heightmap, lastø1, cø1, jitter(rightø1, spread));
+ heightmapSetIfUnset(heightmap, cø1, cø1, jitter(centerø1, spread));
+ mpdDisplace(topLeftCorner(heightmap), nextSpreadø1, spreadReduction);
+ mpdDisplace(topRightCorner(heightmap), nextSpreadø1, spreadReduction);
+ mpdDisplace(bottomLeftCorner(heightmap), nextSpreadø1, spreadReduction);
+ return mpdDisplace(bottomRightCorner(heightmap), nextSpreadø1, spreadReduction);
+ })() : void 0;
+ }.call(this);
+};
+var midpointDisplacement = exports.midpointDisplacement = function midpointDisplacement(heightmap) {
+ return function () {
+ var initialSpreadø1 = 0.3;
+ var spreadReductionø1 = 0.55;
+ mpdInitCorners(heightmap);
+ mpdDisplace(heightmap, initialSpreadø1, spreadReductionø1);
+ return normalize(heightmap);
+ }.call(this);
+};
+var makeDirectionalLight = exports.makeDirectionalLight = function makeDirectionalLight() {
+ return function () {
+ var lightø1 = new THREE.DirectionalLight(16777215, 1);
+ lightø1.position.set(100, 0, 150);
+ return lightø1;
+ }.call(this);
+};
+var makeCamera = exports.makeCamera = function makeCamera() {
+ return function () {
+ var cameraø1 = new THREE.PerspectiveCamera(55, width / height, 0.1, 1000);
+ cameraø1.position.set(0, -100, 150);
+ return cameraø1;
+ }.call(this);
+};
+var makeRenderer = exports.makeRenderer = function makeRenderer() {
+ return function () {
+ var rendererø1 = new THREE.WebGLRenderer({ 'antialias': false });
+ rendererø1.setClearColor(16777215);
+ rendererø1.setSize(width, height);
+ rendererø1.setPixelRatio(2);
+ return rendererø1;
+ }.call(this);
+};
+var makeGeometry = exports.makeGeometry = function makeGeometry(heightmap) {
+ return function () {
+ var resolutionø1 = heightmap.shape[0];
+ var geometryø1 = new THREE.PlaneGeometry(terrainSize, terrainSize, resolutionø1 - 1, resolutionø1 - 1);
+ return geometryø1;
+ }.call(this);
+};
+var makeControls = exports.makeControls = function makeControls(camera, renderer) {
+ return function () {
+ var controlsø1 = new THREE.TrackballControls(camera, renderer.domElement);
+ controlsø1.rotateSpeed = 1.4;
+ controlsø1.zoomSpeed = 0.5;
+ controlsø1.staticMoving = true;
+ controlsø1.dynamicDampingFactor = 0.3;
+ return controlsø1;
+ }.call(this);
+};
+var makePlane = exports.makePlane = function makePlane(geometry) {
+ return function () {
+ var materialø1 = new THREE.MeshLambertMaterial({
+ 'wireframe': wireframe,
+ 'wireframeLinewidth': wireframeWidth,
+ 'color': 47872
+ });
+ return new THREE.Mesh(geometry, materialø1);
+ }.call(this);
+};
+var attachToDom = exports.attachToDom = function attachToDom(renderer, elName, refreshFn) {
+ return function () {
+ var containerø1 = document.getElementById(elName);
+ var settingsø1 = document.createElement('div');
+ var refreshButtonø1 = document.createElement('button');
+ var buttonTextø1 = document.createTextNode('Refresh');
+ var cancelScrollø1 = function (e) {
+ return e.preventDefault();
+ };
+ refreshButtonø1.onclick = refreshFn;
+ renderer.domElement.onmousewheel = cancelScrollø1;
+ renderer.domElement.addEventListener('MozMousePixelScroll', cancelScrollø1, false);
+ refreshButtonø1.appendChild(buttonTextø1);
+ containerø1.appendChild(renderer.domElement);
+ containerø1.appendChild(settingsø1);
+ return settingsø1.appendChild(refreshButtonø1);
+ }.call(this);
+};
+var updateGeometry = exports.updateGeometry = function updateGeometry(geometry, heightmap) {
+ (function loop() {
+ var recur = loop;
+ var iø1 = 0;
+ do {
+ recur = iø1 < geometry.vertices.length ? (function () {
+ geometry.vertices[iø1].z = terrainHeight * heightmap.data[iø1];
+ return loop[0] = iø1 + 1, loop;
+ })() : void 0;
+ } while (iø1 = loop[0], recur === loop);
+ return recur;
+ }.call(this));
+ geometry.computeVertexNormals();
+ return geometry;
+};
+var makeFinal = exports.makeFinal = function makeFinal(elementId) {
+ var scene = new THREE.Scene();
+ scene.add(new THREE.AxisHelper(100));
+ var clock = new THREE.Clock();
+ var camera = makeCamera();
+ var renderer = makeRenderer();
+ var geometry = void 0;
+ var plane = void 0;
+ scene.add(makeDirectionalLight());
+ scene.add(new THREE.AmbientLight(16777215, 0.05));
+ var refresh = function refresh() {
+ return function () {
+ var heightmapø1 = makeHeightmap(6);
+ console.log('Generating terrain...');
+ (function () {
+ var G__7ø1 = new Date().getTime();
+ var G__9ø1 = (function () {
+ return midpointDisplacement(heightmapø1);
+ })();
+ var G__8ø1 = new Date().getTime();
+ console.log('Elapsed time: ' + (G__8ø1 - G__7ø1) + 'ms.');
+ return G__9ø1;
+ }.call(this));
+ console.log('Rebuilding geometry...');
+ (function () {
+ var G__10ø1 = new Date().getTime();
+ var G__12ø1 = (function () {
+ geometry = makeGeometry(heightmapø1);
+ return updateGeometry(geometry, heightmapø1);
+ })();
+ var G__11ø1 = new Date().getTime();
+ console.log('Elapsed time: ' + (G__11ø1 - G__10ø1) + 'ms.');
+ return G__12ø1;
+ }.call(this));
+ console.log('Rebuilding plane...');
+ return function () {
+ var G__13ø1 = new Date().getTime();
+ var G__15ø1 = (function () {
+ scene.remove(plane);
+ plane = makePlane(geometry);
+ return scene.add(plane);
+ })();
+ var G__14ø1 = new Date().getTime();
+ console.log('Elapsed time: ' + (G__14ø1 - G__13ø1) + 'ms.');
+ return G__15ø1;
+ }.call(this);
+ }.call(this);
+ };
+ attachToDom(renderer, elementId, refresh);
+ var controls = makeControls(camera, renderer);
+ var render = function render() {
+ return function () {
+ var deltaø1 = clock.getDelta();
+ requestAnimationFrame(render);
+ controls.update(deltaø1);
+ return renderer.render(scene, camera);
+ }.call(this);
+ };
+ refresh();
+ render();
+ return void 0;
+};
+var run = exports.run = function run() {
+ return makeFinal('demo-final');
+};
+$(run);
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFub255bW91cy53aXNwIl0sIm5hbWVzIjpbIl9uc18iLCJpZCIsImRvYyIsIndpZHRoIiwiZXhwb3J0cyIsImhlaWdodCIsIndpcmVmcmFtZSIsIndpcmVmcmFtZVdpZHRoIiwidGVycmFpbkhlaWdodCIsInRlcnJhaW5TaXplIiwiaW5jIiwieCIsImRlYyIsIm1pZHBvaW50IiwiYSIsImIiLCJhdmVyYWdlMiIsImF2ZXJhZ2U0IiwiYyIsImQiLCJzYWZlQXZlcmFnZSIsInRvdGFsw7gxIiwiY291bnTDuDEiLCJyYW5kIiwiTWF0aCIsInJhbmRvbSIsInJhbmRBcm91bmRaZXJvIiwic3ByZWFkIiwiaml0dGVyIiwidmFsdWUiLCJoZWlnaHRtYXBSZXNvbHV0aW9uIiwiaGVpZ2h0bWFwIiwic2hhcGUiLCJoZWlnaHRtYXBMYXN0SW5kZXgiLCJoZWlnaHRtYXBDZW50ZXJJbmRleCIsImhlaWdodG1hcEdldCIsInkiLCJnZXQiLCJoZWlnaHRtYXBHZXRTYWZlIiwibGFzdMO4MSIsImhlaWdodG1hcFNldCIsInZhbCIsInNldCIsImhlaWdodG1hcFNldElmVW5zZXQiLCJub3JtYWxpemUiLCJtYXjDuDEiLCJJbmZpbml0eSIsIm1pbsO4MSIsImVsw7gxIiwic3BhbsO4MSIsInjDuDEiLCJ5w7gxIiwibWFrZUhlaWdodG1hcCIsImV4cG9uZW50IiwicmVzb2x1dGlvbsO4MSIsInBvdyIsImhlaWdodG1hcMO4MSIsIm5kYXJyYXkiLCJGbG9hdDY0QXJyYXkiLCJyZXNvbHV0aW9uIiwibGFzdCIsInRvcExlZnRDb3JuZXIiLCJjZW50ZXLDuDEiLCJsbyIsImhpIiwidG9wUmlnaHRDb3JuZXIiLCJib3R0b21MZWZ0Q29ybmVyIiwiYm90dG9tUmlnaHRDb3JuZXIiLCJtcGRJbml0Q29ybmVycyIsIm1wZERpc3BsYWNlIiwic3ByZWFkUmVkdWN0aW9uIiwiY8O4MSIsImJvdHRvbUxlZnTDuDEiLCJib3R0b21SaWdodMO4MSIsInRvcExlZnTDuDEiLCJ0b3BSaWdodMO4MSIsInRvcMO4MSIsImxlZnTDuDEiLCJib3R0b23DuDEiLCJyaWdodMO4MSIsIm5leHRTcHJlYWTDuDEiLCJtaWRwb2ludERpc3BsYWNlbWVudCIsImluaXRpYWxTcHJlYWTDuDEiLCJzcHJlYWRSZWR1Y3Rpb27DuDEiLCJtYWtlRGlyZWN0aW9uYWxMaWdodCIsImxpZ2h0w7gxIiwiVEhSRUUiLCJEaXJlY3Rpb25hbExpZ2h0IiwicG9zaXRpb24uc2V0IiwibWFrZUNhbWVyYSIsImNhbWVyYcO4MSIsIlBlcnNwZWN0aXZlQ2FtZXJhIiwibWFrZVJlbmRlcmVyIiwicmVuZGVyZXLDuDEiLCJXZWJHTFJlbmRlcmVyIiwic2V0Q2xlYXJDb2xvciIsInNldFNpemUiLCJzZXRQaXhlbFJhdGlvIiwibWFrZUdlb21ldHJ5IiwiZ2VvbWV0cnnDuDEiLCJQbGFuZUdlb21ldHJ5IiwibWFrZUNvbnRyb2xzIiwiY2FtZXJhIiwicmVuZGVyZXIiLCJjb250cm9sc8O4MSIsIlRyYWNrYmFsbENvbnRyb2xzIiwiZG9tRWxlbWVudCIsInJvdGF0ZVNwZWVkIiwiem9vbVNwZWVkIiwic3RhdGljTW92aW5nIiwiZHluYW1pY0RhbXBpbmdGYWN0b3IiLCJtYWtlUGxhbmUiLCJnZW9tZXRyeSIsIm1hdGVyaWFsw7gxIiwiTWVzaExhbWJlcnRNYXRlcmlhbCIsIk1lc2giLCJhdHRhY2hUb0RvbSIsImVsTmFtZSIsInJlZnJlc2hGbiIsImNvbnRhaW5lcsO4MSIsImRvY3VtZW50IiwiZ2V0RWxlbWVudEJ5SWQiLCJzZXR0aW5nc8O4MSIsImNyZWF0ZUVsZW1lbnQiLCJyZWZyZXNoQnV0dG9uw7gxIiwiYnV0dG9uVGV4dMO4MSIsImNyZWF0ZVRleHROb2RlIiwiY2FuY2VsU2Nyb2xsw7gxIiwiZSIsInByZXZlbnREZWZhdWx0Iiwib25jbGljayIsImRvbUVsZW1lbnQub25tb3VzZXdoZWVsIiwiZG9tRWxlbWVudC5hZGRFdmVudExpc3RlbmVyIiwiYXBwZW5kQ2hpbGQiLCJ1cGRhdGVHZW9tZXRyeSIsImnDuDEiLCJ2ZXJ0aWNlcy5sZW5ndGgiLCJ2ZXJ0aWNlcyIsInoiLCJkYXRhIiwiY29tcHV0ZVZlcnRleE5vcm1hbHMiLCJtYWtlRmluYWwiLCJlbGVtZW50SWQiLCJzY2VuZSIsIlNjZW5lIiwiYWRkIiwiQXhpc0hlbHBlciIsImNsb2NrIiwiQ2xvY2siLCJwbGFuZSIsIkFtYmllbnRMaWdodCIsInJlZnJlc2giLCJyZW1vdmUiLCJjb250cm9scyIsInJlbmRlciIsImRlbHRhw7gxIiwiZ2V0RGVsdGEiLCJyZXF1ZXN0QW5pbWF0aW9uRnJhbWUiLCJ1cGRhdGUiLCJydW4iLCIkIl0sIm1hcHBpbmdzIjoiO0lBQUEsSUFBQ0EsSSxHQUFEO0FBQUEsUUFBQUMsRSxFQUFJLE1BQUo7QUFBQSxRQUFBQyxHLEVBQUEsSyxDQUFBO0FBQUEsTTs7O0FBSUEsSUFBS0MsS0FBQSxHQUFBQyxPQUFBLENBQUFELEtBQUEsR0FBTSxHQUFYLEM7QUFDQSxJQUFLRSxNQUFBLEdBQUFELE9BQUEsQ0FBQUMsTUFBQSxHQUFPLEdBQVosQztBQUNBLElBQUtDLFNBQUEsR0FBQUYsT0FBQSxDQUFBRSxTQUFBLEcsSUFBTCxDO0FBQ0EsSUFBS0MsY0FBQSxHQUFBSCxPQUFBLENBQUFHLGNBQUEsR0FBZ0IsR0FBckIsQztBQUNBLElBQUtDLGFBQUEsR0FBQUosT0FBQSxDQUFBSSxhQUFBLEdBQWUsRUFBcEIsQztBQUNBLElBQUtDLFdBQUEsR0FBQUwsT0FBQSxDQUFBSyxXQUFBLEdBQWEsR0FBbEIsQzs7OztBQW9CQSxJQUFNQyxHQUFBLEdBQUFOLE9BQUEsQ0FBQU0sR0FBQSxHQUFOLFNBQU1BLEdBQU4sQ0FBV0MsQ0FBWCxFQUNFO0FBQUEsV0FBR0EsQ0FBSCxHQUFLLENBQUw7QUFBQSxDQURGLEM7QUFHQSxJQUFNQyxHQUFBLEdBQUFSLE9BQUEsQ0FBQVEsR0FBQSxHQUFOLFNBQU1BLEdBQU4sQ0FBV0QsQ0FBWCxFQUNFO0FBQUEsV0FBR0EsQ0FBSCxHQUFLLENBQUw7QUFBQSxDQURGLEM7Ozs7Ozs7OztBQXdFQSxJQUFNRSxRQUFBLEdBQUFULE9B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O0FBQUEsUyxLQUFOLEMsSUFBQTtBQUFBLEtBREYsQztJQU1DaUQsT0FBRCxHO0lBQ0NHLE1BQUQsRzs7Q0F4Q0YsQztBQTRDQSxJQUFNSyxHQUFBLEdBQUEzSixPQUFBLENBQUEySixHQUFBLEdBQU4sU0FBTUEsR0FBTixHQUNFO0FBQUEsV0FBQ2xCLFNBQUQsQ0FBWSxZQUFaO0FBQUEsQ0FERixDO0FBR0NtQixDQUFELENBQUdELEdBQUgiLCJzb3VyY2VzQ29udGVudCI6WyIobnMgZGVtb1xuICAoOnJlcXVpcmUgW25kYXJyYXldKSlcblxuOyBDb25zdGFudHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuKGRlZiB3aWR0aCA2MTApXG4oZGVmIGhlaWdodCA0MDApXG4oZGVmIHdpcmVmcmFtZSB0cnVlKVxuKGRlZiB3aXJlZnJhbWUtd2lkdGggMS4yKVxuKGRlZiB0ZXJyYWluLWhlaWdodCA1MClcbihkZWYgdGVycmFpbi1zaXplIDEwMClcblxuOyBHZW5lcmFsIFV0aWxpdGllcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuKGRlZm1hY3JvIHdoZW4gW2NvbmRpdGlvbiAmIGJvZHldXG4gIGAoaWYgfmNvbmRpdGlvblxuICAgICAoZG8gfkBib2R5KSkpXG5cbihkZWZtYWNybyB3aGVuLW5vdCBbY29uZGl0aW9uICYgYm9keV1cbiAgYCh3aGVuIChub3QgfmNvbmRpdGlvbilcbiAgICAgfkBib2R5KSlcblxuKGRlZm1hY3JvIC0+IFsmIG9wZXJhdGlvbnNdXG4gIChyZWR1Y2VcbiAgICAoZm4gW2Zvcm0gb3BlcmF0aW9uXVxuICAgICAgKGNvbnMgKGZpcnN0IG9wZXJhdGlvbilcbiAgICAgICAgICAgIChjb25zIGZvcm0gKHJlc3Qgb3BlcmF0aW9uKSkpKVxuICAgIChmaXJzdCBvcGVyYXRpb25zKVxuICAgIChyZXN0IG9wZXJhdGlvbnMpKSlcblxuXG4oZGVmbiBpbmMgW3hdXG4gICgrIHggMSkpXG5cbihkZWZuIGRlYyBbeF1cbiAgKC0geCAxKSlcblxuXG4oZGVmbWFjcm8gZG8tdGltZXMgW3Zhcm5hbWUgbGltaXQgJiBib2R5XVxuICAobGV0IFtlbmQgKGdlbnN5bSldXG4gICAgYChsZXQgW35lbmQgfmxpbWl0XVxuICAgICAgIChsb29wIFt+dmFybmFtZSAwXVxuICAgICAgICAgKHdoZW4gKDwgfnZhcm5hbWUgfmVuZClcbiAgICAgICAgICAgfkBib2R5XG4gICAgICAgICAgIChyZWN1ciAoaW5jIH52YXJuYW1lKSkpKSkpKVxuXG4oZGVmbWFjcm8gZG8tc3RyaWRlIFt2YXJuYW1lcyBzdGFydC1mb3JtIGVuZC1mb3JtIHN0cmlkZS1mb3JtICYgYm9keV1cbiAgKGxldCBbc3RyaWRlIChnZW5zeW0gXCJzdHJpZGVcIilcbiAgICAgICAgc3RhcnQgKGdlbnN5bSBcInN0YXJ0XCIpXG4gICAgICAgIGVuZCAoZ2Vuc3ltIFwiZW5kXCIpXG4gICAgICAgIGJ1aWxkIChmbiBidWlsZCBbdmFyc11cbiAgICAgICAgICAgICAgICAoaWYgKGVtcHR5PyB2YXJzKVxuICAgICAgICAgICAgICAgICAgYChkbyB+QGJvZHkpXG4gICAgICAgICAgICAgICAgICAobGV0IFt2YXJuYW1lIChmaXJzdCB2YXJzKV1cbiAgICAgICAgICAgICAgICAgICAgYChsb29wIFt+dmFybmFtZSB+c3RhcnRdXG4gICAgICAgICAgICAgICAgICAgICAgICh3aGVuICg8IH52YXJuYW1lIH5lbmQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgfihidWlsZCAocmVzdCB2YXJzKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAocmVjdXIgKCsgfnZhcm5hbWUgfnN0cmlkZSkpKSkpKSldXG4gICAgOyBGaXggdGhlIG51bWJlcnMgb25jZSBvdXRzaWRlIHRoZSBuZXN0ZWQgbG9vcHMsXG4gICAgOyBhbmQgdGhlbiBidWlsZCB0aGUgZ3V0cy5cbiAgICBgKGxldCBbfnN0YXJ0IH5zdGFydC1mb3JtXG4gICAgICAgICAgIH5lbmQgfmVuZC1mb3JtXG4gICAgICAgICAgIH5zdHJpZGUgfnN0cmlkZS1mb3JtXVxuICAgICAgIH4oYnVpbGQgdmFybmFtZXMpKSkpXG5cblxuKGRlZm1hY3JvIGRvLW5kYXJyYXkgW3ZhcnMgYXJyYXktZm9ybSAmIGJvZHldXG4gIChsZXQgW2FycmF5LXZhciAoZ2Vuc3ltIFwiYXJyYXlcIilcbiAgICAgICAgYnVpbGQgKGZuIGJ1aWxkIFt2YXJzIG5dXG4gICAgICAgICAgICAgICAgKGlmIChlbXB0eT8gdmFycylcbiAgICAgICAgICAgICAgICAgIGAoZG8gfkBib2R5KVxuICAgICAgICAgICAgICAgICAgYChkby10aW1lcyB+KGZpcnN0IHZhcnMpIChhZ2V0ICguLXNoYXBlIH5hcnJheS12YXIpIH5uKVxuICAgICAgICAgICAgICAgICAgICAgfihidWlsZCAocmVzdCB2YXJzKSAoaW5jIG4pKSkpKV1cbiAgICBgKGxldCBbfmFycmF5LXZhciB+YXJyYXktZm9ybV1cbiAgICAgICB+KGJ1aWxkIHZhcnMgMCkpKSlcblxuKGRlZm1hY3JvIGRvLW5kYXJyYXktZWwgW2VsZW1lbnQgYXJyYXktZm9ybSAmIGJvZHldXG4gIChsZXQgW2luZGV4IChnZW5zeW0gXCJpbmRleFwiKVxuICAgICAgICBhcnJheSAoZ2Vuc3ltIFwiYXJyYXlcIildXG4gICAgYChsZXQgW35hcnJheSB+YXJyYXktZm9ybV1cbiAgICAgICAoZG8tdGltZXMgfmluZGV4ICguLWxlbmd0aCAoLi1kYXRhIH5hcnJheSkpXG4gICAgICAgICAobGV0IFt+ZWxlbWVudCAoYWdldCAoLi1kYXRhIH5hcnJheSkgfmluZGV4KV1cbiAgICAgICAgICAgfkBib2R5KSkpKSlcblxuXG4oZGVmbWFjcm8gaW5jISBbcGxhY2VdXG4gIGAoc2V0ISB+cGxhY2UgKGluYyB+cGxhY2UpKSlcblxuKGRlZm1hY3JvIGFkZCEgW3BsYWNlIGFtb3VudF1cbiAgYChzZXQhIH5wbGFjZSAoKyB+cGxhY2UgfmFtb3VudCkpKVxuXG5cbihkZWZtYWNybyBsIFsmIGZvcm1zXVxuICBgKGNvbnNvbGUubG9nIH5AZm9ybXMpKVxuXG4oZGVmbWFjcm8gdGltZSBbJiBib2R5XVxuICAobGV0IFtzdGFydCAoZ2Vuc3ltKVxuICAgICAgICBlbmQgKGdlbnN5bSlcbiAgICAgICAgcmVzdWx0IChnZW5zeW0pXVxuICAgIGAobGV0IFt+c3RhcnQgKC5nZXRUaW1lIChuZXcgRGF0ZSkpXG4gICAgICAgICAgIH5yZXN1bHQgKGRvIH5AYm9keSlcbiAgICAgICAgICAgfmVuZCAoLmdldFRpbWUgKG5ldyBEYXRlKSldXG4gICAgICAgKGwgKCsgXCJFbGFwc2VkIHRpbWU6IFwiICgtIH5lbmQgfnN0YXJ0KSBcIm1zLlwiKSlcbiAgICAgICB+cmVzdWx0KSkpXG5cblxuKGRlZm4gbWlkcG9pbnQgW2EgYl1cbiAgKC8gKCsgYSBiKSAyKSlcblxuKGRlZm4gYXZlcmFnZTIgW2EgYl1cbiAgKC8gKCsgYSBiKSAyKSlcblxuKGRlZm4gYXZlcmFnZTQgW2EgYiBjIGRdXG4gICgvICgrIGEgYiBjIGQpIDQpKVxuXG4oZGVmbiBzYWZlLWF2ZXJhZ2UgW2EgYiBjIGRdXG4gIChsZXQgW3RvdGFsIDAgY291bnQgMF1cbiAgICAod2hlbiBhIChhZGQhIHRvdGFsIGEpIChpbmMhIGNvdW50KSlcbiAgICAod2hlbiBiIChhZGQhIHRvdGFsIGIpIChpbmMhIGNvdW50KSlcbiAgICAod2hlbiBjIChhZGQhIHRvdGFsIGMpIChpbmMhIGNvdW50KSlcbiAgICAod2hlbiBkIChhZGQhIHRvdGFsIGQpIChpbmMhIGNvdW50KSlcbiAgICAoLyB0b3RhbCBjb3VudCkpKVxuXG5cbjsgUmFuZG9tbmVzcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbihkZWZuIHJhbmQgW11cbiAgKE1hdGgucmFuZG9tKSlcblxuKGRlZm4gcmFuZC1hcm91bmQtemVybyBbc3ByZWFkXVxuICAoLSAoKiBzcHJlYWQgKHJhbmQpIDIpIHNwcmVhZCkpXG5cbihkZWZuIGppdHRlciBbdmFsdWUgc3ByZWFkXVxuICAoKyB2YWx1ZSAocmFuZC1hcm91bmQtemVybyBzcHJlYWQpKSlcblxuXG47IEhlaWdodG1hcCBIZWxwZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4oZGVmbiBoZWlnaHRtYXAtcmVzb2x1dGlvbiBbaGVpZ2h0bWFwXVxuICAoYWdldCBoZWlnaHRtYXAuc2hhcGUgMCkpXG5cbihkZWZuIGhlaWdodG1hcC1sYXN0LWluZGV4IFtoZWlnaHRtYXBdXG4gIChkZWMgKGhlaWdodG1hcC1yZXNvbHV0aW9uIGhlaWdodG1hcCkpKVxuXG4oZGVmbiBoZWlnaHRtYXAtY2VudGVyLWluZGV4IFtoZWlnaHRtYXBdXG4gIChtaWRwb2ludCAwIChoZWlnaHRtYXAtbGFzdC1pbmRleCBoZWlnaHRtYXApKSlcblxuXG4oZGVmbiBoZWlnaHRtYXAtZ2V0IFtoZWlnaHRtYXAgeCB5XVxuICAoLmdldCBoZWlnaHRtYXAgeCB5KSlcblxuKGRlZm4gaGVpZ2h0bWFwLWdldC1zYWZlIFtoZWlnaHRtYXAgeCB5XVxuICAobGV0IFtsYXN0IChoZWlnaHRtYXAtbGFzdC1pbmRleCBoZWlnaHRtYXApXVxuICAgICh3aGVuIChhbmQgKDw9IDAgeCBsYXN0KVxuICAgICAgICAgICAgICAgKDw9IDAgeSBsYXN0KSlcbiAgICAgIChoZWlnaHRtYXAtZ2V0IGhlaWdodG1hcCB4IHkpKSkpXG5cbihkZWZuIGhlaWdodG1hcC1zZXQhIFtoZWlnaHRtYXAgeCB5IHZhbF1cbiAgKC5zZXQgaGVpZ2h0bWFwIHggeSB2YWwpKVxuXG4oZGVmbiBoZWlnaHRtYXAtc2V0LWlmLXVuc2V0ISBbaGVpZ2h0bWFwIHggeSB2YWxdXG4gICh3aGVuICg9PSAwIChoZWlnaHRtYXAtZ2V0IGhlaWdodG1hcCB4IHkpKVxuICAgIChoZWlnaHRtYXAtc2V0ISBoZWlnaHRtYXAgeCB5IHZhbCkpKVxuXG5cbihkZWZuIG5vcm1hbGl6ZSBbaGVpZ2h0bWFwXVxuICAobGV0IFttYXggKC0gSW5maW5pdHkpXG4gICAgICAgIG1pbiBJbmZpbml0eV1cbiAgICAoZG8tbmRhcnJheS1lbCBlbCBoZWlnaHRtYXBcbiAgICAgICh3aGVuICg8IG1heCBlbCkgKHNldCEgbWF4IGVsKSlcbiAgICAgICh3aGVuICg+IG1pbiBlbCkgKHNldCEgbWluIGVsKSkpXG4gICAgKGxldCBbc3BhbiAoLSBtYXggbWluKV1cbiAgICAgIChkby1uZGFycmF5IFt4IHldIGhlaWdodG1hcFxuICAgICAgICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIHggeVxuICAgICAgICAgICAgICAgICAgICAgICAgKC8gKC0gKGhlaWdodG1hcC1nZXQgaGVpZ2h0bWFwIHggeSkgbWluKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BhbikpKSkpKVxuXG5cbihkZWZuIG1ha2UtaGVpZ2h0bWFwIFtleHBvbmVudF1cbiAgKGxldCBbcmVzb2x1dGlvbiAoKyAoTWF0aC5wb3cgMiBleHBvbmVudCkgMSldXG4gICAgKGxldCBbaGVpZ2h0bWFwIChuZGFycmF5IChuZXcgRmxvYXQ2NEFycmF5ICgqIHJlc29sdXRpb24gcmVzb2x1dGlvbikpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyZXNvbHV0aW9uIHJlc29sdXRpb25dKV1cbiAgICAgIChzZXQhIGhlaWdodG1hcC5leHBvbmVudCBleHBvbmVudClcbiAgICAgIChzZXQhIGhlaWdodG1hcC5yZXNvbHV0aW9uIHJlc29sdXRpb24pXG4gICAgICAoc2V0ISBoZWlnaHRtYXAubGFzdCAoZGVjIHJlc29sdXRpb24pKVxuICAgICAgaGVpZ2h0bWFwKSkpXG5cblxuKGRlZm4gdG9wLWxlZnQtY29ybmVyIFtoZWlnaHRtYXBdXG4gIChsZXQgW2NlbnRlciAoaGVpZ2h0bWFwLWNlbnRlci1pbmRleCBoZWlnaHRtYXApXVxuICAgICgtPiBoZWlnaHRtYXBcbiAgICAgICgubG8gMCAwKVxuICAgICAgKC5oaSAoaW5jIGNlbnRlcikgKGluYyBjZW50ZXIpKSkpKVxuXG4oZGVmbiB0b3AtcmlnaHQtY29ybmVyIFtoZWlnaHRtYXBdXG4gIChsZXQgW2NlbnRlciAoaGVpZ2h0bWFwLWNlbnRlci1pbmRleCBoZWlnaHRtYXApXVxuICAgICgtPiBoZWlnaHRtYXBcbiAgICAgICgubG8gY2VudGVyIDApXG4gICAgICAoLmhpIChpbmMgY2VudGVyKSAoaW5jIGNlbnRlcikpKSkpXG5cbihkZWZuIGJvdHRvbS1sZWZ0LWNvcm5lciBbaGVpZ2h0bWFwXVxuICAobGV0IFtjZW50ZXIgKGhlaWdodG1hcC1jZW50ZXItaW5kZXggaGVpZ2h0bWFwKV1cbiAgICAoLT4gaGVpZ2h0bWFwXG4gICAgICAoLmxvIDAgY2VudGVyKVxuICAgICAgKC5oaSAoaW5jIGNlbnRlcikgKGluYyBjZW50ZXIpKSkpKVxuXG4oZGVmbiBib3R0b20tcmlnaHQtY29ybmVyIFtoZWlnaHRtYXBdXG4gIChsZXQgW2NlbnRlciAoaGVpZ2h0bWFwLWNlbnRlci1pbmRleCBoZWlnaHRtYXApXVxuICAgICgtPiBoZWlnaHRtYXBcbiAgICAgICgubG8gY2VudGVyIGNlbnRlcilcbiAgICAgICguaGkgKGluYyBjZW50ZXIpIChpbmMgY2VudGVyKSkpKSlcblxuXG47IE1pZHBvaW50IERpc3BsYWNlbWVudCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4oZGVmbiBtcGQtaW5pdC1jb3JuZXJzIFtoZWlnaHRtYXBdXG4gIChsZXQgW2xhc3QgKGhlaWdodG1hcC1sYXN0LWluZGV4IGhlaWdodG1hcCldXG4gICAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCAwICAgIDAgICAgKHJhbmQpKVxuICAgIChoZWlnaHRtYXAtc2V0ISBoZWlnaHRtYXAgMCAgICBsYXN0IChyYW5kKSlcbiAgICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIGxhc3QgMCAgICAocmFuZCkpXG4gICAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCBsYXN0IGxhc3QgKHJhbmQpKSkpXG5cbihkZWZuIG1wZC1kaXNwbGFjZSBbaGVpZ2h0bWFwIHNwcmVhZCBzcHJlYWQtcmVkdWN0aW9uXVxuICAobGV0IFtsYXN0IChoZWlnaHRtYXAtbGFzdC1pbmRleCBoZWlnaHRtYXApXG4gICAgICAgIGMgKG1pZHBvaW50IDAgbGFzdClcblxuICAgICAgICBib3R0b20tbGVmdCAgKGhlaWdodG1hcC1nZXQgaGVpZ2h0bWFwIDAgICAgMClcbiAgICAgICAgYm90dG9tLXJpZ2h0IChoZWlnaHRtYXAtZ2V0IGhlaWdodG1hcCBsYXN0IDApXG4gICAgICAgIHRvcC1sZWZ0ICAgICAoaGVpZ2h0bWFwLWdldCBoZWlnaHRtYXAgMCAgICBsYXN0KVxuICAgICAgICB0b3AtcmlnaHQgICAgKGhlaWdodG1hcC1nZXQgaGVpZ2h0bWFwIGxhc3QgbGFzdClcblxuICAgICAgICB0b3AgICAgKGF2ZXJhZ2UyIHRvcC1sZWZ0IHRvcC1yaWdodClcbiAgICAgICAgbGVmdCAgIChhdmVyYWdlMiBib3R0b20tbGVmdCB0b3AtbGVmdClcbiAgICAgICAgYm90dG9tIChhdmVyYWdlMiBib3R0b20tbGVmdCBib3R0b20tcmlnaHQpXG4gICAgICAgIHJpZ2h0ICAoYXZlcmFnZTIgYm90dG9tLXJpZ2h0IHRvcC1yaWdodClcbiAgICAgICAgY2VudGVyIChhdmVyYWdlNCB0b3AgbGVmdCBib3R0b20gcmlnaHQpXG5cbiAgICAgICAgbmV4dC1zcHJlYWQgKCogc3ByZWFkIHNwcmVhZC1yZWR1Y3Rpb24pXVxuICAgIChoZWlnaHRtYXAtc2V0LWlmLXVuc2V0ISBoZWlnaHRtYXAgYyAgICAwICAgIChqaXR0ZXIgYm90dG9tIHNwcmVhZCkpXG4gICAgKGhlaWdodG1hcC1zZXQtaWYtdW5zZXQhIGhlaWdodG1hcCBjICAgIGxhc3QgKGppdHRlciB0b3Agc3ByZWFkKSlcbiAgICAoaGVpZ2h0bWFwLXNldC1pZi11bnNldCEgaGVpZ2h0bWFwIDAgICAgYyAgICAoaml0dGVyIGxlZnQgc3ByZWFkKSlcbiAgICAoaGVpZ2h0bWFwLXNldC1pZi11bnNldCEgaGVpZ2h0bWFwIGxhc3QgYyAgICAoaml0dGVyIHJpZ2h0IHNwcmVhZCkpXG4gICAgKGhlaWdodG1hcC1zZXQtaWYtdW5zZXQhIGhlaWdodG1hcCBjICAgIGMgICAgKGppdHRlciBjZW50ZXIgc3ByZWFkKSlcbiAgICAod2hlbi1ub3QgKD09IDMgKGhlaWdodG1hcC1yZXNvbHV0aW9uIGhlaWdodG1hcCkpXG4gICAgICAobXBkLWRpc3BsYWNlICh0b3AtbGVmdC1jb3JuZXIgaGVpZ2h0bWFwKSBuZXh0LXNwcmVhZCBzcHJlYWQtcmVkdWN0aW9uKVxuICAgICAgKG1wZC1kaXNwbGFjZSAodG9wLXJpZ2h0LWNvcm5lciBoZWlnaHRtYXApIG5leHQtc3ByZWFkIHNwcmVhZC1yZWR1Y3Rpb24pXG4gICAgICAobXBkLWRpc3BsYWNlIChib3R0b20tbGVmdC1jb3JuZXIgaGVpZ2h0bWFwKSBuZXh0LXNwcmVhZCBzcHJlYWQtcmVkdWN0aW9uKVxuICAgICAgKG1wZC1kaXNwbGFjZSAoYm90dG9tLXJpZ2h0LWNvcm5lciBoZWlnaHRtYXApIG5leHQtc3ByZWFkIHNwcmVhZC1yZWR1Y3Rpb24pKSkpXG5cbihkZWZuIG1pZHBvaW50LWRpc3BsYWNlbWVudCBbaGVpZ2h0bWFwXVxuICAobGV0IFtpbml0aWFsLXNwcmVhZCAwLjMgXG4gICAgICAgIHNwcmVhZC1yZWR1Y3Rpb24gMC41NV1cbiAgICAobXBkLWluaXQtY29ybmVycyBoZWlnaHRtYXApXG4gICAgKG1wZC1kaXNwbGFjZSBoZWlnaHRtYXAgaW5pdGlhbC1zcHJlYWQgc3ByZWFkLXJlZHVjdGlvbilcbiAgICAobm9ybWFsaXplIGhlaWdodG1hcCkpKVxuXG5cbjsgVGhyZWUuanMgSGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbihkZWZuIG1ha2UtZGlyZWN0aW9uYWwtbGlnaHQgW11cbiAgKGxldCBbbGlnaHQgKG5ldyBUSFJFRS5EaXJlY3Rpb25hbExpZ2h0IDB4ZmZmZmZmIDEpXVxuICAgIChsaWdodC5wb3NpdGlvbi5zZXQgMTAwIDAgMTUwKVxuICAgIGxpZ2h0KSlcblxuKGRlZm4gbWFrZS1jYW1lcmEgW11cbiAgKGxldCBbY2FtZXJhIChuZXcgVEhSRUUuUGVyc3BlY3RpdmVDYW1lcmFcbiAgICAgICAgICAgICAgICAgICAgNTUsXG4gICAgICAgICAgICAgICAgICAgICgvIHdpZHRoIGhlaWdodClcbiAgICAgICAgICAgICAgICAgICAgMC4xLFxuICAgICAgICAgICAgICAgICAgICAxMDAwKV1cbiAgICAoY2FtZXJhLnBvc2l0aW9uLnNldCAwIC0xMDAgMTUwKVxuICAgIGNhbWVyYSkpXG5cbihkZWZuIG1ha2UtcmVuZGVyZXIgW11cbiAgKGxldCBbcmVuZGVyZXIgKG5ldyBUSFJFRS5XZWJHTFJlbmRlcmVyIHs6YW50aWFsaWFzIGZhbHNlfSldXG4gICAgKHJlbmRlcmVyLnNldENsZWFyQ29sb3IgMHhmZmZmZmYpXG4gICAgKHJlbmRlcmVyLnNldFNpemUgd2lkdGggaGVpZ2h0KVxuICAgIChyZW5kZXJlci5zZXRQaXhlbFJhdGlvIDIpXG4gICAgcmVuZGVyZXIpKVxuXG4oZGVmbiBtYWtlLWdlb21ldHJ5IFtoZWlnaHRtYXBdXG4gIChsZXQgW3Jlc29sdXRpb24gKGFnZXQgaGVpZ2h0bWFwLnNoYXBlIDApXG4gICAgICAgIGdlb21ldHJ5IChuZXcgVEhSRUUuUGxhbmVHZW9tZXRyeVxuICAgICAgICAgICAgICAgICAgICAgIHRlcnJhaW4tc2l6ZVxuICAgICAgICAgICAgICAgICAgICAgIHRlcnJhaW4tc2l6ZVxuICAgICAgICAgICAgICAgICAgICAgICgtIHJlc29sdXRpb24gMSlcbiAgICAgICAgICAgICAgICAgICAgICAoLSByZXNvbHV0aW9uIDEpKV1cbiAgICBnZW9tZXRyeSkpXG5cbihkZWZuIG1ha2UtY29udHJvbHMgW2NhbWVyYSByZW5kZXJlcl1cbiAgKGxldCBbY29udHJvbHMgKG5ldyBUSFJFRS5UcmFja2JhbGxDb250cm9scyBjYW1lcmEgcmVuZGVyZXIuZG9tRWxlbWVudCldXG4gICAgKHNldCEgY29udHJvbHMucm90YXRlU3BlZWQgMS40KVxuICAgIChzZXQhIGNvbnRyb2xzLnpvb21TcGVlZCAwLjUpXG4gICAgKHNldCEgY29udHJvbHMuc3RhdGljTW92aW5nIHRydWUpXG4gICAgKHNldCEgY29udHJvbHMuZHluYW1pY0RhbXBpbmdGYWN0b3IgMC4zKVxuICAgIGNvbnRyb2xzKSlcblxuKGRlZm4gbWFrZS1wbGFuZSBbZ2VvbWV0cnldXG4gIChsZXQgW21hdGVyaWFsIChuZXcgVEhSRUUuTWVzaExhbWJlcnRNYXRlcmlhbFxuICAgICAgICAgICAgICAgICAgICAgIHs6d2lyZWZyYW1lIHdpcmVmcmFtZVxuICAgICAgICAgICAgICAgICAgICAgICA6d2lyZWZyYW1lTGluZXdpZHRoIHdpcmVmcmFtZS13aWR0aFxuICAgICAgICAgICAgICAgICAgICAgICA6Y29sb3IgMHgwMGJiMDB9KV1cbiAgICAobmV3IFRIUkVFLk1lc2ggZ2VvbWV0cnkgbWF0ZXJpYWwpKSlcblxuXG4oZGVmbiBhdHRhY2gtdG8tZG9tIFtyZW5kZXJlciBlbC1uYW1lIHJlZnJlc2gtZm5dXG4gIChsZXQgW2NvbnRhaW5lciAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQgZWwtbmFtZSlcbiAgICAgICAgc2V0dGluZ3MgKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgXCJkaXZcIilcbiAgICAgICAgcmVmcmVzaC1idXR0b24gKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgXCJidXR0b25cIilcbiAgICAgICAgYnV0dG9uLXRleHQgKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlIFwiUmVmcmVzaFwiKVxuICAgICAgICBjYW5jZWwtc2Nyb2xsIChmbiBbZV0gKC5wcmV2ZW50RGVmYXVsdCBlKSldXG4gICAgKHNldCEgcmVmcmVzaC1idXR0b24ub25jbGljayByZWZyZXNoLWZuKVxuICAgIChzZXQhIHJlbmRlcmVyLmRvbUVsZW1lbnQub25tb3VzZXdoZWVsIGNhbmNlbC1zY3JvbGwpXG4gICAgKHJlbmRlcmVyLmRvbUVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lciBcIk1vek1vdXNlUGl4ZWxTY3JvbGxcIiBjYW5jZWwtc2Nyb2xsIGZhbHNlKVxuICAgICguYXBwZW5kQ2hpbGQgcmVmcmVzaC1idXR0b24gYnV0dG9uLXRleHQpXG4gICAgKC5hcHBlbmRDaGlsZCBjb250YWluZXIgcmVuZGVyZXIuZG9tRWxlbWVudClcbiAgICAoLmFwcGVuZENoaWxkIGNvbnRhaW5lciBzZXR0aW5ncylcbiAgICAoLmFwcGVuZENoaWxkIHNldHRpbmdzIHJlZnJlc2gtYnV0dG9uKSkpXG5cblxuKGRlZm4gdXBkYXRlLWdlb21ldHJ5IFtnZW9tZXRyeSBoZWlnaHRtYXBdXG4gIChsb29wIFtpIDBdXG4gICAgKGlmICg8IGkgZ2VvbWV0cnkudmVydGljZXMubGVuZ3RoKVxuICAgICAgKGRvIChzZXQhICguLXogKGFnZXQgZ2VvbWV0cnkudmVydGljZXMgaSkpXG4gICAgICAgICAgICAgICAgKCogdGVycmFpbi1oZWlnaHQgKGFnZXQgKC4tZGF0YSBoZWlnaHRtYXApIGkpKSlcbiAgICAgICAgKHJlY3VyICgrIGkgMSkpKSkpXG4gIChnZW9tZXRyeS5jb21wdXRlVmVydGV4Tm9ybWFscylcbiAgZ2VvbWV0cnkpXG5cblxuOyBNYWluIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuKGRlZm4gbWFrZS1maW5hbCBbZWxlbWVudC1pZF1cbiAgKGRlZiBzY2VuZSAobmV3IFRIUkVFLlNjZW5lKSlcbiAgKHNjZW5lLmFkZCAobmV3IFRIUkVFLkF4aXNIZWxwZXIgMTAwKSlcblxuICAoZGVmIGNsb2NrIChuZXcgVEhSRUUuQ2xvY2spKVxuICAoZGVmIGNhbWVyYSAobWFrZS1jYW1lcmEpKVxuICAoZGVmIHJlbmRlcmVyIChtYWtlLXJlbmRlcmVyKSlcblxuICAoZGVmIGdlb21ldHJ5KVxuICAoZGVmIHBsYW5lKVxuXG4gIChzY2VuZS5hZGQgKG1ha2UtZGlyZWN0aW9uYWwtbGlnaHQpKVxuICAoc2NlbmUuYWRkIChuZXcgVEhSRUUuQW1iaWVudExpZ2h0IDB4ZmZmZmZmIDAuMDUpKVxuXG4gIChkZWZuIHJlZnJlc2ggW11cbiAgICAobGV0IFtoZWlnaHRtYXAgKG1ha2UtaGVpZ2h0bWFwIDYpXVxuICAgICAgKGwgXCJHZW5lcmF0aW5nIHRlcnJhaW4uLi5cIilcbiAgICAgICh0aW1lIChtaWRwb2ludC1kaXNwbGFjZW1lbnQgaGVpZ2h0bWFwKSlcblxuICAgICAgKGwgXCJSZWJ1aWxkaW5nIGdlb21ldHJ5Li4uXCIpXG4gICAgICAodGltZVxuICAgICAgICAoc2V0ISBnZW9tZXRyeSAobWFrZS1nZW9tZXRyeSBoZWlnaHRtYXApKVxuICAgICAgICAodXBkYXRlLWdlb21ldHJ5IGdlb21ldHJ5IGhlaWdodG1hcCkpXG5cbiAgICAgIChsIFwiUmVidWlsZGluZyBwbGFuZS4uLlwiKVxuICAgICAgKHRpbWVcbiAgICAgICAgKHNjZW5lLnJlbW92ZSBwbGFuZSlcbiAgICAgICAgKHNldCEgcGxhbmUgKG1ha2UtcGxhbmUgZ2VvbWV0cnkpKVxuICAgICAgICAoc2NlbmUuYWRkIHBsYW5lKSkpKVxuXG4gIChhdHRhY2gtdG8tZG9tIHJlbmRlcmVyIGVsZW1lbnQtaWQgcmVmcmVzaClcbiAgKGRlZiBjb250cm9scyAobWFrZS1jb250cm9scyBjYW1lcmEgcmVuZGVyZXIpKVxuXG4gIChkZWZuIHJlbmRlciBbXVxuICAgIChsZXQgW2RlbHRhIChjbG9jay5nZXREZWx0YSldXG4gICAgICAocmVxdWVzdEFuaW1hdGlvbkZyYW1lIHJlbmRlcilcbiAgICAgICgudXBkYXRlIGNvbnRyb2xzIGRlbHRhKVxuICAgICAgKHJlbmRlcmVyLnJlbmRlciBzY2VuZSBjYW1lcmEpKSlcblxuICAocmVmcmVzaClcbiAgKHJlbmRlcilcblxuICBuaWwpXG5cbihkZWZuIHJ1biBbXVxuICAobWFrZS1maW5hbCBcImRlbW8tZmluYWxcIikpXG5cbigkIHJ1bilcblxuXG47IHZpbTogbHcrPWRvLXRpbWVzIGx3Kz1kby1uZXN0ZWQgOlxuIl19