rob@100: ;(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o hubfn.$methodArgsIndex ? rob@100: hubfn.$overloads[hubfn.$methodArgsIndex] : null) || rob@100: hubfn.$defaultOverload; rob@100: return fn.apply(this, arguments); rob@100: }; rob@100: hubfn.$overloads = overloads; rob@100: if ("$methodArgsIndex" in basefn) { rob@100: hubfn.$methodArgsIndex = basefn.$methodArgsIndex; rob@100: } rob@100: hubfn.$defaultOverload = defaultOverload; rob@100: hubfn.name = name; rob@100: object[name] = hubfn; rob@100: } rob@100: rob@100: /** rob@100: * class overloading, part 2 rob@100: */ rob@100: rob@100: function extendClass(subClass, baseClass) { rob@100: function extendGetterSetter(propertyName) { rob@100: defaultScope.defineProperty(subClass, propertyName, { rob@100: get: function() { rob@100: return baseClass[propertyName]; rob@100: }, rob@100: set: function(v) { rob@100: baseClass[propertyName]=v; rob@100: }, rob@100: enumerable: true rob@100: }); rob@100: } rob@100: rob@100: var properties = []; rob@100: for (var propertyName in baseClass) { rob@100: if (typeof baseClass[propertyName] === 'function') { rob@100: overloadBaseClassFunction(subClass, propertyName, baseClass[propertyName]); rob@100: } else if(propertyName.charAt(0) !== "$" && !(propertyName in subClass)) { rob@100: // Delaying the properties extension due to the IE9 bug (see #918). rob@100: properties.push(propertyName); rob@100: } rob@100: } rob@100: while (properties.length > 0) { rob@100: extendGetterSetter(properties.shift()); rob@100: } rob@100: rob@100: subClass.$super = baseClass; rob@100: } rob@100: rob@100: /** rob@100: * class overloading, part 3 rob@100: */ rob@100: defaultScope.extendClassChain = function(base) { rob@100: var path = [base]; rob@100: for (var self = base.$upcast; self; self = self.$upcast) { rob@100: extendClass(self, base); rob@100: path.push(self); rob@100: base = self; rob@100: } rob@100: while (path.length > 0) { rob@100: path.pop().$self=base; rob@100: } rob@100: }; rob@100: rob@100: // static rob@100: defaultScope.extendStaticMembers = function(derived, base) { rob@100: extendClass(derived, base); rob@100: }; rob@100: rob@100: // interface rob@100: defaultScope.extendInterfaceMembers = function(derived, base) { rob@100: extendClass(derived, base); rob@100: }; rob@100: rob@100: /** rob@100: * Java methods and JavaScript functions differ enough that rob@100: * we need a special function to make sure it all links up rob@100: * as classical hierarchical class chains. rob@100: */ rob@100: defaultScope.addMethod = function(object, name, fn, hasMethodArgs) { rob@100: var existingfn = object[name]; rob@100: if (existingfn || hasMethodArgs) { rob@100: var args = fn.length; rob@100: // builds the overload methods table rob@100: if ("$overloads" in existingfn) { rob@100: existingfn.$overloads[args] = fn; rob@100: } else { rob@100: var hubfn = function() { rob@100: var fn = hubfn.$overloads[arguments.length] || rob@100: ("$methodArgsIndex" in hubfn && arguments.length > hubfn.$methodArgsIndex ? rob@100: hubfn.$overloads[hubfn.$methodArgsIndex] : null) || rob@100: hubfn.$defaultOverload; rob@100: return fn.apply(this, arguments); rob@100: }; rob@100: var overloads = []; rob@100: if (existingfn) { rob@100: overloads[existingfn.length] = existingfn; rob@100: } rob@100: overloads[args] = fn; rob@100: hubfn.$overloads = overloads; rob@100: hubfn.$defaultOverload = existingfn || fn; rob@100: if (hasMethodArgs) { rob@100: hubfn.$methodArgsIndex = args; rob@100: } rob@100: hubfn.name = name; rob@100: object[name] = hubfn; rob@100: } rob@100: } else { rob@100: object[name] = fn; rob@100: } rob@100: }; rob@100: rob@100: // internal helper function rob@100: function isNumericalJavaType(type) { rob@100: if (typeof type !== "string") { rob@100: return false; rob@100: } rob@100: return ["byte", "int", "char", "color", "float", "long", "double"].indexOf(type) !== -1; rob@100: } rob@100: rob@100: /** rob@100: * Java's arrays are pre-filled when declared with rob@100: * an initial size, but no content. JS arrays are not. rob@100: */ rob@100: defaultScope.createJavaArray = function(type, bounds) { rob@100: var result = null, rob@100: defaultValue = null; rob@100: if (typeof type === "string") { rob@100: if (type === "boolean") { rob@100: defaultValue = false; rob@100: } else if (isNumericalJavaType(type)) { rob@100: defaultValue = 0; rob@100: } rob@100: } rob@100: if (typeof bounds[0] === 'number') { rob@100: var itemsCount = 0 | bounds[0]; rob@100: if (bounds.length <= 1) { rob@100: result = []; rob@100: result.length = itemsCount; rob@100: for (var i = 0; i < itemsCount; ++i) { rob@100: result[i] = defaultValue; rob@100: } rob@100: } else { rob@100: result = []; rob@100: var newBounds = bounds.slice(1); rob@100: for (var j = 0; j < itemsCount; ++j) { rob@100: result.push(defaultScope.createJavaArray(type, newBounds)); rob@100: } rob@100: } rob@100: } rob@100: return result; rob@100: }; rob@100: rob@100: // screenWidth and screenHeight are shared by all instances. rob@100: // and return the width/height of the browser's viewport. rob@100: defaultScope.defineProperty(defaultScope, 'screenWidth', rob@100: { get: function() { return window.innerWidth; } }); rob@100: rob@100: defaultScope.defineProperty(defaultScope, 'screenHeight', rob@100: { get: function() { return window.innerHeight; } }); rob@100: rob@100: return defaultScope; rob@100: }; rob@100: rob@100: },{}],6:[function(require,module,exports){ rob@100: /** rob@100: * Finalise the Processing.js object. rob@100: */ rob@100: module.exports = function finalizeProcessing(Processing, options) { rob@100: rob@100: // unpack options rob@100: var window = options.window, rob@100: document = options.document, rob@100: XMLHttpRequest = window.XMLHttpRequest, rob@100: noop = options.noop, rob@100: isDOMPresent = options.isDOMPresent, rob@100: version = options.version, rob@100: undef; rob@100: rob@100: // versioning rob@100: Processing.version = (version ? version : "@DEV-VERSION@"); rob@100: rob@100: // Share lib space rob@100: Processing.lib = {}; rob@100: rob@100: /** rob@100: * External libraries can be added to the global Processing rob@100: * objects with the `registerLibrary` function. rob@100: */ rob@100: Processing.registerLibrary = function(name, library) { rob@100: Processing.lib[name] = library; rob@100: if(library.hasOwnProperty("init")) { rob@100: library.init(defaultScope); rob@100: } rob@100: }; rob@100: rob@100: /** rob@100: * This is the object that acts as our version of PApplet. rob@100: * This can be called as Processing.Sketch() or as rob@100: * Processing.Sketch(function) in which case the function rob@100: * must be an already-compiled-to-JS sketch function. rob@100: */ rob@100: Processing.Sketch = function(attachFunction) { rob@100: this.attachFunction = attachFunction; rob@100: this.options = { rob@100: pauseOnBlur: false, rob@100: globalKeyEvents: false rob@100: }; rob@100: rob@100: /* Optional Sketch event hooks: rob@100: * onLoad - parsing/preloading is done, before sketch starts rob@100: * onSetup - setup() has been called, before first draw() rob@100: * onPause - noLoop() has been called, pausing draw loop rob@100: * onLoop - loop() has been called, resuming draw loop rob@100: * onFrameStart - draw() loop about to begin rob@100: * onFrameEnd - draw() loop finished rob@100: * onExit - exit() done being called rob@100: */ rob@100: this.onLoad = noop; rob@100: this.onSetup = noop; rob@100: this.onPause = noop; rob@100: this.onLoop = noop; rob@100: this.onFrameStart = noop; rob@100: this.onFrameEnd = noop; rob@100: this.onExit = noop; rob@100: rob@100: this.params = {}; rob@100: this.imageCache = { rob@100: pending: 0, rob@100: images: {}, rob@100: // Opera requires special administration for preloading rob@100: operaCache: {}, rob@100: // Specify an optional img arg if the image is already loaded in the DOM, rob@100: // otherwise href will get loaded. rob@100: add: function(href, img) { rob@100: // Prevent muliple loads for an image, in case it gets rob@100: // preloaded more than once, or is added via JS and then preloaded. rob@100: if (this.images[href]) { rob@100: return; rob@100: } rob@100: rob@100: if (!isDOMPresent) { rob@100: this.images[href] = null; rob@100: } rob@100: rob@100: // No image in the DOM, kick-off a background load rob@100: if (!img) { rob@100: img = new Image(); rob@100: img.onload = (function(owner) { rob@100: return function() { rob@100: owner.pending--; rob@100: }; rob@100: }(this)); rob@100: this.pending++; rob@100: img.src = href; rob@100: } rob@100: rob@100: this.images[href] = img; rob@100: rob@100: // Opera will not load images until they are inserted into the DOM. rob@100: if (window.opera) { rob@100: var div = document.createElement("div"); rob@100: div.appendChild(img); rob@100: // we can't use "display: none", since that makes it invisible, and thus not load rob@100: div.style.position = "absolute"; rob@100: div.style.opacity = 0; rob@100: div.style.width = "1px"; rob@100: div.style.height= "1px"; rob@100: if (!this.operaCache[href]) { rob@100: document.body.appendChild(div); rob@100: this.operaCache[href] = div; rob@100: } rob@100: } rob@100: } rob@100: }; rob@100: rob@100: this.sourceCode = undefined; rob@100: this.attach = function(processing) { rob@100: // either attachFunction or sourceCode must be present on attach rob@100: if(typeof this.attachFunction === "function") { rob@100: this.attachFunction(processing); rob@100: } else if(this.sourceCode) { rob@100: var func = ((new Function("return (" + this.sourceCode + ");"))()); rob@100: func(processing); rob@100: this.attachFunction = func; rob@100: } else { rob@100: throw "Unable to attach sketch to the processing instance"; rob@100: } rob@100: }; rob@100: rob@100: this.toString = function() { rob@100: var i; rob@100: var code = "((function(Sketch) {\n"; rob@100: code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; rob@100: for(i in this.options) { rob@100: if(this.options.hasOwnProperty(i)) { rob@100: var value = this.options[i]; rob@100: code += "sketch.options." + i + " = " + rob@100: (typeof value === 'string' ? '\"' + value + '\"' : "" + value) + ";\n"; rob@100: } rob@100: } rob@100: for(i in this.imageCache) { rob@100: if(this.options.hasOwnProperty(i)) { rob@100: code += "sketch.imageCache.add(\"" + i + "\");\n"; rob@100: } rob@100: } rob@100: // TODO serialize fonts rob@100: code += "return sketch;\n})(Processing.Sketch))"; rob@100: return code; rob@100: }; rob@100: }; rob@100: rob@100: /** rob@100: * aggregate all source code into a single file, then rewrite that rob@100: * source and bind to canvas via new Processing(canvas, sourcestring). rob@100: * @param {CANVAS} canvas The html canvas element to bind to rob@100: * @param {String[]} source The array of files that must be loaded rob@100: */ rob@100: var loadSketchFromSources = Processing.loadSketchFromSources = function(canvas, sources) { rob@100: var code = [], errors = [], sourcesCount = sources.length, loaded = 0; rob@100: rob@100: function ajaxAsync(url, callback) { rob@100: var xhr = new XMLHttpRequest(); rob@100: xhr.onreadystatechange = function() { rob@100: if (xhr.readyState === 4) { rob@100: var error; rob@100: if (xhr.status !== 200 && xhr.status !== 0) { rob@100: error = "Invalid XHR status " + xhr.status; rob@100: } else if (xhr.responseText === "") { rob@100: // Give a hint when loading fails due to same-origin issues on file:/// urls rob@100: if ( ("withCredentials" in new XMLHttpRequest()) && rob@100: (new XMLHttpRequest()).withCredentials === false && rob@100: window.location.protocol === "file:" ) { rob@100: 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."; rob@100: } else { rob@100: error = "File is empty."; rob@100: } rob@100: } rob@100: rob@100: callback(xhr.responseText, error); rob@100: } rob@100: }; rob@100: xhr.open("GET", url, true); rob@100: if (xhr.overrideMimeType) { rob@100: xhr.overrideMimeType("application/json"); rob@100: } rob@100: xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); // no cache rob@100: xhr.send(null); rob@100: } rob@100: rob@100: function loadBlock(index, filename) { rob@100: function callback(block, error) { rob@100: code[index] = block; rob@100: ++loaded; rob@100: if (error) { rob@100: errors.push(filename + " ==> " + error); rob@100: } rob@100: if (loaded === sourcesCount) { rob@100: if (errors.length === 0) { rob@100: try { rob@100: return new Processing(canvas, code.join("\n")); rob@100: } catch(e) { rob@100: console.log("Processing.js: Unable to execute pjs sketch."); rob@100: throw e; rob@100: } rob@100: } else { rob@100: throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); rob@100: } rob@100: } rob@100: } rob@100: if (filename.charAt(0) === '#') { rob@100: // trying to get script from the element rob@100: var scriptElement = document.getElementById(filename.substring(1)); rob@100: if (scriptElement) { rob@100: callback(scriptElement.text || scriptElement.textContent); rob@100: } else { rob@100: callback("", "Unable to load pjs sketch: element with id \'" + filename.substring(1) + "\' was not found"); rob@100: } rob@100: return; rob@100: } rob@100: rob@100: ajaxAsync(filename, callback); rob@100: } rob@100: rob@100: for (var i = 0; i < sourcesCount; ++i) { rob@100: loadBlock(i, sources[i]); rob@100: } rob@100: }; rob@100: rob@100: /** rob@100: * Automatic initialization function. rob@100: */ rob@100: var init = function() { rob@100: document.removeEventListener('DOMContentLoaded', init, false); rob@100: rob@100: // before running through init, clear the instances list, to prevent rob@100: // sketch duplication when page content is dynamically swapped without rob@100: // swapping out processing.js rob@100: processingInstances = []; rob@100: Processing.instances = processingInstances; rob@100: rob@100: var canvas = document.getElementsByTagName('canvas'), rob@100: filenames; rob@100: rob@100: for (var i = 0, l = canvas.length; i < l; i++) { rob@100: // datasrc and data-src are deprecated. rob@100: var processingSources = canvas[i].getAttribute('data-processing-sources'); rob@100: if (processingSources === null) { rob@100: // Temporary fallback for datasrc and data-src rob@100: processingSources = canvas[i].getAttribute('data-src'); rob@100: if (processingSources === null) { rob@100: processingSources = canvas[i].getAttribute('datasrc'); rob@100: } rob@100: } rob@100: if (processingSources) { rob@100: filenames = processingSources.split(/\s+/g); rob@100: for (var j = 0; j < filenames.length;) { rob@100: if (filenames[j]) { rob@100: j++; rob@100: } else { rob@100: filenames.splice(j, 1); rob@100: } rob@100: } rob@100: loadSketchFromSources(canvas[i], filenames); rob@100: } rob@100: } rob@100: rob@100: // also process all