Path: blob/main/projects/polybranch/js/libs/processing.js
1835 views
/***12P R O C E S S I N G . J S - 1.4.13a port of the Processing visualization language45Processing.js is licensed under the MIT License, see LICENSE.6For a list of copyright holders, please refer to AUTHORS.78http://processingjs.org910***/1112(function(window, document, Math, undef) {13var nop = function() {};14var debug = function() {15if ("console" in window) return function(msg) {16window.console.log("Processing.js: " + msg)17};18return nop19}();20var ajax = function(url) {21var xhr = new XMLHttpRequest;22xhr.open("GET", url, false);23if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain");24xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT");25xhr.send(null);26if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status;27return xhr.responseText28};29var isDOMPresent = "document" in this && !("fake" in this.document);30document.head = document.head || document.getElementsByTagName("head")[0];3132function setupTypedArray(name, fallback) {33if (name in window) return window[name];34if (typeof window[fallback] === "function") return window[fallback];35return function(obj) {36if (obj instanceof Array) return obj;37if (typeof obj === "number") {38var arr = [];39arr.length = obj;40return arr41}42}43}44if (document.documentMode >= 9 && !document.doctype) throw "The doctype directive is missing. The recommended doctype in Internet Explorer is the HTML5 doctype: <!DOCTYPE html>";45var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"),46Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"),47Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"),48Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray");49var PConstants = {50X: 0,51Y: 1,52Z: 2,53R: 3,54G: 4,55B: 5,56A: 6,57U: 7,58V: 8,59NX: 9,60NY: 10,61NZ: 11,62EDGE: 12,63SR: 13,64SG: 14,65SB: 15,66SA: 16,67SW: 17,68TX: 18,69TY: 19,70TZ: 20,71VX: 21,72VY: 22,73VZ: 23,74VW: 24,75AR: 25,76AG: 26,77AB: 27,78DR: 3,79DG: 4,80DB: 5,81DA: 6,82SPR: 28,83SPG: 29,84SPB: 30,85SHINE: 31,86ER: 32,87EG: 33,88EB: 34,89BEEN_LIT: 35,90VERTEX_FIELD_COUNT: 36,91P2D: 1,92JAVA2D: 1,93WEBGL: 2,94P3D: 2,95OPENGL: 2,96PDF: 0,97DXF: 0,98OTHER: 0,99WINDOWS: 1,100MAXOSX: 2,101LINUX: 3,102EPSILON: 1.0E-4,103MAX_FLOAT: 3.4028235E38,104MIN_FLOAT: -3.4028235E38,105MAX_INT: 2147483647,106MIN_INT: -2147483648,107PI: Math.PI,108TWO_PI: 2 * Math.PI,109HALF_PI: Math.PI / 2,110THIRD_PI: Math.PI / 3,111QUARTER_PI: Math.PI / 4,112DEG_TO_RAD: Math.PI / 180,113RAD_TO_DEG: 180 / Math.PI,114WHITESPACE: " \t\n\r\u000c\u00a0",115RGB: 1,116ARGB: 2,117HSB: 3,118ALPHA: 4,119CMYK: 5,120TIFF: 0,121TARGA: 1,122JPEG: 2,123GIF: 3,124BLUR: 11,125GRAY: 12,126INVERT: 13,127OPAQUE: 14,128POSTERIZE: 15,129THRESHOLD: 16,130ERODE: 17,131DILATE: 18,132REPLACE: 0,133BLEND: 1 << 0,134ADD: 1 << 1,135SUBTRACT: 1 << 2,136LIGHTEST: 1 << 3,137DARKEST: 1 << 4,138DIFFERENCE: 1 << 5,139EXCLUSION: 1 << 6,140MULTIPLY: 1 << 7,141SCREEN: 1 << 8,142OVERLAY: 1 << 9,143HARD_LIGHT: 1 << 10,144SOFT_LIGHT: 1 << 11,145DODGE: 1 << 12,146BURN: 1 << 13,147ALPHA_MASK: 4278190080,148RED_MASK: 16711680,149GREEN_MASK: 65280,150BLUE_MASK: 255,151CUSTOM: 0,152ORTHOGRAPHIC: 2,153PERSPECTIVE: 3,154POINT: 2,155POINTS: 2,156LINE: 4,157LINES: 4,158TRIANGLE: 8,159TRIANGLES: 9,160TRIANGLE_STRIP: 10,161TRIANGLE_FAN: 11,162QUAD: 16,163QUADS: 16,164QUAD_STRIP: 17,165POLYGON: 20,166PATH: 21,167RECT: 30,168ELLIPSE: 31,169ARC: 32,170SPHERE: 40,171BOX: 41,172GROUP: 0,173PRIMITIVE: 1,174GEOMETRY: 3,175VERTEX: 0,176BEZIER_VERTEX: 1,177CURVE_VERTEX: 2,178BREAK: 3,179CLOSESHAPE: 4,180OPEN: 1,181CLOSE: 2,182CORNER: 0,183CORNERS: 1,184RADIUS: 2,185CENTER_RADIUS: 2,186CENTER: 3,187DIAMETER: 3,188CENTER_DIAMETER: 3,189BASELINE: 0,190TOP: 101,191BOTTOM: 102,192NORMAL: 1,193NORMALIZED: 1,194IMAGE: 2,195MODEL: 4,196SHAPE: 5,197SQUARE: "butt",198ROUND: "round",199PROJECT: "square",200MITER: "miter",201BEVEL: "bevel",202AMBIENT: 0,203DIRECTIONAL: 1,204SPOT: 3,205BACKSPACE: 8,206TAB: 9,207ENTER: 10,208RETURN: 13,209ESC: 27,210DELETE: 127,211CODED: 65535,212SHIFT: 16,213CONTROL: 17,214ALT: 18,215CAPSLK: 20,216PGUP: 33,217PGDN: 34,218END: 35,219HOME: 36,220LEFT: 37,221UP: 38,222RIGHT: 39,223DOWN: 40,224F1: 112,225F2: 113,226F3: 114,227F4: 115,228F5: 116,229F6: 117,230F7: 118,231F8: 119,232F9: 120,233F10: 121,234F11: 122,235F12: 123,236NUMLK: 144,237META: 157,238INSERT: 155,239ARROW: "default",240CROSS: "crosshair",241HAND: "pointer",242MOVE: "move",243TEXT: "text",244WAIT: "wait",245NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto",246DISABLE_OPENGL_2X_SMOOTH: 1,247ENABLE_OPENGL_2X_SMOOTH: -1,248ENABLE_OPENGL_4X_SMOOTH: 2,249ENABLE_NATIVE_FONTS: 3,250DISABLE_DEPTH_TEST: 4,251ENABLE_DEPTH_TEST: -4,252ENABLE_DEPTH_SORT: 5,253DISABLE_DEPTH_SORT: -5,254DISABLE_OPENGL_ERROR_REPORT: 6,255ENABLE_OPENGL_ERROR_REPORT: -6,256ENABLE_ACCURATE_TEXTURES: 7,257DISABLE_ACCURATE_TEXTURES: -7,258HINT_COUNT: 10,259SINCOS_LENGTH: 720,260PRECISIONB: 15,261PRECISIONF: 1 << 15,262PREC_MAXVAL: (1 << 15) - 1,263PREC_ALPHA_SHIFT: 24 - 15,264PREC_RED_SHIFT: 16 - 15,265NORMAL_MODE_AUTO: 0,266NORMAL_MODE_SHAPE: 1,267NORMAL_MODE_VERTEX: 2,268MAX_LIGHTS: 8269};270271function virtHashCode(obj) {272if (typeof obj === "string") {273var hash = 0;274for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295;275return hash276}277if (typeof obj !== "object") return obj & 4294967295;278if (obj.hashCode instanceof Function) return obj.hashCode();279if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536);280return obj.$id281}282function virtEquals(obj, other) {283if (obj === null || other === null) return obj === null && other === null;284if (typeof obj === "string") return obj === other;285if (typeof obj !== "object") return obj === other;286if (obj.equals instanceof Function) return obj.equals(other);287return obj === other288}289var ObjectIterator = function(obj) {290if (obj.iterator instanceof291Function) return obj.iterator();292if (obj instanceof Array) {293var index = -1;294this.hasNext = function() {295return ++index < obj.length296};297this.next = function() {298return obj[index]299}300} else throw "Unable to iterate: " + obj;301};302var ArrayList = function() {303function Iterator(array) {304var index = 0;305this.hasNext = function() {306return index < array.length307};308this.next = function() {309return array[index++]310};311this.remove = function() {312array.splice(index, 1)313}314}315function ArrayList(a) {316var array;317if (a instanceof ArrayList) array = a.toArray();318else {319array = [];320if (typeof a === "number") array.length = a > 0 ? a : 0321}322this.get = function(i) {323return array[i]324};325this.contains = function(item) {326return this.indexOf(item) > -1327};328this.indexOf = function(item) {329for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i;330return -1331};332this.lastIndexOf = function(item) {333for (var i = array.length - 1; i >= 0; --i) if (virtEquals(item, array[i])) return i;334return -1335};336this.add = function() {337if (arguments.length === 1) array.push(arguments[0]);338else if (arguments.length === 2) {339var arg0 = arguments[0];340if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]);341else throw arg0 + " is not a valid index";342else throw typeof arg0 + " is not a number";343} else throw "Please use the proper number of parameters.";344};345this.addAll = function(arg1, arg2) {346var it;347if (typeof arg1 === "number") {348if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length;349it = new ObjectIterator(arg2);350while (it.hasNext()) array.splice(arg1++, 0, it.next())351} else {352it = new ObjectIterator(arg1);353while (it.hasNext()) array.push(it.next())354}355};356this.set = function() {357if (arguments.length === 2) {358var arg0 = arguments[0];359if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]);360else throw arg0 + " is not a valid index.";361else throw typeof arg0 + " is not a number";362} else throw "Please use the proper number of parameters.";363};364this.size = function() {365return array.length366};367this.clear = function() {368array.length = 0369};370this.remove = function(item) {371if (typeof item === "number") return array.splice(item, 1)[0];372item = this.indexOf(item);373if (item > -1) {374array.splice(item, 1);375return true376}377return false378};379this.removeAll = function(c) {380var i, x, item, newList = new ArrayList;381newList.addAll(this);382this.clear();383for (i = 0, x = 0; i < newList.size(); i++) {384item = newList.get(i);385if (!c.contains(item)) this.add(x++, item)386}387if (this.size() < newList.size()) return true;388return false389};390this.isEmpty = function() {391return !array.length392};393this.clone = function() {394return new ArrayList(this)395};396this.toArray = function() {397return array.slice(0)398};399this.iterator = function() {400return new Iterator(array)401}402}403return ArrayList404}();405var HashMap = function() {406function HashMap() {407if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone();408var initialCapacity = arguments.length > 0 ? arguments[0] : 16;409var loadFactor = arguments.length > 1 ? arguments[1] : 0.75;410var buckets = [];411buckets.length = initialCapacity;412var count = 0;413var hashMap = this;414415function getBucketIndex(key) {416var index = virtHashCode(key) % buckets.length;417return index < 0 ? buckets.length + index : index418}419function ensureLoad() {420if (count <= loadFactor * buckets.length) return;421var allEntries = [];422for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]);423var newBucketsLength = buckets.length * 2;424buckets = [];425buckets.length = newBucketsLength;426for (var j = 0; j < allEntries.length; ++j) {427var index = getBucketIndex(allEntries[j].key);428var bucket = buckets[index];429if (bucket === undef) buckets[index] = bucket = [];430bucket.push(allEntries[j])431}432}433function Iterator(conversion, removeItem) {434var bucketIndex = 0;435var itemIndex = -1;436var endOfBuckets = false;437var currentItem;438439function findNext() {440while (!endOfBuckets) {441++itemIndex;442if (bucketIndex >= buckets.length) endOfBuckets = true;443else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) {444itemIndex = -1;445++bucketIndex446} else return447}448}449this.hasNext = function() {450return !endOfBuckets451};452this.next = function() {453currentItem = conversion(buckets[bucketIndex][itemIndex]);454findNext();455return currentItem456};457this.remove = function() {458if (currentItem !== undef) {459removeItem(currentItem);460--itemIndex;461findNext()462}463};464findNext()465}466function Set(conversion, isIn, removeItem) {467this.clear = function() {468hashMap.clear()469};470this.contains = function(o) {471return isIn(o)472};473this.containsAll = function(o) {474var it = o.iterator();475while (it.hasNext()) if (!this.contains(it.next())) return false;476return true477};478this.isEmpty = function() {479return hashMap.isEmpty()480};481this.iterator = function() {482return new Iterator(conversion, removeItem)483};484this.remove = function(o) {485if (this.contains(o)) {486removeItem(o);487return true488}489return false490};491this.removeAll = function(c) {492var it = c.iterator();493var changed = false;494while (it.hasNext()) {495var item = it.next();496if (this.contains(item)) {497removeItem(item);498changed = true499}500}501return true502};503this.retainAll = function(c) {504var it = this.iterator();505var toRemove = [];506while (it.hasNext()) {507var entry = it.next();508if (!c.contains(entry)) toRemove.push(entry)509}510for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]);511return toRemove.length > 0512};513this.size = function() {514return hashMap.size()515};516this.toArray = function() {517var result = [];518var it = this.iterator();519while (it.hasNext()) result.push(it.next());520return result521}522}523function Entry(pair) {524this._isIn = function(map) {525return map === hashMap && pair.removed === undef526};527this.equals = function(o) {528return virtEquals(pair.key, o.getKey())529};530this.getKey = function() {531return pair.key532};533this.getValue = function() {534return pair.value535};536this.hashCode = function(o) {537return virtHashCode(pair.key)538};539this.setValue = function(value) {540var old = pair.value;541pair.value = value;542return old543}544}545this.clear = function() {546count = 0;547buckets = [];548buckets.length = initialCapacity549};550this.clone = function() {551var map = new HashMap;552map.putAll(this);553return map554};555this.containsKey = function(key) {556var index = getBucketIndex(key);557var bucket = buckets[index];558if (bucket === undef) return false;559for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true;560return false561};562this.containsValue = function(value) {563for (var i = 0; i < buckets.length; ++i) {564var bucket = buckets[i];565if (bucket === undef) continue;566for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true567}568return false569};570this.entrySet = function() {571return new Set(function(pair) {572return new Entry(pair)573},574575576function(pair) {577return pair instanceof Entry && pair._isIn(hashMap)578},579580581function(pair) {582return hashMap.remove(pair.getKey())583})584};585this.get = function(key) {586var index = getBucketIndex(key);587var bucket = buckets[index];588if (bucket === undef) return null;589for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value;590return null591};592this.isEmpty = function() {593return count === 0594};595this.keySet = function() {596return new Set(function(pair) {597return pair.key598},599600601function(key) {602return hashMap.containsKey(key)603},604605606function(key) {607return hashMap.remove(key)608})609};610this.values = function() {611return new Set(function(pair) {612return pair.value613},614615616function(value) {617return hashMap.containsValue(value)618},619620function(value) {621return hashMap.removeByValue(value)622})623};624this.put = function(key, value) {625var index = getBucketIndex(key);626var bucket = buckets[index];627if (bucket === undef) {628++count;629buckets[index] = [{630key: key,631value: value632}];633ensureLoad();634return null635}636for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) {637var previous = bucket[i].value;638bucket[i].value = value;639return previous640}++count;641bucket.push({642key: key,643value: value644});645ensureLoad();646return null647};648this.putAll = function(m) {649var it = m.entrySet().iterator();650while (it.hasNext()) {651var entry = it.next();652this.put(entry.getKey(), entry.getValue())653}654};655this.remove = function(key) {656var index = getBucketIndex(key);657var bucket = buckets[index];658if (bucket === undef) return null;659for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) {660--count;661var previous = bucket[i].value;662bucket[i].removed = true;663if (bucket.length > 1) bucket.splice(i, 1);664else buckets[index] = undef;665return previous666}667return null668};669this.removeByValue = function(value) {670var bucket, i, ilen, pair;671for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) {672pair = buckets[bucket][i];673if (pair.value === value) {674buckets[bucket].splice(i, 1);675return true676}677}678return false679};680this.size = function() {681return count682}683}684return HashMap685}();686var PVector = function() {687function PVector(x, y, z) {688this.x = x || 0;689this.y = y || 0;690this.z = z || 0691}692PVector.dist = function(v1, v2) {693return v1.dist(v2)694};695PVector.dot = function(v1, v2) {696return v1.dot(v2)697};698PVector.cross = function(v1, v2) {699return v1.cross(v2)700};701PVector.angleBetween = function(v1, v2) {702return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag()))703};704PVector.prototype = {705set: function(v, y, z) {706if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0);707else {708this.x = v;709this.y = y;710this.z = z711}712},713get: function() {714return new PVector(this.x, this.y, this.z)715},716mag: function() {717var x = this.x,718y = this.y,719z = this.z;720return Math.sqrt(x * x + y * y + z * z)721},722add: function(v, y, z) {723if (arguments.length === 1) {724this.x += v.x;725this.y += v.y;726this.z += v.z727} else {728this.x += v;729this.y += y;730this.z += z731}732},733sub: function(v, y, z) {734if (arguments.length === 1) {735this.x -= v.x;736this.y -= v.y;737this.z -= v.z738} else {739this.x -= v;740this.y -= y;741this.z -= z742}743},744mult: function(v) {745if (typeof v === "number") {746this.x *= v;747this.y *= v;748this.z *= v749} else {750this.x *= v.x;751this.y *= v.y;752this.z *= v.z753}754},755div: function(v) {756if (typeof v === "number") {757this.x /= v;758this.y /= v;759this.z /= v760} else {761this.x /= v.x;762this.y /= v.y;763this.z /= v.z764}765},766dist: function(v) {767var dx = this.x - v.x,768dy = this.y - v.y,769dz = this.z - v.z;770return Math.sqrt(dx * dx + dy * dy + dz * dz)771},772dot: function(v, y, z) {773if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z;774return this.x * v + this.y * y + this.z * z775},776cross: function(v) {777var x = this.x,778y = this.y,779z = this.z;780return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y)781},782normalize: function() {783var m = this.mag();784if (m > 0) this.div(m)785},786limit: function(high) {787if (this.mag() > high) {788this.normalize();789this.mult(high)790}791},792heading2D: function() {793return -Math.atan2(-this.y, this.x)794},795toString: function() {796return "[" + this.x + ", " + this.y + ", " + this.z + "]"797},798array: function() {799return [this.x, this.y, this.z]800}801};802803function createPVectorMethod(method) {804return function(v1, v2) {805var v = v1.get();806v[method](v2);807return v808}809}810for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method);811return PVector812}();813814function DefaultScope() {}815DefaultScope.prototype = PConstants;816var defaultScope = new DefaultScope;817defaultScope.ArrayList = ArrayList;818defaultScope.HashMap = HashMap;819defaultScope.PVector = PVector;820defaultScope.ObjectIterator = ObjectIterator;821defaultScope.PConstants = PConstants;822defaultScope.defineProperty = function(obj, name, desc) {823if ("defineProperty" in Object) Object.defineProperty(obj, name, desc);824else {825if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get);826if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set)827}828};829830function overloadBaseClassFunction(object, name, basefn) {831if (!object.hasOwnProperty(name) || typeof object[name] !== "function") {832object[name] = basefn;833return834}835var fn = object[name];836if ("$overloads" in fn) {837fn.$defaultOverload = basefn;838return839}840if (! ("$overloads" in basefn) && fn.length === basefn.length) return;841var overloads, defaultOverload;842if ("$overloads" in basefn) {843overloads = basefn.$overloads.slice(0);844overloads[fn.length] = fn;845defaultOverload = basefn.$defaultOverload846} else {847overloads = [];848overloads[basefn.length] = basefn;849overloads[fn.length] = fn;850defaultOverload = fn851}852var hubfn = function() {853var fn = hubfn.$overloads[arguments.length] || ("$methodArgsIndex" in hubfn && arguments.length > hubfn.$methodArgsIndex ? hubfn.$overloads[hubfn.$methodArgsIndex] : null) || hubfn.$defaultOverload;854return fn.apply(this, arguments)855};856hubfn.$overloads = overloads;857if ("$methodArgsIndex" in basefn) hubfn.$methodArgsIndex = basefn.$methodArgsIndex;858hubfn.$defaultOverload = defaultOverload;859hubfn.name = name;860object[name] = hubfn861}862function extendClass(subClass, baseClass) {863function extendGetterSetter(propertyName) {864defaultScope.defineProperty(subClass, propertyName, {865get: function() {866return baseClass[propertyName]867},868set: function(v) {869baseClass[propertyName] = v870},871enumerable: true872})873}874var properties = [];875for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") overloadBaseClassFunction(subClass, propertyName, baseClass[propertyName]);876else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName);877while (properties.length > 0) extendGetterSetter(properties.shift());878subClass.$super = baseClass879}880defaultScope.extendClassChain = function(base) {881var path = [base];882for (var self = base.$upcast; self; self = self.$upcast) {883extendClass(self, base);884path.push(self);885base = self886}887while (path.length > 0) path.pop().$self = base888};889defaultScope.extendStaticMembers = function(derived, base) {890extendClass(derived, base)891};892defaultScope.extendInterfaceMembers = function(derived, base) {893extendClass(derived, base)894};895defaultScope.addMethod = function(object, name, fn, hasMethodArgs) {896var existingfn = object[name];897if (existingfn || hasMethodArgs) {898var args = fn.length;899if ("$overloads" in existingfn) existingfn.$overloads[args] = fn;900else {901var hubfn = function() {902var fn = hubfn.$overloads[arguments.length] || ("$methodArgsIndex" in hubfn && arguments.length > hubfn.$methodArgsIndex ? hubfn.$overloads[hubfn.$methodArgsIndex] : null) || hubfn.$defaultOverload;903return fn.apply(this, arguments)904};905var overloads = [];906if (existingfn) overloads[existingfn.length] = existingfn;907overloads[args] = fn;908hubfn.$overloads = overloads;909hubfn.$defaultOverload = existingfn || fn;910if (hasMethodArgs) hubfn.$methodArgsIndex = args;911hubfn.name = name;912object[name] = hubfn913}914} else object[name] = fn915};916917function isNumericalJavaType(type) {918if (typeof type !== "string") return false;919return ["byte", "int", "char", "color", "float", "long", "double"].indexOf(type) !== -1920}921defaultScope.createJavaArray = function(type, bounds) {922var result = null,923defaultValue = null;924if (typeof type === "string") if (type === "boolean") defaultValue = false;925else if (isNumericalJavaType(type)) defaultValue = 0;926if (typeof bounds[0] === "number") {927var itemsCount = 0 | bounds[0];928if (bounds.length <= 1) {929result = [];930result.length = itemsCount;931for (var i = 0; i < itemsCount; ++i) result[i] = defaultValue932} else {933result = [];934var newBounds = bounds.slice(1);935for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds))936}937}938return result939};940var colors = {941aliceblue: "#f0f8ff",942antiquewhite: "#faebd7",943aqua: "#00ffff",944aquamarine: "#7fffd4",945azure: "#f0ffff",946beige: "#f5f5dc",947bisque: "#ffe4c4",948black: "#000000",949blanchedalmond: "#ffebcd",950blue: "#0000ff",951blueviolet: "#8a2be2",952brown: "#a52a2a",953burlywood: "#deb887",954cadetblue: "#5f9ea0",955chartreuse: "#7fff00",956chocolate: "#d2691e",957coral: "#ff7f50",958cornflowerblue: "#6495ed",959cornsilk: "#fff8dc",960crimson: "#dc143c",961cyan: "#00ffff",962darkblue: "#00008b",963darkcyan: "#008b8b",964darkgoldenrod: "#b8860b",965darkgray: "#a9a9a9",966darkgreen: "#006400",967darkkhaki: "#bdb76b",968darkmagenta: "#8b008b",969darkolivegreen: "#556b2f",970darkorange: "#ff8c00",971darkorchid: "#9932cc",972darkred: "#8b0000",973darksalmon: "#e9967a",974darkseagreen: "#8fbc8f",975darkslateblue: "#483d8b",976darkslategray: "#2f4f4f",977darkturquoise: "#00ced1",978darkviolet: "#9400d3",979deeppink: "#ff1493",980deepskyblue: "#00bfff",981dimgray: "#696969",982dodgerblue: "#1e90ff",983firebrick: "#b22222",984floralwhite: "#fffaf0",985forestgreen: "#228b22",986fuchsia: "#ff00ff",987gainsboro: "#dcdcdc",988ghostwhite: "#f8f8ff",989gold: "#ffd700",990goldenrod: "#daa520",991gray: "#808080",992green: "#008000",993greenyellow: "#adff2f",994honeydew: "#f0fff0",995hotpink: "#ff69b4",996indianred: "#cd5c5c",997indigo: "#4b0082",998ivory: "#fffff0",999khaki: "#f0e68c",1000lavender: "#e6e6fa",1001lavenderblush: "#fff0f5",1002lawngreen: "#7cfc00",1003lemonchiffon: "#fffacd",1004lightblue: "#add8e6",1005lightcoral: "#f08080",1006lightcyan: "#e0ffff",1007lightgoldenrodyellow: "#fafad2",1008lightgrey: "#d3d3d3",1009lightgreen: "#90ee90",1010lightpink: "#ffb6c1",1011lightsalmon: "#ffa07a",1012lightseagreen: "#20b2aa",1013lightskyblue: "#87cefa",1014lightslategray: "#778899",1015lightsteelblue: "#b0c4de",1016lightyellow: "#ffffe0",1017lime: "#00ff00",1018limegreen: "#32cd32",1019linen: "#faf0e6",1020magenta: "#ff00ff",1021maroon: "#800000",1022mediumaquamarine: "#66cdaa",1023mediumblue: "#0000cd",1024mediumorchid: "#ba55d3",1025mediumpurple: "#9370d8",1026mediumseagreen: "#3cb371",1027mediumslateblue: "#7b68ee",1028mediumspringgreen: "#00fa9a",1029mediumturquoise: "#48d1cc",1030mediumvioletred: "#c71585",1031midnightblue: "#191970",1032mintcream: "#f5fffa",1033mistyrose: "#ffe4e1",1034moccasin: "#ffe4b5",1035navajowhite: "#ffdead",1036navy: "#000080",1037oldlace: "#fdf5e6",1038olive: "#808000",1039olivedrab: "#6b8e23",1040orange: "#ffa500",1041orangered: "#ff4500",1042orchid: "#da70d6",1043palegoldenrod: "#eee8aa",1044palegreen: "#98fb98",1045paleturquoise: "#afeeee",1046palevioletred: "#d87093",1047papayawhip: "#ffefd5",1048peachpuff: "#ffdab9",1049peru: "#cd853f",1050pink: "#ffc0cb",1051plum: "#dda0dd",1052powderblue: "#b0e0e6",1053purple: "#800080",1054red: "#ff0000",1055rosybrown: "#bc8f8f",1056royalblue: "#4169e1",1057saddlebrown: "#8b4513",1058salmon: "#fa8072",1059sandybrown: "#f4a460",1060seagreen: "#2e8b57",1061seashell: "#fff5ee",1062sienna: "#a0522d",1063silver: "#c0c0c0",1064skyblue: "#87ceeb",1065slateblue: "#6a5acd",1066slategray: "#708090",1067snow: "#fffafa",1068springgreen: "#00ff7f",1069steelblue: "#4682b4",1070tan: "#d2b48c",1071teal: "#008080",1072thistle: "#d8bfd8",1073tomato: "#ff6347",1074turquoise: "#40e0d0",1075violet: "#ee82ee",1076wheat: "#f5deb3",1077white: "#ffffff",1078whitesmoke: "#f5f5f5",1079yellow: "#ffff00",1080yellowgreen: "#9acd32"1081};1082(function(Processing) {1083var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "),1084count = unsupportedP5.length,1085prettyName, p5Name;10861087function createUnsupportedFunc(n) {1088return function() {1089throw "Processing.js does not support " + n + ".";1090}1091}1092while (count--) {1093prettyName = unsupportedP5[count];1094p5Name = prettyName.replace("()", "");1095Processing[p5Name] = createUnsupportedFunc(prettyName)1096}1097})(defaultScope);1098defaultScope.defineProperty(defaultScope, "screenWidth", {1099get: function() {1100return window.innerWidth1101}1102});1103defaultScope.defineProperty(defaultScope, "screenHeight", {1104get: function() {1105return window.innerHeight1106}1107});1108defaultScope.defineProperty(defaultScope, "online", {1109get: function() {1110return true1111}1112});1113var processingInstances = [];1114var processingInstanceIds = {};1115var removeInstance = function(id) {1116processingInstances.splice(processingInstanceIds[id], 1);1117delete processingInstanceIds[id]1118};1119var addInstance = function(processing) {1120if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length;1121processingInstanceIds[processing.externals.canvas.id] = processingInstances.length;1122processingInstances.push(processing)1123};11241125function computeFontMetrics(pfont) {1126var emQuad = 250,1127correctionFactor = pfont.size / emQuad,1128canvas = document.createElement("canvas");1129canvas.width = 2 * emQuad;1130canvas.height = 2 * emQuad;1131canvas.style.opacity = 0;1132var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"),1133ctx = canvas.getContext("2d");1134ctx.font = cfmFont;1135var protrusions = "dbflkhyjqpg";1136canvas.width = ctx.measureText(protrusions).width;1137ctx.font = cfmFont;1138var leadDiv = document.createElement("div");1139leadDiv.style.position = "absolute";1140leadDiv.style.opacity = 0;1141leadDiv.style.fontFamily = '"' + pfont.name + '"';1142leadDiv.style.fontSize = emQuad + "px";1143leadDiv.innerHTML = protrusions + "<br/>" + protrusions;1144document.body.appendChild(leadDiv);1145var w = canvas.width,1146h = canvas.height,1147baseline = h / 2;1148ctx.fillStyle = "white";1149ctx.fillRect(0, 0, w, h);1150ctx.fillStyle = "black";1151ctx.fillText(protrusions, 0, baseline);1152var pixelData = ctx.getImageData(0, 0, w, h).data;1153var i = 0,1154w4 = w * 4,1155len = pixelData.length;1156while (++i < len && pixelData[i] === 255) nop();1157var ascent = Math.round(i / w4);1158i = len - 1;1159while (--i > 0 && pixelData[i] === 255) nop();1160var descent = Math.round(i / w4);1161pfont.ascent = correctionFactor * (baseline - ascent);1162pfont.descent = correctionFactor * (descent - baseline);1163if (document.defaultView.getComputedStyle) {1164var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height");1165leadDivHeight = correctionFactor * leadDivHeight.replace("px", "");1166if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2)1167}1168document.body.removeChild(leadDiv);1169if (pfont.caching) return ctx1170}1171function PFont(name, size) {1172if (name === undef) name = "";1173this.name = name;1174if (size === undef) size = 0;1175this.size = size;1176this.glyph = false;1177this.ascent = 0;1178this.descent = 0;1179this.leading = 1.2 * size;1180var illegalIndicator = name.indexOf(" Italic Bold");1181if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator);1182this.style = "normal";1183var italicsIndicator = name.indexOf(" Italic");1184if (italicsIndicator !== -1) {1185name = name.substring(0, italicsIndicator);1186this.style = "italic"1187}1188this.weight = "normal";1189var boldIndicator = name.indexOf(" Bold");1190if (boldIndicator !== -1) {1191name = name.substring(0, boldIndicator);1192this.weight = "bold"1193}1194this.family = "sans-serif";1195if (name !== undef) switch (name) {1196case "sans-serif":1197case "serif":1198case "monospace":1199case "fantasy":1200case "cursive":1201this.family = name;1202break;1203default:1204this.family = '"' + name + '", sans-serif';1205break1206}1207this.context2d = computeFontMetrics(this);1208this.css = this.getCSSDefinition();1209if (this.context2d) this.context2d.font = this.css1210}1211PFont.prototype.caching = true;1212PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) {1213if (fontSize === undef) fontSize = this.size + "px";1214if (lineHeight === undef) lineHeight = this.leading + "px";1215var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family];1216return components.join(" ")1217};1218PFont.prototype.measureTextWidth = function(string) {1219return this.context2d.measureText(string).width1220};1221PFont.prototype.measureTextWidthFallback = function(string) {1222var canvas = document.createElement("canvas"),1223ctx = canvas.getContext("2d");1224ctx.font = this.css;1225return ctx.measureText(string).width1226};1227PFont.PFontCache = {1228length: 01229};1230PFont.get = function(fontName, fontSize) {1231fontSize = (fontSize * 10 + 0.5 | 0) / 10;1232var cache = PFont.PFontCache,1233idx = fontName + "/" + fontSize;1234if (!cache[idx]) {1235cache[idx] = new PFont(fontName, fontSize);1236cache.length++;1237if (cache.length === 50) {1238PFont.prototype.measureTextWidth = PFont.prototype.measureTextWidthFallback;1239PFont.prototype.caching = false;1240var entry;1241for (entry in cache) if (entry !== "length") cache[entry].context2d = null;1242return new PFont(fontName, fontSize)1243}1244if (cache.length === 400) {1245PFont.PFontCache = {};1246PFont.get = PFont.getFallback;1247return new PFont(fontName, fontSize)1248}1249}1250return cache[idx]1251};1252PFont.getFallback = function(fontName, fontSize) {1253return new PFont(fontName, fontSize)1254};1255PFont.list = function() {1256return ["sans-serif", "serif", "monospace", "fantasy", "cursive"]1257};1258PFont.preloading = {1259template: {},1260initialized: false,1261initialize: function() {1262var generateTinyFont = function() {1263var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#";1264var expand = function(input) {1265return "AAAAAAAA".substr(~~input ? 7 - input : 6)1266};1267return encoded.replace(/[#237]/g, expand)1268};1269var fontface = document.createElement("style");1270fontface.setAttribute("type", "text/css");1271fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}";1272document.head.appendChild(fontface);1273var element = document.createElement("span");1274element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;';1275element.innerHTML = "AAAAAAAA";1276document.body.appendChild(element);1277this.template = element;1278this.initialized = true1279},1280getElementWidth: function(element) {1281return document.defaultView.getComputedStyle(element, "").getPropertyValue("width")1282},1283timeAttempted: 0,1284pending: function(intervallength) {1285if (!this.initialized) this.initialize();1286var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template);1287for (var i = 0; i < this.fontList.length; i++) {1288element = this.fontList[i];1289computedWidthFont = this.getElementWidth(element);1290if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) {1291this.timeAttempted += intervallength;1292return true1293} else {1294document.body.removeChild(element);1295this.fontList.splice(i--, 1);1296this.timeAttempted = 01297}1298}1299if (this.fontList.length === 0) return false;1300return true1301},1302fontList: [],1303addedList: {},1304add: function(fontSrc) {1305if (!this.initialized) this.initialize();1306var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc,1307fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc;1308if (this.addedList[fontName]) return;1309var style = document.createElement("style");1310style.setAttribute("type", "text/css");1311style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n";1312document.head.appendChild(style);1313this.addedList[fontName] = true;1314var element = document.createElement("span");1315element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;";1316element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy';1317element.innerHTML = "AAAAAAAA";1318document.body.appendChild(element);1319this.fontList.push(element)1320}1321};1322defaultScope.PFont = PFont;1323var Processing = this.Processing = function(aCanvas, aCode) {1324if (! (this instanceof1325Processing)) throw "called Processing constructor as if it were a function: missing 'new'.";1326var curElement, pgraphicsMode = aCanvas === undef && aCode === undef;1327if (pgraphicsMode) curElement = document.createElement("canvas");1328else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas;1329if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id.";13301331function unimplemented(s) {1332Processing.debug("Unimplemented - " + s)1333}1334var p = this;1335p.externals = {1336canvas: curElement,1337context: undef,1338sketch: undef1339};1340p.name = "Processing.js Instance";1341p.use3DContext = false;1342p.focused = false;1343p.breakShape = false;1344p.glyphTable = {};1345p.pmouseX = 0;1346p.pmouseY = 0;1347p.mouseX = 0;1348p.mouseY = 0;1349p.mouseButton = 0;1350p.mouseScroll = 0;1351p.mouseClicked = undef;1352p.mouseDragged = undef;1353p.mouseMoved = undef;1354p.mousePressed = undef;1355p.mouseReleased = undef;1356p.mouseScrolled = undef;1357p.mouseOver = undef;1358p.mouseOut = undef;1359p.touchStart = undef;1360p.touchEnd = undef;1361p.touchMove = undef;1362p.touchCancel = undef;1363p.key = undef;1364p.keyCode = undef;1365p.keyPressed = nop;1366p.keyReleased = nop;1367p.keyTyped = nop;1368p.draw = undef;1369p.setup = undef;1370p.__mousePressed = false;1371p.__keyPressed = false;1372p.__frameRate = 60;1373p.frameCount = 0;1374p.width = 100;1375p.height = 100;1376var curContext, curSketch, drawing, online = true,1377doFill = true,1378fillStyle = [1, 1, 1, 1],1379currentFillColor = 4294967295,1380isFillDirty = true,1381doStroke = true,1382strokeStyle = [0, 0, 0, 1],1383currentStrokeColor = 4278190080,1384isStrokeDirty = true,1385lineWidth = 1,1386loopStarted = false,1387renderSmooth = false,1388doLoop = true,1389looping = 0,1390curRectMode = 0,1391curEllipseMode = 3,1392normalX = 0,1393normalY = 0,1394normalZ = 0,1395normalMode = 0,1396curFrameRate = 60,1397curMsPerFrame = 1E3 / curFrameRate,1398curCursor = 'default',1399oldCursor = curElement.style.cursor,1400curShape = 20,1401curShapeCount = 0,1402curvePoints = [],1403curTightness = 0,1404curveDet = 20,1405curveInited = false,1406backgroundObj = -3355444,1407bezDetail = 20,1408colorModeA = 255,1409colorModeX = 255,1410colorModeY = 255,1411colorModeZ = 255,1412pathOpen = false,1413mouseDragging = false,1414pmouseXLastFrame = 0,1415pmouseYLastFrame = 0,1416curColorMode = 1,1417curTint = null,1418curTint3d = null,1419getLoaded = false,1420start = Date.now(),1421timeSinceLastFPS = start,1422framesSinceLastFPS = 0,1423textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = {1424attributes: {},1425locations: {}1426},1427programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = {1428width: 0,1429height: 01430},1431curTextureMode = 2,1432usingTexture = false,1433textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37,1434verticalTextAlignment = 0,1435textMode = 4,1436curFontName = "Arial",1437curTextSize = 12,1438curTextAscent = 9,1439curTextDescent = 2,1440curTextLeading = 14,1441curTextFont = PFont.get(curFontName, curTextSize),1442originalContext, proxyContext = null,1443isContextReplaced = false,1444setPixelsCached, maxPixelsCached = 1E3,1445pressedKeysMap = [],1446lastPressedKeyCode = null,1447codedKeys = [16,144817, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157];1449var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop;1450if (document.defaultView && document.defaultView.getComputedStyle) {1451stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0;1452stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0;1453styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0;1454styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 01455}1456var lightCount = 0;1457var sphereDetailV = 0,1458sphereDetailU = 0,1459sphereX = [],1460sphereY = [],1461sphereZ = [],1462sinLUT = new Float32Array(720),1463cosLUT = new Float32Array(720),1464sphereVerts, sphereNorms;1465var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false,1466frustumMode = false,1467cameraFOV = 60 * (Math.PI / 180),1468cameraX = p.width / 2,1469cameraY = p.height / 2,1470cameraZ = cameraY / Math.tan(cameraFOV / 2),1471cameraNear = cameraZ / 10,1472cameraFar = cameraZ * 10,1473cameraAspect = p.width / p.height;1474var vertArray = [],1475curveVertArray = [],1476curveVertCount = 0,1477isCurve = false,1478isBezier = false,1479firstVert = true;1480var curShapeMode = 0;1481var styleArray = [];1482var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5,14830.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]);1484var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]);1485var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0,14860, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]);1487var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]);1488var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]);1489var vertexShaderSrcUnlitShape = "varying vec4 vFrontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float uPointSize;" + "void main(void) {" + " vFrontColor = aColor;" + " gl_PointSize = uPointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}";1490var fragmentShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 vFrontColor;" + "uniform bool uSmooth;" + "void main(void){" + " if(uSmooth == true){" + " float dist = distance(gl_PointCoord, vec2(0.5));" + " if(dist > 0.5){" + " discard;" + " }" + " }" + " gl_FragColor = vFrontColor;" + "}";1491var vertexShaderSrc2D = "varying vec4 vFrontColor;" + "attribute vec3 aVertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 uColor;" + "uniform mat4 uModel;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float uPointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = uPointSize;" + " vFrontColor = uColor;" + " gl_Position = uProjection * uView * uModel * vec4(aVertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}";1492var fragmentShaderSrc2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 vFrontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int uIsDrawingText;" + "uniform bool uSmooth;" + "void main(void){" + " if(uSmooth == true){" + " float dist = distance(gl_PointCoord, vec2(0.5));" + " if(dist > 0.5){" + " discard;" + " }" + " }" + " if(uIsDrawingText == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(vFrontColor.rgb * alpha, alpha);" + " }" + " else{" + " gl_FragColor = vFrontColor;" + " }" + "}";1493var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent);1494var vertexShaderSrc3D = "varying vec4 vFrontColor;" + "attribute vec3 aVertex;" + "attribute vec3 aNormal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 uColor;" + "uniform bool uUsingMat;" + "uniform vec3 uSpecular;" + "uniform vec3 uMaterialEmissive;" + "uniform vec3 uMaterialAmbient;" + "uniform vec3 uMaterialSpecular;" + "uniform float uShininess;" + "uniform mat4 uModel;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform mat4 uNormalTransform;" + "uniform int uLightCount;" + "uniform vec3 uFalloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light uLights0;" + "uniform Light uLights1;" + "uniform Light uLights2;" + "uniform Light uLights3;" + "uniform Light uLights4;" + "uniform Light uLights5;" + "uniform Light uLights6;" + "uniform Light uLights7;" + "Light getLight(int index){" + " if(index == 0) return uLights0;" + " if(index == 1) return uLights1;" + " if(index == 2) return uLights2;" + " if(index == 3) return uLights3;" + " if(index == 4) return uLights4;" + " if(index == 5) return uLights5;" + " if(index == 6) return uLights6;" + " return uLights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( uFalloff[0] + ( uFalloff[1] * d ) + ( uFalloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerFactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerFactor = pow( nDotVH, uShininess );" + " }" + " col += light.color * nDotVP;" + " spec += uSpecular * powerFactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerFactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( uFalloff[0] + ( uFalloff[1] * d ) + ( uFalloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerFactor = 0.0;" + " }" + " else {" + " powerFactor = pow( nDotHV, uShininess );" + " }" + " spec += uSpecular * powerFactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerFactor = 0.0;" + " vec3 VP = light.position - ecPos;" + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( uFalloff[0] + ( uFalloff[1] * d ) + ( uFalloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ) );" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ) );" + " if( nDotVP != 0.0 ) {" + " powerFactor = pow( nDotHV, uShininess );" + " }" + " spec += uSpecular * powerFactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0 );" + " vec3 finalDiffuse = vec3( 0.0 );" + " vec3 finalSpecular = vec3( 0.0 );" + " vec4 col = uColor;" + " if ( uColor[0] == -1.0 ){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( uNormalTransform * vec4( aNormal, 0.0 ) ));" + " vec4 ecPos4 = uView * uModel * vec4(aVertex, 1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( uLightCount == 0 ) {" + " vFrontColor = col + vec4(uMaterialSpecular, 1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= uLightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( uUsingMat == false ) {" + " vFrontColor = vec4(" + " vec3( col ) * finalAmbient +" + " vec3( col ) * finalDiffuse +" + " vec3( col ) * finalSpecular," + " col[3] );" + " }" + " else{" + " vFrontColor = vec4( " + " uMaterialEmissive + " + " (vec3(col) * uMaterialAmbient * finalAmbient ) + " + " (vec3(col) * finalDiffuse) + " + " (uMaterialSpecular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = uProjection * uView * uModel * vec4( aVertex, 1.0 );" + "}";1495var fragmentShaderSrc3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 vFrontColor;" + "uniform sampler2D uSampler;" + "uniform bool uUsingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if( uUsingTexture ){" + " gl_FragColor = vec4(texture2D(uSampler, vTexture.xy)) * vFrontColor;" + " }" + " else{" + " gl_FragColor = vFrontColor;" + " }" + "}";14961497function uniformf(cacheId, programObj, varName, varValue) {1498var varLocation = curContextCache.locations[cacheId];1499if (varLocation === undef) {1500varLocation = curContext.getUniformLocation(programObj, varName);1501curContextCache.locations[cacheId] = varLocation1502}1503if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue);1504else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue);1505else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue);1506else curContext.uniform1f(varLocation, varValue)1507}1508function uniformi(cacheId, programObj, varName, varValue) {1509var varLocation = curContextCache.locations[cacheId];1510if (varLocation === undef) {1511varLocation = curContext.getUniformLocation(programObj, varName);1512curContextCache.locations[cacheId] = varLocation1513}1514if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue);1515else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue);1516else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue);1517else curContext.uniform1i(varLocation, varValue)1518}1519function uniformMatrix(cacheId, programObj, varName, transpose, matrix) {1520var varLocation = curContextCache.locations[cacheId];1521if (varLocation === undef) {1522varLocation = curContext.getUniformLocation(programObj, varName);1523curContextCache.locations[cacheId] = varLocation1524}1525if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix);1526else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix);1527else curContext.uniformMatrix2fv(varLocation, transpose, matrix)1528}1529function vertexAttribPointer(cacheId, programObj, varName, size, VBO) {1530var varLocation = curContextCache.attributes[cacheId];1531if (varLocation === undef) {1532varLocation = curContext.getAttribLocation(programObj, varName);1533curContextCache.attributes[cacheId] = varLocation1534}1535if (varLocation !== -1) {1536curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO);1537curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0);1538curContext.enableVertexAttribArray(varLocation)1539}1540}1541function disableVertexAttribPointer(cacheId, programObj, varName) {1542var varLocation = curContextCache.attributes[cacheId];1543if (varLocation === undef) {1544varLocation = curContext.getAttribLocation(programObj, varName);1545curContextCache.attributes[cacheId] = varLocation1546}1547if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation)1548}1549var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) {1550var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER);1551curContext.shaderSource(vertexShaderObject, vetexShaderSource);1552curContext.compileShader(vertexShaderObject);1553if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject);1554var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER);1555curContext.shaderSource(fragmentShaderObject, fragmentShaderSource);1556curContext.compileShader(fragmentShaderObject);1557if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject);1558var programObject = curContext.createProgram();1559curContext.attachShader(programObject, vertexShaderObject);1560curContext.attachShader(programObject, fragmentShaderObject);1561curContext.linkProgram(programObject);1562if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders.";1563return programObject1564};1565var imageModeCorner = function(x, y, w, h, whAreSizes) {1566return {1567x: x,1568y: y,1569w: w,1570h: h1571}1572};1573var imageModeConvert = imageModeCorner;1574var imageModeCorners = function(x, y, w, h, whAreSizes) {1575return {1576x: x,1577y: y,1578w: whAreSizes ? w : w - x,1579h: whAreSizes ? h : h - y1580}1581};1582var imageModeCenter = function(x, y, w, h, whAreSizes) {1583return {1584x: x - w / 2,1585y: y - h / 2,1586w: w,1587h: h1588}1589};1590var DrawingShared = function() {};1591var Drawing2D = function() {};1592var Drawing3D = function() {};1593var DrawingPre = function() {};1594Drawing2D.prototype = new DrawingShared;1595Drawing2D.prototype.constructor = Drawing2D;1596Drawing3D.prototype = new DrawingShared;1597Drawing3D.prototype.constructor = Drawing3D;1598DrawingPre.prototype = new DrawingShared;1599DrawingPre.prototype.constructor = DrawingPre;1600DrawingShared.prototype.a3DOnlyFunction = nop;1601var charMap = {};1602var Char = p.Character = function(chr) {1603if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0);1604else if (typeof chr === "number") this.code = chr;1605else if (chr instanceof Char) this.code = chr;1606else this.code = NaN;1607return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code]1608};1609Char.prototype.toString = function() {1610return String.fromCharCode(this.code)1611};1612Char.prototype.valueOf = function() {1613return this.code1614};1615var PShape = p.PShape = function(family) {1616this.family = family || 0;1617this.visible = true;1618this.style = true;1619this.children = [];1620this.nameTable = [];1621this.params = [];1622this.name = "";1623this.image = null;1624this.matrix = null;1625this.kind = null;1626this.close = null;1627this.width = null;1628this.height = null;1629this.parent = null1630};1631PShape.prototype = {1632isVisible: function() {1633return this.visible1634},1635setVisible: function(visible) {1636this.visible = visible1637},1638disableStyle: function() {1639this.style = false;1640for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle()1641},1642enableStyle: function() {1643this.style = true;1644for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle()1645},1646getFamily: function() {1647return this.family1648},1649getWidth: function() {1650return this.width1651},1652getHeight: function() {1653return this.height1654},1655setName: function(name) {1656this.name = name1657},1658getName: function() {1659return this.name1660},1661draw: function(renderContext) {1662renderContext = renderContext || p;1663if (this.visible) {1664this.pre(renderContext);1665this.drawImpl(renderContext);1666this.post(renderContext)1667}1668},1669drawImpl: function(renderContext) {1670if (this.family === 0) this.drawGroup(renderContext);1671else if (this.family === 1) this.drawPrimitive(renderContext);1672else if (this.family === 3) this.drawGeometry(renderContext);1673else if (this.family === 21) this.drawPath(renderContext)1674},1675drawPath: function(renderContext) {1676var i, j;1677if (this.vertices.length === 0) return;1678renderContext.beginShape();1679if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) renderContext.vertex(this.vertices[i][0], this.vertices[i][1]);1680else for (i = 0, j = this.vertices.length; i < j; i++) renderContext.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]);1681else {1682var index = 0;1683if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) {1684renderContext.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index]["moveTo"]);1685renderContext.breakShape = false;1686index++1687} else if (this.vertexCodes[i] === 1) {1688renderContext.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]);1689index += 31690} else if (this.vertexCodes[i] === 2) {1691renderContext.curveVertex(this.vertices[index][0], this.vertices[index][1]);1692index++1693} else {1694if (this.vertexCodes[i] === 3) renderContext.breakShape = true1695} else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) {1696renderContext.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]);1697if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true;1698else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false;1699renderContext.breakShape = false1700} else if (this.vertexCodes[i] === 1) {1701renderContext.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]);1702index += 31703} else if (this.vertexCodes[i] === 2) {1704renderContext.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]);1705index++1706} else if (this.vertexCodes[i] === 3) renderContext.breakShape = true1707}1708renderContext.endShape(this.close ? 2 : 1)1709},1710drawGeometry: function(renderContext) {1711var i, j;1712renderContext.beginShape(this.kind);1713if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) renderContext.vertex(this.vertices[i]);1714else for (i = 0, j = this.vertices.length; i < j; i++) {1715var vert = this.vertices[i];1716if (vert[2] === 0) renderContext.vertex(vert[0], vert[1]);1717else renderContext.vertex(vert[0], vert[1], vert[2])1718}1719renderContext.endShape()1720},1721drawGroup: function(renderContext) {1722for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw(renderContext)1723},1724drawPrimitive: function(renderContext) {1725if (this.kind === 2) renderContext.point(this.params[0], this.params[1]);1726else if (this.kind === 4) if (this.params.length === 4) renderContext.line(this.params[0], this.params[1], this.params[2], this.params[3]);1727else renderContext.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]);1728else if (this.kind === 8) renderContext.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]);1729else if (this.kind === 16) renderContext.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]);1730else if (this.kind === 30) if (this.image !== null) {1731var imMode = imageModeConvert;1732renderContext.imageMode(0);1733renderContext.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]);1734imageModeConvert = imMode1735} else {1736var rcMode = curRectMode;1737renderContext.rectMode(0);1738renderContext.rect(this.params[0], this.params[1], this.params[2], this.params[3]);1739curRectMode = rcMode1740} else if (this.kind === 31) {1741var elMode = curEllipseMode;1742renderContext.ellipseMode(0);1743renderContext.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]);1744curEllipseMode = elMode1745} else if (this.kind === 32) {1746var eMode = curEllipseMode;1747renderContext.ellipseMode(0);1748renderContext.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]);1749curEllipseMode = eMode1750} else if (this.kind === 41) if (this.params.length === 1) renderContext.box(this.params[0]);1751else renderContext.box(this.params[0], this.params[1], this.params[2]);1752else if (this.kind === 40) renderContext.sphere(this.params[0])1753},1754pre: function(renderContext) {1755if (this.matrix) {1756renderContext.pushMatrix();1757renderContext.transform(this.matrix)1758}1759if (this.style) {1760renderContext.pushStyle();1761this.styles(renderContext)1762}1763},1764post: function(renderContext) {1765if (this.matrix) renderContext.popMatrix();1766if (this.style) renderContext.popStyle()1767},1768styles: function(renderContext) {1769if (this.stroke) {1770renderContext.stroke(this.strokeColor);1771renderContext.strokeWeight(this.strokeWeight);1772renderContext.strokeCap(this.strokeCap);1773renderContext.strokeJoin(this.strokeJoin)1774} else renderContext.noStroke();1775if (this.fill) renderContext.fill(this.fillColor);1776else renderContext.noFill()1777},1778getChild: function(child) {1779var i, j;1780if (typeof child === "number") return this.children[child];1781var found;1782if (child === "" || this.name === child) return this;1783if (this.nameTable.length > 0) {1784for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) {1785found = this.nameTable[i];1786break1787}1788if (found) return found1789}1790for (i = 0, j = this.children.length; i < j; i++) {1791found = this.children[i].getChild(child);1792if (found) return found1793}1794return null1795},1796getChildCount: function() {1797return this.children.length1798},1799addChild: function(child) {1800this.children.push(child);1801child.parent = this;1802if (child.getName() !== null) this.addName(child.getName(), child)1803},1804addName: function(name, shape) {1805if (this.parent !== null) this.parent.addName(name, shape);1806else this.nameTable.push([name, shape])1807},1808translate: function() {1809if (arguments.length === 2) {1810this.checkMatrix(2);1811this.matrix.translate(arguments[0], arguments[1])1812} else {1813this.checkMatrix(3);1814this.matrix.translate(arguments[0], arguments[1], 0)1815}1816},1817checkMatrix: function(dimensions) {1818if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D;1819else this.matrix = new p.PMatrix3D;1820else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D1821},1822rotateX: function(angle) {1823this.rotate(angle, 1, 0, 0)1824},1825rotateY: function(angle) {1826this.rotate(angle, 0, 1, 0)1827},1828rotateZ: function(angle) {1829this.rotate(angle, 0, 0, 1)1830},1831rotate: function() {1832if (arguments.length === 1) {1833this.checkMatrix(2);1834this.matrix.rotate(arguments[0])1835} else {1836this.checkMatrix(3);1837this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3])1838}1839},1840scale: function() {1841if (arguments.length === 2) {1842this.checkMatrix(2);1843this.matrix.scale(arguments[0], arguments[1])1844} else if (arguments.length === 3) {1845this.checkMatrix(2);1846this.matrix.scale(arguments[0], arguments[1], arguments[2])1847} else {1848this.checkMatrix(2);1849this.matrix.scale(arguments[0])1850}1851},1852resetMatrix: function() {1853this.checkMatrix(2);1854this.matrix.reset()1855},1856applyMatrix: function(matrix) {1857if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1);1858else if (arguments.length === 6) {1859this.checkMatrix(2);1860this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1)1861} else if (arguments.length === 16) {1862this.checkMatrix(3);1863this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15])1864}1865}1866};1867var PShapeSVG = p.PShapeSVG = function() {1868p.PShape.call(this);1869if (arguments.length === 1) {1870this.element = arguments[0];1871this.vertexCodes = [];1872this.vertices = [];1873this.opacity = 1;1874this.stroke = false;1875this.strokeColor = 4278190080;1876this.strokeWeight = 1;1877this.strokeCap = 'butt';1878this.strokeJoin = 'miter';1879this.strokeGradient = null;1880this.strokeGradientPaint = null;1881this.strokeName = null;1882this.strokeOpacity = 1;1883this.fill = true;1884this.fillColor = 4278190080;1885this.fillGradient = null;1886this.fillGradientPaint = null;1887this.fillName = null;1888this.fillOpacity = 1;1889if (this.element.getName() !== "svg") throw "root is not <svg>, it's <" + this.element.getName() + ">";1890} else if (arguments.length === 2) if (typeof arguments[1] === "string") {1891if (arguments[1].indexOf(".svg") > -1) {1892this.element = new p.XMLElement(p, arguments[1]);1893this.vertexCodes = [];1894this.vertices = [];1895this.opacity = 1;1896this.stroke = false;1897this.strokeColor = 4278190080;1898this.strokeWeight = 1;1899this.strokeCap = 'butt';1900this.strokeJoin = 'miter';1901this.strokeGradient = "";1902this.strokeGradientPaint = "";1903this.strokeName = "";1904this.strokeOpacity = 1;1905this.fill = true;1906this.fillColor = 4278190080;1907this.fillGradient = null;1908this.fillGradientPaint = null;1909this.fillOpacity = 11910}1911} else if (arguments[0]) {1912this.element = arguments[1];1913this.vertexCodes = arguments[0].vertexCodes.slice();1914this.vertices = arguments[0].vertices.slice();1915this.stroke = arguments[0].stroke;1916this.strokeColor = arguments[0].strokeColor;1917this.strokeWeight = arguments[0].strokeWeight;1918this.strokeCap = arguments[0].strokeCap;1919this.strokeJoin = arguments[0].strokeJoin;1920this.strokeGradient = arguments[0].strokeGradient;1921this.strokeGradientPaint = arguments[0].strokeGradientPaint;1922this.strokeName = arguments[0].strokeName;1923this.fill = arguments[0].fill;1924this.fillColor = arguments[0].fillColor;1925this.fillGradient = arguments[0].fillGradient;1926this.fillGradientPaint = arguments[0].fillGradientPaint;1927this.fillName = arguments[0].fillName;1928this.strokeOpacity = arguments[0].strokeOpacity;1929this.fillOpacity = arguments[0].fillOpacity;1930this.opacity = arguments[0].opacity1931}1932this.name = this.element.getStringAttribute("id");1933var displayStr = this.element.getStringAttribute("display", "inline");1934this.visible = displayStr !== "none";1935var str = this.element.getAttribute("transform");1936if (str) this.matrix = this.parseMatrix(str);1937var viewBoxStr = this.element.getStringAttribute("viewBox");1938if (viewBoxStr !== null) {1939var viewBox = viewBoxStr.split(" ");1940this.width = viewBox[2];1941this.height = viewBox[3]1942}1943var unitWidth = this.element.getStringAttribute("width");1944var unitHeight = this.element.getStringAttribute("height");1945if (unitWidth !== null) {1946this.width = this.parseUnitSize(unitWidth);1947this.height = this.parseUnitSize(unitHeight)1948} else if (this.width === 0 || this.height === 0) {1949this.width = 1;1950this.height = 1;1951throw "The width and/or height is not " + "readable in the <svg> tag of this file.";1952}1953this.parseColors(this.element);1954this.parseChildren(this.element)1955};1956PShapeSVG.prototype = new PShape;1957PShapeSVG.prototype.parseMatrix = function() {1958function getCoords(s) {1959var m = [];1960s.replace(/\((.*?)\)/, function() {1961return function(all, params) {1962m = params.replace(/,+/g, " ").split(/\s+/)1963}1964}());1965return m1966}1967return function(str) {1968this.checkMatrix(2);1969var pieces = [];1970str.replace(/\s*(\w+)\((.*?)\)/g, function(all) {1971pieces.push(p.trim(all))1972});1973if (pieces.length === 0) return null;1974for (var i = 0, j = pieces.length; i < j; i++) {1975var m = getCoords(pieces[i]);1976if (pieces[i].indexOf("matrix") !== -1) this.matrix.set(m[0], m[2], m[4], m[1], m[3], m[5]);1977else if (pieces[i].indexOf("translate") !== -1) {1978var tx = m[0];1979var ty = m.length === 2 ? m[1] : 0;1980this.matrix.translate(tx, ty)1981} else if (pieces[i].indexOf("scale") !== -1) {1982var sx = m[0];1983var sy = m.length === 2 ? m[1] : m[0];1984this.matrix.scale(sx, sy)1985} else if (pieces[i].indexOf("rotate") !== -1) {1986var angle = m[0];1987if (m.length === 1) this.matrix.rotate(p.radians(angle));1988else if (m.length === 3) {1989this.matrix.translate(m[1], m[2]);1990this.matrix.rotate(p.radians(m[0]));1991this.matrix.translate(-m[1], -m[2])1992}1993} else if (pieces[i].indexOf("skewX") !== -1) this.matrix.skewX(parseFloat(m[0]));1994else if (pieces[i].indexOf("skewY") !== -1) this.matrix.skewY(m[0]);1995else if (pieces[i].indexOf("shearX") !== -1) this.matrix.shearX(m[0]);1996else if (pieces[i].indexOf("shearY") !== -1) this.matrix.shearY(m[0])1997}1998return this.matrix1999}2000}();2001PShapeSVG.prototype.parseChildren = function(element) {2002var newelement = element.getChildren();2003var children = new p.PShape;2004for (var i = 0, j = newelement.length; i < j; i++) {2005var kid = this.parseChild(newelement[i]);2006if (kid) children.addChild(kid)2007}2008this.children.push(children)2009};2010PShapeSVG.prototype.getName = function() {2011return this.name2012};2013PShapeSVG.prototype.parseChild = function(elem) {2014var name = elem.getName();2015var shape;2016if (name === "g") shape = new PShapeSVG(this, elem);2017else if (name === "defs") shape = new PShapeSVG(this, elem);2018else if (name === "line") {2019shape = new PShapeSVG(this, elem);2020shape.parseLine()2021} else if (name === "circle") {2022shape = new PShapeSVG(this, elem);2023shape.parseEllipse(true)2024} else if (name === "ellipse") {2025shape = new PShapeSVG(this, elem);2026shape.parseEllipse(false)2027} else if (name === "rect") {2028shape = new PShapeSVG(this, elem);2029shape.parseRect()2030} else if (name === "polygon") {2031shape = new PShapeSVG(this, elem);2032shape.parsePoly(true)2033} else if (name === "polyline") {2034shape = new PShapeSVG(this, elem);2035shape.parsePoly(false)2036} else if (name === "path") {2037shape = new PShapeSVG(this, elem);2038shape.parsePath()2039} else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient");2040else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient");2041else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text");2042else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter");2043else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask");2044else nop();2045return shape2046};2047PShapeSVG.prototype.parsePath = function() {2048this.family = 21;2049this.kind = 0;2050var pathDataChars = [];2051var c;2052var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " "));2053if (pathData === null) return;2054pathData = p.__toCharArray(pathData);2055var cx = 0,2056cy = 0,2057ctrlX = 0,2058ctrlY = 0,2059ctrlX1 = 0,2060ctrlX2 = 0,2061ctrlY1 = 0,2062ctrlY2 = 0,2063endX = 0,2064endY = 0,2065ppx = 0,2066ppy = 0,2067px = 0,2068py = 0,2069i = 0,2070valOf = 0;2071var str = "";2072var tmpArray = [];2073var flag = false;2074var lastInstruction;2075var command;2076var j, k;2077while (i < pathData.length) {2078valOf = pathData[i].valueOf();2079if (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 122) {2080j = i;2081i++;2082if (i < pathData.length) {2083tmpArray = [];2084valOf = pathData[i].valueOf();2085while (! (valOf >= 65 && valOf <= 90 || valOf >= 97 && valOf <= 100 || valOf >= 102 && valOf <= 122) && flag === false) {2086if (valOf === 32) {2087if (str !== "") {2088tmpArray.push(parseFloat(str));2089str = ""2090}2091i++2092} else if (valOf === 45) if (pathData[i - 1].valueOf() === 101) {2093str += pathData[i].toString();2094i++2095} else {2096if (str !== "") tmpArray.push(parseFloat(str));2097str = pathData[i].toString();2098i++2099} else {2100str += pathData[i].toString();2101i++2102}2103if (i === pathData.length) flag = true;2104else valOf = pathData[i].valueOf()2105}2106}2107if (str !== "") {2108tmpArray.push(parseFloat(str));2109str = ""2110}2111command = pathData[j];2112valOf = command.valueOf();2113if (valOf === 77) {2114if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) {2115cx = tmpArray[0];2116cy = tmpArray[1];2117this.parsePathMoveto(cx, cy);2118if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) {2119cx = tmpArray[j];2120cy = tmpArray[j + 1];2121this.parsePathLineto(cx, cy)2122}2123}2124} else if (valOf === 109) {2125if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) {2126cx += tmpArray[0];2127cy += tmpArray[1];2128this.parsePathMoveto(cx, cy);2129if (tmpArray.length > 2) for (j = 2, k = tmpArray.length; j < k; j += 2) {2130cx += tmpArray[j];2131cy += tmpArray[j + 1];2132this.parsePathLineto(cx, cy)2133}2134}2135} else if (valOf === 76) {2136if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) {2137cx = tmpArray[j];2138cy = tmpArray[j + 1];2139this.parsePathLineto(cx, cy)2140}2141} else if (valOf === 108) {2142if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) {2143cx += tmpArray[j];2144cy += tmpArray[j + 1];2145this.parsePathLineto(cx, cy)2146}2147} else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) {2148cx = tmpArray[j];2149this.parsePathLineto(cx, cy)2150} else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) {2151cx += tmpArray[j];2152this.parsePathLineto(cx, cy)2153} else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) {2154cy = tmpArray[j];2155this.parsePathLineto(cx, cy)2156} else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) {2157cy += tmpArray[j];2158this.parsePathLineto(cx, cy)2159} else if (valOf === 67) {2160if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) {2161ctrlX1 = tmpArray[j];2162ctrlY1 = tmpArray[j + 1];2163ctrlX2 = tmpArray[j + 2];2164ctrlY2 = tmpArray[j + 3];2165endX = tmpArray[j + 4];2166endY = tmpArray[j + 5];2167this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY);2168cx = endX;2169cy = endY2170}2171} else if (valOf === 99) {2172if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; j += 6) {2173ctrlX1 = cx + tmpArray[j];2174ctrlY1 = cy + tmpArray[j + 1];2175ctrlX2 = cx + tmpArray[j + 2];2176ctrlY2 = cy + tmpArray[j + 3];2177endX = cx + tmpArray[j + 4];2178endY = cy + tmpArray[j + 5];2179this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY);2180cx = endX;2181cy = endY2182}2183} else if (valOf === 83) {2184if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) {2185if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") {2186ppx = this.vertices[this.vertices.length - 2][0];2187ppy = this.vertices[this.vertices.length - 2][1];2188px = this.vertices[this.vertices.length - 1][0];2189py = this.vertices[this.vertices.length - 1][1];2190ctrlX1 = px + (px - ppx);2191ctrlY1 = py + (py - ppy)2192} else {2193ctrlX1 = this.vertices[this.vertices.length - 1][0];2194ctrlY1 = this.vertices[this.vertices.length - 1][1]2195}2196ctrlX2 = tmpArray[j];2197ctrlY2 = tmpArray[j + 1];2198endX = tmpArray[j + 2];2199endY = tmpArray[j + 3];2200this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY);2201cx = endX;2202cy = endY2203}2204} else if (valOf === 115) {2205if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) {2206if (lastInstruction.toLowerCase() === "c" || lastInstruction.toLowerCase() === "s") {2207ppx = this.vertices[this.vertices.length - 2][0];2208ppy = this.vertices[this.vertices.length - 2][1];2209px = this.vertices[this.vertices.length - 1][0];2210py = this.vertices[this.vertices.length - 1][1];2211ctrlX1 = px + (px - ppx);2212ctrlY1 = py + (py - ppy)2213} else {2214ctrlX1 = this.vertices[this.vertices.length - 1][0];2215ctrlY1 = this.vertices[this.vertices.length - 1][1]2216}2217ctrlX2 = cx + tmpArray[j];2218ctrlY2 = cy + tmpArray[j + 1];2219endX = cx + tmpArray[j + 2];2220endY = cy + tmpArray[j + 3];2221this.parsePathCurveto(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY);2222cx = endX;2223cy = endY2224}2225} else if (valOf === 81) {2226if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) {2227ctrlX = tmpArray[j];2228ctrlY = tmpArray[j + 1];2229endX = tmpArray[j + 2];2230endY = tmpArray[j + 3];2231this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY);2232cx = endX;2233cy = endY2234}2235} else if (valOf === 113) {2236if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; j += 4) {2237ctrlX = cx + tmpArray[j];2238ctrlY = cy + tmpArray[j + 1];2239endX = cx + tmpArray[j + 2];2240endY = cy + tmpArray[j + 3];2241this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY);2242cx = endX;2243cy = endY2244}2245} else if (valOf === 84) {2246if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) {2247if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") {2248ppx = this.vertices[this.vertices.length - 2][0];2249ppy = this.vertices[this.vertices.length - 2][1];2250px = this.vertices[this.vertices.length - 1][0];2251py = this.vertices[this.vertices.length - 1][1];2252ctrlX = px + (px - ppx);2253ctrlY = py + (py - ppy)2254} else {2255ctrlX = cx;2256ctrlY = cy2257}2258endX = tmpArray[j];2259endY = tmpArray[j + 1];2260this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY);2261cx = endX;2262cy = endY2263}2264} else if (valOf === 116) {2265if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) {2266if (lastInstruction.toLowerCase() === "q" || lastInstruction.toLowerCase() === "t") {2267ppx = this.vertices[this.vertices.length - 2][0];2268ppy = this.vertices[this.vertices.length - 2][1];2269px = this.vertices[this.vertices.length - 1][0];2270py = this.vertices[this.vertices.length - 1][1];2271ctrlX = px + (px - ppx);2272ctrlY = py + (py - ppy)2273} else {2274ctrlX = cx;2275ctrlY = cy2276}2277endX = cx + tmpArray[j];2278endY = cy + tmpArray[j + 1];2279this.parsePathQuadto(cx, cy, ctrlX, ctrlY, endX, endY);2280cx = endX;2281cy = endY2282}2283} else if (valOf === 90 || valOf === 122) this.close = true;2284lastInstruction = command.toString()2285} else i++2286}2287};2288PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) {2289if (this.vertices.length > 0) {2290this.parsePathCode(1);2291this.parsePathVertex(x1 + (cx - x1) * 2 / 3, y1 + (cy - y1) * 2 / 3);2292this.parsePathVertex(x2 + (cx - x2) * 2 / 3, y2 + (cy - y2) * 2 / 3);2293this.parsePathVertex(x2, y2)2294} else throw "Path must start with M/m";2295};2296PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) {2297if (this.vertices.length > 0) {2298this.parsePathCode(1);2299this.parsePathVertex(x1, y1);2300this.parsePathVertex(x2, y2);2301this.parsePathVertex(x3, y3)2302} else throw "Path must start with M/m";2303};2304PShapeSVG.prototype.parsePathLineto = function(px, py) {2305if (this.vertices.length > 0) {2306this.parsePathCode(0);2307this.parsePathVertex(px, py);2308this.vertices[this.vertices.length - 1]["moveTo"] = false2309} else throw "Path must start with M/m";2310};2311PShapeSVG.prototype.parsePathMoveto = function(px, py) {2312if (this.vertices.length > 0) this.parsePathCode(3);2313this.parsePathCode(0);2314this.parsePathVertex(px, py);2315this.vertices[this.vertices.length - 1]["moveTo"] = true2316};2317PShapeSVG.prototype.parsePathVertex = function(x, y) {2318var verts = [];2319verts[0] = x;2320verts[1] = y;2321this.vertices.push(verts)2322};2323PShapeSVG.prototype.parsePathCode = function(what) {2324this.vertexCodes.push(what)2325};2326PShapeSVG.prototype.parsePoly = function(val) {2327this.family = 21;2328this.close = val;2329var pointsAttr = p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g, " "));2330if (pointsAttr !== null) {2331var pointsBuffer = pointsAttr.split(" ");2332if (pointsBuffer.length % 2 === 0) for (var i = 0, j = pointsBuffer.length; i < j; i++) {2333var verts = [];2334verts[0] = pointsBuffer[i];2335verts[1] = pointsBuffer[++i];2336this.vertices.push(verts)2337} else throw "Error parsing polygon points: odd number of coordinates provided";2338}2339};2340PShapeSVG.prototype.parseRect = function() {2341this.kind = 30;2342this.family = 1;2343this.params = [];2344this.params[0] = this.element.getFloatAttribute("x");2345this.params[1] = this.element.getFloatAttribute("y");2346this.params[2] = this.element.getFloatAttribute("width");2347this.params[3] = this.element.getFloatAttribute("height");2348if (this.params[2] < 0 || this.params[3] < 0) throw "svg error: negative width or height found while parsing <rect>";2349};2350PShapeSVG.prototype.parseEllipse = function(val) {2351this.kind = 31;2352this.family = 1;2353this.params = [];2354this.params[0] = this.element.getFloatAttribute("cx") | 0;2355this.params[1] = this.element.getFloatAttribute("cy") | 0;2356var rx, ry;2357if (val) {2358rx = ry = this.element.getFloatAttribute("r");2359if (rx < 0) throw "svg error: negative radius found while parsing <circle>";2360} else {2361rx = this.element.getFloatAttribute("rx");2362ry = this.element.getFloatAttribute("ry");2363if (rx < 0 || ry < 0) throw "svg error: negative x-axis radius or y-axis radius found while parsing <ellipse>";2364}2365this.params[0] -= rx;2366this.params[1] -= ry;2367this.params[2] = rx * 2;2368this.params[3] = ry * 22369};2370PShapeSVG.prototype.parseLine = function() {2371this.kind = 4;2372this.family = 1;2373this.params = [];2374this.params[0] = this.element.getFloatAttribute("x1");2375this.params[1] = this.element.getFloatAttribute("y1");2376this.params[2] = this.element.getFloatAttribute("x2");2377this.params[3] = this.element.getFloatAttribute("y2")2378};2379PShapeSVG.prototype.parseColors = function(element) {2380if (element.hasAttribute("opacity")) this.setOpacity(element.getAttribute("opacity"));2381if (element.hasAttribute("stroke")) this.setStroke(element.getAttribute("stroke"));2382if (element.hasAttribute("stroke-width")) this.setStrokeWeight(element.getAttribute("stroke-width"));2383if (element.hasAttribute("stroke-linejoin")) this.setStrokeJoin(element.getAttribute("stroke-linejoin"));2384if (element.hasAttribute("stroke-linecap")) this.setStrokeCap(element.getStringAttribute("stroke-linecap"));2385if (element.hasAttribute("fill")) this.setFill(element.getStringAttribute("fill"));2386if (element.hasAttribute("style")) {2387var styleText = element.getStringAttribute("style");2388var styleTokens = styleText.toString().split(";");2389for (var i = 0, j = styleTokens.length; i < j; i++) {2390var tokens = p.trim(styleTokens[i].split(":"));2391if (tokens[0] === "fill") this.setFill(tokens[1]);2392else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]);2393else if (tokens[0] === "stroke") this.setStroke(tokens[1]);2394else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]);2395else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]);2396else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]);2397else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]);2398else if (tokens[0] === "opacity") this.setOpacity(tokens[1])2399}2400}2401};2402PShapeSVG.prototype.setFillOpacity = function(opacityText) {2403this.fillOpacity = parseFloat(opacityText);2404this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 167772152405};2406PShapeSVG.prototype.setFill = function(fillText) {2407var opacityMask = this.fillColor & 4278190080;2408if (fillText === "none") this.fill = false;2409else if (fillText.indexOf("#") === 0) {2410this.fill = true;2411if (fillText.length === 4) fillText = fillText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3");2412this.fillColor = opacityMask | parseInt(fillText.substring(1), 16) & 167772152413} else if (fillText.indexOf("rgb") === 0) {2414this.fill = true;2415this.fillColor = opacityMask | this.parseRGB(fillText)2416} else if (fillText.indexOf("url(#") === 0) this.fillName = fillText.substring(5, fillText.length - 1);2417else if (colors[fillText]) {2418this.fill = true;2419this.fillColor = opacityMask | parseInt(colors[fillText].substring(1), 16) & 167772152420}2421};2422PShapeSVG.prototype.setOpacity = function(opacity) {2423this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215;2424this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 167772152425};2426PShapeSVG.prototype.setStroke = function(strokeText) {2427var opacityMask = this.strokeColor & 4278190080;2428if (strokeText === "none") this.stroke = false;2429else if (strokeText.charAt(0) === "#") {2430this.stroke = true;2431if (strokeText.length === 4) strokeText = strokeText.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3");2432this.strokeColor = opacityMask | parseInt(strokeText.substring(1), 16) & 167772152433} else if (strokeText.indexOf("rgb") === 0) {2434this.stroke = true;2435this.strokeColor = opacityMask | this.parseRGB(strokeText)2436} else if (strokeText.indexOf("url(#") === 0) this.strokeName = strokeText.substring(5, strokeText.length - 1);2437else if (colors[strokeText]) {2438this.stroke = true;2439this.strokeColor = opacityMask | parseInt(colors[strokeText].substring(1), 16) & 167772152440}2441};2442PShapeSVG.prototype.setStrokeWeight = function(weight) {2443this.strokeWeight = this.parseUnitSize(weight)2444};2445PShapeSVG.prototype.setStrokeJoin = function(linejoin) {2446if (linejoin === "miter") this.strokeJoin = 'miter';2447else if (linejoin === "round") this.strokeJoin = 'round';2448else if (linejoin === "bevel") this.strokeJoin = 'bevel'2449};2450PShapeSVG.prototype.setStrokeCap = function(linecap) {2451if (linecap === "butt") this.strokeCap = 'butt';2452else if (linecap === "round") this.strokeCap = 'round';2453else if (linecap === "square") this.strokeCap = 'square'2454};2455PShapeSVG.prototype.setStrokeOpacity = function(opacityText) {2456this.strokeOpacity = parseFloat(opacityText);2457this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 167772152458};2459PShapeSVG.prototype.parseRGB = function(color) {2460var sub = color.substring(color.indexOf("(") + 1, color.indexOf(")"));2461var values = sub.split(", ");2462return values[0] << 16 | values[1] << 8 | values[2]2463};2464PShapeSVG.prototype.parseUnitSize = function(text) {2465var len = text.length - 2;2466if (len < 0) return text;2467if (text.indexOf("pt") === len) return parseFloat(text.substring(0, len)) * 1.25;2468if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15;2469if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307;2470if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307;2471if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90;2472if (text.indexOf("px") === len) return parseFloat(text.substring(0, len));2473return parseFloat(text)2474};2475p.shape = function(shape, x, y, width, height) {2476if (arguments.length >= 1 && arguments[0] !== null) if (shape.isVisible()) {2477p.pushMatrix();2478if (curShapeMode === 3) if (arguments.length === 5) {2479p.translate(x - width / 2, y - height / 2);2480p.scale(width / shape.getWidth(), height / shape.getHeight())2481} else if (arguments.length === 3) p.translate(x - shape.getWidth() / 2, -shape.getHeight() / 2);2482else p.translate(-shape.getWidth() / 2, -shape.getHeight() / 2);2483else if (curShapeMode === 0) if (arguments.length === 5) {2484p.translate(x, y);2485p.scale(width / shape.getWidth(), height / shape.getHeight())2486} else {2487if (arguments.length === 3) p.translate(x, y)2488} else if (curShapeMode === 1) if (arguments.length === 5) {2489width -= x;2490height -= y;2491p.translate(x, y);2492p.scale(width / shape.getWidth(), height / shape.getHeight())2493} else if (arguments.length === 3) p.translate(x, y);2494shape.draw(p);2495if (arguments.length === 1 && curShapeMode === 3 || arguments.length > 1) p.popMatrix()2496}2497};2498p.shapeMode = function(mode) {2499curShapeMode = mode2500};2501p.loadShape = function(filename) {2502if (arguments.length === 1) if (filename.indexOf(".svg") > -1) return new PShapeSVG(null, filename);2503return null2504};2505var XMLAttribute = function(fname, n, nameSpace, v, t) {2506this.fullName = fname || "";2507this.name = n || "";2508this.namespace = nameSpace || "";2509this.value = v;2510this.type = t2511};2512XMLAttribute.prototype = {2513getName: function() {2514return this.name2515},2516getFullName: function() {2517return this.fullName2518},2519getNamespace: function() {2520return this.namespace2521},2522getValue: function() {2523return this.value2524},2525getType: function() {2526return this.type2527},2528setValue: function(newval) {2529this.value = newval2530}2531};2532var XMLElement = p.XMLElement = function(selector, uri, sysid, line) {2533this.attributes = [];2534this.children = [];2535this.fullName = null;2536this.name = null;2537this.namespace = "";2538this.content = null;2539this.parent = null;2540this.lineNr = "";2541this.systemID = "";2542this.type = "ELEMENT";2543if (selector) if (typeof selector === "string") if (uri === undef && selector.indexOf("<") > -1) this.parse(selector);2544else {2545this.fullName = selector;2546this.namespace = uri;2547this.systemId = sysid;2548this.lineNr = line2549} else this.parse(uri)2550};2551XMLElement.prototype = {2552parse: function(textstring) {2553var xmlDoc;2554try {2555var extension = textstring.substring(textstring.length - 4);2556if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring);2557xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml");2558var elements = xmlDoc.documentElement;2559if (elements) this.parseChildrenRecursive(null, elements);2560else throw "Error loading document";2561return this2562} catch(e) {2563throw e;2564}2565},2566parseChildrenRecursive: function(parent, elementpath) {2567var xmlelement, xmlattribute, tmpattrib, l, m, child;2568if (!parent) {2569this.fullName = elementpath.localName;2570this.name = elementpath.nodeName;2571xmlelement = this2572} else {2573xmlelement = new XMLElement(elementpath.nodeName);2574xmlelement.parent = parent2575}2576if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent);2577if (elementpath.nodeType === 4) return this.createCDataElement(elementpath.textContent);2578if (elementpath.attributes) for (l = 0, m = elementpath.attributes.length; l < m; l++) {2579tmpattrib = elementpath.attributes[l];2580xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType);2581xmlelement.attributes.push(xmlattribute)2582}2583if (elementpath.childNodes) for (l = 0, m = elementpath.childNodes.length; l < m; l++) {2584var node = elementpath.childNodes[l];2585child = xmlelement.parseChildrenRecursive(xmlelement, node);2586if (child !== null) xmlelement.children.push(child)2587}2588return xmlelement2589},2590createElement: function(fullname, namespaceuri, sysid, line) {2591if (sysid === undef) return new XMLElement(fullname, namespaceuri);2592return new XMLElement(fullname, namespaceuri, sysid, line)2593},2594createPCDataElement: function(content, isCDATA) {2595if (content.replace(/^\s+$/g, "") === "") return null;2596var pcdata = new XMLElement;2597pcdata.type = "TEXT";2598pcdata.content = content;2599return pcdata2600},2601createCDataElement: function(content) {2602var cdata = this.createPCDataElement(content);2603if (cdata === null) return null;2604cdata.type = "CDATA";2605var htmlentities = {2606"<": "<",2607">": ">",2608"'": "'",2609'"': """2610},2611entity;2612for (entity in htmlentities) if (!Object.hasOwnProperty(htmlentities, entity)) content = content.replace(new RegExp(entity, "g"), htmlentities[entity]);2613cdata.cdata = content;2614return cdata2615},2616hasAttribute: function() {2617if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null;2618if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null2619},2620equals: function(other) {2621if (! (other instanceof XMLElement)) return false;2622var i, j;2623if (this.fullName !== other.fullName) return false;2624if (this.attributes.length !== other.getAttributeCount()) return false;2625if (this.attributes.length !== other.attributes.length) return false;2626var attr_name, attr_ns, attr_value, attr_type, attr_other;2627for (i = 0, j = this.attributes.length; i < j; i++) {2628attr_name = this.attributes[i].getName();2629attr_ns = this.attributes[i].getNamespace();2630attr_other = other.findAttribute(attr_name, attr_ns);2631if (attr_other === null) return false;2632if (this.attributes[i].getValue() !== attr_other.getValue()) return false;2633if (this.attributes[i].getType() !== attr_other.getType()) return false2634}2635if (this.children.length !== other.getChildCount()) return false;2636if (this.children.length > 0) {2637var child1, child2;2638for (i = 0, j = this.children.length; i < j; i++) {2639child1 = this.getChild(i);2640child2 = other.getChild(i);2641if (!child1.equals(child2)) return false2642}2643return true2644}2645return this.content === other.content2646},2647getContent: function() {2648if (this.type === "TEXT" || this.type === "CDATA") return this.content;2649var children = this.children;2650if (children.length === 1 && (children[0].type === "TEXT" || children[0].type === "CDATA")) return children[0].content;2651return null2652},2653getAttribute: function() {2654var attribute;2655if (arguments.length === 2) {2656attribute = this.findAttribute(arguments[0]);2657if (attribute) return attribute.getValue();2658return arguments[1]2659} else if (arguments.length === 1) {2660attribute = this.findAttribute(arguments[0]);2661if (attribute) return attribute.getValue();2662return null2663} else if (arguments.length === 3) {2664attribute = this.findAttribute(arguments[0], arguments[1]);2665if (attribute) return attribute.getValue();2666return arguments[2]2667}2668},2669getStringAttribute: function() {2670if (arguments.length === 1) return this.getAttribute(arguments[0]);2671if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]);2672return this.getAttribute(arguments[0], arguments[1], arguments[2])2673},2674getString: function(attributeName) {2675return this.getStringAttribute(attributeName)2676},2677getFloatAttribute: function() {2678if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0));2679if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]);2680return this.getAttribute(arguments[0], arguments[1], arguments[2])2681},2682getFloat: function(attributeName) {2683return this.getFloatAttribute(attributeName)2684},2685getIntAttribute: function() {2686if (arguments.length === 1) return this.getAttribute(arguments[0], 0);2687if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]);2688return this.getAttribute(arguments[0], arguments[1], arguments[2])2689},2690getInt: function(attributeName) {2691return this.getIntAttribute(attributeName)2692},2693hasChildren: function() {2694return this.children.length > 02695},2696addChild: function(child) {2697if (child !== null) {2698child.parent = this;2699this.children.push(child)2700}2701},2702insertChild: function(child, index) {2703if (child) {2704if (child.getLocalName() === null && !this.hasChildren()) {2705var lastChild = this.children[this.children.length - 1];2706if (lastChild.getLocalName() === null) {2707lastChild.setContent(lastChild.getContent() + child.getContent());2708return2709}2710}2711child.parent = this;2712this.children.splice(index, 0, child)2713}2714},2715getChild: function(selector) {2716if (typeof selector === "number") return this.children[selector];2717if (selector.indexOf("/") !== -1) return this.getChildRecursive(selector.split("/"), 0);2718var kid, kidName;2719for (var i = 0, j = this.getChildCount(); i < j; i++) {2720kid = this.getChild(i);2721kidName = kid.getName();2722if (kidName !== null && kidName === selector) return kid2723}2724return null2725},2726getChildren: function() {2727if (arguments.length === 1) {2728if (typeof arguments[0] === "number") return this.getChild(arguments[0]);2729if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0);2730var matches = [];2731var kid, kidName;2732for (var i = 0, j = this.getChildCount(); i < j; i++) {2733kid = this.getChild(i);2734kidName = kid.getName();2735if (kidName !== null && kidName === arguments[0]) matches.push(kid)2736}2737return matches2738}2739return this.children2740},2741getChildCount: function() {2742return this.children.length2743},2744getChildRecursive: function(items, offset) {2745if (offset === items.length) return this;2746var kid, kidName, matchName = items[offset];2747for (var i = 0, j = this.getChildCount(); i < j; i++) {2748kid = this.getChild(i);2749kidName = kid.getName();2750if (kidName !== null && kidName === matchName) return kid.getChildRecursive(items, offset + 1)2751}2752return null2753},2754getChildrenRecursive: function(items, offset) {2755if (offset === items.length - 1) return this.getChildren(items[offset]);2756var matches = this.getChildren(items[offset]);2757var kidMatches = [];2758for (var i = 0; i < matches.length; i++) kidMatches = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1));2759return kidMatches2760},2761isLeaf: function() {2762return !this.hasChildren()2763},2764listChildren: function() {2765var arr = [];2766for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName());2767return arr2768},2769removeAttribute: function(name, namespace) {2770this.namespace = namespace || "";2771for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) {2772this.attributes.splice(i, 1);2773break2774}2775},2776removeChild: function(child) {2777if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) {2778this.children.splice(i, 1);2779break2780}2781},2782removeChildAtIndex: function(index) {2783if (this.children.length > index) this.children.splice(index, 1)2784},2785findAttribute: function(name, namespace) {2786this.namespace = namespace || "";2787for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i];2788return null2789},2790setAttribute: function() {2791var attr;2792if (arguments.length === 3) {2793var index = arguments[0].indexOf(":");2794var name = arguments[0].substring(index + 1);2795attr = this.findAttribute(name, arguments[1]);2796if (attr) attr.setValue(arguments[2]);2797else {2798attr = new XMLAttribute(arguments[0], name, arguments[1], arguments[2], "CDATA");2799this.attributes.push(attr)2800}2801} else {2802attr = this.findAttribute(arguments[0]);2803if (attr) attr.setValue(arguments[1]);2804else {2805attr = new XMLAttribute(arguments[0], arguments[0], null, arguments[1], "CDATA");2806this.attributes.push(attr)2807}2808}2809},2810setString: function(attribute, value) {2811this.setAttribute(attribute, value)2812},2813setInt: function(attribute, value) {2814this.setAttribute(attribute, value)2815},2816setFloat: function(attribute, value) {2817this.setAttribute(attribute, value)2818},2819setContent: function(content) {2820if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children");2821this.content = content2822},2823setName: function() {2824if (arguments.length === 1) {2825this.name = arguments[0];2826this.fullName = arguments[0];2827this.namespace = null2828} else {2829var index = arguments[0].indexOf(":");2830if (arguments[1] === null || index < 0) this.name = arguments[0];2831else this.name = arguments[0].substring(index + 1);2832this.fullName = arguments[0];2833this.namespace = arguments[1]2834}2835},2836getName: function() {2837return this.fullName2838},2839getLocalName: function() {2840return this.name2841},2842getAttributeCount: function() {2843return this.attributes.length2844},2845toString: function() {2846if (this.type === "TEXT") return this.content;2847if (this.type === "CDATA") return this.cdata;2848var tagstring = this.fullName;2849var xmlstring = "<" + tagstring;2850var a, c;2851for (a = 0; a < this.attributes.length; a++) {2852var attr = this.attributes[a];2853xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"'2854}2855if (this.children.length === 0) if (this.content === "") xmlstring += "/>";2856else xmlstring += ">" + this.content + "</" + tagstring + ">";2857else {2858xmlstring += ">";2859for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString();2860xmlstring += "</" + tagstring + ">"2861}2862return xmlstring2863}2864};2865XMLElement.parse = function(xmlstring) {2866var element = new XMLElement;2867element.parse(xmlstring);2868return element2869};2870var XML = p.XML = p.XMLElement;2871p.loadXML = function(uri) {2872return new XML(p, uri)2873};2874var printMatrixHelper = function(elements) {2875var big = 0;2876for (var i = 0; i < elements.length; i++) if (i !== 0) big = Math.max(big, Math.abs(elements[i]));2877else big = Math.abs(elements[i]);2878var digits = (big + "").indexOf(".");2879if (digits === 0) digits = 1;2880else if (digits === -1) digits = (big + "").length;2881return digits2882};2883var PMatrix2D = p.PMatrix2D = function() {2884if (arguments.length === 0) this.reset();2885else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.set(arguments[0].array());2886else if (arguments.length === 6) this.set(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5])2887};2888PMatrix2D.prototype = {2889set: function() {2890if (arguments.length === 6) {2891var a = arguments;2892this.set([a[0], a[1], a[2], a[3], a[4], a[5]])2893} else if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) this.elements = arguments[0].array();2894else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice()2895},2896get: function() {2897var outgoing = new PMatrix2D;2898outgoing.set(this.elements);2899return outgoing2900},2901reset: function() {2902this.set([1, 0, 0, 0, 1, 0])2903},2904array: function array() {2905return this.elements.slice()2906},2907translate: function(tx, ty) {2908this.elements[2] = tx * this.elements[0] + ty * this.elements[1] + this.elements[2];2909this.elements[5] = tx * this.elements[3] + ty * this.elements[4] + this.elements[5]2910},2911invTranslate: function(tx, ty) {2912this.translate(-tx, -ty)2913},2914transpose: function() {},2915mult: function(source, target) {2916var x, y;2917if (source instanceof2918PVector) {2919x = source.x;2920y = source.y;2921if (!target) target = new PVector2922} else if (source instanceof Array) {2923x = source[0];2924y = source[1];2925if (!target) target = []2926}2927if (target instanceof Array) {2928target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2];2929target[1] = this.elements[3] * x + this.elements[4] * y + this.elements[5]2930} else if (target instanceof PVector) {2931target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2];2932target.y = this.elements[3] * x + this.elements[4] * y + this.elements[5];2933target.z = 02934}2935return target2936},2937multX: function(x, y) {2938return x * this.elements[0] + y * this.elements[1] + this.elements[2]2939},2940multY: function(x, y) {2941return x * this.elements[3] + y * this.elements[4] + this.elements[5]2942},2943skewX: function(angle) {2944this.apply(1, 0, 1, angle, 0, 0)2945},2946skewY: function(angle) {2947this.apply(1, 0, 1, 0, angle, 0)2948},2949shearX: function(angle) {2950this.apply(1, 0, 1, Math.tan(angle), 0, 0)2951},2952shearY: function(angle) {2953this.apply(1, 0, 1, 0, Math.tan(angle), 0)2954},2955determinant: function() {2956return this.elements[0] * this.elements[4] - this.elements[1] * this.elements[3]2957},2958invert: function() {2959var d = this.determinant();2960if (Math.abs(d) > -2147483648) {2961var old00 = this.elements[0];2962var old01 = this.elements[1];2963var old02 = this.elements[2];2964var old10 = this.elements[3];2965var old11 = this.elements[4];2966var old12 = this.elements[5];2967this.elements[0] = old11 / d;2968this.elements[3] = -old10 / d;2969this.elements[1] = -old01 / d;2970this.elements[4] = old00 / d;2971this.elements[2] = (old01 * old12 - old11 * old02) / d;2972this.elements[5] = (old10 * old02 - old00 * old12) / d;2973return true2974}2975return false2976},2977scale: function(sx, sy) {2978if (sx && !sy) sy = sx;2979if (sx && sy) {2980this.elements[0] *= sx;2981this.elements[1] *= sy;2982this.elements[3] *= sx;2983this.elements[4] *= sy2984}2985},2986invScale: function(sx, sy) {2987if (sx && !sy) sy = sx;2988this.scale(1 / sx, 1 / sy)2989},2990apply: function() {2991var source;2992if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array();2993else if (arguments.length === 6) source = Array.prototype.slice.call(arguments);2994else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0];2995var result = [0, 0, this.elements[2], 0, 0, this.elements[5]];2996var e = 0;2997for (var row = 0; row < 2; row++) for (var col = 0; col < 3; col++, e++) result[e] += this.elements[row * 3 + 0] * source[col + 0] + this.elements[row * 3 + 1] * source[col + 3];2998this.elements = result.slice()2999},3000preApply: function() {3001var source;3002if (arguments.length === 1 && arguments[0] instanceof PMatrix2D) source = arguments[0].array();3003else if (arguments.length === 6) source = Array.prototype.slice.call(arguments);3004else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0];3005var result = [0, 0, source[2], 0, 0, source[5]];3006result[2] = source[2] + this.elements[2] * source[0] + this.elements[5] * source[1];3007result[5] = source[5] + this.elements[2] * source[3] + this.elements[5] * source[4];3008result[0] = this.elements[0] * source[0] + this.elements[3] * source[1];3009result[3] = this.elements[0] * source[3] + this.elements[3] * source[4];3010result[1] = this.elements[1] * source[0] + this.elements[4] * source[1];3011result[4] = this.elements[1] * source[3] + this.elements[4] * source[4];3012this.elements = result.slice()3013},3014rotate: function(angle) {3015var c = Math.cos(angle);3016var s = Math.sin(angle);3017var temp1 = this.elements[0];3018var temp2 = this.elements[1];3019this.elements[0] = c * temp1 + s * temp2;3020this.elements[1] = -s * temp1 + c * temp2;3021temp1 = this.elements[3];3022temp2 = this.elements[4];3023this.elements[3] = c * temp1 + s * temp2;3024this.elements[4] = -s * temp1 + c * temp23025},3026rotateZ: function(angle) {3027this.rotate(angle)3028},3029invRotateZ: function(angle) {3030this.rotateZ(angle - Math.PI)3031},3032print: function() {3033var digits = printMatrixHelper(this.elements);3034var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + "\n" + p.nfs(this.elements[3], digits, 4) + " " + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + "\n\n";3035p.println(output)3036}3037};3038var PMatrix3D = p.PMatrix3D = function() {3039this.reset()3040};3041PMatrix3D.prototype = {3042set: function() {3043if (arguments.length === 16) this.elements = Array.prototype.slice.call(arguments);3044else if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) this.elements = arguments[0].array();3045else if (arguments.length === 1 && arguments[0] instanceof Array) this.elements = arguments[0].slice()3046},3047get: function() {3048var outgoing = new PMatrix3D;3049outgoing.set(this.elements);3050return outgoing3051},3052reset: function() {3053this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]3054},3055array: function array() {3056return this.elements.slice()3057},3058translate: function(tx, ty, tz) {3059if (tz === undef) tz = 0;3060this.elements[3] += tx * this.elements[0] + ty * this.elements[1] + tz * this.elements[2];3061this.elements[7] += tx * this.elements[4] + ty * this.elements[5] + tz * this.elements[6];3062this.elements[11] += tx * this.elements[8] + ty * this.elements[9] + tz * this.elements[10];3063this.elements[15] += tx * this.elements[12] + ty * this.elements[13] + tz * this.elements[14]3064},3065transpose: function() {3066var temp = this.elements[4];3067this.elements[4] = this.elements[1];3068this.elements[1] = temp;3069temp = this.elements[8];3070this.elements[8] = this.elements[2];3071this.elements[2] = temp;3072temp = this.elements[6];3073this.elements[6] = this.elements[9];3074this.elements[9] = temp;3075temp = this.elements[3];3076this.elements[3] = this.elements[12];3077this.elements[12] = temp;3078temp = this.elements[7];3079this.elements[7] = this.elements[13];3080this.elements[13] = temp;3081temp = this.elements[11];3082this.elements[11] = this.elements[14];3083this.elements[14] = temp3084},3085mult: function(source, target) {3086var x, y, z, w;3087if (source instanceof3088PVector) {3089x = source.x;3090y = source.y;3091z = source.z;3092w = 1;3093if (!target) target = new PVector3094} else if (source instanceof Array) {3095x = source[0];3096y = source[1];3097z = source[2];3098w = source[3] || 1;3099if (!target || target.length !== 3 && target.length !== 4) target = [0, 0, 0]3100}3101if (target instanceof Array) if (target.length === 3) {3102target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3];3103target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7];3104target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]3105} else if (target.length === 4) {3106target[0] = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w;3107target[1] = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w;3108target[2] = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w;3109target[3] = this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w3110}3111if (target instanceof PVector) {3112target.x = this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3];3113target.y = this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7];3114target.z = this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11]3115}3116return target3117},3118preApply: function() {3119var source;3120if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array();3121else if (arguments.length === 16) source = Array.prototype.slice.call(arguments);3122else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0];3123var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];3124var e = 0;3125for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[col + 0] * source[row * 4 + 0] + this.elements[col + 4] * source[row * 4 + 1] + this.elements[col + 8] * source[row * 4 + 2] + this.elements[col + 12] * source[row * 4 + 3];3126this.elements = result.slice()3127},3128apply: function() {3129var source;3130if (arguments.length === 1 && arguments[0] instanceof PMatrix3D) source = arguments[0].array();3131else if (arguments.length === 16) source = Array.prototype.slice.call(arguments);3132else if (arguments.length === 1 && arguments[0] instanceof Array) source = arguments[0];3133var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];3134var e = 0;3135for (var row = 0; row < 4; row++) for (var col = 0; col < 4; col++, e++) result[e] += this.elements[row * 4 + 0] * source[col + 0] + this.elements[row * 4 + 1] * source[col + 4] + this.elements[row * 4 + 2] * source[col + 8] + this.elements[row * 4 + 3] * source[col + 12];3136this.elements = result.slice()3137},3138rotate: function(angle, v0, v1, v2) {3139if (!v1) this.rotateZ(angle);3140else {3141var c = p.cos(angle);3142var s = p.sin(angle);3143var t = 1 - c;3144this.apply(t * v0 * v0 + c, t * v0 * v1 - s * v2, t * v0 * v2 + s * v1, 0, t * v0 * v1 + s * v2, t * v1 * v1 + c, t * v1 * v2 - s * v0, 0, t * v0 * v2 - s * v1, t * v1 * v2 + s * v0, t * v2 * v2 + c, 0, 0, 0, 0, 1)3145}3146},3147invApply: function() {3148if (inverseCopy === undef) inverseCopy = new PMatrix3D;3149var a = arguments;3150inverseCopy.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);3151if (!inverseCopy.invert()) return false;3152this.preApply(inverseCopy);3153return true3154},3155rotateX: function(angle) {3156var c = p.cos(angle);3157var s = p.sin(angle);3158this.apply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1])3159},3160rotateY: function(angle) {3161var c = p.cos(angle);3162var s = p.sin(angle);3163this.apply([c,31640, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1])3165},3166rotateZ: function(angle) {3167var c = Math.cos(angle);3168var s = Math.sin(angle);3169this.apply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])3170},3171scale: function(sx, sy, sz) {3172if (sx && !sy && !sz) sy = sz = sx;3173else if (sx && sy && !sz) sz = 1;3174if (sx && sy && sz) {3175this.elements[0] *= sx;3176this.elements[1] *= sy;3177this.elements[2] *= sz;3178this.elements[4] *= sx;3179this.elements[5] *= sy;3180this.elements[6] *= sz;3181this.elements[8] *= sx;3182this.elements[9] *= sy;3183this.elements[10] *= sz;3184this.elements[12] *= sx;3185this.elements[13] *= sy;3186this.elements[14] *= sz3187}3188},3189skewX: function(angle) {3190var t = Math.tan(angle);3191this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)3192},3193skewY: function(angle) {3194var t = Math.tan(angle);3195this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)3196},3197shearX: function(angle) {3198var t = Math.tan(angle);3199this.apply(1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)3200},3201shearY: function(angle) {3202var t = Math.tan(angle);3203this.apply(1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)3204},3205multX: function(x, y, z, w) {3206if (!z) return this.elements[0] * x + this.elements[1] * y + this.elements[3];3207if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3];3208return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3] * w3209},3210multY: function(x, y, z, w) {3211if (!z) return this.elements[4] * x + this.elements[5] * y + this.elements[7];3212if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7];3213return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7] * w3214},3215multZ: function(x, y, z, w) {3216if (!w) return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11];3217return this.elements[8] * x + this.elements[9] * y + this.elements[10] * z + this.elements[11] * w3218},3219multW: function(x, y, z, w) {3220if (!w) return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15];3221return this.elements[12] * x + this.elements[13] * y + this.elements[14] * z + this.elements[15] * w3222},3223invert: function() {3224var fA0 = this.elements[0] * this.elements[5] - this.elements[1] * this.elements[4];3225var fA1 = this.elements[0] * this.elements[6] - this.elements[2] * this.elements[4];3226var fA2 = this.elements[0] * this.elements[7] - this.elements[3] * this.elements[4];3227var fA3 = this.elements[1] * this.elements[6] - this.elements[2] * this.elements[5];3228var fA4 = this.elements[1] * this.elements[7] - this.elements[3] * this.elements[5];3229var fA5 = this.elements[2] * this.elements[7] - this.elements[3] * this.elements[6];3230var fB0 = this.elements[8] * this.elements[13] - this.elements[9] * this.elements[12];3231var fB1 = this.elements[8] * this.elements[14] - this.elements[10] * this.elements[12];3232var fB2 = this.elements[8] * this.elements[15] - this.elements[11] * this.elements[12];3233var fB3 = this.elements[9] * this.elements[14] - this.elements[10] * this.elements[13];3234var fB4 = this.elements[9] * this.elements[15] - this.elements[11] * this.elements[13];3235var fB5 = this.elements[10] * this.elements[15] - this.elements[11] * this.elements[14];3236var fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0;3237if (Math.abs(fDet) <= 1.0E-9) return false;3238var kInv = [];3239kInv[0] = +this.elements[5] * fB5 - this.elements[6] * fB4 + this.elements[7] * fB3;3240kInv[4] = -this.elements[4] * fB5 + this.elements[6] * fB2 - this.elements[7] * fB1;3241kInv[8] = +this.elements[4] * fB4 - this.elements[5] * fB2 + this.elements[7] * fB0;3242kInv[12] = -this.elements[4] * fB3 + this.elements[5] * fB1 - this.elements[6] * fB0;3243kInv[1] = -this.elements[1] * fB5 + this.elements[2] * fB4 - this.elements[3] * fB3;3244kInv[5] = +this.elements[0] * fB5 - this.elements[2] * fB2 + this.elements[3] * fB1;3245kInv[9] = -this.elements[0] * fB4 + this.elements[1] * fB2 - this.elements[3] * fB0;3246kInv[13] = +this.elements[0] * fB3 - this.elements[1] * fB1 + this.elements[2] * fB0;3247kInv[2] = +this.elements[13] * fA5 - this.elements[14] * fA4 + this.elements[15] * fA3;3248kInv[6] = -this.elements[12] * fA5 + this.elements[14] * fA2 - this.elements[15] * fA1;3249kInv[10] = +this.elements[12] * fA4 - this.elements[13] * fA2 + this.elements[15] * fA0;3250kInv[14] = -this.elements[12] * fA3 + this.elements[13] * fA1 - this.elements[14] * fA0;3251kInv[3] = -this.elements[9] * fA5 + this.elements[10] * fA4 - this.elements[11] * fA3;3252kInv[7] = +this.elements[8] * fA5 - this.elements[10] * fA2 + this.elements[11] * fA1;3253kInv[11] = -this.elements[8] * fA4 + this.elements[9] * fA2 - this.elements[11] * fA0;3254kInv[15] = +this.elements[8] * fA3 - this.elements[9] * fA1 + this.elements[10] * fA0;3255var fInvDet = 1 / fDet;3256kInv[0] *= fInvDet;3257kInv[1] *= fInvDet;3258kInv[2] *= fInvDet;3259kInv[3] *= fInvDet;3260kInv[4] *= fInvDet;3261kInv[5] *= fInvDet;3262kInv[6] *= fInvDet;3263kInv[7] *= fInvDet;3264kInv[8] *= fInvDet;3265kInv[9] *= fInvDet;3266kInv[10] *= fInvDet;3267kInv[11] *= fInvDet;3268kInv[12] *= fInvDet;3269kInv[13] *= fInvDet;3270kInv[14] *= fInvDet;3271kInv[15] *= fInvDet;3272this.elements = kInv.slice();3273return true3274},3275toString: function() {3276var str = "";3277for (var i = 0; i < 15; i++) str += this.elements[i] + ", ";3278str += this.elements[15];3279return str3280},3281print: function() {3282var digits = printMatrixHelper(this.elements);3283var output = "" + p.nfs(this.elements[0], digits, 4) + " " + p.nfs(this.elements[1], digits, 4) + " " + p.nfs(this.elements[2], digits, 4) + " " + p.nfs(this.elements[3], digits, 4) + "\n" + p.nfs(this.elements[4], digits, 4) + " " + p.nfs(this.elements[5], digits, 4) + " " + p.nfs(this.elements[6], digits, 4) + " " + p.nfs(this.elements[7], digits, 4) + "\n" + p.nfs(this.elements[8], digits, 4) + " " + p.nfs(this.elements[9], digits, 4) + " " + p.nfs(this.elements[10], digits, 4) + " " + p.nfs(this.elements[11], digits, 4) + "\n" + p.nfs(this.elements[12], digits, 4) + " " + p.nfs(this.elements[13], digits, 4) + " " + p.nfs(this.elements[14], digits, 4) + " " + p.nfs(this.elements[15], digits, 4) + "\n\n";3284p.println(output)3285},3286invTranslate: function(tx, ty, tz) {3287this.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, 0, 0, 0, 1)3288},3289invRotateX: function(angle) {3290var c = Math.cos(-angle);3291var s = Math.sin(-angle);3292this.preApply([1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1])3293},3294invRotateY: function(angle) {3295var c = Math.cos(-angle);3296var s = Math.sin(-angle);3297this.preApply([c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1])3298},3299invRotateZ: function(angle) {3300var c = Math.cos(-angle);3301var s = Math.sin(-angle);3302this.preApply([c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])3303},3304invScale: function(x, y, z) {3305this.preApply([1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1])3306}3307};3308var PMatrixStack = p.PMatrixStack = function() {3309this.matrixStack = []3310};3311PMatrixStack.prototype.load = function() {3312var tmpMatrix = drawing.$newPMatrix();3313if (arguments.length === 1) tmpMatrix.set(arguments[0]);3314else tmpMatrix.set(arguments);3315this.matrixStack.push(tmpMatrix)3316};3317Drawing2D.prototype.$newPMatrix = function() {3318return new PMatrix2D3319};3320Drawing3D.prototype.$newPMatrix = function() {3321return new PMatrix3D3322};3323PMatrixStack.prototype.push = function() {3324this.matrixStack.push(this.peek())3325};3326PMatrixStack.prototype.pop = function() {3327return this.matrixStack.pop()3328};3329PMatrixStack.prototype.peek = function() {3330var tmpMatrix = drawing.$newPMatrix();3331tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]);3332return tmpMatrix3333};3334PMatrixStack.prototype.mult = function(matrix) {3335this.matrixStack[this.matrixStack.length - 1].apply(matrix)3336};3337p.split = function(str, delim) {3338return str.split(delim)3339};3340p.splitTokens = function(str, tokens) {3341if (tokens === undef) return str.split(/\s+/g);3342var chars = tokens.split(/()/g),3343buffer = "",3344len = str.length,3345i, c, tokenized = [];3346for (i = 0; i < len; i++) {3347c = str[i];3348if (chars.indexOf(c) > -1) {3349if (buffer !== "") tokenized.push(buffer);3350buffer = ""3351} else buffer += c3352}3353if (buffer !== "") tokenized.push(buffer);3354return tokenized3355};3356p.append = function(array, element) {3357array[array.length] = element;3358return array3359};3360p.concat = function(array1, array2) {3361return array1.concat(array2)3362};3363p.sort = function(array, numElem) {3364var ret = [];3365if (array.length > 0) {3366var elemsToCopy = numElem > 0 ? numElem : array.length;3367for (var i = 0; i < elemsToCopy; i++) ret.push(array[i]);3368if (typeof array[0] === "string") ret.sort();3369else ret.sort(function(a, b) {3370return a - b3371});3372if (numElem > 0) for (var j = ret.length; j < array.length; j++) ret.push(array[j])3373}3374return ret3375};3376p.splice = function(array, value, index) {3377if (value.length === 0) return array;3378if (value instanceof Array) for (var i = 0, j = index; i < value.length; j++, i++) array.splice(j, 0, value[i]);3379else array.splice(index, 0, value);3380return array3381};3382p.subset = function(array, offset, length) {3383var end = length !== undef ? offset + length : array.length;3384return array.slice(offset, end)3385};3386p.join = function(array, seperator) {3387return array.join(seperator)3388};3389p.shorten = function(ary) {3390var newary = [];3391var len = ary.length;3392for (var i = 0; i < len; i++) newary[i] = ary[i];3393newary.pop();3394return newary3395};3396p.expand = function(ary, targetSize) {3397var temp = ary.slice(0),3398newSize = targetSize || ary.length * 2;3399temp.length = newSize;3400return temp3401};3402p.arrayCopy = function() {3403var src, srcPos = 0,3404dest, destPos = 0,3405length;3406if (arguments.length === 2) {3407src = arguments[0];3408dest = arguments[1];3409length = src.length3410} else if (arguments.length === 3) {3411src = arguments[0];3412dest = arguments[1];3413length = arguments[2]3414} else if (arguments.length === 5) {3415src = arguments[0];3416srcPos = arguments[1];3417dest = arguments[2];3418destPos = arguments[3];3419length = arguments[4]3420}3421for (var i = srcPos, j = destPos; i < length + srcPos; i++, j++) if (dest[j] !== undef) dest[j] = src[i];3422else throw "array index out of bounds exception";3423};3424p.reverse = function(array) {3425return array.reverse()3426};3427p.mix = function(a, b, f) {3428return a + ((b - a) * f >> 8)3429};3430p.peg = function(n) {3431return n < 0 ? 0 : n > 255 ? 255 : n3432};3433p.modes = function() {3434var ALPHA_MASK = 4278190080,3435RED_MASK = 16711680,3436GREEN_MASK = 65280,3437BLUE_MASK = 255,3438min = Math.min,3439max = Math.max;34403441function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) {3442var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24;3443var r = ar + ((cr - ar) * f >> 8);3444r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16;3445var g = ag + ((cg - ag) * f >> 8);3446g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8;3447var b = ab + ((cb - ab) * f >> 8);3448b = b < 0 ? 0 : b > 255 ? 255 : b;3449return a | r | g | b3450}3451return {3452replace: function(c1, c2) {3453return c23454},3455blend: function(c1, c2) {3456var f = (c2 & ALPHA_MASK) >>> 24,3457ar = c1 & RED_MASK,3458ag = c1 & GREEN_MASK,3459ab = c1 & BLUE_MASK,3460br = c2 & RED_MASK,3461bg = c2 & GREEN_MASK,3462bb = c2 & BLUE_MASK;3463return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK3464},3465add: function(c1, c2) {3466var f = (c2 & ALPHA_MASK) >>> 24;3467return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK)3468},3469subtract: function(c1, c2) {3470var f = (c2 & ALPHA_MASK) >>> 24;3471return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0)3472},3473lightest: function(c1, c2) {3474var f = (c2 & ALPHA_MASK) >>> 24;3475return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8)3476},3477darkest: function(c1, c2) {3478var f = (c2 & ALPHA_MASK) >>> 24,3479ar = c1 & RED_MASK,3480ag = c1 & GREEN_MASK,3481ab = c1 & BLUE_MASK,3482br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f),3483bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f),3484bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8);3485return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK3486},3487difference: function(c1, c2) {3488var f = (c2 & ALPHA_MASK) >>> 24,3489ar = (c1 & RED_MASK) >> 16,3490ag = (c1 & GREEN_MASK) >> 8,3491ab = c1 & BLUE_MASK,3492br = (c2 & RED_MASK) >> 16,3493bg = (c2 & GREEN_MASK) >> 8,3494bb = c2 & BLUE_MASK,3495cr = ar > br ? ar - br : br - ar,3496cg = ag > bg ? ag - bg : bg - ag,3497cb = ab > bb ? ab - bb : bb - ab;3498return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb)3499},3500exclusion: function(c1, c2) {3501var f = (c2 & ALPHA_MASK) >>> 24,3502ar = (c1 & RED_MASK) >> 16,3503ag = (c1 & GREEN_MASK) >> 8,3504ab = c1 & BLUE_MASK,3505br = (c2 & RED_MASK) >> 16,3506bg = (c2 & GREEN_MASK) >> 8,3507bb = c2 & BLUE_MASK,3508cr = ar + br - (ar * br >> 7),3509cg = ag + bg - (ag * bg >> 7),3510cb = ab + bb - (ab * bb >> 7);3511return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb)3512},3513multiply: function(c1, c2) {3514var f = (c2 & ALPHA_MASK) >>> 24,3515ar = (c1 & RED_MASK) >> 16,3516ag = (c1 & GREEN_MASK) >> 8,3517ab = c1 & BLUE_MASK,3518br = (c2 & RED_MASK) >> 16,3519bg = (c2 & GREEN_MASK) >> 8,3520bb = c2 & BLUE_MASK,3521cr = ar * br >> 8,3522cg = ag * bg >> 8,3523cb = ab * bb >> 8;3524return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb)3525},3526screen: function(c1, c2) {3527var f = (c2 & ALPHA_MASK) >>> 24,3528ar = (c1 & RED_MASK) >> 16,3529ag = (c1 & GREEN_MASK) >> 8,3530ab = c1 & BLUE_MASK,3531br = (c2 & RED_MASK) >> 16,3532bg = (c2 & GREEN_MASK) >> 8,3533bb = c2 & BLUE_MASK,3534cr = 255 - ((255 - ar) * (255 - br) >> 8),3535cg = 255 - ((255 - ag) * (255 - bg) >> 8),3536cb = 255 - ((255 - ab) * (255 - bb) >> 8);3537return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb)3538},3539hard_light: function(c1, c2) {3540var f = (c2 & ALPHA_MASK) >>> 24,3541ar = (c1 & RED_MASK) >> 16,3542ag = (c1 & GREEN_MASK) >> 8,3543ab = c1 & BLUE_MASK,3544br = (c2 & RED_MASK) >> 16,3545bg = (c2 & GREEN_MASK) >> 8,3546bb = c2 & BLUE_MASK,3547cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7),3548cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7),3549cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7);3550return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb)3551},3552soft_light: function(c1, c2) {3553var f = (c2 & ALPHA_MASK) >>> 24,3554ar = (c1 & RED_MASK) >> 16,3555ag = (c1 & GREEN_MASK) >> 8,3556ab = c1 & BLUE_MASK,3557br = (c2 & RED_MASK) >> 16,3558bg = (c2 & GREEN_MASK) >> 8,3559bb = c2 & BLUE_MASK,3560cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15),3561cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15),3562cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15);3563return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb)3564},3565overlay: function(c1, c2) {3566var f = (c2 & ALPHA_MASK) >>> 24,3567ar = (c1 & RED_MASK) >> 16,3568ag = (c1 & GREEN_MASK) >> 8,3569ab = c1 & BLUE_MASK,3570br = (c2 & RED_MASK) >> 16,3571bg = (c2 & GREEN_MASK) >> 8,3572bb = c2 & BLUE_MASK,3573cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7),3574cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7),3575cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7);3576return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb)3577},3578dodge: function(c1, c2) {3579var f = (c2 & ALPHA_MASK) >>> 24,3580ar = (c1 & RED_MASK) >> 16,3581ag = (c1 & GREEN_MASK) >> 8,3582ab = c1 & BLUE_MASK,3583br = (c2 & RED_MASK) >> 16,3584bg = (c2 & GREEN_MASK) >> 8,3585bb = c2 & BLUE_MASK;3586var cr = 255;3587if (br !== 255) {3588cr = (ar << 8) / (255 - br);3589cr = cr < 0 ? 0 : cr > 255 ? 255 : cr3590}3591var cg = 255;3592if (bg !== 255) {3593cg = (ag << 8) / (255 - bg);3594cg = cg < 0 ? 0 : cg > 255 ? 255 : cg3595}3596var cb = 255;3597if (bb !== 255) {3598cb = (ab << 8) / (255 - bb);3599cb = cb < 0 ? 0 : cb > 255 ? 255 : cb3600}3601return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb)3602},3603burn: function(c1, c2) {3604var f = (c2 & ALPHA_MASK) >>> 24,3605ar = (c1 & RED_MASK) >> 16,3606ag = (c1 & GREEN_MASK) >> 8,3607ab = c1 & BLUE_MASK,3608br = (c2 & RED_MASK) >> 16,3609bg = (c2 & GREEN_MASK) >> 8,3610bb = c2 & BLUE_MASK;3611var cr = 0;3612if (br !== 0) {3613cr = (255 - ar << 8) / br;3614cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr)3615}3616var cg = 0;3617if (bg !== 0) {3618cg = (255 - ag << 8) / bg;3619cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg)3620}3621var cb = 0;3622if (bb !== 0) {3623cb = (255 - ab << 8) / bb;3624cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb)3625}3626return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb)3627}3628}3629}();36303631function color$4(aValue1, aValue2, aValue3, aValue4) {3632var r, g, b, a;3633if (curColorMode === 3) {3634var rgb = p.color.toRGB(aValue1, aValue2, aValue3);3635r = rgb[0];3636g = rgb[1];3637b = rgb[2]3638} else {3639r = Math.round(255 * (aValue1 / colorModeX));3640g = Math.round(255 * (aValue2 / colorModeY));3641b = Math.round(255 * (aValue3 / colorModeZ))3642}3643a = Math.round(255 * (aValue4 / colorModeA));3644r = r < 0 ? 0 : r;3645g = g < 0 ? 0 : g;3646b = b < 0 ? 0 : b;3647a = a < 0 ? 0 : a;3648r = r > 255 ? 255 : r;3649g = g > 255 ? 255 : g;3650b = b > 255 ? 255 : b;3651a = a > 255 ? 255 : a;3652return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 2553653}3654function color$2(aValue1, aValue2) {3655var a;3656if (aValue1 & 4278190080) {3657a = Math.round(255 * (aValue2 / colorModeA));3658a = a > 255 ? 255 : a;3659a = a < 0 ? 0 : a;3660return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080)3661}3662if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2);3663if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2)3664}3665function color$1(aValue1) {3666if (aValue1 <= colorModeX && aValue1 >= 0) {3667if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA);3668if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA)3669}3670if (aValue1) {3671if (aValue1 > 2147483647) aValue1 -= 4294967296;3672return aValue13673}3674}3675p.color = function(aValue1, aValue2, aValue3, aValue4) {3676if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4);3677if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA);3678if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2);3679if (typeof aValue1 === "number") return color$1(aValue1);3680return color$4(colorModeX, colorModeY, colorModeZ, colorModeA)3681};3682p.color.toString = function(colorInt) {3683return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")"3684};3685p.color.toInt = function(r, g, b, a) {3686return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 2553687};3688p.color.toArray = function(colorInt) {3689return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255]3690};3691p.color.toGLArray = function(colorInt) {3692return [((colorInt & 16711680) >>> 16) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt >> 24) & 255) / 255]3693};3694p.color.toRGB = function(h, s, b) {3695h = h > colorModeX ? colorModeX : h;3696s = s > colorModeY ? colorModeY : s;3697b = b > colorModeZ ? colorModeZ : b;3698h = h / colorModeX * 360;3699s = s / colorModeY * 100;3700b = b / colorModeZ * 100;3701var br = Math.round(b / 100 * 255);3702if (s === 0) return [br, br, br];3703var hue = h % 360;3704var f = hue % 60;3705var p = Math.round(b * (100 - s) / 1E4 * 255);3706var q = Math.round(b * (6E3 - s * f) / 6E5 * 255);3707var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 255);3708switch (Math.floor(hue / 60)) {3709case 0:3710return [br, t, p];3711case 1:3712return [q, br, p];3713case 2:3714return [p, br, t];3715case 3:3716return [p, q, br];3717case 4:3718return [t, p, br];3719case 5:3720return [br, p, q]3721}3722};37233724function colorToHSB(colorInt) {3725var red, green, blue;3726red = ((colorInt >> 16) & 255) / 255;3727green = ((colorInt >> 8) & 255) / 255;3728blue = (colorInt & 255) / 255;3729var max = p.max(p.max(red, green), blue),3730min = p.min(p.min(red, green), blue),3731hue, saturation;3732if (min === max) return [0, 0, max * colorModeZ];3733saturation = (max - min) / max;3734if (red === max) hue = (green - blue) / (max - min);3735else if (green === max) hue = 2 + (blue - red) / (max - min);3736else hue = 4 + (red - green) / (max - min);3737hue /= 6;3738if (hue < 0) hue += 1;3739else if (hue > 1) hue -= 1;3740return [hue * colorModeX, saturation * colorModeY, max * colorModeZ]3741}3742p.brightness = function(colInt) {3743return colorToHSB(colInt)[2]3744};3745p.saturation = function(colInt) {3746return colorToHSB(colInt)[1]3747};3748p.hue = function(colInt) {3749return colorToHSB(colInt)[0]3750};3751p.red = function(aColor) {3752return ((aColor >> 16) & 255) / 255 * colorModeX3753};3754p.green = function(aColor) {3755return ((aColor & 65280) >>> 8) / 255 * colorModeY3756};3757p.blue = function(aColor) {3758return (aColor & 255) / 255 * colorModeZ3759};3760p.alpha = function(aColor) {3761return ((aColor >> 24) & 255) / 255 * colorModeA3762};3763p.lerpColor = function(c1, c2, amt) {3764var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2;3765var hsb1, hsb2, rgb, h, s;3766var colorBits1 = p.color(c1);3767var colorBits2 = p.color(c2);3768if (curColorMode === 3) {3769hsb1 = colorToHSB(colorBits1);3770a1 = ((colorBits1 >> 24) & 255) / colorModeA;3771hsb2 = colorToHSB(colorBits2);3772a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA;3773h = p.lerp(hsb1[0], hsb2[0], amt);3774s = p.lerp(hsb1[1], hsb2[1], amt);3775b = p.lerp(hsb1[2], hsb2[2], amt);3776rgb = p.color.toRGB(h, s, b);3777a = p.lerp(a1, a2, amt) * colorModeA;3778return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 2553779}3780r1 = (colorBits1 >> 16) & 255;3781g1 = (colorBits1 >> 8) & 255;3782b1 = colorBits1 & 255;3783a1 = ((colorBits1 >> 24) & 255) / colorModeA;3784r2 = (colorBits2 & 16711680) >>> 16;3785g2 = (colorBits2 >> 8) & 255;3786b2 = colorBits2 & 255;3787a2 = ((colorBits2 >> 24) & 255) / colorModeA;3788r = p.lerp(r1, r2, amt) | 0;3789g = p.lerp(g1, g2, amt) | 0;3790b = p.lerp(b1, b2, amt) | 0;3791a = p.lerp(a1, a2, amt) * colorModeA;3792return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 2553793};3794p.colorMode = function() {3795curColorMode = arguments[0];3796if (arguments.length > 1) {3797colorModeX = arguments[1];3798colorModeY = arguments[2] || arguments[1];3799colorModeZ = arguments[3] || arguments[1];3800colorModeA = arguments[4] || arguments[1]3801}3802};3803p.blendColor = function(c1, c2, mode) {3804if (mode === 0) return p.modes.replace(c1, c2);3805else if (mode === 1) return p.modes.blend(c1, c2);3806else if (mode === 2) return p.modes.add(c1, c2);3807else if (mode === 4) return p.modes.subtract(c1, c2);3808else if (mode === 8) return p.modes.lightest(c1, c2);3809else if (mode === 16) return p.modes.darkest(c1, c2);3810else if (mode === 32) return p.modes.difference(c1, c2);3811else if (mode === 64) return p.modes.exclusion(c1, c2);3812else if (mode === 128) return p.modes.multiply(c1, c2);3813else if (mode === 256) return p.modes.screen(c1, c2);3814else if (mode === 1024) return p.modes.hard_light(c1, c2);3815else if (mode === 2048) return p.modes.soft_light(c1, c2);3816else if (mode === 512) return p.modes.overlay(c1, c2);3817else if (mode === 4096) return p.modes.dodge(c1, c2);3818else if (mode === 8192) return p.modes.burn(c1, c2)3819};38203821function saveContext() {3822curContext.save()3823}3824function restoreContext() {3825curContext.restore();3826isStrokeDirty = true;3827isFillDirty = true3828}3829p.printMatrix = function() {3830modelView.print()3831};3832Drawing2D.prototype.translate = function(x, y) {3833modelView.translate(x, y);3834modelViewInv.invTranslate(x, y);3835curContext.translate(x, y)3836};3837Drawing3D.prototype.translate = function(x, y, z) {3838modelView.translate(x, y, z);3839modelViewInv.invTranslate(x, y, z)3840};3841Drawing2D.prototype.scale = function(x, y) {3842modelView.scale(x, y);3843modelViewInv.invScale(x, y);3844curContext.scale(x, y || x)3845};3846Drawing3D.prototype.scale = function(x, y, z) {3847modelView.scale(x, y, z);3848modelViewInv.invScale(x, y, z)3849};3850Drawing2D.prototype.transform = function(pmatrix) {3851var e = pmatrix.array();3852curContext.transform(e[0], e[3], e[1], e[4], e[2], e[5])3853};3854Drawing3D.prototype.transformm = function(pmatrix3d) {3855throw "p.transform is currently not supported in 3D mode";3856};3857Drawing2D.prototype.pushMatrix = function() {3858userMatrixStack.load(modelView);3859userReverseMatrixStack.load(modelViewInv);3860saveContext()3861};3862Drawing3D.prototype.pushMatrix = function() {3863userMatrixStack.load(modelView);3864userReverseMatrixStack.load(modelViewInv)3865};3866Drawing2D.prototype.popMatrix = function() {3867modelView.set(userMatrixStack.pop());3868modelViewInv.set(userReverseMatrixStack.pop());3869restoreContext()3870};3871Drawing3D.prototype.popMatrix = function() {3872modelView.set(userMatrixStack.pop());3873modelViewInv.set(userReverseMatrixStack.pop())3874};3875Drawing2D.prototype.resetMatrix = function() {3876modelView.reset();3877modelViewInv.reset();3878curContext.setTransform(1, 0, 0, 1, 0, 0)3879};3880Drawing3D.prototype.resetMatrix = function() {3881modelView.reset();3882modelViewInv.reset()3883};3884DrawingShared.prototype.applyMatrix = function() {3885var a = arguments;3886modelView.apply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);3887modelViewInv.invApply(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15])3888};3889Drawing2D.prototype.applyMatrix = function() {3890var a = arguments;3891for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0;3892a[10] = a[15] = 1;3893DrawingShared.prototype.applyMatrix.apply(this, a)3894};3895p.rotateX = function(angleInRadians) {3896modelView.rotateX(angleInRadians);3897modelViewInv.invRotateX(angleInRadians)3898};3899Drawing2D.prototype.rotateZ = function() {3900throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead.";3901};3902Drawing3D.prototype.rotateZ = function(angleInRadians) {3903modelView.rotateZ(angleInRadians);3904modelViewInv.invRotateZ(angleInRadians)3905};3906p.rotateY = function(angleInRadians) {3907modelView.rotateY(angleInRadians);3908modelViewInv.invRotateY(angleInRadians)3909};3910Drawing2D.prototype.rotate = function(angleInRadians) {3911modelView.rotateZ(angleInRadians);3912modelViewInv.invRotateZ(angleInRadians);3913curContext.rotate(angleInRadians)3914};3915Drawing3D.prototype.rotate = function(angleInRadians) {3916p.rotateZ(angleInRadians)3917};3918Drawing2D.prototype.shearX = function(angleInRadians) {3919modelView.shearX(angleInRadians);3920curContext.transform(1, 0, angleInRadians, 1, 0, 0)3921};3922Drawing3D.prototype.shearX = function(angleInRadians) {3923modelView.shearX(angleInRadians)3924};3925Drawing2D.prototype.shearY = function(angleInRadians) {3926modelView.shearY(angleInRadians);3927curContext.transform(1, angleInRadians, 0, 1, 0, 0)3928};3929Drawing3D.prototype.shearY = function(angleInRadians) {3930modelView.shearY(angleInRadians)3931};3932p.pushStyle = function() {3933saveContext();3934p.pushMatrix();3935var newState = {3936"doFill": doFill,3937"currentFillColor": currentFillColor,3938"doStroke": doStroke,3939"currentStrokeColor": currentStrokeColor,3940"curTint": curTint,3941"curRectMode": curRectMode,3942"curColorMode": curColorMode,3943"colorModeX": colorModeX,3944"colorModeZ": colorModeZ,3945"colorModeY": colorModeY,3946"colorModeA": colorModeA,3947"curTextFont": curTextFont,3948"horizontalTextAlignment": horizontalTextAlignment,3949"verticalTextAlignment": verticalTextAlignment,3950"textMode": textMode,3951"curFontName": curFontName,3952"curTextSize": curTextSize,3953"curTextAscent": curTextAscent,3954"curTextDescent": curTextDescent,3955"curTextLeading": curTextLeading3956};3957styleArray.push(newState)3958};3959p.popStyle = function() {3960var oldState = styleArray.pop();3961if (oldState) {3962restoreContext();3963p.popMatrix();3964doFill = oldState.doFill;3965currentFillColor = oldState.currentFillColor;3966doStroke = oldState.doStroke;3967currentStrokeColor = oldState.currentStrokeColor;3968curTint = oldState.curTint;3969curRectMode = oldState.curRectMode;3970curColorMode = oldState.curColorMode;3971colorModeX = oldState.colorModeX;3972colorModeZ = oldState.colorModeZ;3973colorModeY = oldState.colorModeY;3974colorModeA = oldState.colorModeA;3975curTextFont = oldState.curTextFont;3976curFontName = oldState.curFontName;3977curTextSize = oldState.curTextSize;3978horizontalTextAlignment = oldState.horizontalTextAlignment;3979verticalTextAlignment = oldState.verticalTextAlignment;3980textMode = oldState.textMode;3981curTextAscent = oldState.curTextAscent;3982curTextDescent = oldState.curTextDescent;3983curTextLeading = oldState.curTextLeading3984} else throw "Too many popStyle() without enough pushStyle()";3985};3986p.year = function() {3987return (new Date).getFullYear()3988};3989p.month = function() {3990return (new Date).getMonth() + 13991};3992p.day = function() {3993return (new Date).getDate()3994};3995p.hour = function() {3996return (new Date).getHours()3997};3998p.minute = function() {3999return (new Date).getMinutes()4000};4001p.second = function() {4002return (new Date).getSeconds()4003};4004p.millis = function() {4005return Date.now() - start4006};40074008function redrawHelper() {4009var sec = (Date.now() - timeSinceLastFPS) / 1E3;4010framesSinceLastFPS++;4011var fps = framesSinceLastFPS / sec;4012if (sec > 0.5) {4013timeSinceLastFPS = Date.now();4014framesSinceLastFPS = 0;4015p.__frameRate = fps4016}4017p.frameCount++4018}4019Drawing2D.prototype.redraw = function() {4020redrawHelper();4021curContext.lineWidth = lineWidth;4022var pmouseXLastEvent = p.pmouseX,4023pmouseYLastEvent = p.pmouseY;4024p.pmouseX = pmouseXLastFrame;4025p.pmouseY = pmouseYLastFrame;4026saveContext();4027p.draw();4028restoreContext();4029pmouseXLastFrame = p.mouseX;4030pmouseYLastFrame = p.mouseY;4031p.pmouseX = pmouseXLastEvent;4032p.pmouseY = pmouseYLastEvent4033};4034Drawing3D.prototype.redraw = function() {4035redrawHelper();4036var pmouseXLastEvent = p.pmouseX,4037pmouseYLastEvent = p.pmouseY;4038p.pmouseX = pmouseXLastFrame;4039p.pmouseY = pmouseYLastFrame;4040curContext.clear(curContext.DEPTH_BUFFER_BIT);4041curContextCache = {4042attributes: {},4043locations: {}4044};4045p.noLights();4046p.lightFalloff(1, 0, 0);4047p.shininess(1);4048p.ambient(255, 255, 255);4049p.specular(0, 0, 0);4050p.emissive(0, 0, 0);4051p.camera();4052p.draw();4053pmouseXLastFrame = p.mouseX;4054pmouseYLastFrame = p.mouseY;4055p.pmouseX = pmouseXLastEvent;4056p.pmouseY = pmouseYLastEvent4057};4058p.noLoop = function() {4059doLoop = false;4060loopStarted = false;4061clearInterval(looping);4062curSketch.onPause()4063};4064p.loop = function() {4065if (loopStarted) return;4066timeSinceLastFPS = Date.now();4067framesSinceLastFPS = 0;4068looping = window.setInterval(function() {4069try {4070curSketch.onFrameStart();4071p.redraw();4072curSketch.onFrameEnd()4073} catch(e_loop) {4074window.clearInterval(looping);4075throw e_loop;4076}4077},4078curMsPerFrame);4079doLoop = true;4080loopStarted = true;4081curSketch.onLoop()4082};4083p.frameRate = function(aRate) {4084curFrameRate = aRate;4085curMsPerFrame = 1E3 / curFrameRate;4086if (doLoop) {4087p.noLoop();4088p.loop()4089}4090};4091var eventHandlers = [];40924093function attachEventHandler(elem, type, fn) {4094if (elem.addEventListener) elem.addEventListener(type, fn, false);4095else elem.attachEvent("on" + type, fn);4096eventHandlers.push({4097elem: elem,4098type: type,4099fn: fn4100})4101}4102function detachEventHandler(eventHandler) {4103var elem = eventHandler.elem,4104type = eventHandler.type,4105fn = eventHandler.fn;4106if (elem.removeEventListener) elem.removeEventListener(type, fn, false);4107else if (elem.detachEvent) elem.detachEvent("on" + type, fn)4108}4109p.exit = function() {4110window.clearInterval(looping);4111removeInstance(p.externals.canvas.id);4112delete curElement.onmousedown;4113for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p);4114var i = eventHandlers.length;4115while (i--) detachEventHandler(eventHandlers[i]);4116curSketch.onExit()4117};4118p.cursor = function() {4119if (arguments.length > 1 || arguments.length === 1 && arguments[0] instanceof p.PImage) {4120var image = arguments[0],4121x, y;4122if (arguments.length >= 3) {4123x = arguments[1];4124y = arguments[2];4125if (x < 0 || y < 0 || y >= image.height || x >= image.width) throw "x and y must be non-negative and less than the dimensions of the image";4126} else {4127x = image.width >>> 1;4128y = image.height >>> 14129}4130var imageDataURL = image.toDataURL();4131var style = 'url("' + imageDataURL + '") ' + x + " " + y + ", default";4132curCursor = curElement.style.cursor = style4133} else if (arguments.length === 1) {4134var mode = arguments[0];4135curCursor = curElement.style.cursor = mode4136} else curCursor = curElement.style.cursor = oldCursor4137};4138p.noCursor = function() {4139curCursor = curElement.style.cursor = PConstants.NOCURSOR4140};4141p.link = function(href, target) {4142if (target !== undef) window.open(href, target);4143else window.location = href4144};4145p.beginDraw = nop;4146p.endDraw = nop;4147Drawing2D.prototype.toImageData = function(x, y, w, h) {4148x = x !== undef ? x : 0;4149y = y !== undef ? y : 0;4150w = w !== undef ? w : p.width;4151h = h !== undef ? h : p.height;4152return curContext.getImageData(x, y, w, h)4153};4154Drawing3D.prototype.toImageData = function(x, y, w, h) {4155x = x !== undef ? x : 0;4156y = y !== undef ? y : 0;4157w = w !== undef ? w : p.width;4158h = h !== undef ? h : p.height;4159var c = document.createElement("canvas"),4160ctx = c.getContext("2d"),4161obj = ctx.createImageData(w, h),4162uBuff = new Uint8Array(w * h * 4);4163curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff);4164for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)];4165return obj4166};4167p.status = function(text) {4168window.status = text4169};4170p.binary = function(num, numBits) {4171var bit;4172if (numBits > 0) bit = numBits;4173else if (num instanceof Char) {4174bit = 16;4175num |= 04176} else {4177bit = 32;4178while (bit > 1 && !(num >>> bit - 1 & 1)) bit--4179}4180var result = "";4181while (bit > 0) result += num >>> --bit & 1 ? "1" : "0";4182return result4183};4184p.unbinary = function(binaryString) {4185var i = binaryString.length - 1,4186mask = 1,4187result = 0;4188while (i >= 0) {4189var ch = binaryString[i--];4190if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number";4191if (ch === "1") result += mask;4192mask <<= 14193}4194return result4195};41964197function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) {4198var sign = value < 0 ? minus : plus;4199var autoDetectDecimals = rightDigits === 0;4200var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits;4201var absValue = Math.abs(value);4202if (autoDetectDecimals) {4203rightDigitsOfDefault = 1;4204absValue *= 10;4205while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) {4206++rightDigitsOfDefault;4207absValue *= 104208}4209} else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault);4210var number, doubled = absValue * 2;4211if (Math.floor(absValue) === absValue) number = absValue;4212else if (Math.floor(doubled) === doubled) {4213var floored = Math.floor(absValue);4214number = floored + floored % 24215} else number = Math.round(absValue);4216var buffer = "";4217var totalDigits = leftDigits + rightDigitsOfDefault;4218while (totalDigits > 0 || number > 0) {4219totalDigits--;4220buffer = "" + number % 10 + buffer;4221number = Math.floor(number / 10)4222}4223if (group !== undef) {4224var i = buffer.length - 3 - rightDigitsOfDefault;4225while (i > 0) {4226buffer = buffer.substring(0, i) + group + buffer.substring(i);4227i -= 34228}4229}4230if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length);4231return sign + buffer4232}4233function nfCore(value, plus, minus, leftDigits, rightDigits, group) {4234if (value instanceof Array) {4235var arr = [];4236for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group));4237return arr4238}4239return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group)4240}4241p.nf = function(value, leftDigits, rightDigits) {4242return nfCore(value, "", "-", leftDigits, rightDigits)4243};4244p.nfs = function(value, leftDigits, rightDigits) {4245return nfCore(value, " ", "-", leftDigits, rightDigits)4246};4247p.nfp = function(value, leftDigits, rightDigits) {4248return nfCore(value, "+", "-", leftDigits, rightDigits)4249};4250p.nfc = function(value, leftDigits, rightDigits) {4251return nfCore(value, "", "-", leftDigits, rightDigits, ",")4252};4253var decimalToHex = function(d, padding) {4254padding = padding === undef || padding === null ? padding = 8 : padding;4255if (d < 0) d = 4294967295 + d + 1;4256var hex = Number(d).toString(16).toUpperCase();4257while (hex.length < padding) hex = "0" + hex;4258if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length);4259return hex4260};4261p.hex = function(value, len) {4262if (arguments.length === 1) if (value instanceof Char) len = 4;4263else len = 8;4264return decimalToHex(value, len)4265};42664267function unhexScalar(hex) {4268var value = parseInt("0x" + hex, 16);4269if (value > 2147483647) value -= 4294967296;4270return value4271}4272p.unhex = function(hex) {4273if (hex instanceof Array) {4274var arr = [];4275for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i]));4276return arr4277}4278return unhexScalar(hex)4279};4280p.loadStrings = function(filename) {4281if (localStorage[filename]) return localStorage[filename].split("\n");4282var filecontent = ajax(filename);4283if (typeof filecontent !== "string" || filecontent === "") return [];4284filecontent = filecontent.replace(/(\r\n?)/g, "\n").replace(/\n$/, "");4285return filecontent.split("\n")4286};4287p.saveStrings = function(filename, strings) {4288localStorage[filename] = strings.join("\n")4289};4290p.loadBytes = function(url) {4291var string = ajax(url);4292var ret = [];4293for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i));4294return ret4295};42964297function removeFirstArgument(args) {4298return Array.prototype.slice.call(args, 1)4299}4300p.matchAll = function(aString, aRegExp) {4301var results = [],4302latest;4303var regexp = new RegExp(aRegExp, "g");4304while ((latest = regexp.exec(aString)) !== null) {4305results.push(latest);4306if (latest[0].length === 0)++regexp.lastIndex4307}4308return results.length > 0 ? results : null4309};4310p.__contains = function(subject, subStr) {4311if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments));4312return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -14313};4314p.__replaceAll = function(subject, regex, replacement) {4315if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments));4316return subject.replace(new RegExp(regex, "g"), replacement)4317};4318p.__replaceFirst = function(subject, regex, replacement) {4319if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments));4320return subject.replace(new RegExp(regex, ""), replacement)4321};4322p.__replace = function(subject, what, replacement) {4323if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments));4324if (what instanceof RegExp) return subject.replace(what, replacement);4325if (typeof what !== "string") what = what.toString();4326if (what === "") return subject;4327var i = subject.indexOf(what);4328if (i < 0) return subject;4329var j = 0,4330result = "";4331do {4332result += subject.substring(j, i) + replacement;4333j = i + what.length4334} while ((i = subject.indexOf(what, j)) >= 0);4335return result + subject.substring(j)4336};4337p.__equals = function(subject, other) {4338if (subject.equals instanceof4339Function) return subject.equals.apply(subject, removeFirstArgument(arguments));4340return subject.valueOf() === other.valueOf()4341};4342p.__equalsIgnoreCase = function(subject, other) {4343if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments));4344return subject.toLowerCase() === other.toLowerCase()4345};4346p.__toCharArray = function(subject) {4347if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments));4348var chars = [];4349for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i));4350return chars4351};4352p.__split = function(subject, regex, limit) {4353if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments));4354var pattern = new RegExp(regex);4355if (limit === undef || limit < 1) return subject.split(pattern);4356var result = [],4357currSubject = subject,4358pos;4359while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) {4360var match = pattern.exec(currSubject).toString();4361result.push(currSubject.substring(0, pos));4362currSubject = currSubject.substring(pos + match.length)4363}4364if (pos !== -1 || currSubject !== "") result.push(currSubject);4365return result4366};4367p.__codePointAt = function(subject, idx) {4368var code = subject.charCodeAt(idx),4369hi, low;4370if (55296 <= code && code <= 56319) {4371hi = code;4372low = subject.charCodeAt(idx + 1);4373return (hi - 55296) * 1024 + (low - 56320) + 655364374}4375return code4376};4377p.match = function(str, regexp) {4378return str.match(regexp)4379};4380p.__matches = function(str, regexp) {4381return (new RegExp(regexp)).test(str)4382};4383p.__startsWith = function(subject, prefix, toffset) {4384if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments));4385toffset = toffset || 0;4386if (toffset < 0 || toffset > subject.length) return false;4387return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset4388};4389p.__endsWith = function(subject, suffix) {4390if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments));4391var suffixLen = suffix ? suffix.length : 0;4392return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen4393};4394p.__hashCode = function(subject) {4395if (subject.hashCode instanceof4396Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments));4397return virtHashCode(subject)4398};4399p.__printStackTrace = function(subject) {4400p.println("Exception: " + subject.toString())4401};4402var logBuffer = [];4403p.println = function(message) {4404var bufferLen = logBuffer.length;4405if (bufferLen) {4406Processing.logger.log(logBuffer.join(""));4407logBuffer.length = 04408}4409if (arguments.length === 0 && bufferLen === 0) Processing.logger.log("");4410else if (arguments.length !== 0) Processing.logger.log(message)4411};4412p.print = function(message) {4413logBuffer.push(message)4414};4415p.str = function(val) {4416if (val instanceof Array) {4417var arr = [];4418for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + "");4419return arr4420}4421return val.toString() + ""4422};4423p.trim = function(str) {4424if (str instanceof Array) {4425var arr = [];4426for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, ""));4427return arr4428}4429return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "")4430};44314432function booleanScalar(val) {4433if (typeof val === "number") return val !== 0;4434if (typeof val === "boolean") return val;4435if (typeof val === "string") return val.toLowerCase() === "true";4436if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 1164437}4438p.parseBoolean = function(val) {4439if (val instanceof Array) {4440var ret = [];4441for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i]));4442return ret4443}4444return booleanScalar(val)4445};4446p.parseByte = function(what) {4447if (what instanceof Array) {4448var bytes = [];4449for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127);4450return bytes4451}4452return 0 - (what & 128) | what & 1274453};4454p.parseChar = function(key) {4455if (typeof key === "number") return new Char(String.fromCharCode(key & 65535));4456if (key instanceof Array) {4457var ret = [];4458for (var i = 0; i < key.length; i++) ret.push(new Char(String.fromCharCode(key[i] & 65535)));4459return ret4460}4461throw "char() may receive only one argument of type int, byte, int[], or byte[].";4462};44634464function floatScalar(val) {4465if (typeof val === "number") return val;4466if (typeof val === "boolean") return val ? 1 : 0;4467if (typeof val === "string") return parseFloat(val);4468if (val instanceof Char) return val.code4469}4470p.parseFloat = function(val) {4471if (val instanceof4472Array) {4473var ret = [];4474for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i]));4475return ret4476}4477return floatScalar(val)4478};44794480function intScalar(val, radix) {4481if (typeof val === "number") return val & 4294967295;4482if (typeof val === "boolean") return val ? 1 : 0;4483if (typeof val === "string") {4484var number = parseInt(val, radix || 10);4485return number & 42949672954486}4487if (val instanceof Char) return val.code4488}4489p.parseInt = function(val, radix) {4490if (val instanceof Array) {4491var ret = [];4492for (var i = 0; i < val.length; i++) if (typeof val[i] === "string" && !/^\s*[+\-]?\d+\s*$/.test(val[i])) ret.push(0);4493else ret.push(intScalar(val[i], radix));4494return ret4495}4496return intScalar(val, radix)4497};4498p.__int_cast = function(val) {4499return 0 | val4500};4501p.__instanceof = function(obj, type) {4502if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator";4503if (typeof obj === "string") return type === Object || type === String;4504if (obj instanceof type) return true;4505if (typeof obj !== "object" || obj === null) return false;4506var objType = obj.constructor;4507if (type.$isInterface) {4508var interfaces = [];4509while (objType) {4510if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces);4511objType = objType.$base4512}4513while (interfaces.length > 0) {4514var i = interfaces.shift();4515if (i === type) return true;4516if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces)4517}4518return false4519}4520while (objType.hasOwnProperty("$base")) {4521objType = objType.$base;4522if (objType === type) return true4523}4524return false4525};4526p.abs = Math.abs;4527p.ceil = Math.ceil;4528p.constrain = function(aNumber, aMin, aMax) {4529return aNumber > aMax ? aMax : aNumber < aMin ? aMin : aNumber4530};4531p.dist = function() {4532var dx, dy, dz;4533if (arguments.length === 4) {4534dx = arguments[0] - arguments[2];4535dy = arguments[1] - arguments[3];4536return Math.sqrt(dx * dx + dy * dy)4537}4538if (arguments.length === 6) {4539dx = arguments[0] - arguments[3];4540dy = arguments[1] - arguments[4];4541dz = arguments[2] - arguments[5];4542return Math.sqrt(dx * dx + dy * dy + dz * dz)4543}4544};4545p.exp = Math.exp;4546p.floor = Math.floor;4547p.lerp = function(value1, value2, amt) {4548return (value2 - value1) * amt + value14549};4550p.log = Math.log;4551p.mag = function(a, b, c) {4552if (c) return Math.sqrt(a * a + b * b + c * c);4553return Math.sqrt(a * a + b * b)4554};4555p.map = function(value, istart, istop, ostart, ostop) {4556return ostart + (ostop - ostart) * ((value - istart) / (istop - istart))4557};4558p.max = function() {4559if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[1] : arguments[0];4560var numbers = arguments.length === 1 ? arguments[0] : arguments;4561if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected";4562var max = numbers[0],4563count = numbers.length;4564for (var i = 1; i < count; ++i) if (max < numbers[i]) max = numbers[i];4565return max4566};4567p.min = function() {4568if (arguments.length === 2) return arguments[0] < arguments[1] ? arguments[0] : arguments[1];4569var numbers = arguments.length === 1 ? arguments[0] : arguments;4570if (! ("length" in numbers && numbers.length > 0)) throw "Non-empty array is expected";4571var min = numbers[0],4572count = numbers.length;4573for (var i = 1; i < count; ++i) if (min > numbers[i]) min = numbers[i];4574return min4575};4576p.norm = function(aNumber, low, high) {4577return (aNumber - low) / (high - low)4578};4579p.pow = Math.pow;4580p.round = Math.round;4581p.sq = function(aNumber) {4582return aNumber * aNumber4583};4584p.sqrt = Math.sqrt;4585p.acos = Math.acos;4586p.asin = Math.asin;4587p.atan = Math.atan;4588p.atan2 = Math.atan2;4589p.cos = Math.cos;4590p.degrees = function(aAngle) {4591return aAngle * 180 / Math.PI4592};4593p.radians = function(aAngle) {4594return aAngle / 180 * Math.PI4595};4596p.sin = Math.sin;4597p.tan = Math.tan;4598var currentRandom = Math.random;4599p.random = function() {4600if (arguments.length === 0) return currentRandom();4601if (arguments.length === 1) return currentRandom() * arguments[0];4602var aMin = arguments[0],4603aMax = arguments[1];4604return currentRandom() * (aMax - aMin) + aMin4605};46064607function Marsaglia(i1, i2) {4608var z = i1 || 362436069,4609w = i2 || 521288629;4610var nextInt = function() {4611z = 36969 * (z & 65535) + (z >>> 16) & 4294967295;4612w = 18E3 * (w & 65535) + (w >>> 16) & 4294967295;4613return ((z & 65535) << 16 | w & 65535) & 42949672954614};4615this.nextDouble = function() {4616var i = nextInt() / 4294967296;4617return i < 0 ? 1 + i : i4618};4619this.nextInt = nextInt4620}4621Marsaglia.createRandomized = function() {4622var now = new Date;4623return new Marsaglia(now / 6E4 & 4294967295, now & 4294967295)4624};4625p.randomSeed = function(seed) {4626currentRandom = (new Marsaglia(seed)).nextDouble4627};4628p.Random = function(seed) {4629var haveNextNextGaussian = false,4630nextNextGaussian, random;4631this.nextGaussian = function() {4632if (haveNextNextGaussian) {4633haveNextNextGaussian = false;4634return nextNextGaussian4635}4636var v1, v2, s;4637do {4638v1 = 2 * random() - 1;4639v2 = 2 * random() - 1;4640s = v1 * v1 + v2 * v24641} while (s >= 1 || s === 0);4642var multiplier = Math.sqrt(-2 * Math.log(s) / s);4643nextNextGaussian = v2 * multiplier;4644haveNextNextGaussian = true;4645return v1 * multiplier4646};4647random = seed === undef ? Math.random : (new Marsaglia(seed)).nextDouble4648};46494650function PerlinNoise(seed) {4651var rnd = seed !== undef ? new Marsaglia(seed) : Marsaglia.createRandomized();4652var i, j;4653var perm = new Uint8Array(512);4654for (i = 0; i < 256; ++i) perm[i] = i;4655for (i = 0; i < 256; ++i) {4656var t = perm[j = rnd.nextInt() & 255];4657perm[j] = perm[i];4658perm[i] = t4659}4660for (i = 0; i < 256; ++i) perm[i + 256] = perm[i];46614662function grad3d(i, x, y, z) {4663var h = i & 15;4664var u = h < 8 ? x : y,4665v = h < 4 ? y : h === 12 || h === 14 ? x : z;4666return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v)4667}4668function grad2d(i, x, y) {4669var v = (i & 1) === 0 ? x : y;4670return (i & 2) === 0 ? -v : v4671}4672function grad1d(i, x) {4673return (i & 1) === 0 ? -x : x4674}4675function lerp(t, a, b) {4676return a + t * (b - a)4677}4678this.noise3d = function(x, y, z) {4679var X = Math.floor(x) & 255,4680Y = Math.floor(y) & 255,4681Z = Math.floor(z) & 255;4682x -= Math.floor(x);4683y -= Math.floor(y);4684z -= Math.floor(z);4685var fx = (3 - 2 * x) * x * x,4686fy = (3 - 2 * y) * y * y,4687fz = (3 - 2 * z) * z * z;4688var p0 = perm[X] + Y,4689p00 = perm[p0] + Z,4690p01 = perm[p0 + 1] + Z,4691p1 = perm[X + 1] + Y,4692p10 = perm[p1] + Z,4693p11 = perm[p1 + 1] + Z;4694return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1))))4695};4696this.noise2d = function(x, y) {4697var X = Math.floor(x) & 255,4698Y = Math.floor(y) & 255;4699x -= Math.floor(x);4700y -= Math.floor(y);4701var fx = (3 - 2 * x) * x * x,4702fy = (3 - 2 * y) * y * y;4703var p0 = perm[X] + Y,4704p1 = perm[X + 1] + Y;4705return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1)))4706};4707this.noise1d = function(x) {4708var X = Math.floor(x) & 255;4709x -= Math.floor(x);4710var fx = (3 - 2 * x) * x * x;4711return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1))4712}4713}4714var noiseProfile = {4715generator: undef,4716octaves: 4,4717fallout: 0.5,4718seed: undef4719};4720p.noise = function(x, y, z) {4721if (noiseProfile.generator === undef) noiseProfile.generator = new PerlinNoise(noiseProfile.seed);4722var generator = noiseProfile.generator;4723var effect = 1,4724k = 1,4725sum = 0;4726for (var i = 0; i < noiseProfile.octaves; ++i) {4727effect *= noiseProfile.fallout;4728switch (arguments.length) {4729case 1:4730sum += effect * (1 + generator.noise1d(k * x)) / 2;4731break;4732case 2:4733sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2;4734break;4735case 3:4736sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2;4737break4738}4739k *= 24740}4741return sum4742};4743p.noiseDetail = function(octaves, fallout) {4744noiseProfile.octaves = octaves;4745if (fallout !== undef) noiseProfile.fallout = fallout4746};4747p.noiseSeed = function(seed) {4748noiseProfile.seed = seed;4749noiseProfile.generator = undef4750};4751DrawingShared.prototype.size = function(aWidth, aHeight, aMode) {4752if (doStroke) p.stroke(0);4753if (doFill) p.fill(255);4754var savedProperties = {4755fillStyle: curContext.fillStyle,4756strokeStyle: curContext.strokeStyle,4757lineCap: curContext.lineCap,4758lineJoin: curContext.lineJoin4759};4760if (curElement.style.length > 0) {4761curElement.style.removeProperty("width");4762curElement.style.removeProperty("height")4763}4764curElement.width = p.width = aWidth || 100;4765curElement.height = p.height = aHeight || 100;4766for (var prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop];4767p.textFont(curTextFont);4768p.background();4769maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05);4770p.externals.context = curContext;4771for (var i = 0; i < 720; i++) {4772sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5);4773cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5)4774}4775};4776Drawing2D.prototype.size = function(aWidth, aHeight, aMode) {4777if (curContext === undef) {4778curContext = curElement.getContext("2d");4779userMatrixStack = new PMatrixStack;4780userReverseMatrixStack = new PMatrixStack;4781modelView = new PMatrix2D;4782modelViewInv = new PMatrix2D4783}4784DrawingShared.prototype.size.apply(this, arguments)4785};4786Drawing3D.prototype.size = function() {4787var size3DCalled = false;4788return function size(aWidth, aHeight, aMode) {4789if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed.";4790size3DCalled = true;47914792function getGLContext(canvas) {4793var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"],4794gl;4795for (var i = 0, l = ctxNames.length; i < l; i++) {4796gl = canvas.getContext(ctxNames[i], {4797antialias: false,4798preserveDrawingBuffer: true4799});4800if (gl) break4801}4802return gl4803}4804try {4805curElement.width = p.width = aWidth || 100;4806curElement.height = p.height = aHeight || 100;4807curContext = getGLContext(curElement);4808canTex = curContext.createTexture();4809textTex = curContext.createTexture()4810} catch(e_size) {4811Processing.debug(e_size)4812}4813if (!curContext) throw "WebGL context is not supported on this browser.";4814curContext.viewport(0, 0, curElement.width, curElement.height);4815curContext.enable(curContext.DEPTH_TEST);4816curContext.enable(curContext.BLEND);4817curContext.blendFunc(curContext.SRC_ALPHA, curContext.ONE_MINUS_SRC_ALPHA);4818programObject2D = createProgramObject(curContext, vertexShaderSrc2D, fragmentShaderSrc2D);4819programObjectUnlitShape = createProgramObject(curContext, vertexShaderSrcUnlitShape, fragmentShaderSrcUnlitShape);4820p.strokeWeight(1);4821programObject3D = createProgramObject(curContext, vertexShaderSrc3D, fragmentShaderSrc3D);4822curContext.useProgram(programObject3D);4823uniformi("usingTexture3d", programObject3D, "usingTexture", usingTexture);4824p.lightFalloff(1, 0, 0);4825p.shininess(1);4826p.ambient(255, 255, 255);4827p.specular(0, 0, 0);4828p.emissive(0, 0, 0);4829boxBuffer = curContext.createBuffer();4830curContext.bindBuffer(curContext.ARRAY_BUFFER, boxBuffer);4831curContext.bufferData(curContext.ARRAY_BUFFER, boxVerts, curContext.STATIC_DRAW);4832boxNormBuffer = curContext.createBuffer();4833curContext.bindBuffer(curContext.ARRAY_BUFFER, boxNormBuffer);4834curContext.bufferData(curContext.ARRAY_BUFFER, boxNorms, curContext.STATIC_DRAW);4835boxOutlineBuffer = curContext.createBuffer();4836curContext.bindBuffer(curContext.ARRAY_BUFFER, boxOutlineBuffer);4837curContext.bufferData(curContext.ARRAY_BUFFER, boxOutlineVerts, curContext.STATIC_DRAW);4838rectBuffer = curContext.createBuffer();4839curContext.bindBuffer(curContext.ARRAY_BUFFER, rectBuffer);4840curContext.bufferData(curContext.ARRAY_BUFFER, rectVerts, curContext.STATIC_DRAW);4841rectNormBuffer = curContext.createBuffer();4842curContext.bindBuffer(curContext.ARRAY_BUFFER, rectNormBuffer);4843curContext.bufferData(curContext.ARRAY_BUFFER, rectNorms, curContext.STATIC_DRAW);4844sphereBuffer = curContext.createBuffer();4845lineBuffer = curContext.createBuffer();4846fillBuffer = curContext.createBuffer();4847fillColorBuffer = curContext.createBuffer();4848strokeColorBuffer = curContext.createBuffer();4849shapeTexVBO = curContext.createBuffer();4850pointBuffer = curContext.createBuffer();4851curContext.bindBuffer(curContext.ARRAY_BUFFER, pointBuffer);4852curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 0]), curContext.STATIC_DRAW);4853textBuffer = curContext.createBuffer();4854curContext.bindBuffer(curContext.ARRAY_BUFFER, textBuffer);4855curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]), curContext.STATIC_DRAW);4856textureBuffer = curContext.createBuffer();4857curContext.bindBuffer(curContext.ARRAY_BUFFER, textureBuffer);4858curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), curContext.STATIC_DRAW);4859indexBuffer = curContext.createBuffer();4860curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer);4861curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 2, 3, 0]), curContext.STATIC_DRAW);4862cam = new PMatrix3D;4863cameraInv = new PMatrix3D;4864modelView = new PMatrix3D;4865modelViewInv = new PMatrix3D;4866projection = new PMatrix3D;4867p.camera();4868p.perspective();4869userMatrixStack = new PMatrixStack;4870userReverseMatrixStack = new PMatrixStack;4871curveBasisMatrix = new PMatrix3D;4872curveToBezierMatrix = new PMatrix3D;4873curveDrawMatrix = new PMatrix3D;4874bezierDrawMatrix = new PMatrix3D;4875bezierBasisInverse = new PMatrix3D;4876bezierBasisMatrix = new PMatrix3D;4877bezierBasisMatrix.set(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0);4878DrawingShared.prototype.size.apply(this, arguments)4879}4880}();4881Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction;4882Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) {4883if (lightCount === 8) throw "can only create " + 8 + " lights";4884var pos = new PVector(x, y, z);4885var view = new PMatrix3D;4886view.scale(1, -1, 1);4887view.apply(modelView.array());4888view.mult(pos, pos);4889var col = color$4(r, g, b, 0);4890var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255];4891curContext.useProgram(programObject3D);4892uniformf("uLights.color.3d." + lightCount, programObject3D, "uLights" + lightCount + ".color", normalizedCol);4893uniformf("uLights.position.3d." + lightCount, programObject3D, "uLights" + lightCount + ".position", pos.array());4894uniformi("uLights.type.3d." + lightCount, programObject3D, "uLights" + lightCount + ".type", 0);4895uniformi("uLightCount3d", programObject3D, "uLightCount", ++lightCount)4896};4897Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction;4898Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) {4899if (lightCount === 8) throw "can only create " + 8 + " lights";4900curContext.useProgram(programObject3D);4901var mvm = new PMatrix3D;4902mvm.scale(1, -1, 1);4903mvm.apply(modelView.array());4904mvm = mvm.array();4905var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz];4906var col = color$4(r, g, b, 0);4907var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255];4908uniformf("uLights.color.3d." + lightCount, programObject3D, "uLights" + lightCount + ".color", normalizedCol);4909uniformf("uLights.position.3d." + lightCount, programObject3D, "uLights" + lightCount + ".position", dir);4910uniformi("uLights.type.3d." + lightCount, programObject3D, "uLights" + lightCount + ".type", 1);4911uniformi("uLightCount3d", programObject3D, "uLightCount", ++lightCount)4912};4913Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction;4914Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) {4915curContext.useProgram(programObject3D);4916uniformf("uFalloff3d", programObject3D, "uFalloff", [constant, linear, quadratic])4917};4918Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction;4919Drawing3D.prototype.lightSpecular = function(r, g, b) {4920var col = color$4(r, g, b, 0);4921var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255];4922curContext.useProgram(programObject3D);4923uniformf("uSpecular3d", programObject3D, "uSpecular", normalizedCol)4924};4925p.lights = function() {4926p.ambientLight(128, 128, 128);4927p.directionalLight(128, 128, 128, 0, 0, -1);4928p.lightFalloff(1, 0, 0);4929p.lightSpecular(0, 0, 0)4930};4931Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction;4932Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) {4933if (lightCount === 8) throw "can only create " + 8 + " lights";4934var pos = new PVector(x, y, z);4935var view = new PMatrix3D;4936view.scale(1, -1, 1);4937view.apply(modelView.array());4938view.mult(pos, pos);4939var col = color$4(r, g, b, 0);4940var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255];4941curContext.useProgram(programObject3D);4942uniformf("uLights.color.3d." + lightCount, programObject3D, "uLights" + lightCount + ".color", normalizedCol);4943uniformf("uLights.position.3d." + lightCount, programObject3D, "uLights" + lightCount + ".position", pos.array());4944uniformi("uLights.type.3d." + lightCount, programObject3D, "uLights" + lightCount + ".type", 2);4945uniformi("uLightCount3d", programObject3D, "uLightCount", ++lightCount)4946};4947Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction;4948Drawing3D.prototype.noLights = function() {4949lightCount = 0;4950curContext.useProgram(programObject3D);4951uniformi("uLightCount3d", programObject3D, "uLightCount", lightCount)4952};4953Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction;4954Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) {4955if (lightCount === 8) throw "can only create " + 8 + " lights";4956curContext.useProgram(programObject3D);4957var pos = new PVector(x, y, z);4958var mvm = new PMatrix3D;4959mvm.scale(1, -1, 1);4960mvm.apply(modelView.array());4961mvm.mult(pos, pos);4962mvm = mvm.array();4963var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] *4964nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz];4965var col = color$4(r, g, b, 0);4966var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255];4967uniformf("uLights.color.3d." + lightCount, programObject3D, "uLights" + lightCount + ".color", normalizedCol);4968uniformf("uLights.position.3d." + lightCount, programObject3D, "uLights" + lightCount + ".position", pos.array());4969uniformf("uLights.direction.3d." + lightCount, programObject3D, "uLights" + lightCount + ".direction", dir);4970uniformf("uLights.concentration.3d." + lightCount, programObject3D, "uLights" + lightCount + ".concentration", concentration);4971uniformf("uLights.angle.3d." + lightCount, programObject3D, "uLights" + lightCount + ".angle", angle);4972uniformi("uLights.type.3d." + lightCount, programObject3D, "uLights" + lightCount + ".type", 3);4973uniformi("uLightCount3d", programObject3D, "uLightCount", ++lightCount)4974};4975Drawing2D.prototype.beginCamera = function() {4976throw "beginCamera() is not available in 2D mode";4977};4978Drawing3D.prototype.beginCamera = function() {4979if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()";4980manipulatingCamera = true;4981modelView = cameraInv;4982modelViewInv = cam4983};4984Drawing2D.prototype.endCamera = function() {4985throw "endCamera() is not available in 2D mode";4986};4987Drawing3D.prototype.endCamera = function() {4988if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()";4989modelView.set(cam);4990modelViewInv.set(cameraInv);4991manipulatingCamera = false4992};4993p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) {4994if (eyeX === undef) {4995cameraX = p.width / 2;4996cameraY = p.height / 2;4997cameraZ = cameraY / Math.tan(cameraFOV / 2);4998eyeX = cameraX;4999eyeY = cameraY;5000eyeZ = cameraZ;5001centerX = cameraX;5002centerY = cameraY;5003centerZ = 0;5004upX = 0;5005upY = 1;5006upZ = 05007}5008var z = new PVector(eyeX - centerX, eyeY - centerY, eyeZ - centerZ);5009var y = new PVector(upX, upY, upZ);5010z.normalize();5011var x = PVector.cross(y, z);5012y = PVector.cross(z, x);5013x.normalize();5014y.normalize();5015var xX = x.x,5016xY = x.y,5017xZ = x.z;5018var yX = y.x,5019yY = y.y,5020yZ = y.z;5021var zX = z.x,5022zY = z.y,5023zZ = z.z;5024cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1);5025cam.translate(-eyeX, -eyeY, -eyeZ);5026cameraInv.reset();5027cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1);5028cameraInv.translate(eyeX, eyeY, eyeZ);5029modelView.set(cam);5030modelViewInv.set(cameraInv)5031};5032p.perspective = function(fov, aspect, near, far) {5033if (arguments.length === 0) {5034cameraY = curElement.height / 2;5035cameraZ = cameraY / Math.tan(cameraFOV / 2);5036cameraNear = cameraZ / 10;5037cameraFar = cameraZ * 10;5038cameraAspect = p.width / p.height;5039fov = cameraFOV;5040aspect = cameraAspect;5041near = cameraNear;5042far = cameraFar5043}5044var yMax, yMin, xMax, xMin;5045yMax = near * Math.tan(fov / 2);5046yMin = -yMax;5047xMax = yMax * aspect;5048xMin = yMin * aspect;5049p.frustum(xMin, xMax, yMin, yMax, near, far)5050};5051Drawing2D.prototype.frustum = function() {5052throw "Processing.js: frustum() is not supported in 2D mode";5053};5054Drawing3D.prototype.frustum = function(left, right, bottom, top, near, far) {5055frustumMode = true;5056projection = new PMatrix3D;5057projection.set(2 * near / (right - left), 0, (right + left) / (right - left), 0, 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 0, 0, -1, 0);5058var proj = new PMatrix3D;5059proj.set(projection);5060proj.transpose();5061curContext.useProgram(programObject2D);5062uniformMatrix("projection2d", programObject2D, "uProjection", false, proj.array());5063curContext.useProgram(programObject3D);5064uniformMatrix("projection3d", programObject3D, "uProjection", false, proj.array());5065curContext.useProgram(programObjectUnlitShape);5066uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array())5067};5068p.ortho = function(left, right, bottom, top, near, far) {5069if (arguments.length === 0) {5070left = 0;5071right = p.width;5072bottom = 0;5073top = p.height;5074near = -10;5075far = 105076}5077var x = 2 / (right - left);5078var y = 2 / (top - bottom);5079var z = -2 / (far - near);5080var tx = -(right + left) / (right - left);5081var ty = -(top + bottom) / (top - bottom);5082var tz = -(far + near) / (far - near);5083projection = new PMatrix3D;5084projection.set(x, 0, 0, tx, 0, y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1);5085var proj = new PMatrix3D;5086proj.set(projection);5087proj.transpose();5088curContext.useProgram(programObject2D);5089uniformMatrix("projection2d", programObject2D, "uProjection", false, proj.array());5090curContext.useProgram(programObject3D);5091uniformMatrix("projection3d", programObject3D, "uProjection", false, proj.array());5092curContext.useProgram(programObjectUnlitShape);5093uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array());5094frustumMode = false5095};5096p.printProjection = function() {5097projection.print()5098};5099p.printCamera = function() {5100cam.print()5101};5102Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction;5103Drawing3D.prototype.box = function(w, h, d) {5104if (!h || !d) h = d = w;5105var model = new PMatrix3D;5106model.scale(w, h, d);5107var view = new PMatrix3D;5108view.scale(1, -1, 1);5109view.apply(modelView.array());5110view.transpose();5111if (doFill) {5112curContext.useProgram(programObject3D);5113uniformMatrix("model3d", programObject3D, "uModel", false, model.array());5114uniformMatrix("view3d", programObject3D, "uView", false, view.array());5115curContext.enable(curContext.POLYGON_OFFSET_FILL);5116curContext.polygonOffset(1, 1);5117uniformf("color3d", programObject3D, "uColor", fillStyle);5118if (lightCount > 0) {5119var v = new PMatrix3D;5120v.set(view);5121var m = new PMatrix3D;5122m.set(model);5123v.mult(m);5124var normalMatrix = new PMatrix3D;5125normalMatrix.set(v);5126normalMatrix.invert();5127normalMatrix.transpose();5128uniformMatrix("uNormalTransform3d", programObject3D, "uNormalTransform", false, normalMatrix.array());5129vertexAttribPointer("aNormal3d", programObject3D, "aNormal", 3, boxNormBuffer)5130} else disableVertexAttribPointer("aNormal3d", programObject3D, "aNormal");5131vertexAttribPointer("aVertex3d", programObject3D, "aVertex", 3, boxBuffer);5132disableVertexAttribPointer("aColor3d", programObject3D, "aColor");5133disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture");5134curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3);5135curContext.disable(curContext.POLYGON_OFFSET_FILL)5136}5137if (lineWidth > 0 && doStroke) {5138curContext.useProgram(programObject2D);5139uniformMatrix("uModel2d", programObject2D, "uModel", false, model.array());5140uniformMatrix("uView2d", programObject2D, "uView", false, view.array());5141uniformf("uColor2d", programObject2D, "uColor", strokeStyle);5142uniformi("uIsDrawingText2d", programObject2D, "uIsDrawingText", false);5143vertexAttribPointer("vertex2d", programObject2D, "aVertex", 3, boxOutlineBuffer);5144disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord");5145curContext.drawArrays(curContext.LINES, 0, boxOutlineVerts.length / 3)5146}5147};5148var initSphere = function() {5149var i;5150sphereVerts = [];5151for (i = 0; i < sphereDetailU; i++) {5152sphereVerts.push(0);5153sphereVerts.push(-1);5154sphereVerts.push(0);5155sphereVerts.push(sphereX[i]);5156sphereVerts.push(sphereY[i]);5157sphereVerts.push(sphereZ[i])5158}5159sphereVerts.push(0);5160sphereVerts.push(-1);5161sphereVerts.push(0);5162sphereVerts.push(sphereX[0]);5163sphereVerts.push(sphereY[0]);5164sphereVerts.push(sphereZ[0]);5165var v1, v11, v2;5166var voff = 0;5167for (i = 2; i < sphereDetailV; i++) {5168v1 = v11 = voff;5169voff += sphereDetailU;5170v2 = voff;5171for (var j = 0; j < sphereDetailU; j++) {5172sphereVerts.push(sphereX[v1]);5173sphereVerts.push(sphereY[v1]);5174sphereVerts.push(sphereZ[v1++]);5175sphereVerts.push(sphereX[v2]);5176sphereVerts.push(sphereY[v2]);5177sphereVerts.push(sphereZ[v2++])5178}5179v1 = v11;5180v2 = voff;5181sphereVerts.push(sphereX[v1]);5182sphereVerts.push(sphereY[v1]);5183sphereVerts.push(sphereZ[v1]);5184sphereVerts.push(sphereX[v2]);5185sphereVerts.push(sphereY[v2]);5186sphereVerts.push(sphereZ[v2])5187}5188for (i = 0; i < sphereDetailU; i++) {5189v2 = voff + i;5190sphereVerts.push(sphereX[v2]);5191sphereVerts.push(sphereY[v2]);5192sphereVerts.push(sphereZ[v2]);5193sphereVerts.push(0);5194sphereVerts.push(1);5195sphereVerts.push(0)5196}5197sphereVerts.push(sphereX[voff]);5198sphereVerts.push(sphereY[voff]);5199sphereVerts.push(sphereZ[voff]);5200sphereVerts.push(0);5201sphereVerts.push(1);5202sphereVerts.push(0);5203curContext.bindBuffer(curContext.ARRAY_BUFFER, sphereBuffer);5204curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(sphereVerts), curContext.STATIC_DRAW)5205};5206p.sphereDetail = function(ures, vres) {5207var i;5208if (arguments.length === 1) ures = vres = arguments[0];5209if (ures < 3) ures = 3;5210if (vres < 2) vres = 2;5211if (ures === sphereDetailU && vres === sphereDetailV) return;5212var delta = 720 / ures;5213var cx = new Float32Array(ures);5214var cz = new Float32Array(ures);5215for (i = 0; i < ures; i++) {5216cx[i] = cosLUT[i * delta % 720 | 0];5217cz[i] = sinLUT[i * delta % 720 | 0]5218}5219var vertCount = ures * (vres - 1) + 2;5220var currVert = 0;5221sphereX = new Float32Array(vertCount);5222sphereY = new Float32Array(vertCount);5223sphereZ = new Float32Array(vertCount);5224var angle_step = 720 * 0.5 / vres;5225var angle = angle_step;5226for (i = 1; i < vres; i++) {5227var curradius = sinLUT[angle % 720 | 0];5228var currY = -cosLUT[angle % 720 | 0];5229for (var j = 0; j < ures; j++) {5230sphereX[currVert] = cx[j] * curradius;5231sphereY[currVert] = currY;5232sphereZ[currVert++] = cz[j] * curradius5233}5234angle += angle_step5235}5236sphereDetailU = ures;5237sphereDetailV = vres;5238initSphere()5239};5240Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction;5241Drawing3D.prototype.sphere = function() {5242var sRad = arguments[0];5243if (sphereDetailU < 3 || sphereDetailV < 2) p.sphereDetail(30);5244var model = new PMatrix3D;5245model.scale(sRad, sRad, sRad);5246var view = new PMatrix3D;5247view.scale(1, -1, 1);5248view.apply(modelView.array());5249view.transpose();5250if (doFill) {5251if (lightCount > 0) {5252var v = new PMatrix3D;5253v.set(view);5254var m = new PMatrix3D;5255m.set(model);5256v.mult(m);5257var normalMatrix = new PMatrix3D;5258normalMatrix.set(v);5259normalMatrix.invert();5260normalMatrix.transpose();5261uniformMatrix("uNormalTransform3d", programObject3D, "uNormalTransform", false, normalMatrix.array());5262vertexAttribPointer("aNormal3d", programObject3D, "aNormal", 3, sphereBuffer)5263} else disableVertexAttribPointer("aNormal3d", programObject3D, "aNormal");5264curContext.useProgram(programObject3D);5265disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture");5266uniformMatrix("uModel3d", programObject3D, "uModel", false, model.array());5267uniformMatrix("uView3d", programObject3D, "uView", false, view.array());5268vertexAttribPointer("aVertex3d", programObject3D, "aVertex", 3, sphereBuffer);5269disableVertexAttribPointer("aColor3d", programObject3D, "aColor");5270curContext.enable(curContext.POLYGON_OFFSET_FILL);5271curContext.polygonOffset(1, 1);5272uniformf("uColor3d", programObject3D, "uColor", fillStyle);5273curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3);5274curContext.disable(curContext.POLYGON_OFFSET_FILL)5275}5276if (lineWidth > 0 && doStroke) {5277curContext.useProgram(programObject2D);5278uniformMatrix("uModel2d", programObject2D, "uModel", false, model.array());5279uniformMatrix("uView2d", programObject2D, "uView", false, view.array());5280vertexAttribPointer("aVertex2d", programObject2D, "aVertex", 3, sphereBuffer);5281disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord");5282uniformf("uColor2d", programObject2D, "uColor", strokeStyle);5283uniformi("uIsDrawingText", programObject2D, "uIsDrawingText", false);5284curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3)5285}5286};5287p.modelX = function(x, y, z) {5288var mv = modelView.array();5289var ci = cameraInv.array();5290var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3];5291var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7];5292var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11];5293var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15];5294var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw;5295var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw;5296return ow !== 0 ? ox / ow : ox5297};5298p.modelY = function(x, y, z) {5299var mv = modelView.array();5300var ci = cameraInv.array();5301var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3];5302var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7];5303var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11];5304var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15];5305var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw;5306var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw;5307return ow !== 0 ? oy / ow : oy5308};5309p.modelZ = function(x, y, z) {5310var mv = modelView.array();5311var ci = cameraInv.array();5312var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3];5313var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7];5314var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11];5315var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15];5316var oz = ci[8] * ax + ci[9] * ay + ci[10] * az + ci[11] * aw;5317var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw;5318return ow !== 0 ? oz / ow : oz5319};5320Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction;5321Drawing3D.prototype.ambient = function(v1, v2, v3) {5322curContext.useProgram(programObject3D);5323uniformi("uUsingMat3d", programObject3D, "uUsingMat", true);5324var col = p.color(v1, v2, v3);5325uniformf("uMaterialAmbient3d", programObject3D, "uMaterialAmbient", p.color.toGLArray(col).slice(0, 3))5326};5327Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction;5328Drawing3D.prototype.emissive = function(v1, v2, v3) {5329curContext.useProgram(programObject3D);5330uniformi("uUsingMat3d", programObject3D, "uUsingMat", true);5331var col = p.color(v1, v2, v3);5332uniformf("uMaterialEmissive3d", programObject3D, "uMaterialEmissive", p.color.toGLArray(col).slice(0, 3))5333};5334Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction;5335Drawing3D.prototype.shininess = function(shine) {5336curContext.useProgram(programObject3D);5337uniformi("uUsingMat3d", programObject3D, "uUsingMat", true);5338uniformf("uShininess3d", programObject3D, "uShininess", shine)5339};5340Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction;5341Drawing3D.prototype.specular = function(v1, v2, v3) {5342curContext.useProgram(programObject3D);5343uniformi("uUsingMat3d", programObject3D, "uUsingMat", true);5344var col = p.color(v1, v2, v3);5345uniformf("uMaterialSpecular3d", programObject3D, "uMaterialSpecular", p.color.toGLArray(col).slice(0, 3))5346};5347p.screenX = function(x, y, z) {5348var mv = modelView.array();5349if (mv.length === 16) {5350var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3];5351var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7];5352var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11];5353var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15];5354var pj = projection.array();5355var ox = pj[0] * ax + pj[1] * ay + pj[2] * az + pj[3] * aw;5356var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw;5357if (ow !== 0) ox /= ow;5358return p.width * (1 + ox) / 25359}5360return modelView.multX(x, y)5361};5362p.screenY = function screenY(x, y, z) {5363var mv = modelView.array();5364if (mv.length === 16) {5365var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3];5366var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7];5367var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11];5368var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15];5369var pj = projection.array();5370var oy = pj[4] * ax + pj[5] * ay + pj[6] * az + pj[7] * aw;5371var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw;5372if (ow !== 0) oy /= ow;5373return p.height * (1 + oy) / 25374}5375return modelView.multY(x, y)5376};5377p.screenZ = function screenZ(x, y, z) {5378var mv = modelView.array();5379if (mv.length !== 16) return 0;5380var pj = projection.array();5381var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3];5382var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7];5383var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11];5384var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15];5385var oz = pj[8] * ax + pj[9] * ay + pj[10] * az + pj[11] * aw;5386var ow = pj[12] * ax + pj[13] * ay + pj[14] * az + pj[15] * aw;5387if (ow !== 0) oz /= ow;5388return (oz + 1) / 25389};5390DrawingShared.prototype.fill = function() {5391var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]);5392if (color === currentFillColor && doFill) return;5393doFill = true;5394currentFillColor = color5395};5396Drawing2D.prototype.fill = function() {5397DrawingShared.prototype.fill.apply(this, arguments);5398isFillDirty = true5399};5400Drawing3D.prototype.fill = function() {5401DrawingShared.prototype.fill.apply(this, arguments);5402fillStyle = p.color.toGLArray(currentFillColor)5403};54045405function executeContextFill() {5406if (doFill) {5407if (isFillDirty) {5408curContext.fillStyle = p.color.toString(currentFillColor);5409isFillDirty = false5410}5411curContext.fill()5412}5413}5414p.noFill = function() {5415doFill = false5416};5417DrawingShared.prototype.stroke = function() {5418var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]);5419if (color === currentStrokeColor && doStroke) return;5420doStroke = true;5421currentStrokeColor = color5422};5423Drawing2D.prototype.stroke = function() {5424DrawingShared.prototype.stroke.apply(this, arguments);5425isStrokeDirty = true5426};5427Drawing3D.prototype.stroke = function() {5428DrawingShared.prototype.stroke.apply(this, arguments);5429strokeStyle = p.color.toGLArray(currentStrokeColor)5430};54315432function executeContextStroke() {5433if (doStroke) {5434if (isStrokeDirty) {5435curContext.strokeStyle = p.color.toString(currentStrokeColor);5436isStrokeDirty = false5437}5438curContext.stroke()5439}5440}5441p.noStroke = function() {5442doStroke = false5443};5444DrawingShared.prototype.strokeWeight = function(w) {5445lineWidth = w5446};5447Drawing2D.prototype.strokeWeight = function(w) {5448DrawingShared.prototype.strokeWeight.apply(this, arguments);5449curContext.lineWidth = w5450};5451Drawing3D.prototype.strokeWeight = function(w) {5452DrawingShared.prototype.strokeWeight.apply(this, arguments);5453curContext.useProgram(programObject2D);5454uniformf("pointSize2d", programObject2D, "uPointSize", w);5455curContext.useProgram(programObjectUnlitShape);5456uniformf("pointSizeUnlitShape", programObjectUnlitShape, "uPointSize", w);5457curContext.lineWidth(w)5458};5459p.strokeCap = function(value) {5460drawing.$ensureContext().lineCap = value5461};5462p.strokeJoin = function(value) {5463drawing.$ensureContext().lineJoin = value5464};5465Drawing2D.prototype.smooth = function() {5466renderSmooth = true;5467var style = curElement.style;5468style.setProperty("image-rendering", "optimizeQuality", "important");5469style.setProperty("-ms-interpolation-mode", "bicubic", "important");5470if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true5471};5472Drawing3D.prototype.smooth = function() {5473renderSmooth = true5474};5475Drawing2D.prototype.noSmooth = function() {5476renderSmooth = false;5477var style = curElement.style;5478style.setProperty("image-rendering", "optimizeSpeed", "important");5479style.setProperty("image-rendering", "-moz-crisp-edges", "important");5480style.setProperty("image-rendering", "-webkit-optimize-contrast", "important");5481style.setProperty("image-rendering", "optimize-contrast", "important");5482style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important");5483if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false5484};5485Drawing3D.prototype.noSmooth = function() {5486renderSmooth = false5487};5488Drawing2D.prototype.point = function(x, y) {5489if (!doStroke) return;5490x = Math.round(x);5491y = Math.round(y);5492curContext.fillStyle = p.color.toString(currentStrokeColor);5493isFillDirty = true;5494if (lineWidth > 1) {5495curContext.beginPath();5496curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false);5497curContext.fill()5498} else curContext.fillRect(x, y, 1, 1)5499};5500Drawing3D.prototype.point = function(x, y, z) {5501var model = new PMatrix3D;5502model.translate(x, y, z || 0);5503model.transpose();5504var view = new PMatrix3D;5505view.scale(1, -1, 1);5506view.apply(modelView.array());5507view.transpose();5508curContext.useProgram(programObject2D);5509uniformMatrix("uModel2d", programObject2D, "uModel", false, model.array());5510uniformMatrix("uView2d", programObject2D, "uView", false, view.array());5511if (lineWidth > 0 && doStroke) {5512uniformf("uColor2d", programObject2D, "uColor", strokeStyle);5513uniformi("uIsDrawingText2d", programObject2D, "uIsDrawingText", false);5514uniformi("uSmooth2d", programObject2D, "uSmooth", renderSmooth);5515vertexAttribPointer("aVertex2d", programObject2D, "aVertex", 3, pointBuffer);5516disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord");5517curContext.drawArrays(curContext.POINTS, 0, 1)5518}5519};5520p.beginShape = function(type) {5521curShape = type;5522curvePoints = [];5523vertArray = []5524};5525Drawing2D.prototype.vertex = function(x, y, moveTo) {5526var vert = [];5527if (firstVert) firstVert = false;5528vert["isVert"] = true;5529vert[0] = x;5530vert[1] = y;5531vert[2] = 0;5532vert[3] = 0;5533vert[4] = 0;5534vert[5] = currentFillColor;5535vert[6] = currentStrokeColor;5536vertArray.push(vert);5537if (moveTo) vertArray[vertArray.length - 1]["moveTo"] = moveTo5538};5539Drawing3D.prototype.vertex = function(x, y, z, u, v) {5540var vert = [];5541if (firstVert) firstVert = false;5542vert["isVert"] = true;5543if (v === undef && usingTexture) {5544v = u;5545u = z;5546z = 05547}5548if (u !== undef && v !== undef) {5549if (curTextureMode === 2) {5550u /= curTexture.width;5551v /= curTexture.height5552}5553u = u > 1 ? 1 : u;5554u = u < 0 ? 0 : u;5555v = v > 1 ? 1 : v;5556v = v < 0 ? 0 : v5557}5558vert[0] = x;5559vert[1] = y;5560vert[2] = z || 0;5561vert[3] = u || 0;5562vert[4] = v || 0;5563vert[5] = fillStyle[0];5564vert[6] = fillStyle[1];5565vert[7] = fillStyle[2];5566vert[8] = fillStyle[3];5567vert[9] = strokeStyle[0];5568vert[10] = strokeStyle[1];5569vert[11] = strokeStyle[2];5570vert[12] = strokeStyle[3];5571vert[13] = normalX;5572vert[14] = normalY;5573vert[15] = normalZ;5574vertArray.push(vert)5575};5576var point3D = function(vArray, cArray) {5577var view = new PMatrix3D;5578view.scale(1, -1, 1);5579view.apply(modelView.array());5580view.transpose();5581curContext.useProgram(programObjectUnlitShape);5582uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array());5583uniformi("uSmoothUS", programObjectUnlitShape, "uSmooth", renderSmooth);5584vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, pointBuffer);5585curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW);5586vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, fillColorBuffer);5587curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW);5588curContext.drawArrays(curContext.POINTS, 0, vArray.length / 3)5589};5590var line3D = function(vArray, mode, cArray) {5591var ctxMode;5592if (mode === "LINES") ctxMode = curContext.LINES;5593else if (mode === "LINE_LOOP") ctxMode = curContext.LINE_LOOP;5594else ctxMode = curContext.LINE_STRIP;5595var view = new PMatrix3D;5596view.scale(1, -1, 1);5597view.apply(modelView.array());5598view.transpose();5599curContext.useProgram(programObjectUnlitShape);5600uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array());5601vertexAttribPointer("aVertexUS", programObjectUnlitShape, "aVertex", 3, lineBuffer);5602curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW);5603vertexAttribPointer("aColorUS", programObjectUnlitShape, "aColor", 4, strokeColorBuffer);5604curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW);5605curContext.drawArrays(ctxMode, 0, vArray.length / 3)5606};5607var fill3D = function(vArray, mode, cArray, tArray) {5608var ctxMode;5609if (mode === "TRIANGLES") ctxMode = curContext.TRIANGLES;5610else if (mode === "TRIANGLE_FAN") ctxMode = curContext.TRIANGLE_FAN;5611else ctxMode = curContext.TRIANGLE_STRIP;5612var view = new PMatrix3D;5613view.scale(1, -1, 1);5614view.apply(modelView.array());5615view.transpose();5616curContext.useProgram(programObject3D);5617uniformMatrix("model3d", programObject3D, "uModel", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);5618uniformMatrix("view3d", programObject3D, "uView", false, view.array());5619curContext.enable(curContext.POLYGON_OFFSET_FILL);5620curContext.polygonOffset(1, 1);5621uniformf("color3d", programObject3D, "uColor", [-1, 0, 0, 0]);5622vertexAttribPointer("vertex3d", programObject3D, "aVertex", 3, fillBuffer);5623curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW);5624if (usingTexture && curTint !== null) curTint3d(cArray);5625vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer);5626curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW);5627disableVertexAttribPointer("aNormal3d", programObject3D, "aNormal");5628if (usingTexture) {5629uniformi("uUsingTexture3d", programObject3D, "uUsingTexture", usingTexture);5630vertexAttribPointer("aTexture3d", programObject3D, "aTexture", 2, shapeTexVBO);5631curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(tArray), curContext.STREAM_DRAW)5632}5633curContext.drawArrays(ctxMode, 0, vArray.length / 3);5634curContext.disable(curContext.POLYGON_OFFSET_FILL)5635};56365637function fillStrokeClose() {5638executeContextFill();5639executeContextStroke();5640curContext.closePath()5641}5642Drawing2D.prototype.endShape = function(mode) {5643if (vertArray.length === 0) return;5644var closeShape = mode === 2;5645if (closeShape) vertArray.push(vertArray[0]);5646var lineVertArray = [];5647var fillVertArray = [];5648var colorVertArray = [];5649var strokeVertArray = [];5650var texVertArray = [];5651var cachedVertArray;5652firstVert = true;5653var i, j, k;5654var vertArrayLength = vertArray.length;5655for (i = 0; i < vertArrayLength; i++) {5656cachedVertArray = vertArray[i];5657for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j])5658}5659for (i = 0; i < vertArrayLength; i++) {5660cachedVertArray = vertArray[i];5661for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j])5662}5663for (i = 0; i < vertArrayLength; i++) {5664cachedVertArray = vertArray[i];5665for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j])5666}5667for (i = 0; i < vertArrayLength; i++) {5668cachedVertArray = vertArray[i];5669texVertArray.push(cachedVertArray[3]);5670texVertArray.push(cachedVertArray[4])5671}5672if (isCurve && (curShape === 20 || curShape === undef)) {5673if (vertArrayLength > 3) {5674var b = [],5675s = 1 - curTightness;5676curContext.beginPath();5677curContext.moveTo(vertArray[1][0], vertArray[1][1]);5678for (i = 1; i + 2 < vertArrayLength; i++) {5679cachedVertArray = vertArray[i];5680b[0] = [cachedVertArray[0], cachedVertArray[1]];5681b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[1] + (s * vertArray[i + 1][1] - s * vertArray[i - 1][1]) / 6];5682b[2] = [vertArray[i + 1][0] + (s * vertArray[i][0] - s * vertArray[i + 2][0]) / 6, vertArray[i + 1][1] + (s * vertArray[i][1] - s * vertArray[i + 2][1]) / 6];5683b[3] = [vertArray[i + 1][0], vertArray[i + 1][1]];5684curContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1])5685}5686fillStrokeClose()5687}5688} else if (isBezier && (curShape === 20 || curShape === undef)) {5689curContext.beginPath();5690for (i = 0; i < vertArrayLength; i++) {5691cachedVertArray = vertArray[i];5692if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]);5693else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]);5694else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5])5695}5696fillStrokeClose()5697} else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) {5698cachedVertArray = vertArray[i];5699if (doStroke) p.stroke(cachedVertArray[6]);5700p.point(cachedVertArray[0], cachedVertArray[1])5701} else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) {5702cachedVertArray = vertArray[i];5703if (doStroke) p.stroke(vertArray[i + 1][6]);5704p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1])5705} else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) {5706cachedVertArray = vertArray[i];5707curContext.beginPath();5708curContext.moveTo(cachedVertArray[0], cachedVertArray[1]);5709curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]);5710curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]);5711curContext.lineTo(cachedVertArray[0], cachedVertArray[1]);5712if (doFill) {5713p.fill(vertArray[i + 2][5]);5714executeContextFill()5715}5716if (doStroke) {5717p.stroke(vertArray[i + 2][6]);5718executeContextStroke()5719}5720curContext.closePath()5721} else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) {5722cachedVertArray = vertArray[i];5723curContext.beginPath();5724curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]);5725curContext.lineTo(cachedVertArray[0], cachedVertArray[1]);5726if (doStroke) p.stroke(vertArray[i + 1][6]);5727if (doFill) p.fill(vertArray[i + 1][5]);5728if (i + 2 < vertArrayLength) {5729curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]);5730if (doStroke) p.stroke(vertArray[i + 2][6]);5731if (doFill) p.fill(vertArray[i + 2][5])5732}5733fillStrokeClose()5734} else if (curShape === 11) {5735if (vertArrayLength > 2) {5736curContext.beginPath();5737curContext.moveTo(vertArray[0][0], vertArray[0][1]);5738curContext.lineTo(vertArray[1][0], vertArray[1][1]);5739curContext.lineTo(vertArray[2][0], vertArray[2][1]);5740if (doFill) {5741p.fill(vertArray[2][5]);5742executeContextFill()5743}5744if (doStroke) {5745p.stroke(vertArray[2][6]);5746executeContextStroke()5747}5748curContext.closePath();5749for (i = 3; i < vertArrayLength; i++) {5750cachedVertArray = vertArray[i];5751curContext.beginPath();5752curContext.moveTo(vertArray[0][0], vertArray[0][1]);5753curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]);5754curContext.lineTo(cachedVertArray[0], cachedVertArray[1]);5755if (doFill) {5756p.fill(cachedVertArray[5]);5757executeContextFill()5758}5759if (doStroke) {5760p.stroke(cachedVertArray[6]);5761executeContextStroke()5762}5763curContext.closePath()5764}5765}5766} else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) {5767cachedVertArray = vertArray[i];5768curContext.beginPath();5769curContext.moveTo(cachedVertArray[0], cachedVertArray[1]);5770for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]);5771curContext.lineTo(cachedVertArray[0], cachedVertArray[1]);5772if (doFill) {5773p.fill(vertArray[i + 3][5]);5774executeContextFill()5775}5776if (doStroke) {5777p.stroke(vertArray[i + 3][6]);5778executeContextStroke()5779}5780curContext.closePath()5781} else if (curShape === 17) {5782if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) {5783cachedVertArray = vertArray[i];5784curContext.beginPath();5785if (i + 3 < vertArrayLength) {5786curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]);5787curContext.lineTo(cachedVertArray[0], cachedVertArray[1]);5788curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]);5789curContext.lineTo(vertArray[i + 3][0], vertArray[i + 3][1]);5790if (doFill) p.fill(vertArray[i + 3][5]);5791if (doStroke) p.stroke(vertArray[i + 3][6])5792} else {5793curContext.moveTo(cachedVertArray[0], cachedVertArray[1]);5794curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1])5795}5796fillStrokeClose()5797}5798} else {5799curContext.beginPath();5800curContext.moveTo(vertArray[0][0], vertArray[0][1]);5801for (i = 1; i < vertArrayLength; i++) {5802cachedVertArray = vertArray[i];5803if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]);5804else curContext.lineTo(cachedVertArray[0], cachedVertArray[1])5805}5806fillStrokeClose()5807}5808isCurve = false;5809isBezier = false;5810curveVertArray = [];5811curveVertCount = 0;5812if (closeShape) vertArray.pop()5813};5814Drawing3D.prototype.endShape = function(mode) {5815if (vertArray.length === 0) return;5816var closeShape = mode === 2;5817var lineVertArray = [];5818var fillVertArray = [];5819var colorVertArray = [];5820var strokeVertArray = [];5821var texVertArray = [];5822var cachedVertArray;5823firstVert = true;5824var i, j, k;5825var vertArrayLength = vertArray.length;5826for (i = 0; i < vertArrayLength; i++) {5827cachedVertArray = vertArray[i];5828for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j])5829}5830for (i = 0; i < vertArrayLength; i++) {5831cachedVertArray = vertArray[i];5832for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j])5833}5834for (i = 0; i < vertArrayLength; i++) {5835cachedVertArray = vertArray[i];5836for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j])5837}5838for (i = 0; i < vertArrayLength; i++) {5839cachedVertArray = vertArray[i];5840texVertArray.push(cachedVertArray[3]);5841texVertArray.push(cachedVertArray[4])5842}5843if (closeShape) {5844fillVertArray.push(vertArray[0][0]);5845fillVertArray.push(vertArray[0][1]);5846fillVertArray.push(vertArray[0][2]);5847for (i = 5; i < 9; i++) colorVertArray.push(vertArray[0][i]);5848for (i = 9; i < 13; i++) strokeVertArray.push(vertArray[0][i]);5849texVertArray.push(vertArray[0][3]);5850texVertArray.push(vertArray[0][4])5851}5852if (isCurve && (curShape === 20 || curShape === undef)) {5853lineVertArray = fillVertArray;5854if (doStroke) line3D(lineVertArray, null, strokeVertArray);5855if (doFill) fill3D(fillVertArray, null, colorVertArray)5856} else if (isBezier && (curShape === 20 || curShape === undef)) {5857lineVertArray = fillVertArray;5858lineVertArray.splice(lineVertArray.length - 3);5859strokeVertArray.splice(strokeVertArray.length - 4);5860if (doStroke) line3D(lineVertArray, null, strokeVertArray);5861if (doFill) fill3D(fillVertArray, "TRIANGLES", colorVertArray)5862} else {5863if (curShape === 2) {5864for (i = 0; i < vertArrayLength; i++) {5865cachedVertArray = vertArray[i];5866for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j])5867}5868point3D(lineVertArray, strokeVertArray)5869} else if (curShape === 4) {5870for (i = 0; i < vertArrayLength; i++) {5871cachedVertArray = vertArray[i];5872for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j])5873}5874for (i = 0; i < vertArrayLength; i++) {5875cachedVertArray = vertArray[i];5876for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j])5877}5878line3D(lineVertArray, "LINES", strokeVertArray)5879} else if (curShape === 9) {5880if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i += 3) {5881fillVertArray = [];5882texVertArray = [];5883lineVertArray = [];5884colorVertArray = [];5885strokeVertArray = [];5886for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) {5887lineVertArray.push(vertArray[i + j][k]);5888fillVertArray.push(vertArray[i + j][k])5889}5890for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]);5891for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) {5892colorVertArray.push(vertArray[i + j][k]);5893strokeVertArray.push(vertArray[i + j][k + 4])5894}5895if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray);5896if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLES", colorVertArray, texVertArray)5897}5898} else if (curShape === 10) {5899if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; i++) {5900lineVertArray = [];5901fillVertArray = [];5902strokeVertArray = [];5903colorVertArray = [];5904texVertArray = [];5905for (j = 0; j < 3; j++) for (k = 0; k < 3; k++) {5906lineVertArray.push(vertArray[i + j][k]);5907fillVertArray.push(vertArray[i + j][k])5908}5909for (j = 0; j < 3; j++) for (k = 3; k < 5; k++) texVertArray.push(vertArray[i + j][k]);5910for (j = 0; j < 3; j++) for (k = 5; k < 9; k++) {5911strokeVertArray.push(vertArray[i + j][k + 4]);5912colorVertArray.push(vertArray[i + j][k])5913}5914if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray);5915if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray)5916}5917} else if (curShape === 11) {5918if (vertArrayLength > 2) {5919for (i = 0; i < 3; i++) {5920cachedVertArray = vertArray[i];5921for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j])5922}5923for (i = 0; i < 3; i++) {5924cachedVertArray = vertArray[i];5925for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j])5926}5927if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray);5928for (i = 2; i + 1 < vertArrayLength; i++) {5929lineVertArray = [];5930strokeVertArray = [];5931lineVertArray.push(vertArray[0][0]);5932lineVertArray.push(vertArray[0][1]);5933lineVertArray.push(vertArray[0][2]);5934strokeVertArray.push(vertArray[0][9]);5935strokeVertArray.push(vertArray[0][10]);5936strokeVertArray.push(vertArray[0][11]);5937strokeVertArray.push(vertArray[0][12]);5938for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lineVertArray.push(vertArray[i + j][k]);5939for (j = 0; j < 2; j++) for (k = 9; k < 13; k++) strokeVertArray.push(vertArray[i + j][k]);5940if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray)5941}5942if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray)5943}5944} else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) {5945lineVertArray = [];5946for (j = 0; j < 4; j++) {5947cachedVertArray = vertArray[i + j];5948for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[k])5949}5950if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray);5951if (doFill) {5952fillVertArray = [];5953colorVertArray = [];5954texVertArray = [];5955for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]);5956for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j]);5957for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 1][j]);5958for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 1][j]);5959for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 3][j]);5960for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 3][j]);5961for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i + 2][j]);5962for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i + 2][j]);5963if (usingTexture) {5964texVertArray.push(vertArray[i + 0][3]);5965texVertArray.push(vertArray[i + 0][4]);5966texVertArray.push(vertArray[i + 1][3]);5967texVertArray.push(vertArray[i + 1][4]);5968texVertArray.push(vertArray[i + 3][3]);5969texVertArray.push(vertArray[i + 3][4]);5970texVertArray.push(vertArray[i + 2][3]);5971texVertArray.push(vertArray[i + 2][4])5972}5973fill3D(fillVertArray, "TRIANGLE_STRIP", colorVertArray, texVertArray)5974}5975} else if (curShape === 17) {5976var tempArray = [];5977if (vertArrayLength > 3) {5978for (i = 0; i < 2; i++) {5979cachedVertArray = vertArray[i];5980for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j])5981}5982for (i = 0; i < 2; i++) {5983cachedVertArray = vertArray[i];5984for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j])5985}5986line3D(lineVertArray, "LINE_STRIP", strokeVertArray);5987if (vertArrayLength > 4 && vertArrayLength % 2 > 0) {5988tempArray = fillVertArray.splice(fillVertArray.length - 3);5989vertArray.pop()5990}5991for (i = 0; i + 3 < vertArrayLength; i += 2) {5992lineVertArray = [];5993strokeVertArray = [];5994for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 1][j]);5995for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 3][j]);5996for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 2][j]);5997for (j = 0; j < 3; j++) lineVertArray.push(vertArray[i + 0][j]);5998for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 1][j]);5999for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 3][j]);6000for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 2][j]);6001for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[i + 0][j]);6002if (doStroke) line3D(lineVertArray, "LINE_STRIP", strokeVertArray)6003}6004if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_LIST", colorVertArray, texVertArray)6005}6006} else if (vertArrayLength === 1) {6007for (j = 0; j < 3; j++) lineVertArray.push(vertArray[0][j]);6008for (j = 9; j < 13; j++) strokeVertArray.push(vertArray[0][j]);6009point3D(lineVertArray, strokeVertArray)6010} else {6011for (i = 0; i < vertArrayLength; i++) {6012cachedVertArray = vertArray[i];6013for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]);6014for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j])6015}6016if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray);6017else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray);6018if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray)6019}6020usingTexture = false;6021curContext.useProgram(programObject3D);6022uniformi("usingTexture3d", programObject3D, "uUsingTexture", usingTexture)6023}6024isCurve = false;6025isBezier = false;6026curveVertArray = [];6027curveVertCount = 06028};6029var splineForward = function(segments, matrix) {6030var f = 1 / segments;6031var ff = f * f;6032var fff = ff * f;6033matrix.set(0, 0, 0, 1, fff, ff, f, 0, 6 * fff, 2 * ff, 0, 0, 6 * fff, 0, 0, 0)6034};6035var curveInit = function() {6036if (!curveDrawMatrix) {6037curveBasisMatrix = new PMatrix3D;6038curveDrawMatrix = new PMatrix3D;6039curveInited = true6040}6041var s = curTightness;6042curveBasisMatrix.set((s - 1) / 2, (s + 3) / 2, (-3 - s) / 2, (1 - s) / 2, 1 - s, (-5 - s) / 2, s + 2, (s - 1) / 2, (s - 1) / 2, 0, (1 - s) / 2, 0, 0, 1, 0, 0);6043splineForward(curveDet, curveDrawMatrix);6044if (!bezierBasisInverse) curveToBezierMatrix = new PMatrix3D;6045curveToBezierMatrix.set(curveBasisMatrix);6046curveToBezierMatrix.preApply(bezierBasisInverse);6047curveDrawMatrix.apply(curveBasisMatrix)6048};6049Drawing2D.prototype.bezierVertex = function() {6050isBezier = true;6051var vert = [];6052if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()";6053for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i];6054vertArray.push(vert);6055vertArray[vertArray.length - 1]["isVert"] = false6056};6057Drawing3D.prototype.bezierVertex = function() {6058isBezier = true;6059var vert = [];6060if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()";6061if (arguments.length === 9) {6062if (bezierDrawMatrix === undef) bezierDrawMatrix = new PMatrix3D;6063var lastPoint = vertArray.length - 1;6064splineForward(bezDetail, bezierDrawMatrix);6065bezierDrawMatrix.apply(bezierBasisMatrix);6066var draw = bezierDrawMatrix.array();6067var x1 = vertArray[lastPoint][0],6068y1 = vertArray[lastPoint][1],6069z1 = vertArray[lastPoint][2];6070var xplot1 = draw[4] * x1 + draw[5] * arguments[0] + draw[6] * arguments[3] + draw[7] * arguments[6];6071var xplot2 = draw[8] * x1 + draw[9] * arguments[0] + draw[10] * arguments[3] + draw[11] * arguments[6];6072var xplot3 = draw[12] * x1 + draw[13] * arguments[0] + draw[14] * arguments[3] + draw[15] * arguments[6];6073var yplot1 = draw[4] * y1 + draw[5] * arguments[1] + draw[6] * arguments[4] + draw[7] * arguments[7];6074var yplot2 = draw[8] * y1 + draw[9] * arguments[1] + draw[10] * arguments[4] + draw[11] * arguments[7];6075var yplot3 = draw[12] * y1 + draw[13] * arguments[1] + draw[14] * arguments[4] + draw[15] * arguments[7];6076var zplot1 = draw[4] * z1 + draw[5] * arguments[2] + draw[6] * arguments[5] + draw[7] * arguments[8];6077var zplot2 = draw[8] * z1 + draw[9] * arguments[2] + draw[10] * arguments[5] + draw[11] * arguments[8];6078var zplot3 = draw[12] * z1 + draw[13] * arguments[2] + draw[14] * arguments[5] + draw[15] * arguments[8];6079for (var j = 0; j < bezDetail; j++) {6080x1 += xplot1;6081xplot1 += xplot2;6082xplot2 += xplot3;6083y1 += yplot1;6084yplot1 += yplot2;6085yplot2 += yplot3;6086z1 += zplot1;6087zplot1 += zplot2;6088zplot2 += zplot3;6089p.vertex(x1, y1, z1)6090}6091p.vertex(arguments[6], arguments[7], arguments[8])6092}6093};6094p.texture = function(pimage) {6095var curContext = drawing.$ensureContext();6096if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture);6097else if (pimage.localName === "canvas") {6098curContext.bindTexture(curContext.TEXTURE_2D, canTex);6099curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, pimage);6100curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR);6101curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR);6102curContext.generateMipmap(curContext.TEXTURE_2D);6103curTexture.width = pimage.width;6104curTexture.height = pimage.height6105} else {6106var texture = curContext.createTexture(),6107cvs = document.createElement("canvas"),6108cvsTextureCtx = cvs.getContext("2d"),6109pot;6110if (pimage.width & pimage.width - 1 === 0) cvs.width = pimage.width;6111else {6112pot = 1;6113while (pot < pimage.width) pot *= 2;6114cvs.width = pot6115}6116if (pimage.height & pimage.height - 1 === 0) cvs.height = pimage.height;6117else {6118pot = 1;6119while (pot < pimage.height) pot *= 2;6120cvs.height = pot6121}6122cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height);6123curContext.bindTexture(curContext.TEXTURE_2D, texture);6124curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR_MIPMAP_LINEAR);6125curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR);6126curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE);6127curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE);6128curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs);6129curContext.generateMipmap(curContext.TEXTURE_2D);6130pimage.__texture = texture;6131curTexture.width = pimage.width;6132curTexture.height = pimage.height6133}6134usingTexture = true;6135curContext.useProgram(programObject3D);6136uniformi("usingTexture3d", programObject3D, "uUsingTexture", usingTexture)6137};6138p.textureMode = function(mode) {6139curTextureMode = mode6140};6141var curveVertexSegment = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) {6142var x0 = x2;6143var y0 = y2;6144var z0 = z2;6145var draw = curveDrawMatrix.array();6146var xplot1 = draw[4] * x1 + draw[5] * x2 + draw[6] * x3 + draw[7] * x4;6147var xplot2 = draw[8] * x1 + draw[9] * x2 + draw[10] * x3 + draw[11] * x4;6148var xplot3 = draw[12] * x1 + draw[13] * x2 + draw[14] * x3 + draw[15] * x4;6149var yplot1 = draw[4] * y1 + draw[5] * y2 + draw[6] * y3 + draw[7] * y4;6150var yplot2 = draw[8] * y1 + draw[9] * y2 + draw[10] * y3 + draw[11] * y4;6151var yplot3 = draw[12] * y1 + draw[13] * y2 + draw[14] * y3 + draw[15] * y4;6152var zplot1 = draw[4] * z1 + draw[5] * z2 + draw[6] * z3 + draw[7] * z4;6153var zplot2 = draw[8] * z1 + draw[9] * z2 + draw[10] * z3 + draw[11] * z4;6154var zplot3 = draw[12] * z1 + draw[13] * z2 + draw[14] * z3 + draw[15] * z4;6155p.vertex(x0, y0, z0);6156for (var j = 0; j < curveDet; j++) {6157x0 += xplot1;6158xplot1 += xplot2;6159xplot2 += xplot3;6160y0 += yplot1;6161yplot1 += yplot2;6162yplot2 += yplot3;6163z0 += zplot1;6164zplot1 += zplot2;6165zplot2 += zplot3;6166p.vertex(x0, y0, z0)6167}6168};6169Drawing2D.prototype.curveVertex = function(x, y) {6170isCurve = true;6171p.vertex(x, y)6172};6173Drawing3D.prototype.curveVertex = function(x, y, z) {6174isCurve = true;6175if (!curveInited) curveInit();6176var vert = [];6177vert[0] = x;6178vert[1] = y;6179vert[2] = z;6180curveVertArray.push(vert);6181curveVertCount++;6182if (curveVertCount > 3) curveVertexSegment(curveVertArray[curveVertCount - 4][0], curveVertArray[curveVertCount - 4][1], curveVertArray[curveVertCount - 4][2], curveVertArray[curveVertCount - 3][0], curveVertArray[curveVertCount - 3][1], curveVertArray[curveVertCount - 3][2], curveVertArray[curveVertCount - 2][0], curveVertArray[curveVertCount - 2][1], curveVertArray[curveVertCount - 2][2], curveVertArray[curveVertCount - 1][0], curveVertArray[curveVertCount - 1][1], curveVertArray[curveVertCount - 1][2])6183};6184Drawing2D.prototype.curve = function(x1, y1, x2, y2, x3, y3, x4, y4) {6185p.beginShape();6186p.curveVertex(x1, y1);6187p.curveVertex(x2, y2);6188p.curveVertex(x3, y3);6189p.curveVertex(x4, y4);6190p.endShape()6191};6192Drawing3D.prototype.curve = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) {6193if (z4 !== undef) {6194p.beginShape();6195p.curveVertex(x1, y1, z1);6196p.curveVertex(x2, y2, z2);6197p.curveVertex(x3, y3, z3);6198p.curveVertex(x4, y4, z4);6199p.endShape();6200return6201}6202p.beginShape();6203p.curveVertex(x1, y1);6204p.curveVertex(z1, x2);6205p.curveVertex(y2, z2);6206p.curveVertex(x3, y3);6207p.endShape()6208};6209p.curveTightness = function(tightness) {6210curTightness = tightness6211};6212p.curveDetail = function(detail) {6213curveDet = detail;6214curveInit()6215};6216p.rectMode = function(aRectMode) {6217curRectMode = aRectMode6218};6219p.imageMode = function(mode) {6220switch (mode) {6221case 0:6222imageModeConvert = imageModeCorner;6223break;6224case 1:6225imageModeConvert = imageModeCorners;6226break;6227case 3:6228imageModeConvert = imageModeCenter;6229break;6230default:6231throw "Invalid imageMode";6232}6233};6234p.ellipseMode = function(aEllipseMode) {6235curEllipseMode = aEllipseMode6236};6237p.arc = function(x, y, width, height, start, stop) {6238if (width <= 0 || stop < start) return;6239if (curEllipseMode === 1) {6240width = width - x;6241height = height - y6242} else if (curEllipseMode === 2) {6243x = x - width;6244y = y - height;6245width = width * 2;6246height = height * 26247} else if (curEllipseMode === 3) {6248x = x - width / 2;6249y = y - height / 26250}6251while (start < 0) {6252start += 6.283185307179586;6253stop += 6.2831853071795866254}6255if (stop - start > 6.283185307179586) {6256start = 0;6257stop = 6.2831853071795866258}6259var hr = width / 2,6260vr = height / 2,6261centerX = x + hr,6262centerY = y + vr,6263startLUT = 0 | 0.5 + start * p.RAD_TO_DEG * 2,6264stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2,6265i, j;6266if (doFill) {6267var savedStroke = doStroke;6268doStroke = false;6269p.beginShape();6270p.vertex(centerX, centerY);6271for (i = startLUT; i <= stopLUT; i++) {6272j = i % 720;6273p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr)6274}6275p.endShape(2);6276doStroke = savedStroke6277}6278if (doStroke) {6279var savedFill = doFill;6280doFill = false;6281p.beginShape();6282for (i = startLUT; i <= stopLUT; i++) {6283j = i % 720;6284p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr)6285}6286p.endShape();6287doFill = savedFill6288}6289};6290Drawing2D.prototype.line = function(x1, y1, x2, y2) {6291if (!doStroke) return;6292x1 = Math.round(x1);6293x2 = Math.round(x2);6294y1 = Math.round(y1);6295y2 = Math.round(y2);6296if (x1 === x2 && y1 === y2) {6297p.point(x1, y1);6298return6299}6300var swap = undef,6301lineCap = undef,6302drawCrisp = true,6303currentModelView = modelView.array(),6304identityMatrix = [1, 0, 0, 0, 1, 0];6305for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i];6306if (drawCrisp) {6307if (x1 === x2) {6308if (y1 > y2) {6309swap = y1;6310y1 = y2;6311y2 = swap6312}6313y2++;6314if (lineWidth % 2 === 1) curContext.translate(0.5, 0)6315} else if (y1 === y2) {6316if (x1 > x2) {6317swap = x1;6318x1 = x2;6319x2 = swap6320}6321x2++;6322if (lineWidth % 2 === 1) curContext.translate(0, 0.5)6323}6324if (lineWidth === 1) {6325lineCap = curContext.lineCap;6326curContext.lineCap = "butt"6327}6328}6329curContext.beginPath();6330curContext.moveTo(x1 || 0, y1 || 0);6331curContext.lineTo(x2 || 0, y2 || 0);6332executeContextStroke();6333if (drawCrisp) {6334if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0);6335else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5);6336if (lineWidth === 1) curContext.lineCap = lineCap6337}6338};6339Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) {6340if (y2 === undef || z2 === undef) {6341z2 = 0;6342y2 = x2;6343x2 = z1;6344z1 = 06345}6346if (x1 === x2 && y1 === y2 && z1 === z2) {6347p.point(x1, y1, z1);6348return6349}6350var lineVerts = [x1, y1, z1, x2, y2, z2];6351var view = new PMatrix3D;6352view.scale(1, -1, 1);6353view.apply(modelView.array());6354view.transpose();6355if (lineWidth > 0 && doStroke) {6356curContext.useProgram(programObject2D);6357uniformMatrix("uModel2d", programObject2D, "uModel", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);6358uniformMatrix("uView2d", programObject2D, "uView", false, view.array());6359uniformf("uColor2d", programObject2D, "uColor", strokeStyle);6360uniformi("uIsDrawingText", programObject2D, "uIsDrawingText", false);6361vertexAttribPointer("aVertex2d", programObject2D, "aVertex", 3, lineBuffer);6362disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord");6363curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW);6364curContext.drawArrays(curContext.LINES, 0, 2)6365}6366};6367Drawing2D.prototype.bezier = function() {6368if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode";6369p.beginShape();6370p.vertex(arguments[0], arguments[1]);6371p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]);6372p.endShape()6373};6374Drawing3D.prototype.bezier = function() {6375if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode";6376p.beginShape();6377p.vertex(arguments[0], arguments[1], arguments[2]);6378p.bezierVertex(arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]);6379p.endShape()6380};6381p.bezierDetail = function(detail) {6382bezDetail = detail6383};6384p.bezierPoint = function(a, b, c, d, t) {6385return (1 - t) * (1 - t) * (1 - t) * a + 3 * (1 - t) * (1 - t) * t * b + 3 * (1 - t) * t * t * c + t * t * t * d6386};6387p.bezierTangent = function(a, b, c, d, t) {6388return 3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b)6389};6390p.curvePoint = function(a, b, c, d, t) {6391return 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t)6392};6393p.curveTangent = function(a, b, c, d, t) {6394return 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - d) * t + 3 * (-a + 3 * b - 3 * c + d) * t * t)6395};6396p.triangle = function(x1, y1, x2, y2, x3, y3) {6397p.beginShape(9);6398p.vertex(x1, y1, 0);6399p.vertex(x2, y2, 0);6400p.vertex(x3, y3, 0);6401p.endShape()6402};6403p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) {6404p.beginShape(16);6405p.vertex(x1, y1, 0);6406p.vertex(x2, y2, 0);6407p.vertex(x3, y3, 0);6408p.vertex(x4, y4, 0);6409p.endShape()6410};6411var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) {6412if (bl === undef) {6413tr = tl;6414br = tl;6415bl = tl6416}6417var halfWidth = width / 2,6418halfHeight = height / 2;6419if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight);6420if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight);6421if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight);6422if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight);6423if (!doFill || doStroke) curContext.translate(0.5, 0.5);6424curContext.beginPath();6425curContext.moveTo(x + tl, y);6426curContext.lineTo(x + width - tr, y);6427curContext.quadraticCurveTo(x + width, y, x + width, y + tr);6428curContext.lineTo(x + width, y + height - br);6429curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height);6430curContext.lineTo(x + bl, y + height);6431curContext.quadraticCurveTo(x, y + height, x, y + height - bl);6432curContext.lineTo(x, y + tl);6433curContext.quadraticCurveTo(x, y, x + tl, y);6434if (!doFill || doStroke) curContext.translate(-0.5, -0.5);6435executeContextFill();6436executeContextStroke()6437};6438Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) {6439if (!width && !height) return;6440if (curRectMode === 1) {6441width -= x;6442height -= y6443} else if (curRectMode === 2) {6444width *= 2;6445height *= 2;6446x -= width / 2;6447y -= height / 26448} else if (curRectMode === 3) {6449x -= width / 2;6450y -= height / 26451}6452x = Math.round(x);6453y = Math.round(y);6454width = Math.round(width);6455height = Math.round(height);6456if (tl !== undef) {6457roundedRect$2d(x, y, width, height, tl, tr, br, bl);6458return6459}6460if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5);6461curContext.beginPath();6462curContext.rect(x, y, width, height);6463executeContextFill();6464executeContextStroke();6465if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5)6466};6467Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) {6468if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode";6469if (curRectMode === 1) {6470width -= x;6471height -= y6472} else if (curRectMode === 2) {6473width *= 2;6474height *= 2;6475x -= width / 2;6476y -= height / 26477} else if (curRectMode === 3) {6478x -= width / 2;6479y -= height / 26480}6481var model = new PMatrix3D;6482model.translate(x, y, 0);6483model.scale(width, height, 1);6484model.transpose();6485var view = new PMatrix3D;6486view.scale(1, -1, 1);6487view.apply(modelView.array());6488view.transpose();6489if (lineWidth > 0 && doStroke) {6490curContext.useProgram(programObject2D);6491uniformMatrix("uModel2d", programObject2D, "uModel", false, model.array());6492uniformMatrix("uView2d", programObject2D, "uView", false, view.array());6493uniformf("uColor2d", programObject2D, "uColor", strokeStyle);6494uniformi("uIsDrawingText2d", programObject2D, "uIsDrawingText", false);6495vertexAttribPointer("aVertex2d", programObject2D, "aVertex", 3, rectBuffer);6496disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord");6497curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3)6498}6499if (doFill) {6500curContext.useProgram(programObject3D);6501uniformMatrix("uModel3d", programObject3D, "uModel", false, model.array());6502uniformMatrix("uView3d", programObject3D, "uView", false, view.array());6503curContext.enable(curContext.POLYGON_OFFSET_FILL);6504curContext.polygonOffset(1, 1);6505uniformf("color3d", programObject3D, "uColor", fillStyle);6506if (lightCount > 0) {6507var v = new PMatrix3D;6508v.set(view);6509var m = new PMatrix3D;6510m.set(model);6511v.mult(m);6512var normalMatrix = new PMatrix3D;6513normalMatrix.set(v);6514normalMatrix.invert();6515normalMatrix.transpose();6516uniformMatrix("uNormalTransform3d", programObject3D, "uNormalTransform", false, normalMatrix.array());6517vertexAttribPointer("aNormal3d", programObject3D, "aNormal", 3, rectNormBuffer)6518} else disableVertexAttribPointer("normal3d", programObject3D, "aNormal");6519vertexAttribPointer("vertex3d", programObject3D, "aVertex", 3, rectBuffer);6520curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3);6521curContext.disable(curContext.POLYGON_OFFSET_FILL)6522}6523};6524Drawing2D.prototype.ellipse = function(x, y, width, height) {6525x = x || 0;6526y = y || 0;6527if (width <= 0 && height <= 0) return;6528if (curEllipseMode === 2) {6529width *= 2;6530height *= 26531} else if (curEllipseMode === 1) {6532width = width - x;6533height = height - y;6534x += width / 2;6535y += height / 26536} else if (curEllipseMode === 0) {6537x += width / 2;6538y += height / 26539}6540if (width === height) {6541curContext.beginPath();6542curContext.arc(x, y, width / 2, 0, 6.283185307179586, false);6543executeContextFill();6544executeContextStroke()6545} else {6546var w = width / 2,6547h = height / 2,6548C = 0.5522847498307933,6549c_x = C * w,6550c_y = C * h;6551p.beginShape();6552p.vertex(x + w, y);6553p.bezierVertex(x + w, y - c_y, x + c_x, y - h, x, y - h);6554p.bezierVertex(x - c_x, y - h, x - w, y - c_y, x - w, y);6555p.bezierVertex(x - w, y + c_y, x - c_x, y + h, x, y + h);6556p.bezierVertex(x + c_x, y + h, x + w, y + c_y, x + w, y);6557p.endShape()6558}6559};6560Drawing3D.prototype.ellipse = function(x, y, width, height) {6561x = x || 0;6562y = y || 0;6563if (width <= 0 && height <= 0) return;6564if (curEllipseMode === 2) {6565width *= 2;6566height *= 26567} else if (curEllipseMode === 1) {6568width = width - x;6569height = height - y;6570x += width / 2;6571y += height / 26572} else if (curEllipseMode === 0) {6573x += width / 2;6574y += height / 26575}6576var w = width / 2,6577h = height / 2,6578C = 0.5522847498307933,6579c_x = C * w,6580c_y = C * h;6581p.beginShape();6582p.vertex(x + w, y);6583p.bezierVertex(x + w, y - c_y, 0, x + c_x, y - h, 0, x, y - h, 0);6584p.bezierVertex(x - c_x, y - h, 0, x - w, y - c_y, 0, x - w, y, 0);6585p.bezierVertex(x - w, y + c_y, 0, x - c_x, y + h, 0, x, y + h, 0);6586p.bezierVertex(x + c_x, y + h, 0, x + w, y + c_y, 0, x + w, y, 0);6587p.endShape();6588if (doFill) {6589var xAv = 0,6590yAv = 0,6591i, j;6592for (i = 0; i < vertArray.length; i++) {6593xAv += vertArray[i][0];6594yAv += vertArray[i][1]6595}6596xAv /= vertArray.length;6597yAv /= vertArray.length;6598var vert = [],6599fillVertArray = [],6600colorVertArray = [];6601vert[0] = xAv;6602vert[1] = yAv;6603vert[2] = 0;6604vert[3] = 0;6605vert[4] = 0;6606vert[5] = fillStyle[0];6607vert[6] = fillStyle[1];6608vert[7] = fillStyle[2];6609vert[8] = fillStyle[3];6610vert[9] = strokeStyle[0];6611vert[10] = strokeStyle[1];6612vert[11] = strokeStyle[2];6613vert[12] = strokeStyle[3];6614vert[13] = normalX;6615vert[14] = normalY;6616vert[15] = normalZ;6617vertArray.unshift(vert);6618for (i = 0; i < vertArray.length; i++) {6619for (j = 0; j < 3; j++) fillVertArray.push(vertArray[i][j]);6620for (j = 5; j < 9; j++) colorVertArray.push(vertArray[i][j])6621}6622fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray)6623}6624};6625p.normal = function(nx, ny, nz) {6626if (arguments.length !== 3 || !(typeof nx === "number" && typeof ny === "number" && typeof nz === "number")) throw "normal() requires three numeric arguments.";6627normalX = nx;6628normalY = ny;6629normalZ = nz;6630if (curShape !== 0) if (normalMode === 0) normalMode = 1;6631else if (normalMode === 1) normalMode = 26632};6633p.save = function(file, img) {6634if (img !== undef) return window.open(img.toDataURL(), "_blank");6635return window.open(p.externals.canvas.toDataURL(), "_blank")6636};6637var saveNumber = 0;6638p.saveFrame = function(file) {6639if (file === undef) file = "screen-####.png";6640var frameFilename = file.replace(/#+/, function(all) {6641var s = "" + saveNumber++;6642while (s.length < all.length) s = "0" + s;6643return s6644});6645p.save(frameFilename)6646};6647var utilityContext2d = document.createElement("canvas").getContext("2d");6648var canvasDataCache = [undef, undef, undef];66496650function getCanvasData(obj, w, h) {6651var canvasData = canvasDataCache.shift();6652if (canvasData === undef) {6653canvasData = {};6654canvasData.canvas = document.createElement("canvas");6655canvasData.context = canvasData.canvas.getContext("2d")6656}6657canvasDataCache.push(canvasData);6658var canvas = canvasData.canvas,6659context = canvasData.context,6660width = w || obj.width,6661height = h || obj.height;6662canvas.width = width;6663canvas.height = height;6664if (!obj) context.clearRect(0, 0, width, height);6665else if ("data" in obj) context.putImageData(obj, 0, 0);6666else {6667context.clearRect(0, 0, width, height);6668context.drawImage(obj, 0, 0, width, height)6669}6670return canvasData6671}6672function buildPixelsObject(pImage) {6673return {6674getLength: function(aImg) {6675return function() {6676if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length.";6677else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 06678}6679}(pImage),6680getPixel: function(aImg) {6681return function(i) {6682var offset = i * 4,6683data = aImg.imageData.data;6684if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels.";6685return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 2556686}6687}(pImage),6688setPixel: function(aImg) {6689return function(i, c) {6690var offset = i * 4,6691data = aImg.imageData.data;6692if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel.";6693data[offset + 0] = (c >> 16) & 255;6694data[offset + 1] = (c >> 8) & 255;6695data[offset + 2] = c & 255;6696data[offset + 3] = (c >> 24) & 255;6697aImg.__isDirty = true6698}6699}(pImage),6700toArray: function(aImg) {6701return function() {6702var arr = [],6703data = aImg.imageData.data,6704length = aImg.width * aImg.height;6705if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels.";6706for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255);6707return arr6708}6709}(pImage),6710set: function(aImg) {6711return function(arr) {6712var offset, data, c;6713if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels.";6714data = aImg.imageData.data;6715for (var i = 0, aL = arr.length; i < aL; i++) {6716c = arr[i];6717offset = i * 4;6718data[offset + 0] = (c >> 16) & 255;6719data[offset + 1] = (c >> 8) & 255;6720data[offset + 2] = c & 255;6721data[offset + 3] = (c >> 24) & 2556722}6723aImg.__isDirty = true6724}6725}(pImage)6726}6727}6728var PImage = function(aWidth, aHeight, aFormat) {6729this.__isDirty = false;6730if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth);6731else if (aHeight || aFormat) {6732this.width = aWidth || 1;6733this.height = aHeight || 1;6734var canvas = this.sourceImg = document.createElement("canvas");6735canvas.width = this.width;6736canvas.height = this.height;6737var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height);6738this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1;6739if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255;6740this.__isDirty = true;6741this.updatePixels()6742} else {6743this.width = 0;6744this.height = 0;6745this.imageData = utilityContext2d.createImageData(1, 1);6746this.format = 26747}6748this.pixels = buildPixelsObject(this)6749};6750PImage.prototype = {6751__isPImage: true,6752updatePixels: function() {6753var canvas = this.sourceImg;6754if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0);6755this.__isDirty = false6756},6757fromHTMLImageData: function(htmlImg) {6758var canvasData = getCanvasData(htmlImg);6759try {6760var imageData = canvasData.context.getImageData(0, 0, htmlImg.width, htmlImg.height);6761this.fromImageData(imageData)6762} catch(e) {6763if (htmlImg.width && htmlImg.height) {6764this.isRemote = true;6765this.width = htmlImg.width;6766this.height = htmlImg.height6767}6768}6769this.sourceImg = htmlImg6770},6771"get": function(x, y, w, h) {6772if (!arguments.length) return p.get(this);6773if (arguments.length === 2) return p.get(x, y, this);6774if (arguments.length === 4) return p.get(x, y, w, h, this)6775},6776"set": function(x, y, c) {6777p.set(x, y, c, this);6778this.__isDirty = true6779},6780blend: function(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE) {6781if (arguments.length === 9) p.blend(this, srcImg, x, y, width, height, dx, dy, dwidth, dheight, this);6782else if (arguments.length === 10) p.blend(srcImg, x, y, width, height, dx, dy, dwidth, dheight, MODE, this);6783delete this.sourceImg6784},6785copy: function(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {6786if (arguments.length === 8) p.blend(this, srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, 0, this);6787else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this);6788delete this.sourceImg6789},6790filter: function(mode, param) {6791if (arguments.length === 2) p.filter(mode, param, this);6792else if (arguments.length === 1) p.filter(mode, null, this);6793delete this.sourceImg6794},6795save: function(file) {6796p.save(file, this)6797},6798resize: function(w, h) {6799if (this.isRemote) throw "Image is loaded remotely. Cannot resize.";6800if (this.width !== 0 || this.height !== 0) {6801if (w === 0 && h !== 0) w = Math.floor(this.width / this.height * h);6802else if (h === 0 && w !== 0) h = Math.floor(this.height / this.width * w);6803var canvas = getCanvasData(this.imageData).canvas;6804var imageData = getCanvasData(canvas, w, h).context.getImageData(0, 0, w, h);6805this.fromImageData(imageData)6806}6807},6808mask: function(mask) {6809var obj = this.toImageData(),6810i, size;6811if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) {6812mask = mask.toImageData();6813for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i]6814} else throw "mask must have the same dimensions as PImage.";6815else if (mask instanceof6816Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i];6817else throw "mask array must be the same length as PImage pixels array.";6818this.fromImageData(obj)6819},6820loadPixels: nop,6821toImageData: function() {6822if (this.isRemote) return this.sourceImg;6823if (!this.__isDirty) return this.imageData;6824var canvasData = getCanvasData(this.sourceImg);6825return canvasData.context.getImageData(0, 0, this.width, this.height)6826},6827toDataURL: function() {6828if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI.";6829var canvasData = getCanvasData(this.imageData);6830return canvasData.canvas.toDataURL()6831},6832fromImageData: function(canvasImg) {6833var w = canvasImg.width,6834h = canvasImg.height,6835canvas = document.createElement("canvas"),6836ctx = canvas.getContext("2d");6837this.width = canvas.width = w;6838this.height = canvas.height = h;6839ctx.putImageData(canvasImg, 0, 0);6840this.format = 2;6841this.imageData = canvasImg;6842this.sourceImg = canvas6843}6844};6845p.PImage = PImage;6846p.createImage = function(w, h, mode) {6847return new PImage(w, h, mode)6848};6849p.loadImage = function(file, type, callback) {6850if (type) file = file + "." + type;6851var pimg;6852if (curSketch.imageCache.images[file]) {6853pimg = new PImage(curSketch.imageCache.images[file]);6854pimg.loaded = true;6855return pimg6856}6857pimg = new PImage;6858var img = document.createElement("img");6859pimg.sourceImg = img;6860img.onload = function(aImage, aPImage, aCallback) {6861var image = aImage;6862var pimg = aPImage;6863var callback = aCallback;6864return function() {6865pimg.fromHTMLImageData(image);6866pimg.loaded = true;6867if (callback) callback()6868}6869}(img, pimg, callback);6870img.src = file;6871return pimg6872};6873p.requestImage = p.loadImage;68746875function get$2(x, y) {6876var data;6877if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0;6878if (isContextReplaced) {6879var offset = ((0 | x) + p.width * (0 | y)) * 4;6880data = p.imageData.data;6881return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 2556882}6883data = p.toImageData(0 | x, 0 | y, 1, 1).data;6884return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 2556885}6886function get$3(x, y, img) {6887if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y.";6888var offset = y * img.width * 4 + x * 4,6889data = img.imageData.data;6890return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 2556891}6892function get$4(x, y, w, h) {6893var c = new PImage(w, h, 2);6894c.fromImageData(p.toImageData(x, y, w, h));6895return c6896}6897function get$5(x, y, w, h, img) {6898if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y,w,h.";6899var c = new PImage(w, h, 2),6900cData = c.imageData.data,6901imgWidth = img.width,6902imgHeight = img.height,6903imgData = img.imageData.data;6904var startRow = Math.max(0, -y),6905startColumn = Math.max(0, -x),6906stopRow = Math.min(h, imgHeight - y),6907stopColumn = Math.min(w, imgWidth - x);6908for (var i = startRow; i < stopRow; ++i) {6909var sourceOffset = ((y + i) * imgWidth + (x + startColumn)) * 4;6910var targetOffset = (i * w + startColumn) * 4;6911for (var j = startColumn; j < stopColumn; ++j) {6912cData[targetOffset++] = imgData[sourceOffset++];6913cData[targetOffset++] = imgData[sourceOffset++];6914cData[targetOffset++] = imgData[sourceOffset++];6915cData[targetOffset++] = imgData[sourceOffset++]6916}6917}6918c.__isDirty = true;6919return c6920}6921p.get = function(x, y, w, h, img) {6922if (img !== undefined) return get$5(x, y, w, h, img);6923if (h !== undefined) return get$4(x, y, w, h);6924if (w !== undefined) return get$3(x, y, w);6925if (y !== undefined) return get$2(x, y);6926if (x !== undefined) return get$5(0, 0, x.width, x.height, x);6927return get$4(0, 0, p.width, p.height)6928};6929p.createGraphics = function(w, h, render) {6930var pg = new Processing;6931pg.size(w, h, render);6932pg.background(0, 0);6933return pg6934};69356936function resetContext() {6937if (isContextReplaced) {6938curContext = originalContext;6939isContextReplaced = false;6940p.updatePixels()6941}6942}69436944function SetPixelContextWrapper() {6945function wrapFunction(newContext, name) {6946function wrapper() {6947resetContext();6948curContext[name].apply(curContext, arguments)6949}6950newContext[name] = wrapper6951}6952function wrapProperty(newContext, name) {6953function getter() {6954resetContext();6955return curContext[name]6956}6957function setter(value) {6958resetContext();6959curContext[name] = value6960}6961p.defineProperty(newContext, name, {6962get: getter,6963set: setter6964})6965}6966for (var n in curContext) if (typeof curContext[n] === "function") wrapFunction(this, n);6967else wrapProperty(this, n)6968}6969function replaceContext() {6970if (isContextReplaced) return;6971p.loadPixels();6972if (proxyContext === null) {6973originalContext = curContext;6974proxyContext = new SetPixelContextWrapper6975}6976isContextReplaced = true;6977curContext = proxyContext;6978setPixelsCached = 06979}6980function set$3(x, y, c) {6981if (x < p.width && x >= 0 && y >= 0 && y < p.height) {6982replaceContext();6983p.pixels.setPixel((0 | x) + p.width * (0 | y), c);6984if (++setPixelsCached > maxPixelsCached) resetContext()6985}6986}6987function set$4(x, y, obj, img) {6988if (img.isRemote) throw "Image is loaded remotely. Cannot set x,y.";6989var c = p.color.toArray(obj);6990var offset = y * img.width * 4 + x * 4;6991var data = img.imageData.data;6992data[offset] = c[0];6993data[offset + 1] = c[1];6994data[offset + 2] = c[2];6995data[offset + 3] = c[3]6996}6997p.set = function(x, y, obj, img) {6998var color, oldFill;6999if (arguments.length === 3) if (typeof obj === "number") set$3(x, y, obj);7000else {7001if (obj instanceof PImage || obj.__isPImage) p.image(obj, x, y)7002} else if (arguments.length === 4) set$4(x, y, obj, img)7003};7004p.imageData = {};7005p.pixels = {7006getLength: function() {7007return p.imageData.data.length ? p.imageData.data.length / 4 : 07008},7009getPixel: function(i) {7010var offset = i * 4,7011data = p.imageData.data;7012return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 2557013},7014setPixel: function(i, c) {7015var offset = i * 4,7016data = p.imageData.data;7017data[offset + 0] = (c & 16711680) >>> 16;7018data[offset + 1] = (c & 65280) >>> 8;7019data[offset + 2] = c & 255;7020data[offset + 3] = (c & 4278190080) >>> 247021},7022toArray: function() {7023var arr = [],7024length = p.imageData.width * p.imageData.height,7025data = p.imageData.data;7026for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255);7027return arr7028},7029set: function(arr) {7030for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i])7031}7032};7033p.loadPixels = function() {7034p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height)7035};7036p.updatePixels = function() {7037if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0)7038};7039p.hint = function(which) {7040var curContext = drawing.$ensureContext();7041if (which === 4) {7042curContext.disable(curContext.DEPTH_TEST);7043curContext.depthMask(false);7044curContext.clear(curContext.DEPTH_BUFFER_BIT)7045} else if (which === -4) {7046curContext.enable(curContext.DEPTH_TEST);7047curContext.depthMask(true)7048} else if (which === -1 || which === 2) renderSmooth = true;7049else if (which === 1) renderSmooth = false7050};7051var backgroundHelper = function(arg1, arg2, arg3, arg4) {7052var obj;7053if (arg1 instanceof PImage || arg1.__isPImage) {7054obj = arg1;7055if (!obj.loaded) throw "Error using image in background(): PImage not loaded.";7056if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas.";7057} else obj = p.color(arg1, arg2, arg3, arg4);7058backgroundObj = obj7059};7060Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) {7061if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4);7062if (backgroundObj instanceof PImage || backgroundObj.__isPImage) {7063saveContext();7064curContext.setTransform(1, 0, 0, 1, 0, 0);7065p.image(backgroundObj, 0, 0);7066restoreContext()7067} else {7068saveContext();7069curContext.setTransform(1, 0, 0, 1, 0, 0);7070if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height);7071curContext.fillStyle = p.color.toString(backgroundObj);7072curContext.fillRect(0, 0, p.width, p.height);7073isFillDirty = true;7074restoreContext()7075}7076};7077Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) {7078if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4);7079var c = p.color.toGLArray(backgroundObj);7080curContext.clearColor(c[0], c[1], c[2], c[3]);7081curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT)7082};7083Drawing2D.prototype.image = function(img, x, y, w, h) {7084x = Math.round(x);7085y = Math.round(y);7086if (img.width > 0) {7087var wid = w || img.width;7088var hgt = h || img.height;7089var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4);7090var fastImage = !!img.sourceImg && curTint === null;7091if (fastImage) {7092var htmlElement = img.sourceImg;7093if (img.__isDirty) img.updatePixels();7094curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h)7095} else {7096var obj = img.toImageData();7097if (curTint !== null) {7098curTint(obj);7099img.__isDirty = true7100}7101curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h)7102}7103}7104};7105Drawing3D.prototype.image = function(img, x, y, w, h) {7106if (img.width > 0) {7107x = Math.round(x);7108y = Math.round(y);7109w = w || img.width;7110h = h || img.height;7111p.beginShape(p.QUADS);7112p.texture(img);7113p.vertex(x, y, 0, 0, 0);7114p.vertex(x, y + h, 0, 0, h);7115p.vertex(x + w, y + h, 0, w, h);7116p.vertex(x + w, y, 0, w, 0);7117p.endShape()7118}7119};7120p.tint = function(a1, a2, a3, a4) {7121var tintColor = p.color(a1, a2, a3, a4);7122var r = p.red(tintColor) / colorModeX;7123var g = p.green(tintColor) / colorModeY;7124var b = p.blue(tintColor) / colorModeZ;7125var a = p.alpha(tintColor) / colorModeA;7126curTint = function(obj) {7127var data = obj.data,7128length = 4 * obj.width * obj.height;7129for (var i = 0; i < length;) {7130data[i++] *= r;7131data[i++] *= g;7132data[i++] *= b;7133data[i++] *= a7134}7135};7136curTint3d = function(data) {7137for (var i = 0; i < data.length;) {7138data[i++] = r;7139data[i++] = g;7140data[i++] = b;7141data[i++] = a7142}7143}7144};7145p.noTint = function() {7146curTint = null;7147curTint3d = null7148};7149p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) {7150if (dh === undef) {7151dh = dw;7152dw = dy;7153dy = dx;7154dx = sh;7155sh = sw;7156sw = sy;7157sy = sx;7158sx = src;7159src = p7160}7161p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, 0)7162};7163p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) {7164if (src.isRemote) throw "Image is loaded remotely. Cannot blend image.";7165if (mode === undef) {7166mode = dh;7167dh = dw;7168dw = dy;7169dy = dx;7170dx = sh;7171sh = sw;7172sw = sy;7173sy = sx;7174sx = src;7175src = p7176}7177var sx2 = sx + sw,7178sy2 = sy + sh,7179dx2 = dx + dw,7180dy2 = dy + dh,7181dest = pimgdest || p;7182if (pimgdest === undef || mode === undef) p.loadPixels();7183src.loadPixels();7184if (src === p && p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), 0, 0, sx2 - sx - 1, sy2 - sy - 1, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode);7185else p.blit_resize(src, sx, sy, sx2, sy2, dest.imageData.data, dest.width, dest.height, dx, dy, dx2, dy2, mode);7186if (pimgdest === undef) p.updatePixels()7187};7188var buildBlurKernel = function(r) {7189var radius = p.floor(r * 3.5),7190i, radiusi;7191radius = radius < 1 ? 1 : radius < 248 ? radius : 248;7192if (p.shared.blurRadius !== radius) {7193p.shared.blurRadius = radius;7194p.shared.blurKernelSize = 1 + (p.shared.blurRadius << 1);7195p.shared.blurKernel = new Float32Array(p.shared.blurKernelSize);7196var sharedBlurKernal = p.shared.blurKernel;7197var sharedBlurKernelSize = p.shared.blurKernelSize;7198var sharedBlurRadius = p.shared.blurRadius;7199for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0;7200var radiusiSquared = (radius - 1) * (radius - 1);7201for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared;7202sharedBlurKernal[radius] = radius * radius7203}7204};7205var blurARGB = function(r, aImg) {7206var sum, cr, cg, cb, ca, c, m;7207var read, ri, ym, ymi, bk0;7208var wh = aImg.pixels.getLength();7209var r2 = new Float32Array(wh);7210var g2 = new Float32Array(wh);7211var b2 = new Float32Array(wh);7212var a2 = new Float32Array(wh);7213var yi = 0;7214var x, y, i, offset;7215buildBlurKernel(r);7216var aImgHeight = aImg.height;7217var aImgWidth = aImg.width;7218var sharedBlurKernelSize = p.shared.blurKernelSize;7219var sharedBlurRadius = p.shared.blurRadius;7220var sharedBlurKernal = p.shared.blurKernel;7221var pix = aImg.imageData.data;7222for (y = 0; y < aImgHeight; y++) {7223for (x = 0; x < aImgWidth; x++) {7224cb = cg = cr = ca = sum = 0;7225read = x - sharedBlurRadius;7226if (read < 0) {7227bk0 = -read;7228read = 07229} else {7230if (read >= aImgWidth) break;7231bk0 = 07232}7233for (i = bk0; i < sharedBlurKernelSize; i++) {7234if (read >= aImgWidth) break;7235offset = (read + yi) * 4;7236m = sharedBlurKernal[i];7237ca += m * pix[offset + 3];7238cr += m * pix[offset];7239cg += m * pix[offset + 1];7240cb += m * pix[offset + 2];7241sum += m;7242read++7243}7244ri = yi + x;7245a2[ri] = ca / sum;7246r2[ri] = cr / sum;7247g2[ri] = cg / sum;7248b2[ri] = cb / sum7249}7250yi += aImgWidth7251}7252yi = 0;7253ym = -sharedBlurRadius;7254ymi = ym * aImgWidth;7255for (y = 0; y < aImgHeight; y++) {7256for (x = 0; x < aImgWidth; x++) {7257cb = cg = cr = ca = sum = 0;7258if (ym < 0) {7259bk0 = ri = -ym;7260read = x7261} else {7262if (ym >= aImgHeight) break;7263bk0 = 0;7264ri = ym;7265read = x + ymi7266}7267for (i = bk0; i < sharedBlurKernelSize; i++) {7268if (ri >= aImgHeight) break;7269m = sharedBlurKernal[i];7270ca += m * a2[read];7271cr += m * r2[read];7272cg += m * g2[read];7273cb += m * b2[read];7274sum += m;7275ri++;7276read += aImgWidth7277}7278offset = (x + yi) * 4;7279pix[offset] = cr / sum;7280pix[offset + 1] = cg / sum;7281pix[offset + 2] = cb / sum;7282pix[offset + 3] = ca / sum7283}7284yi += aImgWidth;7285ymi += aImgWidth;7286ym++7287}7288};7289var dilate = function(isInverted, aImg) {7290var currIdx = 0;7291var maxIdx = aImg.pixels.getLength();7292var out = new Int32Array(maxIdx);7293var currRowIdx, maxRowIdx, colOrig, colOut, currLum;7294var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown;7295if (!isInverted) while (currIdx < maxIdx) {7296currRowIdx = currIdx;7297maxRowIdx = currIdx + aImg.width;7298while (currIdx < maxRowIdx) {7299colOrig = colOut = aImg.pixels.getPixel(currIdx);7300idxLeft = currIdx - 1;7301idxRight = currIdx + 1;7302idxUp = currIdx - aImg.width;7303idxDown = currIdx + aImg.width;7304if (idxLeft < currRowIdx) idxLeft = currIdx;7305if (idxRight >= maxRowIdx) idxRight = currIdx;7306if (idxUp < 0) idxUp = 0;7307if (idxDown >= maxIdx) idxDown = currIdx;7308colUp = aImg.pixels.getPixel(idxUp);7309colLeft = aImg.pixels.getPixel(idxLeft);7310colDown = aImg.pixels.getPixel(idxDown);7311colRight = aImg.pixels.getPixel(idxRight);7312currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255);7313lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255);7314lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255);7315lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255);7316lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255);7317if (lumLeft > currLum) {7318colOut = colLeft;7319currLum = lumLeft7320}7321if (lumRight > currLum) {7322colOut = colRight;7323currLum = lumRight7324}7325if (lumUp > currLum) {7326colOut = colUp;7327currLum = lumUp7328}7329if (lumDown > currLum) {7330colOut = colDown;7331currLum = lumDown7332}7333out[currIdx++] = colOut7334}7335} else while (currIdx < maxIdx) {7336currRowIdx = currIdx;7337maxRowIdx = currIdx + aImg.width;7338while (currIdx < maxRowIdx) {7339colOrig = colOut = aImg.pixels.getPixel(currIdx);7340idxLeft = currIdx - 1;7341idxRight = currIdx + 1;7342idxUp = currIdx - aImg.width;7343idxDown = currIdx + aImg.width;7344if (idxLeft < currRowIdx) idxLeft = currIdx;7345if (idxRight >= maxRowIdx) idxRight = currIdx;7346if (idxUp < 0) idxUp = 0;7347if (idxDown >= maxIdx) idxDown = currIdx;7348colUp = aImg.pixels.getPixel(idxUp);7349colLeft = aImg.pixels.getPixel(idxLeft);7350colDown = aImg.pixels.getPixel(idxDown);7351colRight = aImg.pixels.getPixel(idxRight);7352currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255);7353lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255);7354lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255);7355lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255);7356lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255);7357if (lumLeft < currLum) {7358colOut = colLeft;7359currLum = lumLeft7360}7361if (lumRight < currLum) {7362colOut = colRight;7363currLum = lumRight7364}7365if (lumUp < currLum) {7366colOut = colUp;7367currLum = lumUp7368}7369if (lumDown < currLum) {7370colOut = colDown;7371currLum = lumDown7372}7373out[currIdx++] = colOut7374}7375}7376aImg.pixels.set(out)7377};7378p.filter = function(kind, param, aImg) {7379var img, col, lum, i;7380if (arguments.length === 3) {7381aImg.loadPixels();7382img = aImg7383} else {7384p.loadPixels();7385img = p7386}7387if (param === undef) param = null;7388if (img.isRemote) throw "Image is loaded remotely. Cannot filter image.";7389var imglen = img.pixels.getLength();7390switch (kind) {7391case 11:7392var radius = param || 1;7393blurARGB(radius, img);7394break;7395case 12:7396if (img.format === 4) {7397for (i = 0; i < imglen; i++) {7398col = 255 - img.pixels.getPixel(i);7399img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col)7400}7401img.format = 17402} else for (i = 0; i < imglen; i++) {7403col = img.pixels.getPixel(i);7404lum = 77 * (col >> 16 & 255) + 151 * (col >> 8 & 255) + 28 * (col & 255) >> 8;7405img.pixels.setPixel(i, col & 4278190080 | lum << 16 | lum << 8 | lum)7406}7407break;7408case 13:7409for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215);7410break;7411case 15:7412if (param === null) throw "Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)";7413var levels = p.floor(param);7414if (levels < 2 || levels > 255) throw "Levels must be between 2 and 255 for filter(POSTERIZE, levels)";7415var levels1 = levels - 1;7416for (i = 0; i < imglen; i++) {7417var rlevel = img.pixels.getPixel(i) >> 16 & 255;7418var glevel = img.pixels.getPixel(i) >> 8 & 255;7419var blevel = img.pixels.getPixel(i) & 255;7420rlevel = (rlevel * levels >> 8) * 255 / levels1;7421glevel = (glevel * levels >> 8) * 255 / levels1;7422blevel = (blevel * levels >> 8) * 255 / levels1;7423img.pixels.setPixel(i, 4278190080 & img.pixels.getPixel(i) | rlevel << 16 | glevel << 8 | blevel)7424}7425break;7426case 14:7427for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080);7428img.format = 1;7429break;7430case 16:7431if (param === null) param = 0.5;7432if (param < 0 || param > 1) throw "Level must be between 0 and 1 for filter(THRESHOLD, level)";7433var thresh = p.floor(param * 255);7434for (i = 0; i < imglen; i++) {7435var max = p.max((img.pixels.getPixel(i) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255));7436img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215))7437}7438break;7439case 17:7440dilate(true, img);7441break;7442case 18:7443dilate(false, img);7444break7445}7446img.updatePixels()7447};7448p.shared = {7449fracU: 0,7450ifU: 0,7451fracV: 0,7452ifV: 0,7453u1: 0,7454u2: 0,7455v1: 0,7456v2: 0,7457sX: 0,7458sY: 0,7459iw: 0,7460iw1: 0,7461ih1: 0,7462ul: 0,7463ll: 0,7464ur: 0,7465lr: 0,7466cUL: 0,7467cLL: 0,7468cUR: 0,7469cLR: 0,7470srcXOffset: 0,7471srcYOffset: 0,7472r: 0,7473g: 0,7474b: 0,7475a: 0,7476srcBuffer: null,7477blurRadius: 0,7478blurKernelSize: 0,7479blurKernel: null7480};7481p.intersect = function(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) {7482var sw = sx2 - sx1 + 1;7483var sh = sy2 - sy1 + 1;7484var dw = dx2 - dx1 + 1;7485var dh = dy2 - dy1 + 1;7486if (dx1 < sx1) {7487dw += dx1 - sx1;7488if (dw > sw) dw = sw7489} else {7490var w = sw + sx1 - dx1;7491if (dw > w) dw = w7492}7493if (dy1 < sy1) {7494dh += dy1 - sy1;7495if (dh > sh) dh = sh7496} else {7497var h = sh + sy1 - dy1;7498if (dh > h) dh = h7499}7500return ! (dw <= 0 || dh <= 0)7501};7502var blendFuncs = {};7503blendFuncs[1] = p.modes.blend;7504blendFuncs[2] = p.modes.add;7505blendFuncs[4] = p.modes.subtract;7506blendFuncs[8] = p.modes.lightest;7507blendFuncs[16] = p.modes.darkest;7508blendFuncs[0] = p.modes.replace;7509blendFuncs[32] = p.modes.difference;7510blendFuncs[64] = p.modes.exclusion;7511blendFuncs[128] = p.modes.multiply;7512blendFuncs[256] = p.modes.screen;7513blendFuncs[512] = p.modes.overlay;7514blendFuncs[1024] = p.modes.hard_light;7515blendFuncs[2048] = p.modes.soft_light;7516blendFuncs[4096] = p.modes.dodge;7517blendFuncs[8192] = p.modes.burn;7518p.blit_resize = function(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) {7519var x, y;7520if (srcX1 < 0) srcX1 = 0;7521if (srcY1 < 0) srcY1 = 0;7522if (srcX2 >= img.width) srcX2 = img.width - 1;7523if (srcY2 >= img.height) srcY2 = img.height - 1;7524var srcW = srcX2 - srcX1;7525var srcH = srcY2 - srcY1;7526var destW = destX2 - destX1;7527var destH = destY2 - destY1;7528if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) return;7529var dx = Math.floor(srcW / destW * 32768);7530var dy = Math.floor(srcH / destH * 32768);7531var pshared = p.shared;7532pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768);7533pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768);7534if (destX1 < 0) {7535destW += destX1;7536destX1 = 07537}7538if (destY1 < 0) {7539destH += destY1;7540destY1 = 07541}7542destW = Math.min(destW, screenW - destX1);7543destH = Math.min(destH, screenH - destY1);7544var destOffset = destY1 * screenW + destX1;7545var destColor;7546pshared.srcBuffer = img.imageData.data;7547pshared.iw = img.width;7548pshared.iw1 = img.width - 1;7549pshared.ih1 = img.height - 1;7550var filterBilinear = p.filter_bilinear,7551filterNewScanline = p.filter_new_scanline,7552blendFunc = blendFuncs[mode],7553blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080,7554RED_MASK = 16711680,7555GREEN_MASK = 65280,7556BLUE_MASK = 255,7557PREC_MAXVAL = 32767,7558PRECISIONB = 15,7559PREC_RED_SHIFT = 1,7560PREC_ALPHA_SHIFT = 9,7561srcBuffer = pshared.srcBuffer,7562min = Math.min;7563for (y = 0; y < destH; y++) {7564pshared.sX = pshared.srcXOffset;7565pshared.fracV = pshared.srcYOffset & PREC_MAXVAL;7566pshared.ifV = PREC_MAXVAL - pshared.fracV;7567pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw;7568pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw;7569for (x = 0; x < destW; x++) {7570idx = (destOffset + x) * 4;7571destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK;7572pshared.fracU = pshared.sX & PREC_MAXVAL;7573pshared.ifU = PREC_MAXVAL - pshared.fracU;7574pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB;7575pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB;7576pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB;7577pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB;7578pshared.u1 = pshared.sX >> PRECISIONB;7579pshared.u2 = min(pshared.u1 + 1, pshared.iw1);7580cULoffset = (pshared.v1 + pshared.u1) * 4;7581cURoffset = (pshared.v1 + pshared.u2) * 4;7582cLLoffset = (pshared.v2 + pshared.u1) * 4;7583cLRoffset = (pshared.v2 + pshared.u2) * 4;7584pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK;7585pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK;7586pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK;7587pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK;7588pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK;7589pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK;7590pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB;7591pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK;7592blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b);7593destPixels[idx] = (blendedColor & RED_MASK) >>> 16;7594destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8;7595destPixels[idx + 2] = blendedColor & BLUE_MASK;7596destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24;7597pshared.sX += dx7598}7599destOffset += screenW;7600pshared.srcYOffset += dy7601}7602};7603p.loadFont = function(name, size) {7604if (name === undef) throw "font name required in loadFont.";7605if (name.indexOf(".svg") === -1) {7606if (size === undef) size = curTextFont.size;7607return PFont.get(name, size)7608}7609var font = p.loadGlyphs(name);7610return {7611name: name,7612css: "12px sans-serif",7613glyph: true,7614units_per_em: font.units_per_em,7615horiz_adv_x: 1 / font.units_per_em * font.horiz_adv_x,7616ascent: font.ascent,7617descent: font.descent,7618width: function(str) {7619var width = 0;7620var len = str.length;7621for (var i = 0; i < len; i++) try {7622width += parseFloat(p.glyphLook(p.glyphTable[name], str[i]).horiz_adv_x)7623} catch(e) {7624Processing.debug(e)7625}7626return width / p.glyphTable[name].units_per_em7627}7628}7629};7630p.createFont = function(name, size) {7631return p.loadFont(name, size)7632};7633p.textFont = function(pfont, size) {7634if (size !== undef) {7635if (!pfont.glyph) pfont = PFont.get(pfont.name, size);7636curTextSize = size7637}7638curTextFont = pfont;7639curFontName = curTextFont.name;7640curTextAscent = curTextFont.ascent;7641curTextDescent = curTextFont.descent;7642curTextLeading = curTextFont.leading;7643var curContext = drawing.$ensureContext();7644curContext.font = curTextFont.css7645};7646p.textSize = function(size) {7647curTextFont = PFont.get(curFontName, size);7648curTextSize = size;7649curTextAscent = curTextFont.ascent;7650curTextDescent = curTextFont.descent;7651curTextLeading = curTextFont.leading;7652var curContext = drawing.$ensureContext();7653curContext.font = curTextFont.css7654};7655p.textAscent = function() {7656return curTextAscent7657};7658p.textDescent = function() {7659return curTextDescent7660};7661p.textLeading = function(leading) {7662curTextLeading = leading7663};7664p.textAlign = function(xalign, yalign) {7665horizontalTextAlignment = xalign;7666verticalTextAlignment = yalign || 07667};76687669function toP5String(obj) {7670if (obj instanceof String) return obj;7671if (typeof obj === "number") {7672if (obj === (0 | obj)) return obj.toString();7673return p.nf(obj, 0, 3)7674}7675if (obj === null || obj === undef) return "";7676return obj.toString()7677}7678Drawing2D.prototype.textWidth = function(str) {7679var lines = toP5String(str).split(/\r?\n/g),7680width = 0;7681var i, linesCount = lines.length;7682curContext.font = curTextFont.css;7683for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i]));7684return width | 07685};7686Drawing3D.prototype.textWidth = function(str) {7687var lines = toP5String(str).split(/\r?\n/g),7688width = 0;7689var i, linesCount = lines.length;7690if (textcanvas === undef) textcanvas = document.createElement("canvas");7691var textContext = textcanvas.getContext("2d");7692textContext.font = curTextFont.css;7693for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width);7694return width | 07695};7696p.glyphLook = function(font, chr) {7697try {7698switch (chr) {7699case "1":7700return font.one;7701case "2":7702return font.two;7703case "3":7704return font.three;7705case "4":7706return font.four;7707case "5":7708return font.five;7709case "6":7710return font.six;7711case "7":7712return font.seven;7713case "8":7714return font.eight;7715case "9":7716return font.nine;7717case "0":7718return font.zero;7719case " ":7720return font.space;7721case "$":7722return font.dollar;7723case "!":7724return font.exclam;7725case '"':7726return font.quotedbl;7727case "#":7728return font.numbersign;7729case "%":7730return font.percent;7731case "&":7732return font.ampersand;7733case "'":7734return font.quotesingle;7735case "(":7736return font.parenleft;7737case ")":7738return font.parenright;7739case "*":7740return font.asterisk;7741case "+":7742return font.plus;7743case ",":7744return font.comma;7745case "-":7746return font.hyphen;7747case ".":7748return font.period;7749case "/":7750return font.slash;7751case "_":7752return font.underscore;7753case ":":7754return font.colon;7755case ";":7756return font.semicolon;7757case "<":7758return font.less;7759case "=":7760return font.equal;7761case ">":7762return font.greater;7763case "?":7764return font.question;7765case "@":7766return font.at;7767case "[":7768return font.bracketleft;7769case "\\":7770return font.backslash;7771case "]":7772return font.bracketright;7773case "^":7774return font.asciicircum;7775case "`":7776return font.grave;7777case "{":7778return font.braceleft;7779case "|":7780return font.bar;7781case "}":7782return font.braceright;7783case "~":7784return font.asciitilde;7785default:7786return font[chr]7787}7788} catch(e) {7789Processing.debug(e)7790}7791};7792Drawing2D.prototype.text$line = function(str, x, y, z, align) {7793var textWidth = 0,7794xOffset = 0;7795if (!curTextFont.glyph) {7796if (str && "fillText" in curContext) {7797if (isFillDirty) {7798curContext.fillStyle = p.color.toString(currentFillColor);7799isFillDirty = false7800}7801if (align === 39 || align === 3) {7802textWidth = curTextFont.measureTextWidth(str);7803if (align === 39) xOffset = -textWidth;7804else xOffset = -textWidth / 27805}7806curContext.fillText(str, x + xOffset, y)7807}7808} else {7809var font = p.glyphTable[curFontName];7810saveContext();7811curContext.translate(x, y + curTextSize);7812if (align === 39 || align === 3) {7813textWidth = font.width(str);7814if (align === 39) xOffset = -textWidth;7815else xOffset = -textWidth / 27816}7817var upem = font.units_per_em,7818newScale = 1 / upem * curTextSize;7819curContext.scale(newScale, newScale);7820for (var i = 0, len = str.length; i < len; i++) try {7821p.glyphLook(font, str[i]).draw()7822} catch(e) {7823Processing.debug(e)7824}7825restoreContext()7826}7827};7828Drawing3D.prototype.text$line = function(str, x, y, z, align) {7829if (textcanvas === undef) textcanvas = document.createElement("canvas");7830var oldContext = curContext;7831curContext = textcanvas.getContext("2d");7832curContext.font = curTextFont.css;7833var textWidth = curTextFont.measureTextWidth(str);7834textcanvas.width = textWidth;7835textcanvas.height = curTextSize;7836curContext = textcanvas.getContext("2d");7837curContext.font = curTextFont.css;7838curContext.textBaseline = "top";7839Drawing2D.prototype.text$line(str, 0, 0, 0, 37);7840var aspect = textcanvas.width / textcanvas.height;7841curContext = oldContext;7842curContext.bindTexture(curContext.TEXTURE_2D, textTex);7843curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, textcanvas);7844curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MAG_FILTER, curContext.LINEAR);7845curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_MIN_FILTER, curContext.LINEAR);7846curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_T, curContext.CLAMP_TO_EDGE);7847curContext.texParameteri(curContext.TEXTURE_2D, curContext.TEXTURE_WRAP_S, curContext.CLAMP_TO_EDGE);7848var xOffset = 0;7849if (align === 39) xOffset = -textWidth;7850else if (align === 3) xOffset = -textWidth / 2;7851var model = new PMatrix3D;7852var scalefactor = curTextSize * 0.5;7853model.translate(x + xOffset - scalefactor / 2, y - scalefactor, z);7854model.scale(-aspect * scalefactor, -scalefactor, scalefactor);7855model.translate(-1, -1, -1);7856model.transpose();7857var view = new PMatrix3D;7858view.scale(1, -1, 1);7859view.apply(modelView.array());7860view.transpose();7861curContext.useProgram(programObject2D);7862vertexAttribPointer("aVertex2d", programObject2D, "aVertex", 3, textBuffer);7863vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer);7864uniformi("uSampler2d", programObject2D, "uSampler", [0]);7865uniformi("uIsDrawingText2d", programObject2D, "uIsDrawingText", true);7866uniformMatrix("uModel2d", programObject2D, "uModel", false, model.array());7867uniformMatrix("uView2d", programObject2D, "uView", false, view.array());7868uniformf("uColor2d", programObject2D, "uColor", fillStyle);7869curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER, indexBuffer);7870curContext.drawElements(curContext.TRIANGLES, 6, curContext.UNSIGNED_SHORT, 0)7871};78727873function text$4(str, x, y, z) {7874var lines, linesCount;7875if (str.indexOf("\n") < 0) {7876lines = [str];7877linesCount = 17878} else {7879lines = str.split(/\r?\n/g);7880linesCount = lines.length7881}7882var yOffset = 0;7883if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent;7884else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2;7885else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading);7886for (var i = 0; i < linesCount; ++i) {7887var line = lines[i];7888drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment);7889yOffset += curTextLeading7890}7891}7892function text$6(str, x, y, width, height, z) {7893if (str.length === 0 || width === 0 || height === 0) return;7894if (curTextSize > height) return;7895var spaceMark = -1;7896var start = 0;7897var lineWidth = 0;7898var drawCommands = [];7899for (var charPos = 0, len = str.length; charPos < len; charPos++) {7900var currentChar = str[charPos];7901var spaceChar = currentChar === " ";7902var letterWidth = curTextFont.measureTextWidth(currentChar);7903if (currentChar !== "\n" && lineWidth + letterWidth <= width) {7904if (spaceChar) spaceMark = charPos;7905lineWidth += letterWidth7906} else {7907if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos;7908else return;7909if (currentChar === "\n") {7910drawCommands.push({7911text: str.substring(start, charPos),7912width: lineWidth7913});7914start = charPos + 17915} else {7916drawCommands.push({7917text: str.substring(start, spaceMark + 1),7918width: lineWidth7919});7920start = spaceMark + 17921}7922lineWidth = 0;7923charPos = start - 17924}7925}7926if (start < len) drawCommands.push({7927text: str.substring(start),7928width: lineWidth7929});7930var xOffset = 1,7931yOffset = curTextAscent;7932if (horizontalTextAlignment === 3) xOffset = width / 2;7933else if (horizontalTextAlignment === 39) xOffset = width;7934var linesCount = drawCommands.length,7935visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading));7936if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent;7937else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1);7938else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading;7939var command, drawCommand, leading;7940for (command = 0; command < linesCount; command++) {7941leading = command * curTextLeading;7942if (yOffset + leading > height - curTextDescent) break;7943drawCommand = drawCommands[command];7944drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment)7945}7946}7947p.text = function() {7948if (textMode === 5) return;7949if (arguments.length === 3) text$4(toP5String(arguments[0]), arguments[1], arguments[2], 0);7950else if (arguments.length === 4) text$4(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3]);7951else if (arguments.length === 5) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], 0);7952else if (arguments.length === 6) text$6(toP5String(arguments[0]), arguments[1], arguments[2], arguments[3], arguments[4], arguments[5])7953};7954p.textMode = function(mode) {7955textMode = mode7956};7957p.loadGlyphs = function(url) {7958var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+",7959path;7960var regex = function(needle, hay) {7961var i = 0,7962results = [],7963latest, regexp = new RegExp(needle, "g");7964latest = results[i] = regexp.exec(hay);7965while (latest) {7966i++;7967latest = results[i] = regexp.exec(hay)7968}7969return results7970};7971var buildPath = function(d) {7972var c = regex("[A-Za-z][0-9\\- ]+|Z", d);7973var beforePathDraw = function() {7974saveContext();7975return drawing.$ensureContext()7976};7977var afterPathDraw = function() {7978executeContextFill();7979executeContextStroke();7980restoreContext()7981};7982path = "return {draw:function(){var curContext=beforePathDraw();curContext.beginPath();";7983x = 0;7984y = 0;7985cx = 0;7986cy = 0;7987nx = 0;7988ny = 0;7989d = 0;7990a = 0;7991lastCom = "";7992lenC = c.length - 1;7993for (var j = 0; j < lenC; j++) {7994var com = c[j][0],7995xy = regex(getXY, com);7996switch (com[0]) {7997case "M":7998x = parseFloat(xy[0][0]);7999y = parseFloat(xy[1][0]);8000path += "curContext.moveTo(" + x + "," + -y + ");";8001break;8002case "L":8003x = parseFloat(xy[0][0]);8004y = parseFloat(xy[1][0]);8005path += "curContext.lineTo(" + x + "," + -y + ");";8006break;8007case "H":8008x = parseFloat(xy[0][0]);8009path += "curContext.lineTo(" + x + "," + -y + ");";8010break;8011case "V":8012y = parseFloat(xy[0][0]);8013path += "curContext.lineTo(" + x + "," + -y + ");";8014break;8015case "T":8016nx = parseFloat(xy[0][0]);8017ny = parseFloat(xy[1][0]);8018if (lastCom === "Q" || lastCom === "T") {8019d = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(cy - y, 2));8020a = Math.PI + Math.atan2(cx - x, cy - y);8021cx = x + Math.sin(a) * d;8022cy = y + Math.cos(a) * d8023} else {8024cx = x;8025cy = y8026}8027path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");";8028x = nx;8029y = ny;8030break;8031case "Q":8032cx = parseFloat(xy[0][0]);8033cy = parseFloat(xy[1][0]);8034nx = parseFloat(xy[2][0]);8035ny = parseFloat(xy[3][0]);8036path += "curContext.quadraticCurveTo(" + cx + "," + -cy + "," + nx + "," + -ny + ");";8037x = nx;8038y = ny;8039break;8040case "Z":8041path += "curContext.closePath();";8042break8043}8044lastCom = com[0]8045}8046path += "afterPathDraw();";8047path += "curContext.translate(" + horiz_adv_x + ",0);";8048path += "}}";8049return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw)8050};8051var parseSVGFont = function(svg) {8052var font = svg.getElementsByTagName("font");8053p.glyphTable[url].horiz_adv_x = font[0].getAttribute("horiz-adv-x");8054var font_face = svg.getElementsByTagName("font-face")[0];8055p.glyphTable[url].units_per_em = parseFloat(font_face.getAttribute("units-per-em"));8056p.glyphTable[url].ascent = parseFloat(font_face.getAttribute("ascent"));8057p.glyphTable[url].descent = parseFloat(font_face.getAttribute("descent"));8058var glyph = svg.getElementsByTagName("glyph"),8059len = glyph.length;8060for (var i = 0; i < len; i++) {8061var unicode = glyph[i].getAttribute("unicode");8062var name = glyph[i].getAttribute("glyph-name");8063horiz_adv_x = glyph[i].getAttribute("horiz-adv-x");8064if (horiz_adv_x === null) horiz_adv_x = p.glyphTable[url].horiz_adv_x;8065d = glyph[i].getAttribute("d");8066if (d !== undef) {8067path = buildPath(d);8068p.glyphTable[url][name] = {8069name: name,8070unicode: unicode,8071horiz_adv_x: horiz_adv_x,8072draw: path.draw8073}8074}8075}8076};8077var loadXML = function() {8078var xmlDoc;8079try {8080xmlDoc = document.implementation.createDocument("", "", null)8081} catch(e_fx_op) {8082Processing.debug(e_fx_op.message);8083return8084}8085try {8086xmlDoc.async = false;8087xmlDoc.load(url);8088parseSVGFont(xmlDoc.getElementsByTagName("svg")[0])8089} catch(e_sf_ch) {8090Processing.debug(e_sf_ch);8091try {8092var xmlhttp = new window.XMLHttpRequest;8093xmlhttp.open("GET", url, false);8094xmlhttp.send(null);8095parseSVGFont(xmlhttp.responseXML.documentElement)8096} catch(e) {8097Processing.debug(e_sf_ch)8098}8099}8100};8101p.glyphTable[url] = {};8102loadXML(url);8103return p.glyphTable[url]8104};8105p.param = function(name) {8106var attributeName = "data-processing-" + name;8107if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName);8108for (var i = 0, len = curElement.childNodes.length; i < len; ++i) {8109var item = curElement.childNodes.item(i);8110if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue;8111if (item.getAttribute("name") === name) return item.getAttribute("value")8112}8113if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name];8114return null8115};81168117function wireDimensionalFunctions(mode) {8118if (mode === "3D") drawing = new Drawing3D;8119else if (mode === "2D") drawing = new Drawing2D;8120else drawing = new DrawingPre;8121for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i];8122drawing.$init()8123}8124function createDrawingPreFunction(name) {8125return function() {8126wireDimensionalFunctions("2D");8127return drawing[name].apply(this, arguments)8128}8129}8130DrawingPre.prototype.translate = createDrawingPreFunction("translate");8131DrawingPre.prototype.transform = createDrawingPreFunction("transform");8132DrawingPre.prototype.scale = createDrawingPreFunction("scale");8133DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix");8134DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix");8135DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix");8136DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix");8137DrawingPre.prototype.rotate = createDrawingPreFunction("rotate");8138DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ");8139DrawingPre.prototype.shearX = createDrawingPreFunction("shearX");8140DrawingPre.prototype.shearY = createDrawingPreFunction("shearY");8141DrawingPre.prototype.redraw = createDrawingPreFunction("redraw");8142DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData");8143DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight");8144DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight");8145DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff");8146DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular");8147DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight");8148DrawingPre.prototype.noLights = createDrawingPreFunction("noLights");8149DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight");8150DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera");8151DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera");8152DrawingPre.prototype.frustum = createDrawingPreFunction("frustum");8153DrawingPre.prototype.box = createDrawingPreFunction("box");8154DrawingPre.prototype.sphere = createDrawingPreFunction("sphere");8155DrawingPre.prototype.ambient = createDrawingPreFunction("ambient");8156DrawingPre.prototype.emissive = createDrawingPreFunction("emissive");8157DrawingPre.prototype.shininess = createDrawingPreFunction("shininess");8158DrawingPre.prototype.specular = createDrawingPreFunction("specular");8159DrawingPre.prototype.fill = createDrawingPreFunction("fill");8160DrawingPre.prototype.stroke = createDrawingPreFunction("stroke");8161DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight");8162DrawingPre.prototype.smooth = createDrawingPreFunction("smooth");8163DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth");8164DrawingPre.prototype.point = createDrawingPreFunction("point");8165DrawingPre.prototype.vertex = createDrawingPreFunction("vertex");8166DrawingPre.prototype.endShape = createDrawingPreFunction("endShape");8167DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex");8168DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex");8169DrawingPre.prototype.curve = createDrawingPreFunction("curve");8170DrawingPre.prototype.line = createDrawingPreFunction("line");8171DrawingPre.prototype.bezier = createDrawingPreFunction("bezier");8172DrawingPre.prototype.rect = createDrawingPreFunction("rect");8173DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse");8174DrawingPre.prototype.background = createDrawingPreFunction("background");8175DrawingPre.prototype.image = createDrawingPreFunction("image");8176DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth");8177DrawingPre.prototype.text$line = createDrawingPreFunction("text$line");8178DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext");8179DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix");8180DrawingPre.prototype.size = function(aWidth, aHeight, aMode) {8181wireDimensionalFunctions(aMode === 2 ? "3D" : "2D");8182p.size(aWidth, aHeight, aMode)8183};8184DrawingPre.prototype.$init = nop;8185Drawing2D.prototype.$init = function() {8186p.size(p.width, p.height);8187curContext.lineCap = "round";8188p.noSmooth();8189p.disableContextMenu()8190};8191Drawing3D.prototype.$init = function() {8192p.use3DContext = true;8193p.disableContextMenu()8194};8195DrawingShared.prototype.$ensureContext = function() {8196return curContext8197};81988199function calculateOffset(curElement, event) {8200var element = curElement,8201offsetX = 0,8202offsetY = 0;8203p.pmouseX = p.mouseX;8204p.pmouseY = p.mouseY;8205if (element.offsetParent) {8206do {8207offsetX += element.offsetLeft;8208offsetY += element.offsetTop8209} while ( !! (element = element.offsetParent))8210}8211element = curElement;8212do {8213offsetX -= element.scrollLeft || 0;8214offsetY -= element.scrollTop || 08215} while ( !! (element = element.parentNode));8216offsetX += stylePaddingLeft;8217offsetY += stylePaddingTop;8218offsetX += styleBorderLeft;8219offsetY += styleBorderTop;8220offsetX += window.pageXOffset;8221offsetY += window.pageYOffset;8222return {8223"X": offsetX,8224"Y": offsetY8225}8226}8227function updateMousePosition(curElement, event) {8228var offset = calculateOffset(curElement, event);8229p.mouseX = event.pageX - offset.X;8230p.mouseY = event.pageY - offset.Y8231}8232function addTouchEventOffset(t) {8233var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]),8234i;8235for (i = 0; i < t.touches.length; i++) {8236var touch = t.touches[i];8237touch.offsetX = touch.pageX - offset.X;8238touch.offsetY = touch.pageY - offset.Y8239}8240for (i = 0; i < t.targetTouches.length; i++) {8241var targetTouch = t.targetTouches[i];8242targetTouch.offsetX = targetTouch.pageX - offset.X;8243targetTouch.offsetY = targetTouch.pageY - offset.Y8244}8245for (i = 0; i < t.changedTouches.length; i++) {8246var changedTouch = t.changedTouches[i];8247changedTouch.offsetX = changedTouch.pageX - offset.X;8248changedTouch.offsetY = changedTouch.pageY - offset.Y8249}8250return t8251}8252attachEventHandler(curElement, "touchstart", function(t) {8253curElement.setAttribute("style", "-webkit-user-select: none");8254curElement.setAttribute("onclick", "void(0)");8255curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)");8256for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) {8257var type = eventHandlers[i].type;8258if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i])8259}8260if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) {8261attachEventHandler(curElement, "touchstart", function(t) {8262if (p.touchStart !== undef) {8263t = addTouchEventOffset(t);8264p.touchStart(t)8265}8266});8267attachEventHandler(curElement, "touchmove", function(t) {8268if (p.touchMove !== undef) {8269t.preventDefault();8270t = addTouchEventOffset(t);8271p.touchMove(t)8272}8273});8274attachEventHandler(curElement, "touchend", function(t) {8275if (p.touchEnd !== undef) {8276t = addTouchEventOffset(t);8277p.touchEnd(t)8278}8279});8280attachEventHandler(curElement, "touchcancel", function(t) {8281if (p.touchCancel !== undef) {8282t = addTouchEventOffset(t);8283p.touchCancel(t)8284}8285})8286} else {8287attachEventHandler(curElement, "touchstart", function(e) {8288updateMousePosition(curElement, e.touches[0]);8289p.__mousePressed = true;8290p.mouseDragging = false;8291p.mouseButton = 37;8292if (typeof p.mousePressed === "function") p.mousePressed()8293});8294attachEventHandler(curElement, "touchmove", function(e) {8295e.preventDefault();8296updateMousePosition(curElement, e.touches[0]);8297if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved();8298if (typeof p.mouseDragged === "function" && p.__mousePressed) {8299p.mouseDragged();8300p.mouseDragging = true8301}8302});8303attachEventHandler(curElement, "touchend", function(e) {8304p.__mousePressed = false;8305if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked();8306if (typeof p.mouseReleased === "function") p.mouseReleased()8307})8308}8309curElement.dispatchEvent(t)8310});8311(function() {8312var enabled = true,8313contextMenu = function(e) {8314e.preventDefault();8315e.stopPropagation()8316};8317p.disableContextMenu = function() {8318if (!enabled) return;8319attachEventHandler(curElement, "contextmenu", contextMenu);8320enabled = false8321};8322p.enableContextMenu = function() {8323if (enabled) return;8324detachEventHandler({8325elem: curElement,8326type: "contextmenu",8327fn: contextMenu8328});8329enabled = true8330}8331})();8332attachEventHandler(curElement, "mousemove", function(e) {8333updateMousePosition(curElement, e);8334if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved();8335if (typeof p.mouseDragged === "function" && p.__mousePressed) {8336p.mouseDragged();8337p.mouseDragging = true8338}8339});8340attachEventHandler(curElement, "mouseout", function(e) {8341if (typeof p.mouseOut === "function") p.mouseOut()8342});8343attachEventHandler(curElement, "mouseover", function(e) {8344updateMousePosition(curElement, e);8345if (typeof p.mouseOver === "function") p.mouseOver()8346});8347curElement.onmousedown = function() {8348curElement.focus();8349return false8350};8351attachEventHandler(curElement, "mousedown", function(e) {8352p.__mousePressed = true;8353p.mouseDragging = false;8354switch (e.which) {8355case 1:8356p.mouseButton = 37;8357break;8358case 2:8359p.mouseButton = 3;8360break;8361case 3:8362p.mouseButton = 39;8363break8364}8365if (typeof p.mousePressed === "function") p.mousePressed()8366});8367attachEventHandler(curElement, "mouseup", function(e) {8368p.__mousePressed = false;8369if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked();8370if (typeof p.mouseReleased === "function") p.mouseReleased()8371});8372var mouseWheelHandler = function(e) {8373var delta = 0;8374if (e.wheelDelta) {8375delta = e.wheelDelta / 120;8376if (window.opera) delta = -delta8377} else if (e.detail) delta = -e.detail / 3;8378p.mouseScroll = delta;8379if (delta && typeof p.mouseScrolled === "function") p.mouseScrolled()8380};8381attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler);8382attachEventHandler(document, "mousewheel", mouseWheelHandler);8383if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0);83848385function getKeyCode(e) {8386var code = e.which || e.keyCode;8387switch (code) {8388case 13:8389return 10;8390case 91:8391case 93:8392case 224:8393return 157;8394case 57392:8395return 17;8396case 46:8397return 127;8398case 45:8399return 1558400}8401return code8402}8403function getKeyChar(e) {8404var c = e.which || e.keyCode;8405var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey;8406switch (c) {8407case 13:8408c = anyShiftPressed ? 13 : 10;8409break;8410case 8:8411c = anyShiftPressed ? 127 : 8;8412break8413}8414return new Char(c)8415}8416function suppressKeyEvent(e) {8417if (typeof e.preventDefault === "function") e.preventDefault();8418else if (typeof e.stopPropagation === "function") e.stopPropagation();8419return false8420}8421function updateKeyPressed() {8422var ch;8423for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) {8424p.__keyPressed = true;8425return8426}8427p.__keyPressed = false8428}8429function resetKeyPressed() {8430p.__keyPressed = false;8431pressedKeysMap = [];8432lastPressedKeyCode = null8433}8434function simulateKeyTyped(code, c) {8435pressedKeysMap[code] = c;8436lastPressedKeyCode = null;8437p.key = c;8438p.keyCode = code;8439p.keyPressed();8440p.keyCode = 0;8441p.keyTyped();8442updateKeyPressed()8443}8444function handleKeydown(e) {8445var code = getKeyCode(e);8446if (code === 127) {8447simulateKeyTyped(code, new Char(127));8448return8449}8450if (codedKeys.indexOf(code) < 0) {8451lastPressedKeyCode = code;8452return8453}8454var c = new Char(65535);8455p.key = c;8456p.keyCode = code;8457pressedKeysMap[code] = c;8458p.keyPressed();8459lastPressedKeyCode = null;8460updateKeyPressed();8461return suppressKeyEvent(e)8462}8463function handleKeypress(e) {8464if (lastPressedKeyCode === null) return;8465var code = lastPressedKeyCode,8466c = getKeyChar(e);8467simulateKeyTyped(code, c);8468return suppressKeyEvent(e)8469}8470function handleKeyup(e) {8471var code = getKeyCode(e),8472c = pressedKeysMap[code];8473if (c === undef) return;8474p.key = c;8475p.keyCode = code;8476p.keyReleased();8477delete pressedKeysMap[code];8478updateKeyPressed()8479}8480if (!pgraphicsMode) {8481if (aCode instanceof Processing.Sketch) curSketch = aCode;8482else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode);8483else if (!aCode) curSketch = new Processing.Sketch(function() {});8484else curSketch = Processing.compile(aCode);8485p.externals.sketch = curSketch;8486wireDimensionalFunctions();8487curElement.onfocus = function() {8488p.focused = true8489};8490curElement.onblur = function() {8491p.focused = false;8492if (!curSketch.options.globalKeyEvents) resetKeyPressed()8493};8494if (curSketch.options.pauseOnBlur) {8495attachEventHandler(window, "focus", function() {8496if (doLoop) p.loop()8497});8498attachEventHandler(window, "blur", function() {8499if (doLoop && loopStarted) {8500p.noLoop();8501doLoop = true8502}8503resetKeyPressed()8504})8505}8506var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement;8507attachEventHandler(keyTrigger, "keydown", handleKeydown);8508attachEventHandler(keyTrigger, "keypress", handleKeypress);8509attachEventHandler(keyTrigger, "keyup", handleKeyup);8510for (var i in Processing.lib) if (Processing.lib.hasOwnProperty(i)) if (Processing.lib[i].hasOwnProperty("attach")) Processing.lib[i].attach(p);8511else if (Processing.lib[i] instanceof Function) Processing.lib[i].call(this);8512var retryInterval = 100;8513var executeSketch = function(processing) {8514if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) {8515if (window.opera) {8516var link, element, operaCache = curSketch.imageCache.operaCache;8517for (link in operaCache) if (operaCache.hasOwnProperty(link)) {8518element = operaCache[link];8519if (element !== null) document.body.removeChild(element);8520delete operaCache[link]8521}8522}8523curSketch.attach(processing, defaultScope);8524curSketch.onLoad(processing);8525if (processing.setup) {8526processing.setup();8527processing.resetMatrix();8528curSketch.onSetup()8529}8530resetContext();8531if (processing.draw) if (!doLoop) processing.redraw();8532else processing.loop()8533} else window.setTimeout(function() {8534executeSketch(processing)8535},8536retryInterval)8537};8538addInstance(this);8539executeSketch(p)8540} else {8541curSketch = new Processing.Sketch;8542wireDimensionalFunctions();8543p.size = function(w, h, render) {8544if (render && render === 2) wireDimensionalFunctions("3D");8545else wireDimensionalFunctions("2D");8546p.size(w, h, render)8547}8548}8549};8550Processing.debug = debug;8551Processing.prototype = defaultScope;85528553function getGlobalMembers() {8554var names = ["abs", "acos", "alpha", "ambient", "ambientLight", "append",8555"applyMatrix", "arc", "arrayCopy", "asin", "atan", "atan2", "background", "beginCamera", "beginDraw", "beginShape", "bezier", "bezierDetail", "bezierPoint", "bezierTangent", "bezierVertex", "binary", "blend", "blendColor", "blit_resize", "blue", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight",8556"disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs",8557"loadImage", "loadPixels", "loadShape", "loadXML", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho",8558"param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "PImage", "pixels", "PMatrix2D", "PMatrix3D", "PMatrixStack", "pmouseX", "pmouseY", "point", "pointLight", "popMatrix", "popStyle", "pow", "print", "printCamera", "println", "printMatrix", "printProjection", "PShape", "PShapeSVG", "pushMatrix", "pushStyle", "quad", "radians", "random", "Random", "randomSeed", "rect", "rectMode", "red", "redraw", "requestImage", "resetMatrix", "reverse", "rotate", "rotateX", "rotateY", "rotateZ", "round", "saturation",8559"save", "saveFrame", "saveStrings", "scale", "screenX", "screenY", "screenZ", "second", "set", "setup", "shape", "shapeMode", "shared", "shearX", "shearY", "shininess", "shorten", "sin", "size", "smooth", "sort", "specular", "sphere", "sphereDetail", "splice", "split", "splitTokens", "spotLight", "sq", "sqrt", "status", "str", "stroke", "strokeCap", "strokeJoin", "strokeWeight", "subset", "tan", "text", "textAlign", "textAscent", "textDescent", "textFont", "textLeading", "textMode", "textSize", "texture", "textureMode", "textWidth", "tint", "toImageData",8560"touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "transform", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "XML", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith", "__matches"];8561var members = {};8562var i, l;8563for (i = 0, l = names.length; i < l; ++i) members[names[i]] = null;8564for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].exports) {8565var exportedNames = Processing.lib[lib].exports;8566for (i = 0, l = exportedNames.length; i < l; ++i) members[exportedNames[i]] = null8567}8568return members8569}8570function parseProcessing(code) {8571var globalMembers = getGlobalMembers();85728573function splitToAtoms(code) {8574var atoms = [];8575var items = code.split(/([\{\[\(\)\]\}])/);8576var result = items[0];8577var stack = [];8578for (var i = 1; i < items.length; i += 2) {8579var item = items[i];8580if (item === "[" || item === "{" || item === "(") {8581stack.push(result);8582result = item8583} else if (item === "]" || item === "}" || item === ")") {8584var kind = item === "}" ? "A" : item === ")" ? "B" : "C";8585var index = atoms.length;8586atoms.push(result + item);8587result = stack.pop() + '"' + kind + (index + 1) + '"'8588}8589result += items[i + 1]8590}8591atoms.unshift(result);8592return atoms8593}8594function injectStrings(code, strings) {8595return code.replace(/'(\d+)'/g, function(all, index) {8596var val = strings[index];8597if (val.charAt(0) === "/") return val;8598return /^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/.test(val) ? "(new $p.Character(" + val + "))" : val8599})8600}8601function trimSpaces(string) {8602var m1 = /^\s*/.exec(string),8603result;8604if (m1[0].length === string.length) result = {8605left: m1[0],8606middle: "",8607right: ""8608};8609else {8610var m2 = /\s*$/.exec(string);8611result = {8612left: m1[0],8613middle: string.substring(m1[0].length, m2.index),8614right: m2[0]8615}8616}8617result.untrim = function(t) {8618return this.left + t + this.right8619};8620return result8621}8622function trim(string) {8623return string.replace(/^\s+/, "").replace(/\s+$/, "")8624}8625function appendToLookupTable(table, array) {8626for (var i = 0, l = array.length; i < l; ++i) table[array[i]] = null;8627return table8628}8629function isLookupTableEmpty(table) {8630for (var i in table) if (table.hasOwnProperty(i)) return false;8631return true8632}8633function getAtomIndex(templ) {8634return templ.substring(2, templ.length - 1)8635}8636var codeWoExtraCr = code.replace(/\r\n?|\n\r/g, "\n");8637var strings = [];8638var codeWoStrings = codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g, function(all, quoted, aposed, regexCtx, prefix, regex, singleComment, comment) {8639var index;8640if (quoted || aposed) {8641index = strings.length;8642strings.push(all);8643return "'" + index + "'"8644}8645if (regexCtx) {8646index = strings.length;8647strings.push(regex);8648return prefix + "'" + index + "'"8649}8650return comment !== "" ? " " : "\n"8651});8652codeWoStrings = codeWoStrings.replace(/__x([0-9A-F]{4})/g, function(all, hexCode) {8653return "__x005F_x" + hexCode8654});8655codeWoStrings = codeWoStrings.replace(/\$/g, "__x0024");8656var genericsWereRemoved;8657var codeWoGenerics = codeWoStrings;8658var replaceFunc = function(all, before, types, after) {8659if ( !! before || !!after) return all;8660genericsWereRemoved = true;8661return ""8662};8663do {8664genericsWereRemoved = false;8665codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\[\])*(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?(?:\s*,\s*(?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\[\])*(?:\s+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc)8666} while (genericsWereRemoved);8667var atoms = splitToAtoms(codeWoGenerics);8668var replaceContext;8669var declaredClasses = {},8670currentClassId, classIdSeed = 0;86718672function addAtom(text, type) {8673var lastIndex = atoms.length;8674atoms.push(text);8675return '"' + type + lastIndex + '"'8676}8677function generateClassId() {8678return "class" + ++classIdSeed8679}8680function appendClass(class_, classId, scopeId) {8681class_.classId = classId;8682class_.scopeId = scopeId;8683declaredClasses[classId] = class_8684}8685var transformClassBody, transformInterfaceBody, transformStatementsBlock, transformStatements, transformMain, transformExpression;8686var classesRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g;8687var methodsRegex = /\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g;8688var fieldTest = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/;8689var cstrsRegex = /\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g;8690var attrAndTypeRegex = /^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/;8691var functionsRegex = /\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g;86928693function extractClassesAndMethods(code) {8694var s = code;8695s = s.replace(classesRegex, function(all) {8696return addAtom(all, "E")8697});8698s = s.replace(methodsRegex, function(all) {8699return addAtom(all, "D")8700});8701s = s.replace(functionsRegex, function(all) {8702return addAtom(all, "H")8703});8704return s8705}8706function extractConstructors(code, className) {8707var result = code.replace(cstrsRegex, function(all, attr, name, params, throws_, body) {8708if (name !== className) return all;8709return addAtom(all, "G")8710});8711return result8712}8713function AstParam(name) {8714this.name = name8715}8716AstParam.prototype.toString = function() {8717return this.name8718};87198720function AstParams(params, methodArgsParam) {8721this.params = params;8722this.methodArgsParam = methodArgsParam8723}8724AstParams.prototype.getNames = function() {8725var names = [];8726for (var i = 0, l = this.params.length; i < l; ++i) names.push(this.params[i].name);8727return names8728};8729AstParams.prototype.prependMethodArgs = function(body) {8730if (!this.methodArgsParam) return body;8731return "{\nvar " + this.methodArgsParam.name + " = Array.prototype.slice.call(arguments, " + this.params.length + ");\n" + body.substring(1)8732};8733AstParams.prototype.toString = function() {8734if (this.params.length === 0) return "()";8735var result = "(";8736for (var i = 0, l = this.params.length; i < l; ++i) result += this.params[i] + ", ";8737return result.substring(0, result.length - 2) + ")"8738};87398740function transformParams(params) {8741var paramsWoPars = trim(params.substring(1, params.length - 1));8742var result = [],8743methodArgsParam = null;8744if (paramsWoPars !== "") {8745var paramList = paramsWoPars.split(",");8746for (var i = 0; i < paramList.length; ++i) {8747var param = /\b([A-Za-z_$][\w$]*\b)(\s*"[ABC][\d]*")*\s*$/.exec(paramList[i]);8748if (i === paramList.length - 1 && paramList[i].indexOf("...") >= 0) {8749methodArgsParam = new AstParam(param[1]);8750break8751}8752result.push(new AstParam(param[1]))8753}8754}8755return new AstParams(result, methodArgsParam)8756}8757function preExpressionTransform(expr) {8758var s = expr;8759s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g, function(all, type, init) {8760return init8761});8762s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g, function(all, type, init) {8763return addAtom(all, "F")8764});8765s = s.replace(functionsRegex, function(all) {8766return addAtom(all, "H")8767});8768s = s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g, function(all, type, index) {8769var args = index.replace(/"C(\d+)"/g, function(all, j) {8770return atoms[j]8771}).replace(/\[\s*\]/g, "[null]").replace(/\s*\]\s*\[\s*/g, ", ");8772var arrayInitializer = "{" + args.substring(1, args.length - 1) + "}";8773var createArrayArgs = "('" + type + "', " + addAtom(arrayInitializer, "A") + ")";8774return "$p.createJavaArray" + addAtom(createArrayArgs, "B")8775});8776s = s.replace(/(\.\s*length)\s*"B\d+"/g, "$1");8777s = s.replace(/#([0-9A-Fa-f]{6})\b/g, function(all, digits) {8778return "0xFF" + digits8779});8780s = s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g, function(all, index, next) {8781var atom = atoms[index];8782if (!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)) return all;8783if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next;8784var indexParts = atom.split(/"C(\d+)"/g);8785if (indexParts.length > 1) if (!/^\[\s*\]$/.test(atoms[indexParts[1]])) return all;8786return "" + next8787});8788s = s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~<\>\=]+)/g, function(all, arg) {8789var trimmed = trimSpaces(arg);8790return trimmed.untrim("__int_cast(" + trimmed.middle + ")")8791});8792s = s.replace(/\bsuper(\s*"B\d+")/g, "$$superCstr$1").replace(/\bsuper(\s*\.)/g, "$$super$1");8793s = s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/, function(all, numberWo0, intPart) {8794if (numberWo0 === intPart) return all;8795return intPart === "" ? "0" + numberWo0 : numberWo08796});8797s = s.replace(/\b(\.?\d+\.?)[fF]\b/g, "$1");8798s = s.replace(/([^\s])%([^=\s])/g, "$1 % $2");8799s = s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g, "__$1");8800s = s.replace(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) {8801return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B'8802});8803s = s.replace(/\bpixels\b\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}]+))?/g, function(all, indexOrLength, index, atomIndex, equalsPart, rightSide) {8804if (index) {8805var atom = atoms[atomIndex];8806if (equalsPart) return "pixels.setPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + "," + rightSide + ")", "B");8807return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B")8808}8809if (indexOrLength) return "pixels.getLength" + addAtom("()", "B");8810if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B");8811return "pixels.toArray" + addAtom("()", "B")8812});8813var repeatJavaReplacement;88148815function replacePrototypeMethods(all, subject, method, atomIndex) {8816var atom = atoms[atomIndex];8817repeatJavaReplacement = true;8818var trimmed = trimSpaces(atom.substring(1, atom.length - 1));8819return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B"))8820}8821do {8822repeatJavaReplacement = false;8823s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt|matches)\s*"B(\d+)"/g, replacePrototypeMethods)8824} while (repeatJavaReplacement);88258826function replaceInstanceof(all, subject, type) {8827repeatJavaReplacement = true;8828return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B")8829}8830do {8831repeatJavaReplacement = false;8832s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof)8833} while (repeatJavaReplacement);8834s = s.replace(/\bthis(\s*"B\d+")/g, "$$constr$1");8835return s8836}8837function AstInlineClass(baseInterfaceName, body) {8838this.baseInterfaceName = baseInterfaceName;8839this.body = body;8840body.owner = this8841}8842AstInlineClass.prototype.toString = function() {8843return "new (" + this.body + ")"8844};88458846function transformInlineClass(class_) {8847var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_);8848var oldClassId = currentClassId,8849newClassId = generateClassId();8850currentClassId = newClassId;8851var uniqueClassName = m[1] + "$" + newClassId;8852var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + m[1]));8853appendClass(inlineClass, newClassId, oldClassId);8854currentClassId = oldClassId;8855return inlineClass8856}88578858function AstFunction(name, params, body) {8859this.name = name;8860this.params = params;8861this.body = body8862}8863AstFunction.prototype.toString = function() {8864var oldContext = replaceContext;8865var names = appendToLookupTable({8866"this": null8867},8868this.params.getNames());8869replaceContext = function(subject) {8870return names.hasOwnProperty(subject.name) ? subject.name : oldContext(subject)8871};8872var result = "function";8873if (this.name) result += " " + this.name;8874var body = this.params.prependMethodArgs(this.body.toString());8875result += this.params + " " + body;8876replaceContext = oldContext;8877return result8878};88798880function transformFunction(class_) {8881var m = (new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/)).exec(class_);8882return new AstFunction(m[1] !== "function" ? m[1] : null, transformParams(atoms[m[2]]), transformStatementsBlock(atoms[m[3]]))8883}8884function AstInlineObject(members) {8885this.members = members8886}8887AstInlineObject.prototype.toString = function() {8888var oldContext = replaceContext;8889replaceContext = function(subject) {8890return subject.name === "this" ? "this" : oldContext(subject)8891};8892var result = "";8893for (var i = 0, l = this.members.length; i < l; ++i) {8894if (this.members[i].label) result += this.members[i].label + ": ";8895result += this.members[i].value.toString() + ", "8896}8897replaceContext = oldContext;8898return result.substring(0, result.length - 2)8899};89008901function transformInlineObject(obj) {8902var members = obj.split(",");8903for (var i = 0; i < members.length; ++i) {8904var label = members[i].indexOf(":");8905if (label < 0) members[i] = {8906value: transformExpression(members[i])8907};8908else members[i] = {8909label: trim(members[i].substring(0, label)),8910value: transformExpression(trim(members[i].substring(label + 1)))8911}8912}8913return new AstInlineObject(members)8914}89158916function expandExpression(expr) {8917if (expr.charAt(0) === "(" || expr.charAt(0) === "[") return expr.charAt(0) + expandExpression(expr.substring(1, expr.length - 1)) + expr.charAt(expr.length - 1);8918if (expr.charAt(0) === "{") {8919if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}";8920return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]"8921}8922var trimmed = trimSpaces(expr);8923var result = preExpressionTransform(trimmed.middle);8924result = result.replace(/"[ABC](\d+)"/g, function(all, index) {8925return expandExpression(atoms[index])8926});8927return trimmed.untrim(result)8928}8929function replaceContextInVars(expr) {8930return expr.replace(/(\.\s*)?((?:\b[A-Za-z_]|\$)[\w$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) {8931if (memberAccessSign) return all;8932var subject = {8933name: identifier,8934member: subMember,8935callSign: !!callSign8936};8937return replaceContext(subject) + (suffix === undef ? "" : suffix)8938})8939}8940function AstExpression(expr, transforms) {8941this.expr = expr;8942this.transforms = transforms8943}8944AstExpression.prototype.toString = function() {8945var transforms = this.transforms;8946var expr = replaceContextInVars(this.expr);8947return expr.replace(/"!(\d+)"/g, function(all, index) {8948return transforms[index].toString()8949})8950};8951transformExpression = function(expr) {8952var transforms = [];8953var s = expandExpression(expr);8954s = s.replace(/"H(\d+)"/g, function(all, index) {8955transforms.push(transformFunction(atoms[index]));8956return '"!' + (transforms.length - 1) + '"'8957});8958s = s.replace(/"F(\d+)"/g, function(all, index) {8959transforms.push(transformInlineClass(atoms[index]));8960return '"!' + (transforms.length - 1) + '"'8961});8962s = s.replace(/"I(\d+)"/g, function(all, index) {8963transforms.push(transformInlineObject(atoms[index]));8964return '"!' + (transforms.length - 1) + '"'8965});8966return new AstExpression(s, transforms)8967};89688969function AstVarDefinition(name, value, isDefault) {8970this.name = name;8971this.value = value;8972this.isDefault = isDefault8973}8974AstVarDefinition.prototype.toString = function() {8975return this.name + " = " + this.value8976};89778978function transformVarDefinition(def, defaultTypeValue) {8979var eqIndex = def.indexOf("=");8980var name, value, isDefault;8981if (eqIndex < 0) {8982name = def;8983value = defaultTypeValue;8984isDefault = true8985} else {8986name = def.substring(0, eqIndex);8987value = transformExpression(def.substring(eqIndex + 1));8988isDefault = false8989}8990return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g, "")), value, isDefault)8991}8992function getDefaultValueForType(type) {8993if (type === "int" || type === "float") return "0";8994if (type === "boolean") return "false";8995if (type === "color") return "0x00000000";8996return "null"8997}8998function AstVar(definitions, varType) {8999this.definitions = definitions;9000this.varType = varType9001}9002AstVar.prototype.getNames = function() {9003var names = [];9004for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name);9005return names9006};9007AstVar.prototype.toString = function() {9008return "var " + this.definitions.join(",")9009};90109011function AstStatement(expression) {9012this.expression = expression9013}9014AstStatement.prototype.toString = function() {9015return this.expression.toString()9016};90179018function transformStatement(statement) {9019if (fieldTest.test(statement)) {9020var attrAndType = attrAndTypeRegex.exec(statement);9021var definitions = statement.substring(attrAndType[0].length).split(",");9022var defaultTypeValue = getDefaultValueForType(attrAndType[2]);9023for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue);9024return new AstVar(definitions, attrAndType[2])9025}9026return new AstStatement(transformExpression(statement))9027}9028function AstForExpression(initStatement, condition, step) {9029this.initStatement = initStatement;9030this.condition = condition;9031this.step = step9032}9033AstForExpression.prototype.toString = function() {9034return "(" + this.initStatement + "; " + this.condition + "; " + this.step + ")"9035};90369037function AstForInExpression(initStatement, container) {9038this.initStatement = initStatement;9039this.container = container9040}9041AstForInExpression.prototype.toString = function() {9042var init = this.initStatement.toString();9043if (init.indexOf("=") >= 0) init = init.substring(0, init.indexOf("="));9044return "(" + init + " in " + this.container + ")"9045};90469047function AstForEachExpression(initStatement, container) {9048this.initStatement = initStatement;9049this.container = container9050}9051AstForEachExpression.iteratorId = 0;9052AstForEachExpression.prototype.toString = function() {9053var init = this.initStatement.toString();9054var iterator = "$it" + AstForEachExpression.iteratorId++;9055var variableName = init.replace(/^\s*var\s*/, "").split("=")[0];9056var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)";9057var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)";9058return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)"9059};90609061function transformForExpression(expr) {9062var content;9063if (/\bin\b/.test(expr)) {9064content = expr.substring(1, expr.length - 1).split(/\bin\b/g);9065return new AstForInExpression(transformStatement(trim(content[0])), transformExpression(content[1]))9066}9067if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) {9068content = expr.substring(1, expr.length - 1).split(":");9069return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1]))9070}9071content = expr.substring(1, expr.length - 1).split(";");9072return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2]))9073}90749075function sortByWeight(array) {9076array.sort(function(a, b) {9077return b.weight - a.weight9078})9079}9080function AstInnerInterface(name, body, isStatic) {9081this.name = name;9082this.body = body;9083this.isStatic = isStatic;9084body.owner = this9085}9086AstInnerInterface.prototype.toString = function() {9087return "" + this.body9088};90899090function AstInnerClass(name, body, isStatic) {9091this.name = name;9092this.body = body;9093this.isStatic = isStatic;9094body.owner = this9095}9096AstInnerClass.prototype.toString = function() {9097return "" + this.body9098};90999100function transformInnerClass(class_) {9101var m = classesRegex.exec(class_);9102classesRegex.lastIndex = 0;9103var isStatic = m[1].indexOf("static") >= 0;9104var body = atoms[getAtomIndex(m[6])],9105innerClass;9106var oldClassId = currentClassId,9107newClassId = generateClassId();9108currentClassId = newClassId;9109if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic);9110else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic);9111appendClass(innerClass, newClassId, oldClassId);9112currentClassId = oldClassId;9113return innerClass9114}9115function AstClassMethod(name, params, body, isStatic) {9116this.name = name;9117this.params = params;9118this.body = body;9119this.isStatic = isStatic9120}9121AstClassMethod.prototype.toString = function() {9122var paramNames = appendToLookupTable({},9123this.params.getNames());9124var oldContext = replaceContext;9125replaceContext = function(subject) {9126return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject)9127};9128var body = this.params.prependMethodArgs(this.body.toString());9129var result = "function " + this.methodId + this.params + " " + body + "\n";9130replaceContext = oldContext;9131return result9132};91339134function transformClassMethod(method) {9135var m = methodsRegex.exec(method);9136methodsRegex.lastIndex = 0;9137var isStatic = m[1].indexOf("static") >= 0;9138var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}";9139return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic)9140}9141function AstClassField(definitions, fieldType, isStatic) {9142this.definitions = definitions;9143this.fieldType = fieldType;9144this.isStatic = isStatic9145}9146AstClassField.prototype.getNames = function() {9147var names = [];9148for (var i = 0, l = this.definitions.length; i < l; ++i) names.push(this.definitions[i].name);9149return names9150};9151AstClassField.prototype.toString = function() {9152var thisPrefix = replaceContext({9153name: "[this]"9154});9155if (this.isStatic) {9156var className = this.owner.name;9157var staticDeclarations = [];9158for (var i = 0, l = this.definitions.length; i < l; ++i) {9159var definition = this.definitions[i];9160var name = definition.name,9161staticName = className + "." + name;9162var declaration = "if(" + staticName + " === void(0)) {\n" + " " + staticName + " = " + definition.value + "; }\n" + "$p.defineProperty(" + thisPrefix + ", " + "'" + name + "', { get: function(){return " + staticName + ";}, " + "set: function(val){" + staticName + " = val;} });\n";9163staticDeclarations.push(declaration)9164}9165return staticDeclarations.join("")9166}9167return thisPrefix + "." + this.definitions.join("; " + thisPrefix + ".")9168};91699170function transformClassField(statement) {9171var attrAndType = attrAndTypeRegex.exec(statement);9172var isStatic = attrAndType[1].indexOf("static") >= 0;9173var definitions = statement.substring(attrAndType[0].length).split(/,\s*/g);9174var defaultTypeValue = getDefaultValueForType(attrAndType[2]);9175for (var i = 0; i < definitions.length; ++i) definitions[i] = transformVarDefinition(definitions[i], defaultTypeValue);9176return new AstClassField(definitions, attrAndType[2], isStatic)9177}9178function AstConstructor(params, body) {9179this.params = params;9180this.body = body9181}9182AstConstructor.prototype.toString = function() {9183var paramNames = appendToLookupTable({},9184this.params.getNames());9185var oldContext = replaceContext;9186replaceContext = function(subject) {9187return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject)9188};9189var prefix = "function $constr_" + this.params.params.length + this.params.toString();9190var body = this.params.prependMethodArgs(this.body.toString());9191if (!/\$(superCstr|constr)\b/.test(body)) body = "{\n$superCstr();\n" + body.substring(1);9192replaceContext = oldContext;9193return prefix + body + "\n"9194};91959196function transformConstructor(cstr) {9197var m = (new RegExp(/"B(\d+)"\s*"A(\d+)"/)).exec(cstr);9198var params = transformParams(atoms[m[1]]);9199return new AstConstructor(params, transformStatementsBlock(atoms[m[2]]))9200}9201function AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) {9202var i, l;9203this.name = name;9204this.interfacesNames = interfacesNames;9205this.methodsNames = methodsNames;9206this.fields = fields;9207this.innerClasses = innerClasses;9208this.misc = misc;9209for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this9210}9211AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) {9212if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners);9213var i, j, l, m;9214for (i = 0, l = this.fields.length; i < l; ++i) {9215var fieldNames = this.fields[i].getNames();9216for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i]9217}9218for (i = 0, l = this.methodsNames.length; i < l; ++i) {9219var methodName = this.methodsNames[i];9220classMethods[methodName] = true9221}9222for (i = 0, l = this.innerClasses.length; i < l; ++i) {9223var innerClass = this.innerClasses[i];9224classInners[innerClass.name] = innerClass9225}9226};9227AstInterfaceBody.prototype.toString = function() {9228function getScopeLevel(p) {9229var i = 0;9230while (p) {9231++i;9232p = p.scope9233}9234return i9235}9236var scopeLevel = getScopeLevel(this.owner);9237var className = this.name;9238var staticDefinitions = "";9239var metadata = "";9240var thisClassFields = {},9241thisClassMethods = {},9242thisClassInners = {};9243this.getMembers(thisClassFields, thisClassMethods, thisClassInners);9244var i, l, j, m;9245if (this.owner.interfaces) {9246var resolvedInterfaces = [],9247resolvedInterface;9248for (i = 0, l = this.interfacesNames.length; i < l; ++i) {9249if (!this.owner.interfaces[i]) continue;9250resolvedInterface = replaceContext({9251name: this.interfacesNames[i]9252});9253resolvedInterfaces.push(resolvedInterface);9254staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n"9255}9256metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n"9257}9258metadata += className + ".$isInterface = true;\n";9259metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n";9260sortByWeight(this.innerClasses);9261for (i = 0, l = this.innerClasses.length; i < l; ++i) {9262var innerClass = this.innerClasses[i];9263if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"9264}9265for (i = 0, l = this.fields.length; i < l; ++i) {9266var field = this.fields[i];9267if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"9268}9269return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()"9270};9271transformInterfaceBody = function(body, name, baseInterfaces) {9272var declarations = body.substring(1, body.length - 1);9273declarations = extractClassesAndMethods(declarations);9274declarations = extractConstructors(declarations, name);9275var methodsNames = [],9276classes = [];9277declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) {9278if (type === "D") methodsNames.push(index);9279else if (type === "E") classes.push(index);9280return ""9281});9282var fields = declarations.split(/;(?:\s*;)*/g);9283var baseInterfaceNames;9284var i, l;9285if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g);9286for (i = 0, l = methodsNames.length; i < l; ++i) {9287var method = transformClassMethod(atoms[methodsNames[i]]);9288methodsNames[i] = method.name9289}9290for (i = 0, l = fields.length - 1; i < l; ++i) {9291var field = trimSpaces(fields[i]);9292fields[i] = transformClassField(field.middle)9293}9294var tail = fields.pop();9295for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]);9296return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, {9297tail: tail9298})9299};93009301function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) {9302var i, l;9303this.name = name;9304this.baseClassName = baseClassName;9305this.interfacesNames = interfacesNames;9306this.functions = functions;9307this.methods = methods;9308this.fields = fields;9309this.cstrs = cstrs;9310this.innerClasses = innerClasses;9311this.misc = misc;9312for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this9313}9314AstClassBody.prototype.getMembers = function(classFields, classMethods, classInners) {9315if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners);9316var i, j, l, m;9317for (i = 0, l = this.fields.length; i < l; ++i) {9318var fieldNames = this.fields[i].getNames();9319for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i]9320}9321for (i = 0, l = this.methods.length; i < l; ++i) {9322var method = this.methods[i];9323classMethods[method.name] = method9324}9325for (i = 0, l = this.innerClasses.length; i < l; ++i) {9326var innerClass = this.innerClasses[i];9327classInners[innerClass.name] = innerClass9328}9329};9330AstClassBody.prototype.toString = function() {9331function getScopeLevel(p) {9332var i = 0;9333while (p) {9334++i;9335p = p.scope9336}9337return i9338}9339var scopeLevel = getScopeLevel(this.owner);9340var selfId = "$this_" + scopeLevel;9341var className = this.name;9342var result = "var " + selfId + " = this;\n";9343var staticDefinitions = "";9344var metadata = "";9345var thisClassFields = {},9346thisClassMethods = {},9347thisClassInners = {};9348this.getMembers(thisClassFields, thisClassMethods, thisClassInners);9349var oldContext = replaceContext;9350replaceContext = function(subject) {9351var name = subject.name;9352if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId;9353if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name;9354if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name;9355if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name;9356return oldContext(subject)9357};9358var resolvedBaseClassName;9359if (this.baseClassName) {9360resolvedBaseClassName = oldContext({9361name: this.baseClassName9362});9363result += "var $super = { $upcast: " + selfId + " };\n";9364result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n";9365metadata += className + ".$base = " + resolvedBaseClassName + ";\n"9366} else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n";9367if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n";9368var i, l, j, m;9369if (this.owner.interfaces) {9370var resolvedInterfaces = [],9371resolvedInterface;9372for (i = 0, l = this.interfacesNames.length; i < l; ++i) {9373if (!this.owner.interfaces[i]) continue;9374resolvedInterface = oldContext({9375name: this.interfacesNames[i]9376});9377resolvedInterfaces.push(resolvedInterface);9378staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n"9379}9380metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n"9381}9382if (this.functions.length > 0) result += this.functions.join("\n") + "\n";9383sortByWeight(this.innerClasses);9384for (i = 0, l = this.innerClasses.length; i < l; ++i) {9385var innerClass = this.innerClasses[i];9386if (innerClass.isStatic) {9387staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n";9388result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n"9389} else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n"9390}9391for (i = 0, l = this.fields.length; i < l; ++i) {9392var field = this.fields[i];9393if (field.isStatic) {9394staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n";9395for (j = 0, m = field.definitions.length; j < m; ++j) {9396var fieldName = field.definitions[j].name,9397staticName = className + "." + fieldName;9398result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n"9399}9400} else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n"9401}9402var methodOverloads = {};9403for (i = 0, l = this.methods.length; i < l; ++i) {9404var method = this.methods[i];9405var overload = methodOverloads[method.name];9406var methodId = method.name + "$" + method.params.params.length;9407var hasMethodArgs = !!method.params.methodArgsParam;9408if (overload) {9409++overload;9410methodId += "_" + overload9411} else overload = 1;9412method.methodId = methodId;9413methodOverloads[method.name] = overload;9414if (method.isStatic) {9415staticDefinitions += method;9416staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ", " + hasMethodArgs + ");\n";9417result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ", " + hasMethodArgs + ");\n"9418} else {9419result += method;9420result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ", " + hasMethodArgs + ");\n"9421}9422}9423result += trim(this.misc.tail);9424if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n";9425result += "function $constr() {\n";9426var cstrsIfs = [];9427for (i = 0, l = this.cstrs.length; i < l; ++i) {9428var paramsLength = this.cstrs[i].params.params.length;9429var methodArgsPresent = !!this.cstrs[i].params.methodArgsParam;9430cstrsIfs.push("if(arguments.length " + (methodArgsPresent ? ">=" : "===") + " " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }")9431}9432if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else ";9433result += "$superCstr();\n}\n";9434result += "$constr.apply(null, arguments);\n";9435replaceContext = oldContext;9436return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()"9437};9438transformClassBody = function(body, name, baseName, interfaces) {9439var declarations = body.substring(1, body.length - 1);9440declarations = extractClassesAndMethods(declarations);9441declarations = extractConstructors(declarations, name);9442var methods = [],9443classes = [],9444cstrs = [],9445functions = [];9446declarations = declarations.replace(/"([DEGH])(\d+)"/g, function(all, type, index) {9447if (type === "D") methods.push(index);9448else if (type === "E") classes.push(index);9449else if (type === "H") functions.push(index);9450else cstrs.push(index);9451return ""9452});9453var fields = declarations.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g);9454var baseClassName, interfacesNames;9455var i;9456if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1");9457if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g);9458for (i = 0; i < functions.length; ++i) functions[i] = transformFunction(atoms[functions[i]]);9459for (i = 0; i < methods.length; ++i) methods[i] = transformClassMethod(atoms[methods[i]]);9460for (i = 0; i < fields.length - 1; ++i) {9461var field = trimSpaces(fields[i]);9462fields[i] = transformClassField(field.middle)9463}9464var tail = fields.pop();9465for (i = 0; i < cstrs.length; ++i) cstrs[i] = transformConstructor(atoms[cstrs[i]]);9466for (i = 0; i < classes.length; ++i) classes[i] = transformInnerClass(atoms[classes[i]]);9467return new AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, classes, {9468tail: tail9469})9470};94719472function AstInterface(name, body) {9473this.name = name;9474this.body = body;9475body.owner = this9476}9477AstInterface.prototype.toString = function() {9478return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n"9479};94809481function AstClass(name, body) {9482this.name = name;9483this.body = body;9484body.owner = this9485}9486AstClass.prototype.toString = function() {9487return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n"9488};94899490function transformGlobalClass(class_) {9491var m = classesRegex.exec(class_);9492classesRegex.lastIndex = 0;9493var body = atoms[getAtomIndex(m[6])];9494var oldClassId = currentClassId,9495newClassId = generateClassId();9496currentClassId = newClassId;9497var globalClass;9498if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4]));9499else globalClass = new AstClass(m[3], transformClassBody(body, m[3], m[4], m[5]));9500appendClass(globalClass, newClassId, oldClassId);9501currentClassId = oldClassId;9502return globalClass9503}9504function AstMethod(name, params, body) {9505this.name = name;9506this.params = params;9507this.body = body9508}9509AstMethod.prototype.toString = function() {9510var paramNames = appendToLookupTable({},9511this.params.getNames());9512var oldContext = replaceContext;9513replaceContext = function(subject) {9514return paramNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject)9515};9516var body = this.params.prependMethodArgs(this.body.toString());9517var result = "function " + this.name + this.params + " " + body + "\n" + "$p." + this.name + " = " + this.name + ";";9518replaceContext = oldContext;9519return result9520};95219522function transformGlobalMethod(method) {9523var m = methodsRegex.exec(method);9524var result = methodsRegex.lastIndex = 0;9525return new AstMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(atoms[getAtomIndex(m[6])]))9526}9527function preStatementsTransform(statements) {9528var s = statements;9529s = s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g, "$1");9530return s9531}9532function AstForStatement(argument, misc) {9533this.argument = argument;9534this.misc = misc9535}9536AstForStatement.prototype.toString = function() {9537return this.misc.prefix + this.argument.toString()9538};95399540function AstCatchStatement(argument, misc) {9541this.argument = argument;9542this.misc = misc9543}9544AstCatchStatement.prototype.toString = function() {9545return this.misc.prefix + this.argument.toString()9546};95479548function AstPrefixStatement(name, argument, misc) {9549this.name = name;9550this.argument = argument;9551this.misc = misc9552}9553AstPrefixStatement.prototype.toString = function() {9554var result = this.misc.prefix;9555if (this.argument !== undef) result += this.argument.toString();9556return result9557};95589559function AstSwitchCase(expr) {9560this.expr = expr9561}9562AstSwitchCase.prototype.toString = function() {9563return "case " + this.expr + ":"9564};95659566function AstLabel(label) {9567this.label = label9568}9569AstLabel.prototype.toString = function() {9570return this.label9571};9572transformStatements = function(statements, transformMethod, transformClass) {9573var nextStatement = new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b(case)\s+([^:]+):|\b([A-Za-z_$][\w$]*\s*:)|(;)/g);9574var res = [];9575statements = preStatementsTransform(statements);9576var lastIndex = 0,9577m, space;9578while ((m = nextStatement.exec(statements)) !== null) {9579if (m[1] !== undef) {9580var i = statements.lastIndexOf('"B', nextStatement.lastIndex);9581var statementsPrefix = statements.substring(lastIndex, i);9582if (m[1] === "for") res.push(new AstForStatement(transformForExpression(atoms[m[2]]), {9583prefix: statementsPrefix9584}));9585else if (m[1] === "catch") res.push(new AstCatchStatement(transformParams(atoms[m[2]]), {9586prefix: statementsPrefix9587}));9588else res.push(new AstPrefixStatement(m[1], transformExpression(atoms[m[2]]), {9589prefix: statementsPrefix9590}))9591} else if (m[3] !== undef) res.push(new AstPrefixStatement(m[3], undef, {9592prefix: statements.substring(lastIndex, nextStatement.lastIndex)9593}));9594else if (m[4] !== undef) {9595space = statements.substring(lastIndex, nextStatement.lastIndex - m[4].length);9596if (trim(space).length !== 0) continue;9597res.push(space);9598var kind = m[4].charAt(1),9599atomIndex = m[5];9600if (kind === "D") res.push(transformMethod(atoms[atomIndex]));9601else if (kind === "E") res.push(transformClass(atoms[atomIndex]));9602else if (kind === "H") res.push(transformFunction(atoms[atomIndex]));9603else res.push(transformStatementsBlock(atoms[atomIndex]))9604} else if (m[6] !== undef) res.push(new AstSwitchCase(transformExpression(trim(m[7]))));9605else if (m[8] !== undef) {9606space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].length);9607if (trim(space).length !== 0) continue;9608res.push(new AstLabel(statements.substring(lastIndex, nextStatement.lastIndex)))9609} else {9610var statement = trimSpaces(statements.substring(lastIndex, nextStatement.lastIndex - 1));9611res.push(statement.left);9612res.push(transformStatement(statement.middle));9613res.push(statement.right + ";")9614}9615lastIndex = nextStatement.lastIndex9616}9617var statementsTail = trimSpaces(statements.substring(lastIndex));9618res.push(statementsTail.left);9619if (statementsTail.middle !== "") {9620res.push(transformStatement(statementsTail.middle));9621res.push(";" + statementsTail.right)9622}9623return res9624};96259626function getLocalNames(statements) {9627var localNames = [];9628for (var i = 0, l = statements.length; i < l; ++i) {9629var statement = statements[i];9630if (statement instanceof AstVar) localNames = localNames.concat(statement.getNames());9631else if (statement instanceof AstForStatement && statement.argument.initStatement instanceof AstVar) localNames = localNames.concat(statement.argument.initStatement.getNames());9632else if (statement instanceof AstInnerInterface || statement instanceof AstInnerClass || statement instanceof AstInterface || statement instanceof AstClass || statement instanceof AstMethod || statement instanceof AstFunction) localNames.push(statement.name)9633}9634return appendToLookupTable({},9635localNames)9636}9637function AstStatementsBlock(statements) {9638this.statements = statements9639}9640AstStatementsBlock.prototype.toString = function() {9641var localNames = getLocalNames(this.statements);9642var oldContext = replaceContext;9643if (!isLookupTableEmpty(localNames)) replaceContext = function(subject) {9644return localNames.hasOwnProperty(subject.name) ? subject.name : oldContext(subject)9645};9646var result = "{\n" + this.statements.join("") + "\n}";9647replaceContext = oldContext;9648return result9649};9650transformStatementsBlock = function(block) {9651var content = trimSpaces(block.substring(1, block.length - 1));9652return new AstStatementsBlock(transformStatements(content.middle))9653};96549655function AstRoot(statements) {9656this.statements = statements9657}9658AstRoot.prototype.toString = function() {9659var classes = [],9660otherStatements = [],9661statement;9662for (var i = 0, len = this.statements.length; i < len; ++i) {9663statement = this.statements[i];9664if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement);9665else otherStatements.push(statement)9666}9667sortByWeight(classes);9668var localNames = getLocalNames(this.statements);9669replaceContext = function(subject) {9670var name = subject.name;9671if (localNames.hasOwnProperty(name)) return name;9672if (globalMembers.hasOwnProperty(name) || PConstants.hasOwnProperty(name) || defaultScope.hasOwnProperty(name)) return "$p." + name;9673return name9674};9675var result = "// this code was autogenerated from PJS\n" + "(function($p) {\n" + classes.join("") + "\n" + otherStatements.join("") + "\n})";9676replaceContext = null;9677return result9678};9679transformMain = function() {9680var statements = extractClassesAndMethods(atoms[0]);9681statements = statements.replace(/\bimport\s+[^;]+;/g, "");9682return new AstRoot(transformStatements(statements, transformGlobalMethod, transformGlobalClass))9683};96849685function generateMetadata(ast) {9686var globalScope = {};9687var id, class_;9688for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) {9689class_ = declaredClasses[id];9690var scopeId = class_.scopeId,9691name = class_.name;9692if (scopeId) {9693var scope = declaredClasses[scopeId];9694class_.scope = scope;9695if (scope.inScope === undef) scope.inScope = {};9696scope.inScope[name] = class_9697} else globalScope[name] = class_9698}9699function findInScopes(class_, name) {9700var parts = name.split(".");9701var currentScope = class_.scope,9702found;9703while (currentScope) {9704if (currentScope.hasOwnProperty(parts[0])) {9705found = currentScope[parts[0]];9706break9707}9708currentScope = currentScope.scope9709}9710if (found === undef) found = globalScope[parts[0]];9711for (var i = 1, l = parts.length; i < l && found; ++i) found = found.inScope[parts[i]];9712return found9713}9714for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) {9715class_ = declaredClasses[id];9716var baseClassName = class_.body.baseClassName;9717if (baseClassName) {9718var parent = findInScopes(class_, baseClassName);9719if (parent) {9720class_.base = parent;9721if (!parent.derived) parent.derived = [];9722parent.derived.push(class_)9723}9724}9725var interfacesNames = class_.body.interfacesNames,9726interfaces = [],9727i, l;9728if (interfacesNames && interfacesNames.length > 0) {9729for (i = 0, l = interfacesNames.length; i < l; ++i) {9730var interface_ = findInScopes(class_, interfacesNames[i]);9731interfaces.push(interface_);9732if (!interface_) continue;9733if (!interface_.derived) interface_.derived = [];9734interface_.derived.push(class_)9735}9736if (interfaces.length > 0) class_.interfaces = interfaces9737}9738}9739}9740function setWeight(ast) {9741var queue = [],9742tocheck = {};9743var id, scopeId, class_;9744for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) {9745class_ = declaredClasses[id];9746if (!class_.inScope && !class_.derived) {9747queue.push(id);9748class_.weight = 09749} else {9750var dependsOn = [];9751if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]);9752if (class_.derived) dependsOn = dependsOn.concat(class_.derived);9753tocheck[id] = dependsOn9754}9755}9756function removeDependentAndCheck(targetId, from) {9757var dependsOn = tocheck[targetId];9758if (!dependsOn) return false;9759var i = dependsOn.indexOf(from);9760if (i < 0) return false;9761dependsOn.splice(i, 1);9762if (dependsOn.length > 0) return false;9763delete tocheck[targetId];9764return true9765}9766while (queue.length > 0) {9767id = queue.shift();9768class_ = declaredClasses[id];9769if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) {9770queue.push(class_.scopeId);9771declaredClasses[class_.scopeId].weight = class_.weight + 19772}9773if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) {9774queue.push(class_.base.classId);9775class_.base.weight = class_.weight + 19776}9777if (class_.interfaces) {9778var i, l;9779for (i = 0, l = class_.interfaces.length; i < l; ++i) {9780if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue;9781queue.push(class_.interfaces[i].classId);9782class_.interfaces[i].weight = class_.weight + 19783}9784}9785}9786}9787var transformed = transformMain();9788generateMetadata(transformed);9789setWeight(transformed);9790var redendered = transformed.toString();9791redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n");9792redendered = redendered.replace(/__x([0-9A-F]{4})/g, function(all, hexCode) {9793return String.fromCharCode(parseInt(hexCode, 16))9794});9795return injectStrings(redendered, strings)9796}97979798function preprocessCode(aCode, sketch) {9799var dm = (new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g)).exec(aCode);9800if (dm && dm.length === 2) {9801var jsonItems = [],9802directives = dm.splice(1, 2)[0].replace(/\{([\s\S]*?)\}/g, function() {9803return function(all, item) {9804jsonItems.push(item);9805return "{" + (jsonItems.length - 1) + "}"9806}9807}()).replace("\n", "").replace("\r", "").split(";");9808var clean = function(s) {9809return s.replace(/^\s*["']?/, "").replace(/["']?\s*$/, "")9810};9811for (var i = 0, dl = directives.length; i < dl; i++) {9812var pair = directives[i].split("=");9813if (pair && pair.length === 2) {9814var key = clean(pair[0]),9815value = clean(pair[1]),9816list = [];9817if (key === "preload") {9818list = value.split(",");9819for (var j = 0, jl = list.length; j < jl; j++) {9820var imageName = clean(list[j]);9821sketch.imageCache.add(imageName)9822}9823} else if (key === "font") {9824list = value.split(",");9825for (var x = 0, xl = list.length; x < xl; x++) {9826var fontName = clean(list[x]),9827index = /^\{(\d*?)\}$/.exec(fontName);9828PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName)9829}9830} else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true";9831else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true";9832else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value;9833else sketch.options[key] = value9834}9835}9836}9837return aCode9838}9839Processing.compile = function(pdeCode) {9840var sketch = new Processing.Sketch;9841var code = preprocessCode(pdeCode, sketch);9842var compiledPde = parseProcessing(code);9843sketch.sourceCode = compiledPde;9844return sketch9845};9846var tinylogLite = function() {9847var tinylogLite = {},9848undef = "undefined",9849func = "function",9850False = !1,9851True = !0,9852logLimit = 512,9853log = "log";9854if (typeof tinylog !== undef && typeof tinylog[log] === func) tinylogLite[log] = tinylog[log];9855else if (typeof document !== undef && !document.fake)(function() {9856var doc = document,9857$div = "div",9858$style = "style",9859$title = "title",9860containerStyles = {9861zIndex: 1E4,9862position: "fixed",9863bottom: "0px",9864width: "100%",9865height: "15%",9866fontFamily: "sans-serif",9867color: "#ccc",9868backgroundColor: "black"9869},9870outputStyles = {9871position: "relative",9872fontFamily: "monospace",9873overflow: "auto",9874height: "100%",9875paddingTop: "5px"9876},9877resizerStyles = {9878height: "5px",9879marginTop: "-5px",9880cursor: "n-resize",9881backgroundColor: "darkgrey"9882},9883closeButtonStyles = {9884position: "absolute",9885top: "5px",9886right: "20px",9887color: "#111",9888MozBorderRadius: "4px",9889webkitBorderRadius: "4px",9890borderRadius: "4px",9891cursor: "pointer",9892fontWeight: "normal",9893textAlign: "center",9894padding: "3px 5px",9895backgroundColor: "#333",9896fontSize: "12px"9897},9898entryStyles = {9899minHeight: "16px"9900},9901entryTextStyles = {9902fontSize: "12px",9903margin: "0 8px 0 8px",9904maxWidth: "100%",9905whiteSpace: "pre-wrap",9906overflow: "auto"9907},9908view = doc.defaultView,9909docElem = doc.documentElement,9910docElemStyle = docElem[$style],9911setStyles = function() {9912var i = arguments.length,9913elemStyle, styles, style;9914while (i--) {9915styles = arguments[i--];9916elemStyle = arguments[i][$style];9917for (style in styles) if (styles.hasOwnProperty(style)) elemStyle[style] = styles[style]9918}9919},9920observer = function(obj, event, handler) {9921if (obj.addEventListener) obj.addEventListener(event, handler, False);9922else if (obj.attachEvent) obj.attachEvent("on" + event, handler);9923return [obj, event, handler]9924},9925unobserve = function(obj, event, handler) {9926if (obj.removeEventListener) obj.removeEventListener(event, handler, False);9927else if (obj.detachEvent) obj.detachEvent("on" + event, handler)9928},9929clearChildren = function(node) {9930var children = node.childNodes,9931child = children.length;9932while (child--) node.removeChild(children.item(0))9933},9934append = function(to, elem) {9935return to.appendChild(elem)9936},9937createElement = function(localName) {9938return doc.createElement(localName)9939},9940createTextNode = function(text) {9941return doc.createTextNode(text)9942},9943createLog = tinylogLite[log] = function(message) {9944var uninit, originalPadding = docElemStyle.paddingBottom,9945container = createElement($div),9946containerStyle = container[$style],9947resizer = append(container, createElement($div)),9948output = append(container, createElement($div)),9949closeButton = append(container, createElement($div)),9950resizingLog = False,9951previousHeight = False,9952previousScrollTop = False,9953messages = 0,9954updateSafetyMargin = function() {9955docElemStyle.paddingBottom = container.clientHeight + "px"9956},9957setContainerHeight = function(height) {9958var viewHeight = view.innerHeight,9959resizerHeight = resizer.clientHeight;9960if (height < 0) height = 0;9961else if (height + resizerHeight > viewHeight) height = viewHeight - resizerHeight;9962containerStyle.height = height / viewHeight * 100 + "%";9963updateSafetyMargin()9964},9965observers = [observer(doc, "mousemove", function(evt) {9966if (resizingLog) {9967setContainerHeight(view.innerHeight - evt.clientY);9968output.scrollTop = previousScrollTop9969}9970}), observer(doc, "mouseup", function() {9971if (resizingLog) resizingLog = previousScrollTop = False9972}), observer(resizer, "dblclick", function(evt) {9973evt.preventDefault();9974if (previousHeight) {9975setContainerHeight(previousHeight);9976previousHeight = False9977} else {9978previousHeight = container.clientHeight;9979containerStyle.height = "0px"9980}9981}), observer(resizer, "mousedown", function(evt) {9982evt.preventDefault();9983resizingLog = True;9984previousScrollTop = output.scrollTop9985}), observer(resizer, "contextmenu", function() {9986resizingLog = False9987}), observer(closeButton, "click", function() {9988uninit()9989})];9990uninit = function() {9991var i = observers.length;9992while (i--) unobserve.apply(tinylogLite, observers[i]);9993docElem.removeChild(container);9994docElemStyle.paddingBottom = originalPadding;9995clearChildren(output);9996clearChildren(container);9997tinylogLite[log] = createLog9998};9999setStyles(container, containerStyles, output, outputStyles, resizer, resizerStyles, closeButton, closeButtonStyles);10000closeButton[$title] = "Close Log";10001append(closeButton, createTextNode("\u2716"));10002resizer[$title] = "Double-click to toggle log minimization";10003docElem.insertBefore(container, docElem.firstChild);10004tinylogLite[log] = function(message) {10005if (messages === logLimit) output.removeChild(output.firstChild);10006else messages++;10007var entry = append(output, createElement($div)),10008entryText = append(entry, createElement($div));10009entry[$title] = (new Date).toLocaleTimeString();10010setStyles(entry, entryStyles, entryText, entryTextStyles);10011append(entryText, createTextNode(message));10012output.scrollTop = output.scrollHeight10013};10014tinylogLite[log](message);10015updateSafetyMargin()10016}10017})();10018else if (typeof print === func) tinylogLite[log] = print;10019return tinylogLite10020}();10021Processing.logger = tinylogLite;10022Processing.version = "1.4.1";10023Processing.lib = {};10024Processing.registerLibrary = function(name, desc) {10025Processing.lib[name] = desc;10026if (desc.hasOwnProperty("init")) desc.init(defaultScope)10027};10028Processing.instances = processingInstances;10029Processing.getInstanceById = function(name) {10030return processingInstances[processingInstanceIds[name]]10031};10032Processing.Sketch = function(attachFunction) {10033this.attachFunction = attachFunction;10034this.options = {10035pauseOnBlur: false,10036globalKeyEvents: false10037};10038this.onLoad = nop;10039this.onSetup = nop;10040this.onPause = nop;10041this.onLoop = nop;10042this.onFrameStart = nop;10043this.onFrameEnd = nop;10044this.onExit = nop;10045this.params = {};10046this.imageCache = {10047pending: 0,10048images: {},10049operaCache: {},10050add: function(href, img) {10051if (this.images[href]) return;10052if (!isDOMPresent) this.images[href] = null;10053if (!img) {10054img = new Image;10055img.onload = function(owner) {10056return function() {10057owner.pending--10058}10059}(this);10060this.pending++;10061img.src = href10062}10063this.images[href] = img;10064if (window.opera) {10065var div = document.createElement("div");10066div.appendChild(img);10067div.style.position = "absolute";10068div.style.opacity = 0;10069div.style.width = "1px";10070div.style.height = "1px";10071if (!this.operaCache[href]) {10072document.body.appendChild(div);10073this.operaCache[href] = div10074}10075}10076}10077};10078this.sourceCode = undefined;10079this.attach = function(processing) {10080if (typeof this.attachFunction === "function") this.attachFunction(processing);10081else if (this.sourceCode) {10082var func = (new Function("return (" + this.sourceCode + ");"))();10083func(processing);10084this.attachFunction = func10085} else throw "Unable to attach sketch to the processing instance";10086};10087this.toString = function() {10088var i;10089var code = "((function(Sketch) {\n";10090code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n";10091for (i in this.options) if (this.options.hasOwnProperty(i)) {10092var value = this.options[i];10093code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n"10094}10095for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n';10096code += "return sketch;\n})(Processing.Sketch))";10097return code10098}10099};10100var loadSketchFromSources = function(canvas, sources) {10101var code = [],10102errors = [],10103sourcesCount = sources.length,10104loaded = 0;1010510106function ajaxAsync(url, callback) {10107var xhr = new XMLHttpRequest;10108xhr.onreadystatechange = function() {10109if (xhr.readyState === 4) {10110var error;10111if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status;10112else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions.";10113else error = "File is empty.";10114callback(xhr.responseText, error)10115}10116};10117xhr.open("GET", url, true);10118if (xhr.overrideMimeType) xhr.overrideMimeType("application/json");10119xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT");10120xhr.send(null)10121}10122function loadBlock(index, filename) {10123function callback(block, error) {10124code[index] = block;10125++loaded;10126if (error) errors.push(filename + " ==> " + error);10127if (loaded === sourcesCount) if (errors.length === 0) try {10128return new Processing(canvas, code.join("\n"))10129} catch(e) {10130throw "Processing.js: Unable to execute pjs sketch: " + e;10131} else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n");10132}10133if (filename.charAt(0) === "#") {10134var scriptElement = document.getElementById(filename.substring(1));10135if (scriptElement) callback(scriptElement.text || scriptElement.textContent);10136else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found");10137return10138}10139ajaxAsync(filename, callback)10140}10141for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i])10142};10143var init = function() {10144document.removeEventListener("DOMContentLoaded", init, false);10145processingInstances = [];10146var canvas = document.getElementsByTagName("canvas"),10147filenames;10148for (var i = 0, l = canvas.length; i < l; i++) {10149var processingSources = canvas[i].getAttribute("data-processing-sources");10150if (processingSources === null) {10151processingSources = canvas[i].getAttribute("data-src");10152if (processingSources === null) processingSources = canvas[i].getAttribute("datasrc")10153}10154if (processingSources) {10155filenames = processingSources.split(/\s+/g);10156for (var j = 0; j < filenames.length;) if (filenames[j]) j++;10157else filenames.splice(j, 1);10158loadSketchFromSources(canvas[i], filenames)10159}10160}10161var s, last, source, instance, nodelist = document.getElementsByTagName("script"),10162scripts = [];10163for (s = nodelist.length - 1; s >= 0; s--) scripts.push(nodelist[s]);10164for (s = 0, last = scripts.length; s < last; s++) {10165var script = scripts[s];10166if (!script.getAttribute) continue;10167var type = script.getAttribute("type");10168if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) {10169var target = script.getAttribute("data-processing-target");10170canvas = undef;10171if (target) canvas = document.getElementById(target);10172else {10173var nextSibling = script.nextSibling;10174while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling;10175if (nextSibling && nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling10176}10177if (canvas) {10178if (script.getAttribute("src")) {10179filenames = script.getAttribute("src").split(/\s+/);10180loadSketchFromSources(canvas, filenames);10181continue10182}10183source = script.textContent || script.text;10184instance = new Processing(canvas, source)10185}10186}10187}10188};10189Processing.reload = function() {10190if (processingInstances.length > 0) for (var i = processingInstances.length - 1; i >= 0; i--) if (processingInstances[i]) processingInstances[i].exit();10191init()10192};10193Processing.loadSketchFromSources = loadSketchFromSources;10194Processing.disableInit = function() {10195if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false)10196};10197if (isDOMPresent) {10198window["Processing"] = Processing;10199document.addEventListener("DOMContentLoaded", init, false)10200} else this.Processing = Processing10201})(window, window.document, Math);10202102031020410205