Math.abs(dy)) {
+ view.rotate(t, 0, 0, -dx * flipX * Math.PI * camera.rotateSpeed / window.innerWidth)
+ } else {
+ var kzoom = camera.zoomSpeed * flipY * dy / window.innerHeight * (t - view.lastT()) / 100.0
+ view.pan(t, 0, 0, distance * (Math.exp(kzoom) - 1))
+ }
+ }, true)
+
+ return camera
+}
+},{"3d-view":38,"mouse-change":196,"mouse-wheel":200,"right-now":210}],125:[function(require,module,exports){
+// Copyright (C) 2011 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Install a leaky WeakMap emulation on platforms that
+ * don't provide a built-in one.
+ *
+ * Assumes that an ES5 platform where, if {@code WeakMap} is
+ * already present, then it conforms to the anticipated ES6
+ * specification. To run this file on an ES5 or almost ES5
+ * implementation where the {@code WeakMap} specification does not
+ * quite conform, run repairES5.js
first.
+ *
+ *
Even though WeakMapModule is not global, the linter thinks it
+ * is, which is why it is in the overrides list below.
+ *
+ *
NOTE: Before using this WeakMap emulation in a non-SES
+ * environment, see the note below about hiddenRecord.
+ *
+ * @author Mark S. Miller
+ * @requires crypto, ArrayBuffer, Uint8Array, navigator, console
+ * @overrides WeakMap, ses, Proxy
+ * @overrides WeakMapModule
+ */
+
+/**
+ * This {@code WeakMap} emulation is observably equivalent to the
+ * ES-Harmony WeakMap, but with leakier garbage collection properties.
+ *
+ *
As with true WeakMaps, in this emulation, a key does not
+ * retain maps indexed by that key and (crucially) a map does not
+ * retain the keys it indexes. A map by itself also does not retain
+ * the values associated with that map.
+ *
+ *
However, the values associated with a key in some map are
+ * retained so long as that key is retained and those associations are
+ * not overridden. For example, when used to support membranes, all
+ * values exported from a given membrane will live for the lifetime
+ * they would have had in the absence of an interposed membrane. Even
+ * when the membrane is revoked, all objects that would have been
+ * reachable in the absence of revocation will still be reachable, as
+ * far as the GC can tell, even though they will no longer be relevant
+ * to ongoing computation.
+ *
+ *
The API implemented here is approximately the API as implemented
+ * in FF6.0a1 and agreed to by MarkM, Andreas Gal, and Dave Herman,
+ * rather than the offially approved proposal page. TODO(erights):
+ * upgrade the ecmascript WeakMap proposal page to explain this API
+ * change and present to EcmaScript committee for their approval.
+ *
+ *
The first difference between the emulation here and that in
+ * FF6.0a1 is the presence of non enumerable {@code get___, has___,
+ * set___, and delete___} methods on WeakMap instances to represent
+ * what would be the hidden internal properties of a primitive
+ * implementation. Whereas the FF6.0a1 WeakMap.prototype methods
+ * require their {@code this} to be a genuine WeakMap instance (i.e.,
+ * an object of {@code [[Class]]} "WeakMap}), since there is nothing
+ * unforgeable about the pseudo-internal method names used here,
+ * nothing prevents these emulated prototype methods from being
+ * applied to non-WeakMaps with pseudo-internal methods of the same
+ * names.
+ *
+ *
Another difference is that our emulated {@code
+ * WeakMap.prototype} is not itself a WeakMap. A problem with the
+ * current FF6.0a1 API is that WeakMap.prototype is itself a WeakMap
+ * providing ambient mutability and an ambient communications
+ * channel. Thus, if a WeakMap is already present and has this
+ * problem, repairES5.js wraps it in a safe wrappper in order to
+ * prevent access to this channel. (See
+ * PATCH_MUTABLE_FROZEN_WEAKMAP_PROTO in repairES5.js).
+ */
+
+/**
+ * If this is a full secureable ES5 platform and the ES-Harmony {@code WeakMap} is
+ * absent, install an approximate emulation.
+ *
+ *
If WeakMap is present but cannot store some objects, use our approximate
+ * emulation as a wrapper.
+ *
+ *
If this is almost a secureable ES5 platform, then WeakMap.js
+ * should be run after repairES5.js.
+ *
+ *
See {@code WeakMap} for documentation of the garbage collection
+ * properties of this WeakMap emulation.
+ */
+(function WeakMapModule() {
+ "use strict";
+
+ if (typeof ses !== 'undefined' && ses.ok && !ses.ok()) {
+ // already too broken, so give up
+ return;
+ }
+
+ /**
+ * In some cases (current Firefox), we must make a choice betweeen a
+ * WeakMap which is capable of using all varieties of host objects as
+ * keys and one which is capable of safely using proxies as keys. See
+ * comments below about HostWeakMap and DoubleWeakMap for details.
+ *
+ * This function (which is a global, not exposed to guests) marks a
+ * WeakMap as permitted to do what is necessary to index all host
+ * objects, at the cost of making it unsafe for proxies.
+ *
+ * Do not apply this function to anything which is not a genuine
+ * fresh WeakMap.
+ */
+ function weakMapPermitHostObjects(map) {
+ // identity of function used as a secret -- good enough and cheap
+ if (map.permitHostObjects___) {
+ map.permitHostObjects___(weakMapPermitHostObjects);
+ }
+ }
+ if (typeof ses !== 'undefined') {
+ ses.weakMapPermitHostObjects = weakMapPermitHostObjects;
+ }
+
+ // IE 11 has no Proxy but has a broken WeakMap such that we need to patch
+ // it using DoubleWeakMap; this flag tells DoubleWeakMap so.
+ var doubleWeakMapCheckSilentFailure = false;
+
+ // Check if there is already a good-enough WeakMap implementation, and if so
+ // exit without replacing it.
+ if (typeof WeakMap === 'function') {
+ var HostWeakMap = WeakMap;
+ // There is a WeakMap -- is it good enough?
+ if (typeof navigator !== 'undefined' &&
+ /Firefox/.test(navigator.userAgent)) {
+ // We're now *assuming not*, because as of this writing (2013-05-06)
+ // Firefox's WeakMaps have a miscellany of objects they won't accept, and
+ // we don't want to make an exhaustive list, and testing for just one
+ // will be a problem if that one is fixed alone (as they did for Event).
+
+ // If there is a platform that we *can* reliably test on, here's how to
+ // do it:
+ // var problematic = ... ;
+ // var testHostMap = new HostWeakMap();
+ // try {
+ // testHostMap.set(problematic, 1); // Firefox 20 will throw here
+ // if (testHostMap.get(problematic) === 1) {
+ // return;
+ // }
+ // } catch (e) {}
+
+ } else {
+ // IE 11 bug: WeakMaps silently fail to store frozen objects.
+ var testMap = new HostWeakMap();
+ var testObject = Object.freeze({});
+ testMap.set(testObject, 1);
+ if (testMap.get(testObject) !== 1) {
+ doubleWeakMapCheckSilentFailure = true;
+ // Fall through to installing our WeakMap.
+ } else {
+ module.exports = WeakMap;
+ return;
+ }
+ }
+ }
+
+ var hop = Object.prototype.hasOwnProperty;
+ var gopn = Object.getOwnPropertyNames;
+ var defProp = Object.defineProperty;
+ var isExtensible = Object.isExtensible;
+
+ /**
+ * Security depends on HIDDEN_NAME being both unguessable and
+ * undiscoverable by untrusted code.
+ *
+ *
Given the known weaknesses of Math.random() on existing
+ * browsers, it does not generate unguessability we can be confident
+ * of.
+ *
+ *
It is the monkey patching logic in this file that is intended
+ * to ensure undiscoverability. The basic idea is that there are
+ * three fundamental means of discovering properties of an object:
+ * The for/in loop, Object.keys(), and Object.getOwnPropertyNames(),
+ * as well as some proposed ES6 extensions that appear on our
+ * whitelist. The first two only discover enumerable properties, and
+ * we only use HIDDEN_NAME to name a non-enumerable property, so the
+ * only remaining threat should be getOwnPropertyNames and some
+ * proposed ES6 extensions that appear on our whitelist. We monkey
+ * patch them to remove HIDDEN_NAME from the list of properties they
+ * returns.
+ *
+ *
TODO(erights): On a platform with built-in Proxies, proxies
+ * could be used to trap and thereby discover the HIDDEN_NAME, so we
+ * need to monkey patch Proxy.create, Proxy.createFunction, etc, in
+ * order to wrap the provided handler with the real handler which
+ * filters out all traps using HIDDEN_NAME.
+ *
+ *
TODO(erights): Revisit Mike Stay's suggestion that we use an
+ * encapsulated function at a not-necessarily-secret name, which
+ * uses the Stiegler shared-state rights amplification pattern to
+ * reveal the associated value only to the WeakMap in which this key
+ * is associated with that value. Since only the key retains the
+ * function, the function can also remember the key without causing
+ * leakage of the key, so this doesn't violate our general gc
+ * goals. In addition, because the name need not be a guarded
+ * secret, we could efficiently handle cross-frame frozen keys.
+ */
+ var HIDDEN_NAME_PREFIX = 'weakmap:';
+ var HIDDEN_NAME = HIDDEN_NAME_PREFIX + 'ident:' + Math.random() + '___';
+
+ if (typeof crypto !== 'undefined' &&
+ typeof crypto.getRandomValues === 'function' &&
+ typeof ArrayBuffer === 'function' &&
+ typeof Uint8Array === 'function') {
+ var ab = new ArrayBuffer(25);
+ var u8s = new Uint8Array(ab);
+ crypto.getRandomValues(u8s);
+ HIDDEN_NAME = HIDDEN_NAME_PREFIX + 'rand:' +
+ Array.prototype.map.call(u8s, function(u8) {
+ return (u8 % 36).toString(36);
+ }).join('') + '___';
+ }
+
+ function isNotHiddenName(name) {
+ return !(
+ name.substr(0, HIDDEN_NAME_PREFIX.length) == HIDDEN_NAME_PREFIX &&
+ name.substr(name.length - 3) === '___');
+ }
+
+ /**
+ * Monkey patch getOwnPropertyNames to avoid revealing the
+ * HIDDEN_NAME.
+ *
+ *
The ES5.1 spec requires each name to appear only once, but as
+ * of this writing, this requirement is controversial for ES6, so we
+ * made this code robust against this case. If the resulting extra
+ * search turns out to be expensive, we can probably relax this once
+ * ES6 is adequately supported on all major browsers, iff no browser
+ * versions we support at that time have relaxed this constraint
+ * without providing built-in ES6 WeakMaps.
+ */
+ defProp(Object, 'getOwnPropertyNames', {
+ value: function fakeGetOwnPropertyNames(obj) {
+ return gopn(obj).filter(isNotHiddenName);
+ }
+ });
+
+ /**
+ * getPropertyNames is not in ES5 but it is proposed for ES6 and
+ * does appear in our whitelist, so we need to clean it too.
+ */
+ if ('getPropertyNames' in Object) {
+ var originalGetPropertyNames = Object.getPropertyNames;
+ defProp(Object, 'getPropertyNames', {
+ value: function fakeGetPropertyNames(obj) {
+ return originalGetPropertyNames(obj).filter(isNotHiddenName);
+ }
+ });
+ }
+
+ /**
+ *
To treat objects as identity-keys with reasonable efficiency
+ * on ES5 by itself (i.e., without any object-keyed collections), we
+ * need to add a hidden property to such key objects when we
+ * can. This raises several issues:
+ *
+ * - Arranging to add this property to objects before we lose the
+ * chance, and
+ *
- Hiding the existence of this new property from most
+ * JavaScript code.
+ *
- Preventing certification theft, where one object is
+ * created falsely claiming to be the key of an association
+ * actually keyed by another object.
+ *
- Preventing value theft, where untrusted code with
+ * access to a key object but not a weak map nevertheless
+ * obtains access to the value associated with that key in that
+ * weak map.
+ *
+ * We do so by
+ *
+ * - Making the name of the hidden property unguessable, so "[]"
+ * indexing, which we cannot intercept, cannot be used to access
+ * a property without knowing the name.
+ *
- Making the hidden property non-enumerable, so we need not
+ * worry about for-in loops or {@code Object.keys},
+ *
- monkey patching those reflective methods that would
+ * prevent extensions, to add this hidden property first,
+ *
- monkey patching those methods that would reveal this
+ * hidden property.
+ *
+ * Unfortunately, because of same-origin iframes, we cannot reliably
+ * add this hidden property before an object becomes
+ * non-extensible. Instead, if we encounter a non-extensible object
+ * without a hidden record that we can detect (whether or not it has
+ * a hidden record stored under a name secret to us), then we just
+ * use the key object itself to represent its identity in a brute
+ * force leaky map stored in the weak map, losing all the advantages
+ * of weakness for these.
+ */
+ function getHiddenRecord(key) {
+ if (key !== Object(key)) {
+ throw new TypeError('Not an object: ' + key);
+ }
+ var hiddenRecord = key[HIDDEN_NAME];
+ if (hiddenRecord && hiddenRecord.key === key) { return hiddenRecord; }
+ if (!isExtensible(key)) {
+ // Weak map must brute force, as explained in doc-comment above.
+ return void 0;
+ }
+
+ // The hiddenRecord and the key point directly at each other, via
+ // the "key" and HIDDEN_NAME properties respectively. The key
+ // field is for quickly verifying that this hidden record is an
+ // own property, not a hidden record from up the prototype chain.
+ //
+ // NOTE: Because this WeakMap emulation is meant only for systems like
+ // SES where Object.prototype is frozen without any numeric
+ // properties, it is ok to use an object literal for the hiddenRecord.
+ // This has two advantages:
+ // * It is much faster in a performance critical place
+ // * It avoids relying on Object.create(null), which had been
+ // problematic on Chrome 28.0.1480.0. See
+ // https://code.google.com/p/google-caja/issues/detail?id=1687
+ hiddenRecord = { key: key };
+
+ // When using this WeakMap emulation on platforms where
+ // Object.prototype might not be frozen and Object.create(null) is
+ // reliable, use the following two commented out lines instead.
+ // hiddenRecord = Object.create(null);
+ // hiddenRecord.key = key;
+
+ // Please contact us if you need this to work on platforms where
+ // Object.prototype might not be frozen and
+ // Object.create(null) might not be reliable.
+
+ try {
+ defProp(key, HIDDEN_NAME, {
+ value: hiddenRecord,
+ writable: false,
+ enumerable: false,
+ configurable: false
+ });
+ return hiddenRecord;
+ } catch (error) {
+ // Under some circumstances, isExtensible seems to misreport whether
+ // the HIDDEN_NAME can be defined.
+ // The circumstances have not been isolated, but at least affect
+ // Node.js v0.10.26 on TravisCI / Linux, but not the same version of
+ // Node.js on OS X.
+ return void 0;
+ }
+ }
+
+ /**
+ * Monkey patch operations that would make their argument
+ * non-extensible.
+ *
+ * The monkey patched versions throw a TypeError if their
+ * argument is not an object, so it should only be done to functions
+ * that should throw a TypeError anyway if their argument is not an
+ * object.
+ */
+ (function(){
+ var oldFreeze = Object.freeze;
+ defProp(Object, 'freeze', {
+ value: function identifyingFreeze(obj) {
+ getHiddenRecord(obj);
+ return oldFreeze(obj);
+ }
+ });
+ var oldSeal = Object.seal;
+ defProp(Object, 'seal', {
+ value: function identifyingSeal(obj) {
+ getHiddenRecord(obj);
+ return oldSeal(obj);
+ }
+ });
+ var oldPreventExtensions = Object.preventExtensions;
+ defProp(Object, 'preventExtensions', {
+ value: function identifyingPreventExtensions(obj) {
+ getHiddenRecord(obj);
+ return oldPreventExtensions(obj);
+ }
+ });
+ })();
+
+ function constFunc(func) {
+ func.prototype = null;
+ return Object.freeze(func);
+ }
+
+ var calledAsFunctionWarningDone = false;
+ function calledAsFunctionWarning() {
+ // Future ES6 WeakMap is currently (2013-09-10) expected to reject WeakMap()
+ // but we used to permit it and do it ourselves, so warn only.
+ if (!calledAsFunctionWarningDone && typeof console !== 'undefined') {
+ calledAsFunctionWarningDone = true;
+ console.warn('WeakMap should be invoked as new WeakMap(), not ' +
+ 'WeakMap(). This will be an error in the future.');
+ }
+ }
+
+ var nextId = 0;
+
+ var OurWeakMap = function() {
+ if (!(this instanceof OurWeakMap)) { // approximate test for new ...()
+ calledAsFunctionWarning();
+ }
+
+ // We are currently (12/25/2012) never encountering any prematurely
+ // non-extensible keys.
+ var keys = []; // brute force for prematurely non-extensible keys.
+ var values = []; // brute force for corresponding values.
+ var id = nextId++;
+
+ function get___(key, opt_default) {
+ var index;
+ var hiddenRecord = getHiddenRecord(key);
+ if (hiddenRecord) {
+ return id in hiddenRecord ? hiddenRecord[id] : opt_default;
+ } else {
+ index = keys.indexOf(key);
+ return index >= 0 ? values[index] : opt_default;
+ }
+ }
+
+ function has___(key) {
+ var hiddenRecord = getHiddenRecord(key);
+ if (hiddenRecord) {
+ return id in hiddenRecord;
+ } else {
+ return keys.indexOf(key) >= 0;
+ }
+ }
+
+ function set___(key, value) {
+ var index;
+ var hiddenRecord = getHiddenRecord(key);
+ if (hiddenRecord) {
+ hiddenRecord[id] = value;
+ } else {
+ index = keys.indexOf(key);
+ if (index >= 0) {
+ values[index] = value;
+ } else {
+ // Since some browsers preemptively terminate slow turns but
+ // then continue computing with presumably corrupted heap
+ // state, we here defensively get keys.length first and then
+ // use it to update both the values and keys arrays, keeping
+ // them in sync.
+ index = keys.length;
+ values[index] = value;
+ // If we crash here, values will be one longer than keys.
+ keys[index] = key;
+ }
+ }
+ return this;
+ }
+
+ function delete___(key) {
+ var hiddenRecord = getHiddenRecord(key);
+ var index, lastIndex;
+ if (hiddenRecord) {
+ return id in hiddenRecord && delete hiddenRecord[id];
+ } else {
+ index = keys.indexOf(key);
+ if (index < 0) {
+ return false;
+ }
+ // Since some browsers preemptively terminate slow turns but
+ // then continue computing with potentially corrupted heap
+ // state, we here defensively get keys.length first and then use
+ // it to update both the keys and the values array, keeping
+ // them in sync. We update the two with an order of assignments,
+ // such that any prefix of these assignments will preserve the
+ // key/value correspondence, either before or after the delete.
+ // Note that this needs to work correctly when index === lastIndex.
+ lastIndex = keys.length - 1;
+ keys[index] = void 0;
+ // If we crash here, there's a void 0 in the keys array, but
+ // no operation will cause a "keys.indexOf(void 0)", since
+ // getHiddenRecord(void 0) will always throw an error first.
+ values[index] = values[lastIndex];
+ // If we crash here, values[index] cannot be found here,
+ // because keys[index] is void 0.
+ keys[index] = keys[lastIndex];
+ // If index === lastIndex and we crash here, then keys[index]
+ // is still void 0, since the aliasing killed the previous key.
+ keys.length = lastIndex;
+ // If we crash here, keys will be one shorter than values.
+ values.length = lastIndex;
+ return true;
+ }
+ }
+
+ return Object.create(OurWeakMap.prototype, {
+ get___: { value: constFunc(get___) },
+ has___: { value: constFunc(has___) },
+ set___: { value: constFunc(set___) },
+ delete___: { value: constFunc(delete___) }
+ });
+ };
+
+ OurWeakMap.prototype = Object.create(Object.prototype, {
+ get: {
+ /**
+ * Return the value most recently associated with key, or
+ * opt_default if none.
+ */
+ value: function get(key, opt_default) {
+ return this.get___(key, opt_default);
+ },
+ writable: true,
+ configurable: true
+ },
+
+ has: {
+ /**
+ * Is there a value associated with key in this WeakMap?
+ */
+ value: function has(key) {
+ return this.has___(key);
+ },
+ writable: true,
+ configurable: true
+ },
+
+ set: {
+ /**
+ * Associate value with key in this WeakMap, overwriting any
+ * previous association if present.
+ */
+ value: function set(key, value) {
+ return this.set___(key, value);
+ },
+ writable: true,
+ configurable: true
+ },
+
+ 'delete': {
+ /**
+ * Remove any association for key in this WeakMap, returning
+ * whether there was one.
+ *
+ *
Note that the boolean return here does not work like the
+ * {@code delete} operator. The {@code delete} operator returns
+ * whether the deletion succeeds at bringing about a state in
+ * which the deleted property is absent. The {@code delete}
+ * operator therefore returns true if the property was already
+ * absent, whereas this {@code delete} method returns false if
+ * the association was already absent.
+ */
+ value: function remove(key) {
+ return this.delete___(key);
+ },
+ writable: true,
+ configurable: true
+ }
+ });
+
+ if (typeof HostWeakMap === 'function') {
+ (function() {
+ // If we got here, then the platform has a WeakMap but we are concerned
+ // that it may refuse to store some key types. Therefore, make a map
+ // implementation which makes use of both as possible.
+
+ // In this mode we are always using double maps, so we are not proxy-safe.
+ // This combination does not occur in any known browser, but we had best
+ // be safe.
+ if (doubleWeakMapCheckSilentFailure && typeof Proxy !== 'undefined') {
+ Proxy = undefined;
+ }
+
+ function DoubleWeakMap() {
+ if (!(this instanceof OurWeakMap)) { // approximate test for new ...()
+ calledAsFunctionWarning();
+ }
+
+ // Preferable, truly weak map.
+ var hmap = new HostWeakMap();
+
+ // Our hidden-property-based pseudo-weak-map. Lazily initialized in the
+ // 'set' implementation; thus we can avoid performing extra lookups if
+ // we know all entries actually stored are entered in 'hmap'.
+ var omap = undefined;
+
+ // Hidden-property maps are not compatible with proxies because proxies
+ // can observe the hidden name and either accidentally expose it or fail
+ // to allow the hidden property to be set. Therefore, we do not allow
+ // arbitrary WeakMaps to switch to using hidden properties, but only
+ // those which need the ability, and unprivileged code is not allowed
+ // to set the flag.
+ //
+ // (Except in doubleWeakMapCheckSilentFailure mode in which case we
+ // disable proxies.)
+ var enableSwitching = false;
+
+ function dget(key, opt_default) {
+ if (omap) {
+ return hmap.has(key) ? hmap.get(key)
+ : omap.get___(key, opt_default);
+ } else {
+ return hmap.get(key, opt_default);
+ }
+ }
+
+ function dhas(key) {
+ return hmap.has(key) || (omap ? omap.has___(key) : false);
+ }
+
+ var dset;
+ if (doubleWeakMapCheckSilentFailure) {
+ dset = function(key, value) {
+ hmap.set(key, value);
+ if (!hmap.has(key)) {
+ if (!omap) { omap = new OurWeakMap(); }
+ omap.set(key, value);
+ }
+ return this;
+ };
+ } else {
+ dset = function(key, value) {
+ if (enableSwitching) {
+ try {
+ hmap.set(key, value);
+ } catch (e) {
+ if (!omap) { omap = new OurWeakMap(); }
+ omap.set___(key, value);
+ }
+ } else {
+ hmap.set(key, value);
+ }
+ return this;
+ };
+ }
+
+ function ddelete(key) {
+ var result = !!hmap['delete'](key);
+ if (omap) { return omap.delete___(key) || result; }
+ return result;
+ }
+
+ return Object.create(OurWeakMap.prototype, {
+ get___: { value: constFunc(dget) },
+ has___: { value: constFunc(dhas) },
+ set___: { value: constFunc(dset) },
+ delete___: { value: constFunc(ddelete) },
+ permitHostObjects___: { value: constFunc(function(token) {
+ if (token === weakMapPermitHostObjects) {
+ enableSwitching = true;
+ } else {
+ throw new Error('bogus call to permitHostObjects___');
+ }
+ })}
+ });
+ }
+ DoubleWeakMap.prototype = OurWeakMap.prototype;
+ module.exports = DoubleWeakMap;
+
+ // define .constructor to hide OurWeakMap ctor
+ Object.defineProperty(WeakMap.prototype, 'constructor', {
+ value: WeakMap,
+ enumerable: false, // as default .constructor is
+ configurable: true,
+ writable: true
+ });
+ })();
+ } else {
+ // There is no host WeakMap, so we must use the emulation.
+
+ // Emulated WeakMaps are incompatible with native proxies (because proxies
+ // can observe the hidden name), so we must disable Proxy usage (in
+ // ArrayLike and Domado, currently).
+ if (typeof Proxy !== 'undefined') {
+ Proxy = undefined;
+ }
+
+ module.exports = OurWeakMap;
+ }
+})();
+
+},{}],126:[function(require,module,exports){
+'use strict'
+
+var weakMap = typeof WeakMap === 'undefined' ? require('weak-map') : WeakMap
+var createBuffer = require('gl-buffer')
+var createVAO = require('gl-vao')
+
+var TriangleCache = new weakMap()
+
+function createABigTriangle(gl) {
+
+ var triangleVAO = TriangleCache.get(gl)
+ if(!triangleVAO || !gl.isBuffer(triangleVAO._triangleBuffer.buffer)) {
+ var buf = createBuffer(gl, new Float32Array([-1, -1, -1, 4, 4, -1]))
+ triangleVAO = createVAO(gl, [
+ { buffer: buf,
+ type: gl.FLOAT,
+ size: 2
+ }
+ ])
+ triangleVAO._triangleBuffer = buf
+ TriangleCache.set(gl, triangleVAO)
+ }
+ triangleVAO.bind()
+ gl.drawArrays(gl.TRIANGLES, 0, 3)
+ triangleVAO.unbind()
+}
+
+module.exports = createABigTriangle
+
+},{"gl-buffer":75,"gl-vao":189,"weak-map":125}],127:[function(require,module,exports){
+'use strict'
+
+module.exports = createAxes
+
+var createText = require('./lib/text.js')
+var createLines = require('./lib/lines.js')
+var createBackground = require('./lib/background.js')
+var getCubeProperties = require('./lib/cube.js')
+var Ticks = require('./lib/ticks.js')
+
+var identity = new Float32Array([
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1])
+
+function copyVec3(a, b) {
+ a[0] = b[0]
+ a[1] = b[1]
+ a[2] = b[2]
+ return a
+}
+
+function Axes(gl) {
+ this.gl = gl
+
+ this.pixelRatio = 1
+
+ this.bounds = [ [-10, -10, -10],
+ [ 10, 10, 10] ]
+ this.ticks = [ [], [], [] ]
+ this.autoTicks = true
+ this.tickSpacing = [ 1, 1, 1 ]
+
+ this.tickEnable = [ true, true, true ]
+ this.tickFont = [ 'sans-serif', 'sans-serif', 'sans-serif' ]
+ this.tickSize = [ 12, 12, 12 ]
+ this.tickAngle = [ 0, 0, 0 ]
+ this.tickColor = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ]
+ this.tickPad = [ 10, 10, 10 ]
+
+ this.lastCubeProps = {
+ cubeEdges: [0,0,0],
+ axis: [0,0,0]
+ }
+
+ this.labels = [ 'x', 'y', 'z' ]
+ this.labelEnable = [ true, true, true ]
+ this.labelFont = 'sans-serif'
+ this.labelSize = [ 20, 20, 20 ]
+ this.labelAngle = [ 0, 0, 0 ]
+ this.labelColor = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ]
+ this.labelPad = [ 10, 10, 10 ]
+
+ this.lineEnable = [ true, true, true ]
+ this.lineMirror = [ false, false, false ]
+ this.lineWidth = [ 1, 1, 1 ]
+ this.lineColor = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ]
+
+ this.lineTickEnable = [ true, true, true ]
+ this.lineTickMirror = [ false, false, false ]
+ this.lineTickLength = [ 0, 0, 0 ]
+ this.lineTickWidth = [ 1, 1, 1 ]
+ this.lineTickColor = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ]
+
+ this.gridEnable = [ true, true, true ]
+ this.gridWidth = [ 1, 1, 1 ]
+ this.gridColor = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ]
+
+ this.zeroEnable = [ true, true, true ]
+ this.zeroLineColor = [ [0,0,0,1], [0,0,0,1], [0,0,0,1] ]
+ this.zeroLineWidth = [ 2, 2, 2 ]
+
+ this.backgroundEnable = [ false, false, false ]
+ this.backgroundColor = [ [0.8, 0.8, 0.8, 0.5],
+ [0.8, 0.8, 0.8, 0.5],
+ [0.8, 0.8, 0.8, 0.5] ]
+
+ this._firstInit = true
+ this._text = null
+ this._lines = null
+ this._background = createBackground(gl)
+}
+
+var proto = Axes.prototype
+
+proto.update = function(options) {
+ options = options || {}
+
+ //Option parsing helper functions
+ function parseOption(nest, cons, name) {
+ if(name in options) {
+ var opt = options[name]
+ var prev = this[name]
+ var next
+ if(nest ? (Array.isArray(opt) && Array.isArray(opt[0])) :
+ Array.isArray(opt) ) {
+ this[name] = next = [ cons(opt[0]), cons(opt[1]), cons(opt[2]) ]
+ } else {
+ this[name] = next = [ cons(opt), cons(opt), cons(opt) ]
+ }
+ for(var i=0; i<3; ++i) {
+ if(next[i] !== prev[i]) {
+ return true
+ }
+ }
+ }
+ return false
+ }
+
+ var NUMBER = parseOption.bind(this, false, Number)
+ var BOOLEAN = parseOption.bind(this, false, Boolean)
+ var STRING = parseOption.bind(this, false, String)
+ var COLOR = parseOption.bind(this, true, function(v) {
+ if(Array.isArray(v)) {
+ if(v.length === 3) {
+ return [ +v[0], +v[1], +v[2], 1.0 ]
+ } else if(v.length === 4) {
+ return [ +v[0], +v[1], +v[2], +v[3] ]
+ }
+ }
+ return [ 0, 0, 0, 1 ]
+ })
+
+ //Tick marks and bounds
+ var nextTicks
+ var ticksUpdate = false
+ var boundsChanged = false
+ if('bounds' in options) {
+ var bounds = options.bounds
+i_loop:
+ for(var i=0; i<2; ++i) {
+ for(var j=0; j<3; ++j) {
+ if(bounds[i][j] !== this.bounds[i][j]) {
+ boundsChanged = true
+ }
+ this.bounds[i][j] = bounds[i][j]
+ }
+ }
+ }
+ if('ticks' in options) {
+ nextTicks = options.ticks
+ ticksUpdate = true
+ this.autoTicks = false
+ for(var i=0; i<3; ++i) {
+ this.tickSpacing[i] = 0.0
+ }
+ } else if(NUMBER('tickSpacing')) {
+ this.autoTicks = true
+ boundsChanged = true
+ }
+
+ if(this._firstInit) {
+ if(!('ticks' in options || 'tickSpacing' in options)) {
+ this.autoTicks = true
+ }
+
+ //Force tick recomputation on first update
+ boundsChanged = true
+ ticksUpdate = true
+ this._firstInit = false
+ }
+
+ if(boundsChanged && this.autoTicks) {
+ nextTicks = Ticks.create(this.bounds, this.tickSpacing)
+ ticksUpdate = true
+ }
+
+ //Compare next ticks to previous ticks, only update if needed
+ if(ticksUpdate) {
+ for(var i=0; i<3; ++i) {
+ nextTicks[i].sort(function(a,b) {
+ return a.x-b.x
+ })
+ }
+ if(Ticks.equal(nextTicks, this.ticks)) {
+ ticksUpdate = false
+ } else {
+ this.ticks = nextTicks
+ }
+ }
+
+ //Parse tick properties
+ BOOLEAN('tickEnable')
+ if(STRING('tickFont')) {
+ ticksUpdate = true //If font changes, must rebuild vbo
+ }
+ NUMBER('tickSize')
+ NUMBER('tickAngle')
+ NUMBER('tickPad')
+ COLOR('tickColor')
+
+ //Axis labels
+ var labelUpdate = STRING('labels')
+ if(STRING('labelFont')) {
+ labelUpdate = true
+ }
+ BOOLEAN('labelEnable')
+ NUMBER('labelSize')
+ NUMBER('labelPad')
+ COLOR('labelColor')
+
+ //Axis lines
+ BOOLEAN('lineEnable')
+ BOOLEAN('lineMirror')
+ NUMBER('lineWidth')
+ COLOR('lineColor')
+
+ //Axis line ticks
+ BOOLEAN('lineTickEnable')
+ BOOLEAN('lineTickMirror')
+ NUMBER('lineTickLength')
+ NUMBER('lineTickWidth')
+ COLOR('lineTickColor')
+
+ //Grid lines
+ BOOLEAN('gridEnable')
+ NUMBER('gridWidth')
+ COLOR('gridColor')
+
+ //Zero line
+ BOOLEAN('zeroEnable')
+ COLOR('zeroLineColor')
+ NUMBER('zeroLineWidth')
+
+ //Background
+ BOOLEAN('backgroundEnable')
+ COLOR('backgroundColor')
+
+ //Update text if necessary
+ if(!this._text) {
+ this._text = createText(
+ this.gl,
+ this.bounds,
+ this.labels,
+ this.labelFont,
+ this.ticks,
+ this.tickFont)
+ } else if(this._text && (labelUpdate || ticksUpdate)) {
+ this._text.update(
+ this.bounds,
+ this.labels,
+ this.labelFont,
+ this.ticks,
+ this.tickFont)
+ }
+
+ //Update lines if necessary
+ if(this._lines && ticksUpdate) {
+ this._lines.dispose()
+ this._lines = null
+ }
+ if(!this._lines) {
+ this._lines = createLines(this.gl, this.bounds, this.ticks)
+ }
+}
+
+function OffsetInfo() {
+ this.primalOffset = [0,0,0]
+ this.primalMinor = [0,0,0]
+ this.mirrorOffset = [0,0,0]
+ this.mirrorMinor = [0,0,0]
+}
+
+var LINE_OFFSET = [ new OffsetInfo(), new OffsetInfo(), new OffsetInfo() ]
+
+function computeLineOffset(result, i, bounds, cubeEdges, cubeAxis) {
+ var primalOffset = result.primalOffset
+ var primalMinor = result.primalMinor
+ var dualOffset = result.mirrorOffset
+ var dualMinor = result.mirrorMinor
+ var e = cubeEdges[i]
+
+ //Calculate offsets
+ for(var j=0; j<3; ++j) {
+ if(i === j) {
+ continue
+ }
+ var a = primalOffset,
+ b = dualOffset,
+ c = primalMinor,
+ d = dualMinor
+ if(e & (1< 0) {
+ c[j] = -1
+ d[j] = 0
+ } else {
+ c[j] = 0
+ d[j] = +1
+ }
+ }
+}
+
+var CUBE_ENABLE = [0,0,0]
+var DEFAULT_PARAMS = {
+ model: identity,
+ view: identity,
+ projection: identity
+}
+
+proto.isOpaque = function() {
+ return true
+}
+
+proto.isTransparent = function() {
+ return false
+}
+
+proto.drawTransparent = function(params) {}
+
+
+var PRIMAL_MINOR = [0,0,0]
+var MIRROR_MINOR = [0,0,0]
+var PRIMAL_OFFSET = [0,0,0]
+
+proto.draw = function(params) {
+ params = params || DEFAULT_PARAMS
+
+ var gl = this.gl
+
+ //Geometry for camera and axes
+ var model = params.model || identity
+ var view = params.view || identity
+ var projection = params.projection || identity
+ var bounds = this.bounds
+
+ //Unpack axis info
+ var cubeParams = getCubeProperties(model, view, projection, bounds)
+ var cubeEdges = cubeParams.cubeEdges
+ var cubeAxis = cubeParams.axis
+
+ var cx = view[12]
+ var cy = view[13]
+ var cz = view[14]
+ var cw = view[15]
+
+ var pixelScaleF = this.pixelRatio * (projection[3]*cx + projection[7]*cy + projection[11]*cz + projection[15]*cw) / gl.drawingBufferHeight
+
+ for(var i=0; i<3; ++i) {
+ this.lastCubeProps.cubeEdges[i] = cubeEdges[i]
+ this.lastCubeProps.axis[i] = cubeAxis[i]
+ }
+
+ //Compute axis info
+ var lineOffset = LINE_OFFSET
+ for(var i=0; i<3; ++i) {
+ computeLineOffset(
+ LINE_OFFSET[i],
+ i,
+ this.bounds,
+ cubeEdges,
+ cubeAxis)
+ }
+
+ //Set up state parameters
+ var gl = this.gl
+
+ //Draw background first
+ var cubeEnable = CUBE_ENABLE
+ for(var i=0; i<3; ++i) {
+ if(this.backgroundEnable[i]) {
+ cubeEnable[i] = cubeAxis[i]
+ } else {
+ cubeEnable[i] = 0
+ }
+ }
+
+ this._background.draw(
+ model,
+ view,
+ projection,
+ bounds,
+ cubeEnable,
+ this.backgroundColor)
+
+ //Draw lines
+ this._lines.bind(
+ model,
+ view,
+ projection,
+ this)
+
+ //First draw grid lines and zero lines
+ for(var i=0; i<3; ++i) {
+ var x = [0,0,0]
+ if(cubeAxis[i] > 0) {
+ x[i] = bounds[1][i]
+ } else {
+ x[i] = bounds[0][i]
+ }
+
+ //Draw grid lines
+ for(var j=0; j<2; ++j) {
+ var u = (i + 1 + j) % 3
+ var v = (i + 1 + (j^1)) % 3
+ if(this.gridEnable[u]) {
+ this._lines.drawGrid(u, v, this.bounds, x, this.gridColor[u], this.gridWidth[u]*this.pixelRatio)
+ }
+ }
+
+ //Draw zero lines (need to do this AFTER all grid lines are drawn)
+ for(var j=0; j<2; ++j) {
+ var u = (i + 1 + j) % 3
+ var v = (i + 1 + (j^1)) % 3
+ if(this.zeroEnable[v]) {
+ //Check if zero line in bounds
+ if(bounds[0][v] <= 0 && bounds[1][v] >= 0) {
+ this._lines.drawZero(u, v, this.bounds, x, this.zeroLineColor[v], this.zeroLineWidth[v]*this.pixelRatio)
+ }
+ }
+ }
+ }
+
+ //Then draw axis lines and tick marks
+ for(var i=0; i<3; ++i) {
+
+ //Draw axis lines
+ if(this.lineEnable[i]) {
+ this._lines.drawAxisLine(i, this.bounds, lineOffset[i].primalOffset, this.lineColor[i], this.lineWidth[i]*this.pixelRatio)
+ }
+ if(this.lineMirror[i]) {
+ this._lines.drawAxisLine(i, this.bounds, lineOffset[i].mirrorOffset, this.lineColor[i], this.lineWidth[i]*this.pixelRatio)
+ }
+
+ //Compute minor axes
+ var primalMinor = copyVec3(PRIMAL_MINOR, lineOffset[i].primalMinor)
+ var mirrorMinor = copyVec3(MIRROR_MINOR, lineOffset[i].mirrorMinor)
+ var tickLength = this.lineTickLength
+ var op = 0
+ for(var j=0; j<3; ++j) {
+ var scaleFactor = pixelScaleF / model[5*j]
+ primalMinor[j] *= tickLength[j] * scaleFactor
+ mirrorMinor[j] *= tickLength[j] * scaleFactor
+ }
+
+ //Draw axis line ticks
+ if(this.lineTickEnable[i]) {
+ this._lines.drawAxisTicks(i, lineOffset[i].primalOffset, primalMinor, this.lineTickColor[i], this.lineTickWidth[i]*this.pixelRatio)
+ }
+ if(this.lineTickMirror[i]) {
+ this._lines.drawAxisTicks(i, lineOffset[i].mirrorOffset, mirrorMinor, this.lineTickColor[i], this.lineTickWidth[i]*this.pixelRatio)
+ }
+ }
+
+ //Draw text sprites
+ this._text.bind(
+ model,
+ view,
+ projection,
+ this.pixelRatio)
+
+ for(var i=0; i<3; ++i) {
+
+ var minor = lineOffset[i].primalMinor
+ var offset = copyVec3(PRIMAL_OFFSET, lineOffset[i].primalOffset)
+
+ for(var j=0; j<3; ++j) {
+ if(this.lineTickEnable[i]) {
+ offset[j] += pixelScaleF * minor[j] * Math.max(this.lineTickLength[j], 0) / model[5*j]
+ }
+ }
+
+ //Draw tick text
+ if(this.tickEnable[i]) {
+
+ //Add tick padding
+ for(var j=0; j<3; ++j) {
+ offset[j] += pixelScaleF * minor[j] * this.tickPad[j] / model[5*j]
+ }
+
+ //Draw axis
+ this._text.drawTicks(
+ i,
+ this.tickSize[i],
+ this.tickAngle[i],
+ offset,
+ this.tickColor[i])
+ }
+
+ //Draw labels
+ if(this.labelEnable[i]) {
+
+ //Add label padding
+ for(var j=0; j<3; ++j) {
+ offset[j] += pixelScaleF * minor[j] * this.labelPad[j] / model[5*j]
+ }
+ offset[i] += 0.5 * (bounds[0][i] + bounds[1][i])
+
+ //Draw axis
+ this._text.drawLabel(
+ i,
+ this.labelSize[i],
+ this.labelAngle[i],
+ offset,
+ this.labelColor[i])
+ }
+ }
+}
+
+proto.dispose = function() {
+ this._text.dispose()
+ this._lines.dispose()
+ this._background.dispose()
+ this._lines = null
+ this._text = null
+ this._background = null
+ this.gl = null
+}
+
+function createAxes(gl, options) {
+ var axes = new Axes(gl)
+ axes.update(options)
+ return axes
+}
+
+},{"./lib/background.js":128,"./lib/cube.js":129,"./lib/lines.js":130,"./lib/text.js":132,"./lib/ticks.js":133}],128:[function(require,module,exports){
+'use strict'
+
+module.exports = createBackgroundCube
+
+var createBuffer = require('gl-buffer')
+var createVAO = require('gl-vao')
+var createShader = require('./shaders').bg
+
+function BackgroundCube(gl, buffer, vao, shader) {
+ this.gl = gl
+ this.buffer = buffer
+ this.vao = vao
+ this.shader = shader
+}
+
+var proto = BackgroundCube.prototype
+
+proto.draw = function(model, view, projection, bounds, enable, colors) {
+ var needsBG = false
+ for(var i=0; i<3; ++i) {
+ needsBG = needsBG || enable[i]
+ }
+ if(!needsBG) {
+ return
+ }
+
+ var gl = this.gl
+
+ gl.enable(gl.POLYGON_OFFSET_FILL)
+ gl.polygonOffset(1, 2)
+
+ this.shader.bind()
+ this.shader.uniforms = {
+ model: model,
+ view: view,
+ projection: projection,
+ bounds: bounds,
+ enable: enable,
+ colors: colors
+ }
+ this.vao.bind()
+ this.vao.draw(this.gl.TRIANGLES, 36)
+
+ gl.disable(gl.POLYGON_OFFSET_FILL)
+}
+
+proto.dispose = function() {
+ this.vao.dispose()
+ this.buffer.dispose()
+ this.shader.dispose()
+}
+
+function createBackgroundCube(gl) {
+ //Create cube vertices
+ var vertices = []
+ var indices = []
+ var ptr = 0
+ for(var d=0; d<3; ++d) {
+ var u = (d+1) % 3
+ var v = (d+2) % 3
+ var x = [0,0,0]
+ var c = [0,0,0]
+ for(var s=-1; s<=1; s+=2) {
+ indices.push(ptr, ptr+2, ptr+1,
+ ptr+1, ptr+2, ptr+3)
+ x[d] = s
+ c[d] = s
+ for(var i=-1; i<=1; i+=2) {
+ x[u] = i
+ for(var j=-1; j<=1; j+=2) {
+ x[v] = j
+ vertices.push(x[0], x[1], x[2],
+ c[0], c[1], c[2])
+ ptr += 1
+ }
+ }
+ //Swap u and v
+ var tt = u
+ u = v
+ v = tt
+ }
+ }
+
+ //Allocate buffer and vertex array
+ var buffer = createBuffer(gl, new Float32Array(vertices))
+ var elements = createBuffer(gl, new Uint16Array(indices), gl.ELEMENT_ARRAY_BUFFER)
+ var vao = createVAO(gl, [
+ {
+ buffer: buffer,
+ type: gl.FLOAT,
+ size: 3,
+ offset: 0,
+ stride: 24
+ },
+ {
+ buffer: buffer,
+ type: gl.FLOAT,
+ size: 3,
+ offset: 12,
+ stride: 24
+ }
+ ], elements)
+
+ //Create shader object
+ var shader = createShader(gl)
+ shader.attributes.position.location = 0
+ shader.attributes.normal.location = 1
+
+ return new BackgroundCube(gl, buffer, vao, shader)
+}
+
+},{"./shaders":131,"gl-buffer":75,"gl-vao":189}],129:[function(require,module,exports){
+"use strict"
+
+module.exports = getCubeEdges
+
+var bits = require('bit-twiddle')
+var multiply = require('gl-mat4/multiply')
+var invert = require('gl-mat4/invert')
+var splitPoly = require('split-polygon')
+var orient = require('robust-orientation')
+
+var mvp = new Array(16)
+var imvp = new Array(16)
+var pCubeVerts = new Array(8)
+var cubeVerts = new Array(8)
+var x = new Array(3)
+var zero3 = [0,0,0]
+
+;(function() {
+ for(var i=0; i<8; ++i) {
+ pCubeVerts[i] =[1,1,1,1]
+ cubeVerts[i] = [1,1,1]
+ }
+})()
+
+
+function transformHg(result, x, mat) {
+ for(var i=0; i<4; ++i) {
+ result[i] = mat[12+i]
+ for(var j=0; j<3; ++j) {
+ result[i] += x[j]*mat[4*j+i]
+ }
+ }
+}
+
+var FRUSTUM_PLANES = [
+ [ 0, 0, 1, 0, 0],
+ [ 0, 0,-1, 1, 0],
+ [ 0,-1, 0, 1, 0],
+ [ 0, 1, 0, 1, 0],
+ [-1, 0, 0, 1, 0],
+ [ 1, 0, 0, 1, 0]
+]
+
+function polygonArea(p) {
+ for(var i=0; i o0) {
+ closest |= 1< o0) {
+ closest |= 1< cubeVerts[i][1]) {
+ bottom = i
+ }
+ }
+
+ //Find left/right neighbors of bottom vertex
+ var left = -1
+ for(var i=0; i<3; ++i) {
+ var idx = bottom ^ (1< cubeVerts[right][0]) {
+ right = idx
+ }
+ }
+
+ //Determine edge axis coordinates
+ var cubeEdges = CUBE_EDGES
+ cubeEdges[0] = cubeEdges[1] = cubeEdges[2] = 0
+ cubeEdges[bits.log2(left^bottom)] = bottom&left
+ cubeEdges[bits.log2(bottom^right)] = bottom&right
+ var top = right ^ 7
+ if(top === closest || top === farthest) {
+ top = left ^ 7
+ cubeEdges[bits.log2(right^top)] = top&right
+ } else {
+ cubeEdges[bits.log2(left^top)] = top&left
+ }
+
+ //Determine visible faces
+ var axis = CUBE_AXIS
+ var cutCorner = closest
+ for(var d=0; d<3; ++d) {
+ if(cutCorner & (1<=0; --j) {
+ var p = positions[c[j]]
+ data.push(scale*p[0], -scale*p[1], t)
+ }
+ }
+ }
+
+ //Generate sprites for all 3 axes, store data in texture atlases
+ var tickOffset = [0,0,0]
+ var tickCount = [0,0,0]
+ var labelOffset = [0,0,0]
+ var labelCount = [0,0,0]
+ for(var d=0; d<3; ++d) {
+
+ //Generate label
+ labelOffset[d] = (data.length/VERTEX_SIZE)|0
+ addItem(0.5*(bounds[0][d]+bounds[1][d]), labels[d], labelFont)
+ labelCount[d] = ((data.length/VERTEX_SIZE)|0) - labelOffset[d]
+
+ //Generate sprites for tick marks
+ tickOffset[d] = (data.length/VERTEX_SIZE)|0
+ for(var i=0; i= 0) {
+ sigFigs = stepStr.length - u - 1
+ }
+ var shift = Math.pow(10, sigFigs)
+ var x = Math.round(spacing * i * shift)
+ var xstr = x + ""
+ if(xstr.indexOf("e") >= 0) {
+ return xstr
+ }
+ var xi = x / shift, xf = x % shift
+ if(x < 0) {
+ xi = -Math.ceil(xi)|0
+ xf = (-xf)|0
+ } else {
+ xi = Math.floor(xi)|0
+ xf = xf|0
+ }
+ var xis = "" + xi
+ if(x < 0) {
+ xis = "-" + xis
+ }
+ if(sigFigs) {
+ var xs = "" + xf
+ while(xs.length < sigFigs) {
+ xs = "0" + xs
+ }
+ return xis + "." + xs
+ } else {
+ return xis
+ }
+}
+
+function defaultTicks(bounds, tickSpacing) {
+ var array = []
+ for(var d=0; d<3; ++d) {
+ var ticks = []
+ var m = 0.5*(bounds[0][d]+bounds[1][d])
+ for(var t=0; t*tickSpacing[d]<=bounds[1][d]; ++t) {
+ ticks.push({x: t*tickSpacing[d], text: prettyPrint(tickSpacing[d], t)})
+ }
+ for(var t=-1; t*tickSpacing[d]>=bounds[0][d]; --t) {
+ ticks.push({x: t*tickSpacing[d], text: prettyPrint(tickSpacing[d], t)})
+ }
+ array.push(ticks)
+ }
+ return array
+}
+
+function ticksEqual(ticksA, ticksB) {
+ for(var i=0; i<3; ++i) {
+ if(ticksA[i].length !== ticksB[i].length) {
+ return false
+ }
+ for(var j=0; j 1.0) {
+ t = 1.0
+ }
+ var ti = 1.0 - t
+ var n = a.length
+ var r = new Array(n)
+ for(var i=0; i 0) || (a > 0 && b < 0)) {
+ var p = lerpW(s, b, t, a)
+ pos.push(p)
+ neg.push(p.slice())
+ }
+ if(b < 0) {
+ neg.push(t.slice())
+ } else if(b > 0) {
+ pos.push(t.slice())
+ } else {
+ pos.push(t.slice())
+ neg.push(t.slice())
+ }
+ a = b
+ }
+ return { positive: pos, negative: neg }
+}
+
+function positive(points, plane) {
+ var pos = []
+ var a = planeT(points[points.length-1], plane)
+ for(var s=points[points.length-1], t=points[0], i=0; i 0) || (a > 0 && b < 0)) {
+ pos.push(lerpW(s, b, t, a))
+ }
+ if(b >= 0) {
+ pos.push(t.slice())
+ }
+ a = b
+ }
+ return pos
+}
+
+function negative(points, plane) {
+ var neg = []
+ var a = planeT(points[points.length-1], plane)
+ for(var s=points[points.length-1], t=points[0], i=0; i 0) || (a > 0 && b < 0)) {
+ neg.push(lerpW(s, b, t, a))
+ }
+ if(b <= 0) {
+ neg.push(t.slice())
+ }
+ a = b
+ }
+ return neg
+}
+},{"robust-dot-product":136,"robust-sum":217}],136:[function(require,module,exports){
+"use strict"
+
+var twoProduct = require("two-product")
+var robustSum = require("robust-sum")
+
+module.exports = robustDotProduct
+
+function robustDotProduct(a, b) {
+ var r = twoProduct(a[0], b[0])
+ for(var i=1; i 0) {
+ var base = Math.round(Math.pow(10, y))
+ return Math.ceil(x/base) * base
+ }
+ return Math.ceil(x)
+}
+
+function defaultBool(x) {
+ if(typeof x === 'boolean') {
+ return x
+ }
+ return true
+}
+
+function createScene(options) {
+ options = options || {}
+
+ var stopped = false
+
+ var pixelRatio = options.pixelRatio || parseFloat(window.devicePixelRatio)
+
+ var canvas = options.canvas
+ if(!canvas) {
+ canvas = document.createElement('canvas')
+ if(options.container) {
+ var container = options.container
+ container.appendChild(canvas)
+ } else {
+ document.body.appendChild(canvas)
+ }
+ }
+
+ var gl = options.gl
+ if(!gl) {
+ gl = getContext(canvas,
+ options.glOptions || {
+ premultipliedAlpha: true,
+ antialias: true
+ })
+ }
+ if(!gl) {
+ throw new Error('webgl not supported')
+ }
+
+ //Initial bounds
+ var bounds = options.bounds || [[-10,-10,-10], [10,10,10]]
+
+ //Create selection
+ var selection = new MouseSelect()
+
+ //Accumulation buffer
+ var accumBuffer = createFBO(gl,
+ [gl.drawingBufferWidth, gl.drawingBufferHeight], {
+ preferFloat: true
+ })
+
+ var accumShader = createShader(gl)
+
+ //Create a camera
+ var cameraOptions = options.camera || {
+ eye: [2,0,0],
+ center: [0,0,0],
+ up: [0,1,0],
+ zoomMin: 0.1,
+ zoomMax: 100,
+ mode: 'turntable'
+ }
+
+ //Create axes
+ var axesOptions = options.axes || {}
+ var axes = createAxes(gl, axesOptions)
+ axes.enable = !axesOptions.disable
+
+ //Create spikes
+ var spikeOptions = options.spikes || {}
+ var spikes = createSpikes(gl, spikeOptions)
+
+ //Object list is empty initially
+ var objects = []
+ var pickBufferIds = []
+ var pickBufferCount = []
+ var pickBuffers = []
+
+ //Dirty flag, skip redraw if scene static
+ var dirty = true
+ var pickDirty = true
+
+ var projection = new Array(16)
+ var model = new Array(16)
+
+ var cameraParams = {
+ view: null,
+ projection: projection,
+ model: model
+ }
+
+ var pickDirty = true
+
+ var viewShape = [ gl.drawingBufferWidth, gl.drawingBufferHeight ]
+
+ //Create scene object
+ var scene = {
+ gl: gl,
+ contextLost: false,
+ pixelRatio: options.pixelRatio || parseFloat(window.devicePixelRatio),
+ canvas: canvas,
+ selection: selection,
+ camera: createCamera(canvas, cameraOptions),
+ axes: axes,
+ axesPixels: null,
+ spikes: spikes,
+ bounds: bounds,
+ objects: objects,
+ shape: viewShape,
+ aspect: options.aspectRatio || [1,1,1],
+ pickRadius: options.pickRadius || 10,
+ zNear: options.zNear || 0.01,
+ zFar: options.zFar || 1000,
+ fovy: options.fovy || Math.PI/4,
+ clearColor: options.clearColor || [0,0,0,0],
+ autoResize: defaultBool(options.autoResize),
+ autoBounds: defaultBool(options.autoBounds),
+ autoScale: !!options.autoScale,
+ autoCenter: defaultBool(options.autoCenter),
+ clipToBounds: defaultBool(options.clipToBounds),
+ snapToData: !!options.snapToData,
+ onselect: options.onselect || null,
+ onrender: options.onrender || null,
+ onclick: options.onclick || null,
+ cameraParams: cameraParams,
+ oncontextloss: null,
+ mouseListener: null
+ }
+
+ var pickShape = [ (gl.drawingBufferWidth/scene.pixelRatio)|0, (gl.drawingBufferHeight/scene.pixelRatio)|0 ]
+
+ function resizeListener() {
+ if(stopped) {
+ return
+ }
+ if(!scene.autoResize) {
+ return
+ }
+ var parent = canvas.parentNode
+ var width = 1
+ var height = 1
+ if(parent && parent !== document.body) {
+ width = parent.clientWidth
+ height = parent.clientHeight
+ } else {
+ width = window.innerWidth
+ height = window.innerHeight
+ }
+ var nextWidth = Math.ceil(width * scene.pixelRatio)|0
+ var nextHeight = Math.ceil(height * scene.pixelRatio)|0
+ if(nextWidth !== canvas.width || nextHeight !== canvas.height) {
+ canvas.width = nextWidth
+ canvas.height = nextHeight
+ var style = canvas.style
+ style.position = style.position || 'absolute'
+ style.left = '0px'
+ style.top = '0px'
+ style.width = width + 'px'
+ style.height = height + 'px'
+ dirty = true
+ }
+ }
+ if(scene.autoResize) {
+ resizeListener()
+ }
+ window.addEventListener('resize', resizeListener)
+
+ function reallocPickIds() {
+ var numObjs = objects.length
+ var numPick = pickBuffers.length
+ for(var i=0; i 0 && pickBufferCount[numPick-1] === 0) {
+ pickBufferCount.pop()
+ pickBuffers.pop().dispose()
+ }
+ }
+
+ scene.update = function(options) {
+ if(stopped) {
+ return
+ }
+ options = options || {}
+ dirty = true
+ pickDirty = true
+ }
+
+ scene.add = function(obj) {
+ if(stopped) {
+ return
+ }
+ obj.axes = axes
+ objects.push(obj)
+ pickBufferIds.push(-1)
+ dirty = true
+ pickDirty = true
+ reallocPickIds()
+ }
+
+ scene.remove = function(obj) {
+ if(stopped) {
+ return
+ }
+ var idx = objects.indexOf(obj)
+ if(idx < 0) {
+ return
+ }
+ objects.splice(idx, 1)
+ pickBufferIds.pop()
+ dirty = true
+ pickDirty = true
+ reallocPickIds()
+ }
+
+ scene.dispose = function() {
+ if(stopped) {
+ return
+ }
+
+ stopped = true
+
+ window.removeEventListener('resize', resizeListener)
+ canvas.removeEventListener('webglcontextlost', checkContextLoss)
+ scene.mouseListener.enabled = false
+
+ if(scene.contextLost) {
+ return
+ }
+
+ //Destroy objects
+ axes.dispose()
+ spikes.dispose()
+ for(var i=0; i selection.distance) {
+ continue
+ }
+ for(var j=0; j>(i*8)) & 0xff)
+ }
+
+ calcScales.call(this)
+
+ shader.bind()
+
+ shader.uniforms.pixelScale = PIXEL_SCALE
+ shader.uniforms.viewTransform = MATRIX
+ shader.uniforms.pickOffset = PICK_OFFSET
+
+ this.positionBuffer.bind()
+ shader.attributes.position.pointer()
+
+ this.offsetBuffer.bind()
+ shader.attributes.offset.pointer()
+
+ this.idBuffer.bind()
+ shader.attributes.id.pointer(gl.UNSIGNED_BYTE, false)
+
+ gl.drawArrays(gl.TRIANGLES, 0, numVertices)
+
+ return offset + this.numPoints
+ }
+})()
+
+proto.pick = function(x, y, value) {
+ var pickOffset = this.pickOffset
+ var pointCount = this.numPoints
+ if(value < pickOffset || value >= pickOffset + pointCount) {
+ return null
+ }
+ var pointId = value - pickOffset
+ var points = this.points
+ return {
+ object: this,
+ pointId: pointId,
+ dataCoord: [ points[2*pointId], points[2*pointId+1] ]
+ }
+}
+
+proto.update = function(options) {
+ options = options || {}
+
+ var positions = options.positions || []
+ var colors = options.colors || []
+ var glyphs = options.glyphs || []
+ var sizes = options.sizes || []
+ var borderWidths = options.borderWidths || []
+ var borderColors = options.borderColors || []
+
+ this.points = positions
+
+ var bounds = this.bounds = [Infinity, Infinity, -Infinity, -Infinity]
+ var numVertices = 0
+ for(var i=0; i> 1
+ for(var j=0; j<2; ++j) {
+ bounds[j] = Math.min(bounds[j], positions[2*i+j])
+ bounds[2+j] = Math.max(bounds[2+j], positions[2*i+j])
+ }
+ }
+
+ if(bounds[0] === bounds[2]) {
+ bounds[2] += 1
+ }
+ if(bounds[3] === bounds[1]) {
+ bounds[3] += 1
+ }
+
+ var sx = 1/(bounds[2] - bounds[0])
+ var sy = 1/(bounds[3] - bounds[1])
+ var tx = bounds[0]
+ var ty = bounds[1]
+
+ var v_position = pool.mallocFloat32(2 * numVertices)
+ var v_offset = pool.mallocFloat32(2 * numVertices)
+ var v_color = pool.mallocUint8(4 * numVertices)
+ var v_ids = pool.mallocUint32(numVertices)
+ var ptr = 0
+
+ for(var i=0; i 1.0) {\n discard;\n }\n vec4 baseColor = mix(borderColor, color, smoothStep(radius, centerFraction));\n float alpha = 1.0 - pow(1.0 - baseColor.a, fragWeight);\n gl_FragColor = vec4(baseColor.rgb * alpha, alpha);\n}\n"
+exports.pickVertex = "#define GLSLIFY 1\nprecision mediump float;\n\nattribute vec2 position;\nattribute vec4 pickId;\n\nuniform mat3 matrix;\nuniform float pointSize;\nuniform vec4 pickOffset;\n\nvarying vec4 fragId;\n\nvoid main() {\n vec3 hgPosition = matrix * vec3(position, 1);\n gl_Position = vec4(hgPosition.xy, 0, hgPosition.z);\n gl_PointSize = pointSize;\n\n vec4 id = pickId + pickOffset;\n id.y += floor(id.x / 256.0);\n id.x -= floor(id.x / 256.0) * 256.0;\n\n id.z += floor(id.y / 256.0);\n id.y -= floor(id.y / 256.0) * 256.0;\n\n id.w += floor(id.z / 256.0);\n id.z -= floor(id.z / 256.0) * 256.0;\n\n fragId = id;\n}\n"
+exports.pickFragment = "#define GLSLIFY 1\nprecision mediump float;\n\nvarying vec4 fragId;\n\nvoid main() {\n float radius = length(2.0*gl_PointCoord.xy-1.0);\n if(radius > 1.0) {\n discard;\n }\n gl_FragColor = fragId / 255.0;\n}\n"
+
+},{}],144:[function(require,module,exports){
+arguments[4][121][0].apply(exports,arguments)
+},{"dup":121}],145:[function(require,module,exports){
+'use strict'
+
+module.exports = sortLevels
+
+var INSERT_SORT_CUTOFF = 32
+
+function sortLevels(data_levels, data_points, data_ids, data_weights, n0) {
+ if (n0 <= 4*INSERT_SORT_CUTOFF) {
+ insertionSort(0, n0 - 1, data_levels, data_points, data_ids, data_weights)
+ } else {
+ quickSort(0, n0 - 1, data_levels, data_points, data_ids, data_weights)
+ }
+}
+
+function insertionSort(left, right, data_levels, data_points, data_ids, data_weights) {
+ for(var i=left+1; i<=right; ++i) {
+ var a_level = data_levels[i]
+ var a_x = data_points[2*i]
+ var a_y = data_points[2*i+1]
+ var a_id = data_ids[i]
+ var a_weight = data_weights[i]
+
+ var j = i
+ while(j > left) {
+ var b_level = data_levels[j-1]
+ var b_x = data_points[2*(j-1)]
+ if(((b_level - a_level) || (a_x - b_x)) >= 0) {
+ break
+ }
+ data_levels[j] = b_level
+ data_points[2*j] = b_x
+ data_points[2*j+1] = data_points[2*j-1]
+ data_ids[j] = data_ids[j-1]
+ data_weights[j] = data_weights[j-1]
+ j -= 1
+ }
+
+ data_levels[j] = a_level
+ data_points[2*j] = a_x
+ data_points[2*j+1] = a_y
+ data_ids[j] = a_id
+ data_weights[j] = a_weight
+ }
+}
+
+function swap(i, j, data_levels, data_points, data_ids, data_weights) {
+ var a_level = data_levels[i]
+ var a_x = data_points[2*i]
+ var a_y = data_points[2*i+1]
+ var a_id = data_ids[i]
+ var a_weight = data_weights[i]
+
+ data_levels[i] = data_levels[j]
+ data_points[2*i] = data_points[2*j]
+ data_points[2*i+1] = data_points[2*j+1]
+ data_ids[i] = data_ids[j]
+ data_weights[i] = data_weights[j]
+
+ data_levels[j] = a_level
+ data_points[2*j] = a_x
+ data_points[2*j+1] = a_y
+ data_ids[j] = a_id
+ data_weights[j] = a_weight
+}
+
+function move(i, j, data_levels, data_points, data_ids, data_weights) {
+ data_levels[i] = data_levels[j]
+ data_points[2*i] = data_points[2*j]
+ data_points[2*i+1] = data_points[2*j+1]
+ data_ids[i] = data_ids[j]
+ data_weights[i] = data_weights[j]
+}
+
+function rotate(i, j, k, data_levels, data_points, data_ids, data_weights) {
+ var a_level = data_levels[i]
+ var a_x = data_points[2*i]
+ var a_y = data_points[2*i+1]
+ var a_id = data_ids[i]
+ var a_weight = data_weights[i]
+
+ data_levels[i] = data_levels[j]
+ data_points[2*i] = data_points[2*j]
+ data_points[2*i+1] = data_points[2*j+1]
+ data_ids[i] = data_ids[j]
+ data_weights[i] = data_weights[j]
+
+ data_levels[j] = data_levels[k]
+ data_points[2*j] = data_points[2*k]
+ data_points[2*j+1] = data_points[2*k+1]
+ data_ids[j] = data_ids[k]
+ data_weights[j] = data_weights[k]
+
+ data_levels[k] = a_level
+ data_points[2*k] = a_x
+ data_points[2*k+1] = a_y
+ data_ids[k] = a_id
+ data_weights[k] = a_weight
+}
+
+function shufflePivot(
+ i, j,
+ a_level, a_x, a_y, a_id, a_weight,
+ data_levels, data_points, data_ids, data_weights) {
+
+ data_levels[i] = data_levels[j]
+ data_points[2*i] = data_points[2*j]
+ data_points[2*i+1] = data_points[2*j+1]
+ data_ids[i] = data_ids[j]
+ data_weights[i] = data_weights[j]
+
+ data_levels[j] = a_level
+ data_points[2*j] = a_x
+ data_points[2*j+1] = a_y
+ data_ids[j] = a_id
+ data_weights[j] = a_weight
+}
+
+function compare(i, j, data_levels, data_points, data_ids) {
+ return ((data_levels[i] - data_levels[j]) ||
+ (data_points[2*j] - data_points[2*i]) ||
+ (data_ids[i] - data_ids[j])) < 0
+}
+
+function comparePivot(i, level, x, y, id, data_levels, data_points, data_ids) {
+ return ((level - data_levels[i]) ||
+ (data_points[2*i] - x) ||
+ (id - data_ids[i])) < 0
+}
+
+function quickSort(left, right, data_levels, data_points, data_ids, data_weights) {
+ var sixth = (right - left + 1) / 6 | 0,
+ index1 = left + sixth,
+ index5 = right - sixth,
+ index3 = left + right >> 1,
+ index2 = index3 - sixth,
+ index4 = index3 + sixth,
+ el1 = index1,
+ el2 = index2,
+ el3 = index3,
+ el4 = index4,
+ el5 = index5,
+ less = left + 1,
+ great = right - 1,
+ tmp = 0
+ if(compare(el1, el2, data_levels, data_points, data_ids, data_weights)) {
+ tmp = el1
+ el1 = el2
+ el2 = tmp
+ }
+ if(compare(el4, el5, data_levels, data_points, data_ids, data_weights)) {
+ tmp = el4
+ el4 = el5
+ el5 = tmp
+ }
+ if(compare(el1, el3, data_levels, data_points, data_ids, data_weights)) {
+ tmp = el1
+ el1 = el3
+ el3 = tmp
+ }
+ if(compare(el2, el3, data_levels, data_points, data_ids, data_weights)) {
+ tmp = el2
+ el2 = el3
+ el3 = tmp
+ }
+ if(compare(el1, el4, data_levels, data_points, data_ids, data_weights)) {
+ tmp = el1
+ el1 = el4
+ el4 = tmp
+ }
+ if(compare(el3, el4, data_levels, data_points, data_ids, data_weights)) {
+ tmp = el3
+ el3 = el4
+ el4 = tmp
+ }
+ if(compare(el2, el5, data_levels, data_points, data_ids, data_weights)) {
+ tmp = el2
+ el2 = el5
+ el5 = tmp
+ }
+ if(compare(el2, el3, data_levels, data_points, data_ids, data_weights)) {
+ tmp = el2
+ el2 = el3
+ el3 = tmp
+ }
+ if(compare(el4, el5, data_levels, data_points, data_ids, data_weights)) {
+ tmp = el4
+ el4 = el5
+ el5 = tmp
+ }
+
+ var pivot1_level = data_levels[el2]
+ var pivot1_x = data_points[2*el2]
+ var pivot1_y = data_points[2*el2+1]
+ var pivot1_id = data_ids[el2]
+ var pivot1_weight = data_weights[el2]
+
+ var pivot2_level = data_levels[el4]
+ var pivot2_x = data_points[2*el4]
+ var pivot2_y = data_points[2*el4+1]
+ var pivot2_id = data_ids[el4]
+ var pivot2_weight = data_weights[el4]
+
+ var ptr0 = el1
+ var ptr2 = el3
+ var ptr4 = el5
+ var ptr5 = index1
+ var ptr6 = index3
+ var ptr7 = index5
+
+ var level_x = data_levels[ptr0]
+ var level_y = data_levels[ptr2]
+ var level_z = data_levels[ptr4]
+ data_levels[ptr5] = level_x
+ data_levels[ptr6] = level_y
+ data_levels[ptr7] = level_z
+
+ for (var i1 = 0; i1 < 2; ++i1) {
+ var x = data_points[2*ptr0+i1]
+ var y = data_points[2*ptr2+i1]
+ var z = data_points[2*ptr4+i1]
+ data_points[2*ptr5+i1] = x
+ data_points[2*ptr6+i1] = y
+ data_points[2*ptr7+i1] = z
+ }
+
+ var id_x = data_ids[ptr0]
+ var id_y = data_ids[ptr2]
+ var id_z = data_ids[ptr4]
+ data_ids[ptr5] = id_x
+ data_ids[ptr6] = id_y
+ data_ids[ptr7] = id_z
+
+ var weight_x = data_weights[ptr0]
+ var weight_y = data_weights[ptr2]
+ var weight_z = data_weights[ptr4]
+ data_weights[ptr5] = weight_x
+ data_weights[ptr6] = weight_y
+ data_weights[ptr7] = weight_z
+
+ move(index2, left, data_levels, data_points, data_ids, data_weights)
+ move(index4, right, data_levels, data_points, data_ids, data_weights)
+ for (var k = less; k <= great; ++k) {
+ if (comparePivot(k,
+ pivot1_level, pivot1_x, pivot1_y, pivot1_id,
+ data_levels, data_points, data_ids)) {
+ if (k !== less) {
+ swap(k, less, data_levels, data_points, data_ids, data_weights)
+ }
+ ++less;
+ } else {
+ if (!comparePivot(k,
+ pivot2_level, pivot2_x, pivot2_y, pivot2_id,
+ data_levels, data_points, data_ids)) {
+ while (true) {
+ if (!comparePivot(great,
+ pivot2_level, pivot2_x, pivot2_y, pivot2_id,
+ data_levels, data_points, data_ids)) {
+ if (--great < k) {
+ break;
+ }
+ continue;
+ } else {
+ if (comparePivot(great,
+ pivot1_level, pivot1_x, pivot1_y, pivot1_id,
+ data_levels, data_points, data_ids)) {
+ rotate(k, less, great, data_levels, data_points, data_ids, data_weights)
+ ++less;
+ --great;
+ } else {
+ swap(k, great, data_levels, data_points, data_ids, data_weights)
+ --great;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ shufflePivot(left, less-1, pivot1_level, pivot1_x, pivot1_y, pivot1_id, pivot1_weight, data_levels, data_points, data_ids, data_weights)
+ shufflePivot(right, great+1, pivot2_level, pivot2_x, pivot2_y, pivot2_id, pivot2_weight, data_levels, data_points, data_ids, data_weights)
+ if (less - 2 - left <= INSERT_SORT_CUTOFF) {
+ insertionSort(left, less - 2, data_levels, data_points, data_ids, data_weights)
+ } else {
+ quickSort(left, less - 2, data_levels, data_points, data_ids, data_weights)
+ }
+ if (right - (great + 2) <= INSERT_SORT_CUTOFF) {
+ insertionSort(great + 2, right, data_levels, data_points, data_ids, data_weights)
+ } else {
+ quickSort(great + 2, right, data_levels, data_points, data_ids, data_weights)
+ }
+ if (great - less <= INSERT_SORT_CUTOFF) {
+ insertionSort(less, great, data_levels, data_points, data_ids, data_weights)
+ } else {
+ quickSort(less, great, data_levels, data_points, data_ids, data_weights)
+ }
+}
+
+},{}],146:[function(require,module,exports){
+'use strict'
+
+var pool = require('typedarray-pool')
+
+var sortLevels = require('./lib/sort')
+
+module.exports = snapPoints
+
+function partition(points, ids, start, end, lox, loy, hix, hiy) {
+ var mid = start
+ for(var i=start; i>> 1
+ if(n < 1) {
+ return []
+ }
+
+ var lox = Infinity, loy = Infinity
+ var hix = -Infinity, hiy = -Infinity
+ for(var i=0; i= Math.max(0.9 * count, 32)) {
+ var mid = (end + start)>>>1
+ snapRec(nx, ny, diam_2, offset, mid, level+1)
+ offset = mid
+ }
+ snapRec(nx, ny, diam_2, offset, nextOffset, level+1)
+ offset = nextOffset
+ }
+ }
+ }
+ snapRec(lox, loy, diam, 0, n, 0)
+ sortLevels(levels, points, ids, weights, n)
+
+ var lod = []
+ var lastLevel = 0
+ var prevOffset = n
+ for(var ptr=n-1; ptr>=0; --ptr) {
+ points[2*ptr] = (points[2*ptr] - lox) * scaleX
+ points[2*ptr+1] = (points[2*ptr+1] - loy) * scaleY
+
+ var level = levels[ptr]
+ if(level === lastLevel) {
+ continue
+ }
+
+ lod.push(new SnapInterval(
+ diam * Math.pow(0.5, level),
+ ptr+1,
+ prevOffset - (ptr+1)
+ ))
+ prevOffset = ptr+1
+
+ lastLevel = level
+ }
+
+ lod.push(new SnapInterval(diam * Math.pow(0.5, level+1), 0, prevOffset))
+ pool.free(levels)
+
+ return lod
+}
+
+},{"./lib/sort":145,"typedarray-pool":233}],147:[function(require,module,exports){
+'use strict'
+
+var createShader = require('gl-shader')
+var createBuffer = require('gl-buffer')
+var bsearch = require('binary-search-bounds')
+var snapPoints = require('snap-points-2d')
+
+var pool = require('typedarray-pool')
+
+var SHADERS = require('./lib/shader')
+
+module.exports = createScatter2D
+
+function Scatter2D(plot, offsetBuffer, pickBuffer, weightBuffer, shader, pickShader) {
+ this.plot = plot
+ this.offsetBuffer = offsetBuffer
+ this.pickBuffer = pickBuffer
+ this.weightBuffer = weightBuffer
+ this.shader = shader
+ this.pickShader = pickShader
+ this.scales = []
+ this.size = 12.0
+ this.borderSize = 1.0
+ this.pointCount = 0
+ this.color = [1,0,0,1]
+ this.borderColor = [0,0,0,1]
+ this.bounds = [Infinity,Infinity,-Infinity,-Infinity]
+ this.pickOffset = 0
+ this.points = null
+ this.xCoords = null
+}
+
+var proto = Scatter2D.prototype
+
+proto.dispose = function() {
+ this.shader.dispose()
+ this.pickShader.dispose()
+ this.offsetBuffer.dispose()
+ this.pickBuffer.dispose()
+ if(this.xCoords) {
+ pool.free(this.xCoords)
+ }
+ this.plot.removeObject(this)
+}
+
+proto.update = function(options) {
+ options = options || {}
+
+ function dflt(opt, value) {
+ if(opt in options) {
+ return options[opt]
+ }
+ return value
+ }
+
+ this.size = dflt('size', 12.0)
+ this.color = dflt('color', [1,0,0,1]).slice()
+ this.borderSize = dflt('borderSize', 1)
+ this.borderColor = dflt('borderColor', [0,0,0,1]).slice()
+
+ //Update point data
+ if(this.xCoords) {
+ pool.free(this.xCoords)
+ }
+ var data = options.positions
+ var packed = pool.mallocFloat32(data.length)
+ var packedId = pool.mallocInt32(data.length>>>1)
+ packed.set(data)
+ var packedW = pool.mallocFloat32(data.length)
+ this.points = data
+ this.scales = snapPoints(packed, packedId, packedW, this.bounds)
+ this.offsetBuffer.update(packed)
+ this.pickBuffer.update(packedId)
+ this.weightBuffer.update(packedW)
+ var xCoords = pool.mallocFloat32(data.length>>>1)
+ for(var i=0,j=0; i>> 1
+ this.pickOffset = 0
+}
+
+proto.drawPick = (function() {
+ var MATRIX = [1,0,0,
+ 0,1,0,
+ 0,0,1]
+ var PICK_VEC4 = [0,0,0,0]
+return function(pickOffset) {
+ var plot = this.plot
+ var shader = this.pickShader
+ var scales = this.scales
+ var offsetBuffer = this.offsetBuffer
+ var pickBuffer = this.pickBuffer
+ var bounds = this.bounds
+ var size = this.size
+ var borderSize = this.borderSize
+ var gl = plot.gl
+ var pixelRatio = plot.pickPixelRatio
+ var viewBox = plot.viewBox
+ var dataBox = plot.dataBox
+
+ if(this.pointCount === 0) {
+ return pickOffset
+ }
+
+ var boundX = bounds[2] - bounds[0]
+ var boundY = bounds[3] - bounds[1]
+ var dataX = dataBox[2] - dataBox[0]
+ var dataY = dataBox[3] - dataBox[1]
+ var screenX = (viewBox[2] - viewBox[0]) * pixelRatio / plot.pixelRatio
+ var screenY = (viewBox[3] - viewBox[1]) * pixelRatio / plot.pixelRatio
+
+ var pixelSize = Math.min(dataX / screenX, dataY / screenY)
+ var targetScale = pixelSize
+
+
+ MATRIX[0] = 2.0 * boundX / dataX
+ MATRIX[4] = 2.0 * boundY / dataY
+ MATRIX[6] = 2.0 * (bounds[0] - dataBox[0]) / dataX - 1.0
+ MATRIX[7] = 2.0 * (bounds[1] - dataBox[1]) / dataY - 1.0
+
+ this.pickOffset = pickOffset
+ PICK_VEC4[0] = ( pickOffset & 0xff)
+ PICK_VEC4[1] = ((pickOffset>>8) & 0xff)
+ PICK_VEC4[2] = ((pickOffset>>16) & 0xff)
+ PICK_VEC4[3] = ((pickOffset>>24) & 0xff)
+
+ shader.bind()
+ shader.uniforms.matrix = MATRIX
+ shader.uniforms.color = this.color
+ shader.uniforms.borderColor = this.borderColor
+ shader.uniforms.pointSize = pixelRatio * (size + borderSize)
+ shader.uniforms.pickOffset = PICK_VEC4
+
+ if(this.borderSize === 0) {
+ shader.uniforms.centerFraction = 2.0;
+ } else {
+ shader.uniforms.centerFraction = size / (size + borderSize + 1.25)
+ }
+
+ offsetBuffer.bind()
+ shader.attributes.position.pointer()
+ pickBuffer.bind()
+ shader.attributes.pickId.pointer(gl.UNSIGNED_BYTE)
+
+ var xCoords = this.xCoords
+ var xStart = (dataBox[0] - bounds[0] - pixelSize * size * pixelRatio) / boundX
+ var xEnd = (dataBox[2] - bounds[0] + pixelSize * size * pixelRatio) / boundX
+
+ for(var scaleNum = scales.length-1; scaleNum >= 0; --scaleNum) {
+ var lod = scales[scaleNum]
+ if(lod.pixelSize < pixelSize && scaleNum > 1) {
+ continue
+ }
+
+ var intervalStart = lod.offset
+ var intervalEnd = lod.count + intervalStart
+
+ var startOffset = bsearch.ge(xCoords, xStart, intervalStart, intervalEnd-1)
+ var endOffset = bsearch.lt(xCoords, xEnd, startOffset, intervalEnd-1)+1
+
+ gl.drawArrays(gl.POINTS, startOffset, endOffset - startOffset)
+ }
+
+ return pickOffset + this.pointCount
+}
+})()
+
+proto.draw = (function() {
+ var MATRIX = [1, 0, 0,
+ 0, 1, 0,
+ 0, 0, 1]
+
+ return function() {
+ var plot = this.plot
+ var shader = this.shader
+ var scales = this.scales
+ var offsetBuffer = this.offsetBuffer
+ var bounds = this.bounds
+ var size = this.size
+ var borderSize = this.borderSize
+ var gl = plot.gl
+ var pixelRatio = plot.pixelRatio
+ var viewBox = plot.viewBox
+ var dataBox = plot.dataBox
+
+ if(this.pointCount === 0) {
+ return
+ }
+
+ var boundX = bounds[2] - bounds[0]
+ var boundY = bounds[3] - bounds[1]
+ var dataX = dataBox[2] - dataBox[0]
+ var dataY = dataBox[3] - dataBox[1]
+ var screenX = viewBox[2] - viewBox[0]
+ var screenY = viewBox[3] - viewBox[1]
+
+ var pixelSize = Math.min(dataX / screenX, dataY / screenY)
+ var targetScale = pixelSize
+
+ MATRIX[0] = 2.0 * boundX / dataX
+ MATRIX[4] = 2.0 * boundY / dataY
+ MATRIX[6] = 2.0 * (bounds[0] - dataBox[0]) / dataX - 1.0
+ MATRIX[7] = 2.0 * (bounds[1] - dataBox[1]) / dataY - 1.0
+
+ shader.bind()
+ shader.uniforms.matrix = MATRIX
+ shader.uniforms.color = this.color
+ shader.uniforms.borderColor = this.borderColor
+ shader.uniforms.pointSize = pixelRatio * (size + borderSize)
+ shader.uniforms.useWeight = 1
+
+ if(this.borderSize === 0) {
+ shader.uniforms.centerFraction = 2.0;
+ } else {
+ shader.uniforms.centerFraction = size / (size + borderSize + 1.25)
+ }
+
+ offsetBuffer.bind()
+ shader.attributes.position.pointer()
+
+ this.weightBuffer.bind()
+ shader.attributes.weight.pointer()
+
+ var xCoords = this.xCoords
+ var xStart = (dataBox[0] - bounds[0] - pixelSize * size * pixelRatio) / boundX
+ var xEnd = (dataBox[2] - bounds[0] + pixelSize * size * pixelRatio) / boundX
+
+ var firstLevel = true
+
+ for(var scaleNum = scales.length-1; scaleNum >= 0; --scaleNum) {
+ var lod = scales[scaleNum]
+ if(lod.pixelSize < pixelSize && scaleNum > 1) {
+ continue
+ }
+
+ var intervalStart = lod.offset
+ var intervalEnd = lod.count + intervalStart
+
+ var startOffset = bsearch.ge(xCoords, xStart, intervalStart, intervalEnd-1)
+ var endOffset = bsearch.lt(xCoords, xEnd, startOffset, intervalEnd-1)+1
+
+ gl.drawArrays(gl.POINTS, startOffset, endOffset - startOffset)
+
+ if(firstLevel) {
+ firstLevel = false
+ shader.uniforms.useWeight = 0
+ }
+ }
+ }
+})()
+
+proto.pick = function(x, y, value) {
+ var pickOffset = this.pickOffset
+ var pointCount = this.pointCount
+ if(value < pickOffset || value >= pickOffset + pointCount) {
+ return null
+ }
+ var pointId = value - pickOffset
+ var points = this.points
+ return {
+ object: this,
+ pointId: pointId,
+ dataCoord: [ points[2*pointId], points[2*pointId+1] ]
+ }
+}
+
+function createScatter2D(plot, options) {
+ var gl = plot.gl
+ var buffer = createBuffer(gl)
+ var pickBuffer = createBuffer(gl)
+ var weightBuffer = createBuffer(gl)
+ var shader = createShader(gl, SHADERS.pointVertex, SHADERS.pointFragment)
+ var pickShader = createShader(gl, SHADERS.pickVertex, SHADERS.pickFragment)
+
+ var result = new Scatter2D(
+ plot, buffer, pickBuffer, weightBuffer, shader, pickShader)
+ result.update(options)
+
+ //Register with plot
+ plot.addObject(result)
+
+ return result
+}
+
+},{"./lib/shader":143,"binary-search-bounds":144,"gl-buffer":75,"gl-shader":154,"snap-points-2d":146,"typedarray-pool":233}],148:[function(require,module,exports){
+"use strict"
+
+var vectorizeText = require("vectorize-text")
+
+module.exports = getGlyph
+
+var GLYPH_CACHE = {}
+
+function getGlyph(symbol, font) {
+ var fontCache = GLYPH_CACHE[font]
+ if(!fontCache) {
+ fontCache = GLYPH_CACHE[font] = {}
+ }
+ if(symbol in fontCache) {
+ return fontCache[symbol]
+ }
+
+ //Get line and triangle meshes for glyph
+ var lineSymbol = vectorizeText(symbol, {
+ textAlign: "center",
+ textBaseline: "middle",
+ lineHeight: 1.0,
+ font: font
+ })
+ var triSymbol = vectorizeText(symbol, {
+ triangles: true,
+ textAlign: "center",
+ textBaseline: "middle",
+ lineHeight: 1.0,
+ font: font
+ })
+
+ //Calculate bounding box
+ var bounds = [[Infinity,Infinity], [-Infinity,-Infinity]]
+ for(var i=0; i= 1) {
+ return true
+ }
+ for(var i=0; i<3; ++i) {
+ if(this.axesProject[i] && this.projectOpacity[i] >= 1) {
+ return true
+ }
+ }
+ return false
+}
+
+var VIEW_SHAPE = [0,0]
+var U_VEC = [0,0,0]
+var V_VEC = [0,0,0]
+var MU_VEC = [0,0,0,1]
+var MV_VEC = [0,0,0,1]
+var SCRATCH_MATRIX = IDENTITY.slice()
+var SCRATCH_VEC = [0,0,0]
+var CLIP_BOUNDS = [[0,0,0], [0,0,0]]
+
+function zeroVec(a) {
+ a[0] = a[1] = a[2] = 0
+ return a
+}
+
+function augment(hg, af) {
+ hg[0] = af[0]
+ hg[1] = af[1]
+ hg[2] = af[2]
+ hg[3] = 1
+ return hg
+}
+
+function setComponent(out, v, i, x) {
+ out[0] = v[0]
+ out[1] = v[1]
+ out[2] = v[2]
+ out[i] = x
+ return out
+}
+
+function getClipBounds(bounds) {
+ var result = CLIP_BOUNDS
+ for(var i=0; i<2; ++i) {
+ for(var j=0; j<3; ++j) {
+ result[i][j] = Math.max(Math.min(bounds[i][j], 1e8), -1e8)
+ }
+ }
+ return result
+}
+
+function drawProject(shader, points, camera, transparent, forceDraw) {
+ var axesProject = points.axesProject
+
+ var gl = points.gl
+ var uniforms = shader.uniforms
+ var model = camera.model || IDENTITY
+ var view = camera.view || IDENTITY
+ var projection = camera.projection || IDENTITY
+ var bounds = points.axesBounds
+ var clipBounds = getClipBounds(points.clipBounds)
+
+ var cubeAxis
+ if(points.axes) {
+ cubeAxis = points.axes.lastCubeProps.axis
+ } else {
+ cubeAxis = [1,1,1]
+ }
+
+ VIEW_SHAPE[0] = 2.0/gl.drawingBufferWidth
+ VIEW_SHAPE[1] = 2.0/gl.drawingBufferHeight
+
+ shader.bind()
+ uniforms.view = view
+ uniforms.projection = projection
+ uniforms.screenSize = VIEW_SHAPE
+ uniforms.highlightId = points.highlightId
+ uniforms.highlightScale = points.highlightScale
+ uniforms.clipBounds = clipBounds
+ uniforms.pickGroup = points.pickId / 255.0
+ uniforms.pixelRatio = points.pixelRatio
+
+ for(var i=0; i<3; ++i) {
+ if(!axesProject[i]) {
+ continue
+ }
+ if((points.projectOpacity[i] < 1) !== transparent) {
+ continue
+ }
+
+ uniforms.scale = points.projectScale[i]
+ uniforms.opacity = points.projectOpacity[i]
+
+ //Project model matrix
+ var pmodel = SCRATCH_MATRIX
+ for(var j=0; j<16; ++j) {
+ pmodel[j] = 0
+ }
+ for(var j=0; j<4; ++j) {
+ pmodel[5*j] = 1
+ }
+ pmodel[5*i] = 0
+ if(cubeAxis[i] < 0) {
+ pmodel[12+i] = bounds[0][i]
+ } else {
+ pmodel[12+i] = bounds[1][i]
+ }
+ mat4mult(pmodel, model, pmodel)
+ uniforms.model = pmodel
+
+ //Compute initial axes
+ var u = (i+1)%3
+ var v = (i+2)%3
+ var du = zeroVec(U_VEC)
+ var dv = zeroVec(V_VEC)
+ du[u] = 1
+ dv[v] = 1
+
+ //Align orientation relative to viewer
+ var mdu = project(projection, view, model, augment(MU_VEC, du))
+ var mdv = project(projection, view, model, augment(MV_VEC, dv))
+ if(Math.abs(mdu[1]) > Math.abs(mdv[1])) {
+ var tmp = mdu
+ mdu = mdv
+ mdv = tmp
+ tmp = du
+ du = dv
+ dv = tmp
+ var t = u
+ u = v
+ v = t
+ }
+ if(mdu[0] < 0) {
+ du[u] = -1
+ }
+ if(mdv[1] > 0) {
+ dv[v] = -1
+ }
+ var su = 0.0
+ var sv = 0.0
+ for(var j=0; j<4; ++j) {
+ su += Math.pow(model[4*u+j], 2)
+ sv += Math.pow(model[4*v+j], 2)
+ }
+ du[u] /= Math.sqrt(su)
+ dv[v] /= Math.sqrt(sv)
+ uniforms.axes[0] = du
+ uniforms.axes[1] = dv
+
+ //Update fragment clip bounds
+ uniforms.fragClipBounds[0] = setComponent(SCRATCH_VEC, clipBounds[0], i, -1e8)
+ uniforms.fragClipBounds[1] = setComponent(SCRATCH_VEC, clipBounds[1], i, 1e8)
+
+ //Draw interior
+ points.vao.draw(gl.TRIANGLES, points.vertexCount)
+
+ //Draw edges
+ if(points.lineWidth > 0) {
+ gl.lineWidth(points.lineWidth)
+ points.vao.draw(gl.LINES, points.lineVertexCount, points.vertexCount)
+ }
+ }
+}
+
+
+var NEG_INFINITY3 = [-1e8, -1e8, -1e8]
+var POS_INFINITY3 = [1e8, 1e8, 1e8]
+var CLIP_GROUP = [NEG_INFINITY3, POS_INFINITY3]
+
+function drawFull(shader, pshader, points, camera, transparent, forceDraw) {
+ var gl = points.gl
+
+ points.vao.bind()
+
+ if(transparent === (points.opacity < 1) || forceDraw) {
+ shader.bind()
+ var uniforms = shader.uniforms
+
+ uniforms.model = camera.model || IDENTITY
+ uniforms.view = camera.view || IDENTITY
+ uniforms.projection = camera.projection || IDENTITY
+
+ VIEW_SHAPE[0] = 2.0/gl.drawingBufferWidth
+ VIEW_SHAPE[1] = 2.0/gl.drawingBufferHeight
+ uniforms.screenSize = VIEW_SHAPE
+
+ uniforms.highlightId = points.highlightId
+ uniforms.highlightScale = points.highlightScale
+
+ uniforms.fragClipBounds = CLIP_GROUP
+ uniforms.clipBounds = points.axes.bounds
+
+ uniforms.opacity = points.opacity
+ uniforms.pickGroup = points.pickId / 255.0
+
+ uniforms.pixelRatio = points.pixelRatio
+
+ //Draw interior
+ points.vao.draw(gl.TRIANGLES, points.vertexCount)
+
+ //Draw edges
+ if(points.lineWidth > 0) {
+ gl.lineWidth(points.lineWidth)
+ points.vao.draw(gl.LINES, points.lineVertexCount, points.vertexCount)
+ }
+ }
+
+ drawProject(pshader, points, camera, transparent, forceDraw)
+
+ points.vao.unbind()
+}
+
+proto.draw = function(camera) {
+ var shader = this.useOrtho ? this.orthoShader : this.shader
+ drawFull(shader, this.projectShader, this, camera, false, false)
+}
+
+proto.drawTransparent = function(camera) {
+ var shader = this.useOrtho ? this.orthoShader : this.shader
+ drawFull(shader, this.projectShader, this, camera, true, false)
+}
+
+proto.drawPick = function(camera) {
+ var shader = this.useOrtho ? this.pickOrthoShader : this.pickPerspectiveShader
+ drawFull(shader, this.pickProjectShader, this, camera, false, true)
+}
+
+proto.pick = function(selected) {
+ if(!selected) {
+ return null
+ }
+ if(selected.id !== this.pickId) {
+ return null
+ }
+ var x = selected.value[2] + (selected.value[1]<<8) + (selected.value[0]<<16)
+ if(x >= this.pointCount || x < 0) {
+ return null
+ }
+
+ //Unpack result
+ var coord = this.points[x]
+ var result = this._selectResult
+ result.index = x
+ for(var i=0; i<3; ++i) {
+ result.position[i] = result.dataCoordinate[i] = coord[i]
+ }
+ return result
+}
+
+proto.highlight = function(selection) {
+ if(!selection) {
+ this.highlightId = [1,1,1,1]
+ } else {
+ var pointId = selection.index
+ var a0 = pointId &0xff
+ var a1 = (pointId>>8) &0xff
+ var a2 = (pointId>>16)&0xff
+ this.highlightId = [a0/255.0, a1/255.0, a2/255.0, 0]
+ }
+}
+
+proto.update = function(options) {
+
+ options = options || {}
+
+ if('perspective' in options) {
+ this.useOrtho = !options.perspective
+ }
+ if('orthographic' in options) {
+ this.useOrtho = !!options.orthographic
+ }
+ if('lineWidth' in options) {
+ this.lineWidth = options.lineWidth
+ }
+ if('project' in options) {
+ if(Array.isArray(options.project)) {
+ this.axesProject = options.project
+ } else {
+ var v = !!options.project
+ this.axesProject = [v,v,v]
+ }
+ }
+ if('projectScale' in options) {
+ if(Array.isArray(options.projectScale)) {
+ this.projectScale = options.projectScale.slice()
+ } else {
+ var s = +options.projectScale
+ this.projectScale = [s,s,s]
+ }
+ }
+ if('projectOpacity' in options) {
+ if(Array.isArray(options.projectOpacity)) {
+ this.projectOpacity = options.projectOpacity.slice()
+ } else {
+ var s = +options.projectOpacity
+ this.projectOpacity = [s,s,s]
+ }
+ }
+ if('opacity' in options) {
+ this.opacity = options.opacity
+ }
+
+ //Set dirty flag
+ this.dirty = true
+
+ //Create new buffers
+ var points = options.position
+ if(!points) {
+ return
+ }
+
+ //Text font
+ var font = options.font || 'normal'
+ var alignment = options.alignment || [0,0]
+
+ //Bounds
+ var lowerBound = [ Infinity, Infinity, Infinity]
+ var upperBound = [-Infinity,-Infinity,-Infinity]
+
+ //Unpack options
+ var glyphs = options.glyph
+ var colors = options.color
+ var sizes = options.size
+ var angles = options.angle
+ var lineColors = options.lineColor
+
+ //Picking geometry
+ var pickCounter = 0
+
+ //First do pass to compute buffer sizes
+ var triVertexCount = 0
+ var lineVertexCount = 0
+
+ //Count number of points and buffer size
+ var numPoints = points.length
+
+count_loop:
+ for(var i=0; i 0) {
+ textOffset[0] = -alignment[0] * (1+glyphBounds[0][0])
+ }
+
+ //Write out inner marker
+ var cells = glyphMesh.cells
+ var verts = glyphMesh.positions
+
+ for(var j=0; j 0) {
+
+ //Draw border
+ var w = lineWidth * pixelRatio
+ boxes.drawBox(loX-w, loY-w, hiX+w, loY+w, borderColor)
+ boxes.drawBox(loX-w, hiY-w, hiX+w, hiY+w, borderColor)
+ boxes.drawBox(loX-w, loY-w, loX+w, hiY+w, borderColor)
+ boxes.drawBox(hiX-w, loY-w, hiX+w, hiY+w, borderColor)
+ }
+}
+
+proto.update = function(options) {
+ options = options || {}
+
+ this.innerFill = !!options.innerFill
+ this.outerFill = !!options.outerFill
+ this.innerColor = (options.innerColor || [0,0,0,0.5]).slice()
+ this.outerColor = (options.outerColor || [0,0,0,0.5]).slice()
+ this.borderColor = (options.borderColor || [0,0,0,1]).slice()
+ this.borderWidth = options.borderWidth || 0
+ this.selectBox = (options.selectBox || this.selectBox).slice()
+}
+
+proto.dispose = function() {
+ this.boxBuffer.dispose()
+ this.boxShader.dispose()
+ this.plot.removeOverlay(this)
+}
+
+function createSelectBox(plot, options) {
+ var gl = plot.gl
+ var buffer = createBuffer(gl, [
+ 0, 0,
+ 0, 1,
+ 1, 0,
+ 1, 1 ])
+ var shader = createShader(gl, SHADERS.boxVertex, SHADERS.boxFragment)
+ var selectBox = new SelectBox(plot, buffer, shader)
+ selectBox.update(options)
+ plot.addOverlay(selectBox)
+ return selectBox
+}
+
+},{"./lib/shaders":151,"gl-buffer":75,"gl-shader":154}],153:[function(require,module,exports){
+'use strict'
+
+module.exports = createSelectBuffer
+
+var createFBO = require('gl-fbo')
+var pool = require('typedarray-pool')
+var ndarray = require('ndarray')
+
+var nextPow2 = require('bit-twiddle').nextPow2
+
+var selectRange = require('cwise/lib/wrapper')({"args":["array",{"offset":[0,0,1],"array":0},{"offset":[0,0,2],"array":0},{"offset":[0,0,3],"array":0},"scalar","scalar","index"],"pre":{"body":"{this_closestD2=1e8,this_closestX=-1,this_closestY=-1}","args":[],"thisVars":["this_closestD2","this_closestX","this_closestY"],"localVars":[]},"body":{"body":"{if(255>_inline_31_arg0_||255>_inline_31_arg1_||255>_inline_31_arg2_||255>_inline_31_arg3_){var _inline_31_l=_inline_31_arg4_-_inline_31_arg6_[0],_inline_31_a=_inline_31_arg5_-_inline_31_arg6_[1],_inline_31_f=_inline_31_l*_inline_31_l+_inline_31_a*_inline_31_a;_inline_31_f this.buffer.length) {
+ pool.free(this.buffer)
+ var buffer = this.buffer = pool.mallocUint8(nextPow2(r*c*4))
+ for(var i=0; i= 0) {
+ var size = attr.type.charAt(attr.type.length-1)|0
+ var locVector = new Array(size)
+ for(var j=0; j= 0) {
+ curLocation += 1
+ }
+ attributeLocations[i] = curLocation
+ }
+ }
+
+ //Rebuild program and recompute all uniform locations
+ var uniformLocations = new Array(uniforms.length)
+ function relink() {
+ wrapper.program = shaderCache.program(
+ gl
+ , wrapper._vref
+ , wrapper._fref
+ , attributeNames
+ , attributeLocations)
+
+ for(var i=0; i= 0) {
+ var d = type.charCodeAt(type.length-1) - 48
+ if(d < 2 || d > 4) {
+ throw new GLError('', 'Invalid data type for attribute ' + name + ': ' + type)
+ }
+ addVectorAttribute(
+ gl
+ , wrapper
+ , locs[0]
+ , locations
+ , d
+ , obj
+ , name)
+ } else if(type.indexOf('mat') >= 0) {
+ var d = type.charCodeAt(type.length-1) - 48
+ if(d < 2 || d > 4) {
+ throw new GLError('', 'Invalid data type for attribute ' + name + ': ' + type)
+ }
+ addMatrixAttribute(
+ gl
+ , wrapper
+ , locs
+ , locations
+ , d
+ , obj
+ , name)
+ } else {
+ throw new GLError('', 'Unknown data type for attribute ' + name + ': ' + type)
+ }
+ break
+ }
+ }
+ return obj
+}
+
+},{"./GLError":155}],157:[function(require,module,exports){
+'use strict'
+
+var coallesceUniforms = require('./reflect')
+var GLError = require("./GLError")
+
+module.exports = createUniformWrapper
+
+//Binds a function and returns a value
+function identity(x) {
+ var c = new Function('y', 'return function(){return y}')
+ return c(x)
+}
+
+function makeVector(length, fill) {
+ var result = new Array(length)
+ for(var i=0; i 4) {
+ throw new GLError('', 'Invalid data type')
+ }
+ switch(type.charAt(0)) {
+ case 'b':
+ case 'i':
+ return 'gl.uniform' + d + 'iv(locations[' + index + '],obj' + path + ')'
+ case 'v':
+ return 'gl.uniform' + d + 'fv(locations[' + index + '],obj' + path + ')'
+ default:
+ throw new GLError('', 'Unrecognized data type for vector ' + name + ': ' + type)
+ }
+ } else if(type.indexOf('mat') === 0 && type.length === 4) {
+ var d = type.charCodeAt(type.length-1) - 48
+ if(d < 2 || d > 4) {
+ throw new GLError('', 'Invalid uniform dimension type for matrix ' + name + ': ' + type)
+ }
+ return 'gl.uniformMatrix' + d + 'fv(locations[' + index + '],false,obj' + path + ')'
+ } else {
+ throw new GLError('', 'Unknown uniform data type for ' + name + ': ' + type)
+ }
+ break
+ }
+ }
+
+ function enumerateIndices(prefix, type) {
+ if(typeof type !== 'object') {
+ return [ [prefix, type] ]
+ }
+ var indices = []
+ for(var id in type) {
+ var prop = type[id]
+ var tprefix = prefix
+ if(parseInt(id) + '' === id) {
+ tprefix += '[' + id + ']'
+ } else {
+ tprefix += '.' + id
+ }
+ if(typeof prop === 'object') {
+ indices.push.apply(indices, enumerateIndices(tprefix, prop))
+ } else {
+ indices.push([tprefix, prop])
+ }
+ }
+ return indices
+ }
+
+ function makeSetter(type) {
+ var code = [ 'return function updateProperty(obj){' ]
+ var indices = enumerateIndices('', type)
+ for(var i=0; i 4) {
+ throw new GLError('', 'Invalid data type')
+ }
+ if(type.charAt(0) === 'b') {
+ return makeVector(d, false)
+ }
+ return makeVector(d, 0)
+ } else if(type.indexOf('mat') === 0 && type.length === 4) {
+ var d = type.charCodeAt(type.length-1) - 48
+ if(d < 2 || d > 4) {
+ throw new GLError('', 'Invalid uniform dimension type for matrix ' + name + ': ' + type)
+ }
+ return makeVector(d*d, 0)
+ } else {
+ throw new GLError('', 'Unknown uniform data type for ' + name + ': ' + type)
+ }
+ break
+ }
+ }
+
+ function storeProperty(obj, prop, type) {
+ if(typeof type === 'object') {
+ var child = processObject(type)
+ Object.defineProperty(obj, prop, {
+ get: identity(child),
+ set: makeSetter(type),
+ enumerable: true,
+ configurable: false
+ })
+ } else {
+ if(locations[type]) {
+ Object.defineProperty(obj, prop, {
+ get: makeGetter(type),
+ set: makeSetter(type),
+ enumerable: true,
+ configurable: false
+ })
+ } else {
+ obj[prop] = defaultValue(uniforms[type].type)
+ }
+ }
+ }
+
+ function processObject(obj) {
+ var result
+ if(Array.isArray(obj)) {
+ result = new Array(obj.length)
+ for(var i=0; i 1) {
+ if(!(x[0] in o)) {
+ o[x[0]] = []
+ }
+ o = o[x[0]]
+ for(var k=1; k 1) {
+ for(var j=0; j
+ *
+ * Copyright (c) 2014-2015, Jon Schlinkert.
+ * Licensed under the MIT license.
+ */
+
+'use strict';
+
+var repeat = require('repeat-string');
+
+module.exports = function padLeft(str, num, ch) {
+ ch = typeof ch !== 'undefined' ? (ch + '') : ' ';
+ return repeat(ch, num) + str;
+};
+},{"repeat-string":164}],164:[function(require,module,exports){
+/*!
+ * repeat-string
+ *
+ * Copyright (c) 2014-2015, Jon Schlinkert.
+ * Licensed under the MIT License.
+ */
+
+'use strict';
+
+/**
+ * Expose `repeat`
+ */
+
+module.exports = repeat;
+
+/**
+ * Repeat the given `string` the specified `number`
+ * of times.
+ *
+ * **Example:**
+ *
+ * ```js
+ * var repeat = require('repeat-string');
+ * repeat('A', 5);
+ * //=> AAAAA
+ * ```
+ *
+ * @param {String} `string` The string to repeat
+ * @param {Number} `number` The number of times to repeat the string
+ * @return {String} Repeated string
+ * @api public
+ */
+
+function repeat(str, num) {
+ if (typeof str !== 'string') {
+ throw new TypeError('repeat-string expects a string.');
+ }
+
+ if (num === 1) return str;
+ if (num === 2) return str + str;
+
+ var max = str.length * num;
+ if (cache !== str || typeof cache === 'undefined') {
+ cache = str;
+ res = '';
+ }
+
+ while (max > res.length && num > 0) {
+ if (num & 1) {
+ res += str;
+ }
+
+ num >>= 1;
+ if (!num) break;
+ str += str;
+ }
+
+ return res.substr(0, max);
+}
+
+/**
+ * Results cache
+ */
+
+var res = '';
+var cache;
+
+},{}],165:[function(require,module,exports){
+module.exports = {
+ 0: 'NONE',
+ 1: 'ONE',
+ 2: 'LINE_LOOP',
+ 3: 'LINE_STRIP',
+ 4: 'TRIANGLES',
+ 5: 'TRIANGLE_STRIP',
+ 6: 'TRIANGLE_FAN',
+ 256: 'DEPTH_BUFFER_BIT',
+ 512: 'NEVER',
+ 513: 'LESS',
+ 514: 'EQUAL',
+ 515: 'LEQUAL',
+ 516: 'GREATER',
+ 517: 'NOTEQUAL',
+ 518: 'GEQUAL',
+ 519: 'ALWAYS',
+ 768: 'SRC_COLOR',
+ 769: 'ONE_MINUS_SRC_COLOR',
+ 770: 'SRC_ALPHA',
+ 771: 'ONE_MINUS_SRC_ALPHA',
+ 772: 'DST_ALPHA',
+ 773: 'ONE_MINUS_DST_ALPHA',
+ 774: 'DST_COLOR',
+ 775: 'ONE_MINUS_DST_COLOR',
+ 776: 'SRC_ALPHA_SATURATE',
+ 1024: 'STENCIL_BUFFER_BIT',
+ 1028: 'FRONT',
+ 1029: 'BACK',
+ 1032: 'FRONT_AND_BACK',
+ 1280: 'INVALID_ENUM',
+ 1281: 'INVALID_VALUE',
+ 1282: 'INVALID_OPERATION',
+ 1285: 'OUT_OF_MEMORY',
+ 1286: 'INVALID_FRAMEBUFFER_OPERATION',
+ 2304: 'CW',
+ 2305: 'CCW',
+ 2849: 'LINE_WIDTH',
+ 2884: 'CULL_FACE',
+ 2885: 'CULL_FACE_MODE',
+ 2886: 'FRONT_FACE',
+ 2928: 'DEPTH_RANGE',
+ 2929: 'DEPTH_TEST',
+ 2930: 'DEPTH_WRITEMASK',
+ 2931: 'DEPTH_CLEAR_VALUE',
+ 2932: 'DEPTH_FUNC',
+ 2960: 'STENCIL_TEST',
+ 2961: 'STENCIL_CLEAR_VALUE',
+ 2962: 'STENCIL_FUNC',
+ 2963: 'STENCIL_VALUE_MASK',
+ 2964: 'STENCIL_FAIL',
+ 2965: 'STENCIL_PASS_DEPTH_FAIL',
+ 2966: 'STENCIL_PASS_DEPTH_PASS',
+ 2967: 'STENCIL_REF',
+ 2968: 'STENCIL_WRITEMASK',
+ 2978: 'VIEWPORT',
+ 3024: 'DITHER',
+ 3042: 'BLEND',
+ 3088: 'SCISSOR_BOX',
+ 3089: 'SCISSOR_TEST',
+ 3106: 'COLOR_CLEAR_VALUE',
+ 3107: 'COLOR_WRITEMASK',
+ 3317: 'UNPACK_ALIGNMENT',
+ 3333: 'PACK_ALIGNMENT',
+ 3379: 'MAX_TEXTURE_SIZE',
+ 3386: 'MAX_VIEWPORT_DIMS',
+ 3408: 'SUBPIXEL_BITS',
+ 3410: 'RED_BITS',
+ 3411: 'GREEN_BITS',
+ 3412: 'BLUE_BITS',
+ 3413: 'ALPHA_BITS',
+ 3414: 'DEPTH_BITS',
+ 3415: 'STENCIL_BITS',
+ 3553: 'TEXTURE_2D',
+ 4352: 'DONT_CARE',
+ 4353: 'FASTEST',
+ 4354: 'NICEST',
+ 5120: 'BYTE',
+ 5121: 'UNSIGNED_BYTE',
+ 5122: 'SHORT',
+ 5123: 'UNSIGNED_SHORT',
+ 5124: 'INT',
+ 5125: 'UNSIGNED_INT',
+ 5126: 'FLOAT',
+ 5386: 'INVERT',
+ 5890: 'TEXTURE',
+ 6401: 'STENCIL_INDEX',
+ 6402: 'DEPTH_COMPONENT',
+ 6406: 'ALPHA',
+ 6407: 'RGB',
+ 6408: 'RGBA',
+ 6409: 'LUMINANCE',
+ 6410: 'LUMINANCE_ALPHA',
+ 7680: 'KEEP',
+ 7681: 'REPLACE',
+ 7682: 'INCR',
+ 7683: 'DECR',
+ 7936: 'VENDOR',
+ 7937: 'RENDERER',
+ 7938: 'VERSION',
+ 9728: 'NEAREST',
+ 9729: 'LINEAR',
+ 9984: 'NEAREST_MIPMAP_NEAREST',
+ 9985: 'LINEAR_MIPMAP_NEAREST',
+ 9986: 'NEAREST_MIPMAP_LINEAR',
+ 9987: 'LINEAR_MIPMAP_LINEAR',
+ 10240: 'TEXTURE_MAG_FILTER',
+ 10241: 'TEXTURE_MIN_FILTER',
+ 10242: 'TEXTURE_WRAP_S',
+ 10243: 'TEXTURE_WRAP_T',
+ 10497: 'REPEAT',
+ 10752: 'POLYGON_OFFSET_UNITS',
+ 16384: 'COLOR_BUFFER_BIT',
+ 32769: 'CONSTANT_COLOR',
+ 32770: 'ONE_MINUS_CONSTANT_COLOR',
+ 32771: 'CONSTANT_ALPHA',
+ 32772: 'ONE_MINUS_CONSTANT_ALPHA',
+ 32773: 'BLEND_COLOR',
+ 32774: 'FUNC_ADD',
+ 32777: 'BLEND_EQUATION_RGB',
+ 32778: 'FUNC_SUBTRACT',
+ 32779: 'FUNC_REVERSE_SUBTRACT',
+ 32819: 'UNSIGNED_SHORT_4_4_4_4',
+ 32820: 'UNSIGNED_SHORT_5_5_5_1',
+ 32823: 'POLYGON_OFFSET_FILL',
+ 32824: 'POLYGON_OFFSET_FACTOR',
+ 32854: 'RGBA4',
+ 32855: 'RGB5_A1',
+ 32873: 'TEXTURE_BINDING_2D',
+ 32926: 'SAMPLE_ALPHA_TO_COVERAGE',
+ 32928: 'SAMPLE_COVERAGE',
+ 32936: 'SAMPLE_BUFFERS',
+ 32937: 'SAMPLES',
+ 32938: 'SAMPLE_COVERAGE_VALUE',
+ 32939: 'SAMPLE_COVERAGE_INVERT',
+ 32968: 'BLEND_DST_RGB',
+ 32969: 'BLEND_SRC_RGB',
+ 32970: 'BLEND_DST_ALPHA',
+ 32971: 'BLEND_SRC_ALPHA',
+ 33071: 'CLAMP_TO_EDGE',
+ 33170: 'GENERATE_MIPMAP_HINT',
+ 33189: 'DEPTH_COMPONENT16',
+ 33306: 'DEPTH_STENCIL_ATTACHMENT',
+ 33635: 'UNSIGNED_SHORT_5_6_5',
+ 33648: 'MIRRORED_REPEAT',
+ 33901: 'ALIASED_POINT_SIZE_RANGE',
+ 33902: 'ALIASED_LINE_WIDTH_RANGE',
+ 33984: 'TEXTURE0',
+ 33985: 'TEXTURE1',
+ 33986: 'TEXTURE2',
+ 33987: 'TEXTURE3',
+ 33988: 'TEXTURE4',
+ 33989: 'TEXTURE5',
+ 33990: 'TEXTURE6',
+ 33991: 'TEXTURE7',
+ 33992: 'TEXTURE8',
+ 33993: 'TEXTURE9',
+ 33994: 'TEXTURE10',
+ 33995: 'TEXTURE11',
+ 33996: 'TEXTURE12',
+ 33997: 'TEXTURE13',
+ 33998: 'TEXTURE14',
+ 33999: 'TEXTURE15',
+ 34000: 'TEXTURE16',
+ 34001: 'TEXTURE17',
+ 34002: 'TEXTURE18',
+ 34003: 'TEXTURE19',
+ 34004: 'TEXTURE20',
+ 34005: 'TEXTURE21',
+ 34006: 'TEXTURE22',
+ 34007: 'TEXTURE23',
+ 34008: 'TEXTURE24',
+ 34009: 'TEXTURE25',
+ 34010: 'TEXTURE26',
+ 34011: 'TEXTURE27',
+ 34012: 'TEXTURE28',
+ 34013: 'TEXTURE29',
+ 34014: 'TEXTURE30',
+ 34015: 'TEXTURE31',
+ 34016: 'ACTIVE_TEXTURE',
+ 34024: 'MAX_RENDERBUFFER_SIZE',
+ 34041: 'DEPTH_STENCIL',
+ 34055: 'INCR_WRAP',
+ 34056: 'DECR_WRAP',
+ 34067: 'TEXTURE_CUBE_MAP',
+ 34068: 'TEXTURE_BINDING_CUBE_MAP',
+ 34069: 'TEXTURE_CUBE_MAP_POSITIVE_X',
+ 34070: 'TEXTURE_CUBE_MAP_NEGATIVE_X',
+ 34071: 'TEXTURE_CUBE_MAP_POSITIVE_Y',
+ 34072: 'TEXTURE_CUBE_MAP_NEGATIVE_Y',
+ 34073: 'TEXTURE_CUBE_MAP_POSITIVE_Z',
+ 34074: 'TEXTURE_CUBE_MAP_NEGATIVE_Z',
+ 34076: 'MAX_CUBE_MAP_TEXTURE_SIZE',
+ 34338: 'VERTEX_ATTRIB_ARRAY_ENABLED',
+ 34339: 'VERTEX_ATTRIB_ARRAY_SIZE',
+ 34340: 'VERTEX_ATTRIB_ARRAY_STRIDE',
+ 34341: 'VERTEX_ATTRIB_ARRAY_TYPE',
+ 34342: 'CURRENT_VERTEX_ATTRIB',
+ 34373: 'VERTEX_ATTRIB_ARRAY_POINTER',
+ 34466: 'NUM_COMPRESSED_TEXTURE_FORMATS',
+ 34467: 'COMPRESSED_TEXTURE_FORMATS',
+ 34660: 'BUFFER_SIZE',
+ 34661: 'BUFFER_USAGE',
+ 34816: 'STENCIL_BACK_FUNC',
+ 34817: 'STENCIL_BACK_FAIL',
+ 34818: 'STENCIL_BACK_PASS_DEPTH_FAIL',
+ 34819: 'STENCIL_BACK_PASS_DEPTH_PASS',
+ 34877: 'BLEND_EQUATION_ALPHA',
+ 34921: 'MAX_VERTEX_ATTRIBS',
+ 34922: 'VERTEX_ATTRIB_ARRAY_NORMALIZED',
+ 34930: 'MAX_TEXTURE_IMAGE_UNITS',
+ 34962: 'ARRAY_BUFFER',
+ 34963: 'ELEMENT_ARRAY_BUFFER',
+ 34964: 'ARRAY_BUFFER_BINDING',
+ 34965: 'ELEMENT_ARRAY_BUFFER_BINDING',
+ 34975: 'VERTEX_ATTRIB_ARRAY_BUFFER_BINDING',
+ 35040: 'STREAM_DRAW',
+ 35044: 'STATIC_DRAW',
+ 35048: 'DYNAMIC_DRAW',
+ 35632: 'FRAGMENT_SHADER',
+ 35633: 'VERTEX_SHADER',
+ 35660: 'MAX_VERTEX_TEXTURE_IMAGE_UNITS',
+ 35661: 'MAX_COMBINED_TEXTURE_IMAGE_UNITS',
+ 35663: 'SHADER_TYPE',
+ 35664: 'FLOAT_VEC2',
+ 35665: 'FLOAT_VEC3',
+ 35666: 'FLOAT_VEC4',
+ 35667: 'INT_VEC2',
+ 35668: 'INT_VEC3',
+ 35669: 'INT_VEC4',
+ 35670: 'BOOL',
+ 35671: 'BOOL_VEC2',
+ 35672: 'BOOL_VEC3',
+ 35673: 'BOOL_VEC4',
+ 35674: 'FLOAT_MAT2',
+ 35675: 'FLOAT_MAT3',
+ 35676: 'FLOAT_MAT4',
+ 35678: 'SAMPLER_2D',
+ 35680: 'SAMPLER_CUBE',
+ 35712: 'DELETE_STATUS',
+ 35713: 'COMPILE_STATUS',
+ 35714: 'LINK_STATUS',
+ 35715: 'VALIDATE_STATUS',
+ 35716: 'INFO_LOG_LENGTH',
+ 35717: 'ATTACHED_SHADERS',
+ 35718: 'ACTIVE_UNIFORMS',
+ 35719: 'ACTIVE_UNIFORM_MAX_LENGTH',
+ 35720: 'SHADER_SOURCE_LENGTH',
+ 35721: 'ACTIVE_ATTRIBUTES',
+ 35722: 'ACTIVE_ATTRIBUTE_MAX_LENGTH',
+ 35724: 'SHADING_LANGUAGE_VERSION',
+ 35725: 'CURRENT_PROGRAM',
+ 36003: 'STENCIL_BACK_REF',
+ 36004: 'STENCIL_BACK_VALUE_MASK',
+ 36005: 'STENCIL_BACK_WRITEMASK',
+ 36006: 'FRAMEBUFFER_BINDING',
+ 36007: 'RENDERBUFFER_BINDING',
+ 36048: 'FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE',
+ 36049: 'FRAMEBUFFER_ATTACHMENT_OBJECT_NAME',
+ 36050: 'FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL',
+ 36051: 'FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE',
+ 36053: 'FRAMEBUFFER_COMPLETE',
+ 36054: 'FRAMEBUFFER_INCOMPLETE_ATTACHMENT',
+ 36055: 'FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT',
+ 36057: 'FRAMEBUFFER_INCOMPLETE_DIMENSIONS',
+ 36061: 'FRAMEBUFFER_UNSUPPORTED',
+ 36064: 'COLOR_ATTACHMENT0',
+ 36096: 'DEPTH_ATTACHMENT',
+ 36128: 'STENCIL_ATTACHMENT',
+ 36160: 'FRAMEBUFFER',
+ 36161: 'RENDERBUFFER',
+ 36162: 'RENDERBUFFER_WIDTH',
+ 36163: 'RENDERBUFFER_HEIGHT',
+ 36164: 'RENDERBUFFER_INTERNAL_FORMAT',
+ 36168: 'STENCIL_INDEX8',
+ 36176: 'RENDERBUFFER_RED_SIZE',
+ 36177: 'RENDERBUFFER_GREEN_SIZE',
+ 36178: 'RENDERBUFFER_BLUE_SIZE',
+ 36179: 'RENDERBUFFER_ALPHA_SIZE',
+ 36180: 'RENDERBUFFER_DEPTH_SIZE',
+ 36181: 'RENDERBUFFER_STENCIL_SIZE',
+ 36194: 'RGB565',
+ 36336: 'LOW_FLOAT',
+ 36337: 'MEDIUM_FLOAT',
+ 36338: 'HIGH_FLOAT',
+ 36339: 'LOW_INT',
+ 36340: 'MEDIUM_INT',
+ 36341: 'HIGH_INT',
+ 36346: 'SHADER_COMPILER',
+ 36347: 'MAX_VERTEX_UNIFORM_VECTORS',
+ 36348: 'MAX_VARYING_VECTORS',
+ 36349: 'MAX_FRAGMENT_UNIFORM_VECTORS',
+ 37440: 'UNPACK_FLIP_Y_WEBGL',
+ 37441: 'UNPACK_PREMULTIPLY_ALPHA_WEBGL',
+ 37442: 'CONTEXT_LOST_WEBGL',
+ 37443: 'UNPACK_COLORSPACE_CONVERSION_WEBGL',
+ 37444: 'BROWSER_DEFAULT_WEBGL'
+}
+
+},{}],166:[function(require,module,exports){
+var gl10 = require('./1.0/numbers')
+
+module.exports = function lookupConstant (number) {
+ return gl10[number]
+}
+
+},{"./1.0/numbers":165}],167:[function(require,module,exports){
+var tokenize = require('glsl-tokenizer')
+var atob = require('atob-lite')
+
+module.exports = getName
+
+function getName(src) {
+ var tokens = Array.isArray(src)
+ ? src
+ : tokenize(src)
+
+ for (var i = 0; i < tokens.length; i++) {
+ var token = tokens[i]
+ if (token.type !== 'preprocessor') continue
+ var match = token.data.match(/\#define\s+SHADER_NAME(_B64)?\s+(.+)$/)
+ if (!match) continue
+ if (!match[2]) continue
+
+ var b64 = match[1]
+ var name = match[2]
+
+ return (b64 ? atob(name) : name).trim()
+ }
+}
+
+},{"atob-lite":168,"glsl-tokenizer":173}],168:[function(require,module,exports){
+module.exports = function _atob(str) {
+ return atob(str)
+}
+
+},{}],169:[function(require,module,exports){
+module.exports = tokenize
+
+var literals = require('./lib/literals')
+ , operators = require('./lib/operators')
+ , builtins = require('./lib/builtins')
+
+var NORMAL = 999 // <-- never emitted
+ , TOKEN = 9999 // <-- never emitted
+ , BLOCK_COMMENT = 0
+ , LINE_COMMENT = 1
+ , PREPROCESSOR = 2
+ , OPERATOR = 3
+ , INTEGER = 4
+ , FLOAT = 5
+ , IDENT = 6
+ , BUILTIN = 7
+ , KEYWORD = 8
+ , WHITESPACE = 9
+ , EOF = 10
+ , HEX = 11
+
+var map = [
+ 'block-comment'
+ , 'line-comment'
+ , 'preprocessor'
+ , 'operator'
+ , 'integer'
+ , 'float'
+ , 'ident'
+ , 'builtin'
+ , 'keyword'
+ , 'whitespace'
+ , 'eof'
+ , 'integer'
+]
+
+function tokenize() {
+ var i = 0
+ , total = 0
+ , mode = NORMAL
+ , c
+ , last
+ , content = []
+ , tokens = []
+ , token_idx = 0
+ , token_offs = 0
+ , line = 1
+ , col = 0
+ , start = 0
+ , isnum = false
+ , isoperator = false
+ , input = ''
+ , len
+
+ return function(data) {
+ tokens = []
+ if (data !== null) return write(data)
+ return end()
+ }
+
+ function token(data) {
+ if (data.length) {
+ tokens.push({
+ type: map[mode]
+ , data: data
+ , position: start
+ , line: line
+ , column: col
+ })
+ }
+ }
+
+ function write(chunk) {
+ i = 0
+ input += chunk
+ len = input.length
+
+ var last
+
+ while(c = input[i], i < len) {
+ last = i
+
+ switch(mode) {
+ case BLOCK_COMMENT: i = block_comment(); break
+ case LINE_COMMENT: i = line_comment(); break
+ case PREPROCESSOR: i = preprocessor(); break
+ case OPERATOR: i = operator(); break
+ case INTEGER: i = integer(); break
+ case HEX: i = hex(); break
+ case FLOAT: i = decimal(); break
+ case TOKEN: i = readtoken(); break
+ case WHITESPACE: i = whitespace(); break
+ case NORMAL: i = normal(); break
+ }
+
+ if(last !== i) {
+ switch(input[last]) {
+ case '\n': col = 0; ++line; break
+ default: ++col; break
+ }
+ }
+ }
+
+ total += i
+ input = input.slice(i)
+ return tokens
+ }
+
+ function end(chunk) {
+ if(content.length) {
+ token(content.join(''))
+ }
+
+ mode = EOF
+ token('(eof)')
+ return tokens
+ }
+
+ function normal() {
+ content = content.length ? [] : content
+
+ if(last === '/' && c === '*') {
+ start = total + i - 1
+ mode = BLOCK_COMMENT
+ last = c
+ return i + 1
+ }
+
+ if(last === '/' && c === '/') {
+ start = total + i - 1
+ mode = LINE_COMMENT
+ last = c
+ return i + 1
+ }
+
+ if(c === '#') {
+ mode = PREPROCESSOR
+ start = total + i
+ return i
+ }
+
+ if(/\s/.test(c)) {
+ mode = WHITESPACE
+ start = total + i
+ return i
+ }
+
+ isnum = /\d/.test(c)
+ isoperator = /[^\w_]/.test(c)
+
+ start = total + i
+ mode = isnum ? INTEGER : isoperator ? OPERATOR : TOKEN
+ return i
+ }
+
+ function whitespace() {
+ if(/[^\s]/g.test(c)) {
+ token(content.join(''))
+ mode = NORMAL
+ return i
+ }
+ content.push(c)
+ last = c
+ return i + 1
+ }
+
+ function preprocessor() {
+ if(c === '\n' && last !== '\\') {
+ token(content.join(''))
+ mode = NORMAL
+ return i
+ }
+ content.push(c)
+ last = c
+ return i + 1
+ }
+
+ function line_comment() {
+ return preprocessor()
+ }
+
+ function block_comment() {
+ if(c === '/' && last === '*') {
+ content.push(c)
+ token(content.join(''))
+ mode = NORMAL
+ return i + 1
+ }
+
+ content.push(c)
+ last = c
+ return i + 1
+ }
+
+ function operator() {
+ if(last === '.' && /\d/.test(c)) {
+ mode = FLOAT
+ return i
+ }
+
+ if(last === '/' && c === '*') {
+ mode = BLOCK_COMMENT
+ return i
+ }
+
+ if(last === '/' && c === '/') {
+ mode = LINE_COMMENT
+ return i
+ }
+
+ if(c === '.' && content.length) {
+ while(determine_operator(content));
+
+ mode = FLOAT
+ return i
+ }
+
+ if(c === ';' || c === ')' || c === '(') {
+ if(content.length) while(determine_operator(content));
+ token(c)
+ mode = NORMAL
+ return i + 1
+ }
+
+ var is_composite_operator = content.length === 2 && c !== '='
+ if(/[\w_\d\s]/.test(c) || is_composite_operator) {
+ while(determine_operator(content));
+ mode = NORMAL
+ return i
+ }
+
+ content.push(c)
+ last = c
+ return i + 1
+ }
+
+ function determine_operator(buf) {
+ var j = 0
+ , idx
+ , res
+
+ do {
+ idx = operators.indexOf(buf.slice(0, buf.length + j).join(''))
+ res = operators[idx]
+
+ if(idx === -1) {
+ if(j-- + buf.length > 0) continue
+ res = buf.slice(0, 1).join('')
+ }
+
+ token(res)
+
+ start += res.length
+ content = content.slice(res.length)
+ return content.length
+ } while(1)
+ }
+
+ function hex() {
+ if(/[^a-fA-F0-9]/.test(c)) {
+ token(content.join(''))
+ mode = NORMAL
+ return i
+ }
+
+ content.push(c)
+ last = c
+ return i + 1
+ }
+
+ function integer() {
+ if(c === '.') {
+ content.push(c)
+ mode = FLOAT
+ last = c
+ return i + 1
+ }
+
+ if(/[eE]/.test(c)) {
+ content.push(c)
+ mode = FLOAT
+ last = c
+ return i + 1
+ }
+
+ if(c === 'x' && content.length === 1 && content[0] === '0') {
+ mode = HEX
+ content.push(c)
+ last = c
+ return i + 1
+ }
+
+ if(/[^\d]/.test(c)) {
+ token(content.join(''))
+ mode = NORMAL
+ return i
+ }
+
+ content.push(c)
+ last = c
+ return i + 1
+ }
+
+ function decimal() {
+ if(c === 'f') {
+ content.push(c)
+ last = c
+ i += 1
+ }
+
+ if(/[eE]/.test(c)) {
+ content.push(c)
+ last = c
+ return i + 1
+ }
+
+ if(/[^\d]/.test(c)) {
+ token(content.join(''))
+ mode = NORMAL
+ return i
+ }
+ content.push(c)
+ last = c
+ return i + 1
+ }
+
+ function readtoken() {
+ if(/[^\d\w_]/.test(c)) {
+ var contentstr = content.join('')
+ if(literals.indexOf(contentstr) > -1) {
+ mode = KEYWORD
+ } else if(builtins.indexOf(contentstr) > -1) {
+ mode = BUILTIN
+ } else {
+ mode = IDENT
+ }
+ token(content.join(''))
+ mode = NORMAL
+ return i
+ }
+ content.push(c)
+ last = c
+ return i + 1
+ }
+}
+
+},{"./lib/builtins":170,"./lib/literals":171,"./lib/operators":172}],170:[function(require,module,exports){
+module.exports = [
+ 'gl_Position'
+ , 'gl_PointSize'
+ , 'gl_ClipVertex'
+ , 'gl_FragCoord'
+ , 'gl_FrontFacing'
+ , 'gl_FragColor'
+ , 'gl_FragData'
+ , 'gl_FragDepth'
+ , 'gl_Color'
+ , 'gl_SecondaryColor'
+ , 'gl_Normal'
+ , 'gl_Vertex'
+ , 'gl_MultiTexCoord0'
+ , 'gl_MultiTexCoord1'
+ , 'gl_MultiTexCoord2'
+ , 'gl_MultiTexCoord3'
+ , 'gl_MultiTexCoord4'
+ , 'gl_MultiTexCoord5'
+ , 'gl_MultiTexCoord6'
+ , 'gl_MultiTexCoord7'
+ , 'gl_FogCoord'
+ , 'gl_MaxLights'
+ , 'gl_MaxClipPlanes'
+ , 'gl_MaxTextureUnits'
+ , 'gl_MaxTextureCoords'
+ , 'gl_MaxVertexAttribs'
+ , 'gl_MaxVertexUniformComponents'
+ , 'gl_MaxVaryingFloats'
+ , 'gl_MaxVertexTextureImageUnits'
+ , 'gl_MaxCombinedTextureImageUnits'
+ , 'gl_MaxTextureImageUnits'
+ , 'gl_MaxFragmentUniformComponents'
+ , 'gl_MaxDrawBuffers'
+ , 'gl_ModelViewMatrix'
+ , 'gl_ProjectionMatrix'
+ , 'gl_ModelViewProjectionMatrix'
+ , 'gl_TextureMatrix'
+ , 'gl_NormalMatrix'
+ , 'gl_ModelViewMatrixInverse'
+ , 'gl_ProjectionMatrixInverse'
+ , 'gl_ModelViewProjectionMatrixInverse'
+ , 'gl_TextureMatrixInverse'
+ , 'gl_ModelViewMatrixTranspose'
+ , 'gl_ProjectionMatrixTranspose'
+ , 'gl_ModelViewProjectionMatrixTranspose'
+ , 'gl_TextureMatrixTranspose'
+ , 'gl_ModelViewMatrixInverseTranspose'
+ , 'gl_ProjectionMatrixInverseTranspose'
+ , 'gl_ModelViewProjectionMatrixInverseTranspose'
+ , 'gl_TextureMatrixInverseTranspose'
+ , 'gl_NormalScale'
+ , 'gl_DepthRangeParameters'
+ , 'gl_DepthRange'
+ , 'gl_ClipPlane'
+ , 'gl_PointParameters'
+ , 'gl_Point'
+ , 'gl_MaterialParameters'
+ , 'gl_FrontMaterial'
+ , 'gl_BackMaterial'
+ , 'gl_LightSourceParameters'
+ , 'gl_LightSource'
+ , 'gl_LightModelParameters'
+ , 'gl_LightModel'
+ , 'gl_LightModelProducts'
+ , 'gl_FrontLightModelProduct'
+ , 'gl_BackLightModelProduct'
+ , 'gl_LightProducts'
+ , 'gl_FrontLightProduct'
+ , 'gl_BackLightProduct'
+ , 'gl_FogParameters'
+ , 'gl_Fog'
+ , 'gl_TextureEnvColor'
+ , 'gl_EyePlaneS'
+ , 'gl_EyePlaneT'
+ , 'gl_EyePlaneR'
+ , 'gl_EyePlaneQ'
+ , 'gl_ObjectPlaneS'
+ , 'gl_ObjectPlaneT'
+ , 'gl_ObjectPlaneR'
+ , 'gl_ObjectPlaneQ'
+ , 'gl_FrontColor'
+ , 'gl_BackColor'
+ , 'gl_FrontSecondaryColor'
+ , 'gl_BackSecondaryColor'
+ , 'gl_TexCoord'
+ , 'gl_FogFragCoord'
+ , 'gl_Color'
+ , 'gl_SecondaryColor'
+ , 'gl_TexCoord'
+ , 'gl_FogFragCoord'
+ , 'gl_PointCoord'
+ , 'radians'
+ , 'degrees'
+ , 'sin'
+ , 'cos'
+ , 'tan'
+ , 'asin'
+ , 'acos'
+ , 'atan'
+ , 'pow'
+ , 'exp'
+ , 'log'
+ , 'exp2'
+ , 'log2'
+ , 'sqrt'
+ , 'inversesqrt'
+ , 'abs'
+ , 'sign'
+ , 'floor'
+ , 'ceil'
+ , 'fract'
+ , 'mod'
+ , 'min'
+ , 'max'
+ , 'clamp'
+ , 'mix'
+ , 'step'
+ , 'smoothstep'
+ , 'length'
+ , 'distance'
+ , 'dot'
+ , 'cross'
+ , 'normalize'
+ , 'faceforward'
+ , 'reflect'
+ , 'refract'
+ , 'matrixCompMult'
+ , 'lessThan'
+ , 'lessThanEqual'
+ , 'greaterThan'
+ , 'greaterThanEqual'
+ , 'equal'
+ , 'notEqual'
+ , 'any'
+ , 'all'
+ , 'not'
+ , 'texture2D'
+ , 'texture2DProj'
+ , 'texture2DLod'
+ , 'texture2DProjLod'
+ , 'textureCube'
+ , 'textureCubeLod'
+ , 'dFdx'
+ , 'dFdy'
+]
+
+},{}],171:[function(require,module,exports){
+module.exports = [
+ // current
+ 'precision'
+ , 'highp'
+ , 'mediump'
+ , 'lowp'
+ , 'attribute'
+ , 'const'
+ , 'uniform'
+ , 'varying'
+ , 'break'
+ , 'continue'
+ , 'do'
+ , 'for'
+ , 'while'
+ , 'if'
+ , 'else'
+ , 'in'
+ , 'out'
+ , 'inout'
+ , 'float'
+ , 'int'
+ , 'void'
+ , 'bool'
+ , 'true'
+ , 'false'
+ , 'discard'
+ , 'return'
+ , 'mat2'
+ , 'mat3'
+ , 'mat4'
+ , 'vec2'
+ , 'vec3'
+ , 'vec4'
+ , 'ivec2'
+ , 'ivec3'
+ , 'ivec4'
+ , 'bvec2'
+ , 'bvec3'
+ , 'bvec4'
+ , 'sampler1D'
+ , 'sampler2D'
+ , 'sampler3D'
+ , 'samplerCube'
+ , 'sampler1DShadow'
+ , 'sampler2DShadow'
+ , 'struct'
+
+ // future
+ , 'asm'
+ , 'class'
+ , 'union'
+ , 'enum'
+ , 'typedef'
+ , 'template'
+ , 'this'
+ , 'packed'
+ , 'goto'
+ , 'switch'
+ , 'default'
+ , 'inline'
+ , 'noinline'
+ , 'volatile'
+ , 'public'
+ , 'static'
+ , 'extern'
+ , 'external'
+ , 'interface'
+ , 'long'
+ , 'short'
+ , 'double'
+ , 'half'
+ , 'fixed'
+ , 'unsigned'
+ , 'input'
+ , 'output'
+ , 'hvec2'
+ , 'hvec3'
+ , 'hvec4'
+ , 'dvec2'
+ , 'dvec3'
+ , 'dvec4'
+ , 'fvec2'
+ , 'fvec3'
+ , 'fvec4'
+ , 'sampler2DRect'
+ , 'sampler3DRect'
+ , 'sampler2DRectShadow'
+ , 'sizeof'
+ , 'cast'
+ , 'namespace'
+ , 'using'
+]
+
+},{}],172:[function(require,module,exports){
+module.exports = [
+ '<<='
+ , '>>='
+ , '++'
+ , '--'
+ , '<<'
+ , '>>'
+ , '<='
+ , '>='
+ , '=='
+ , '!='
+ , '&&'
+ , '||'
+ , '+='
+ , '-='
+ , '*='
+ , '/='
+ , '%='
+ , '&='
+ , '^^'
+ , '^='
+ , '|='
+ , '('
+ , ')'
+ , '['
+ , ']'
+ , '.'
+ , '!'
+ , '~'
+ , '*'
+ , '/'
+ , '%'
+ , '+'
+ , '-'
+ , '<'
+ , '>'
+ , '&'
+ , '^'
+ , '|'
+ , '?'
+ , ':'
+ , '='
+ , ','
+ , ';'
+ , '{'
+ , '}'
+]
+
+},{}],173:[function(require,module,exports){
+var tokenize = require('./index')
+
+module.exports = tokenizeString
+
+function tokenizeString(str) {
+ var generator = tokenize()
+ var tokens = []
+
+ tokens = tokens.concat(generator(str))
+ tokens = tokens.concat(generator(null))
+
+ return tokens
+}
+
+},{"./index":169}],174:[function(require,module,exports){
+(function(window) {
+ var re = {
+ not_string: /[^s]/,
+ number: /[diefg]/,
+ json: /[j]/,
+ not_json: /[^j]/,
+ text: /^[^\x25]+/,
+ modulo: /^\x25{2}/,
+ placeholder: /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijosuxX])/,
+ key: /^([a-z_][a-z_\d]*)/i,
+ key_access: /^\.([a-z_][a-z_\d]*)/i,
+ index_access: /^\[(\d+)\]/,
+ sign: /^[\+\-]/
+ }
+
+ function sprintf() {
+ var key = arguments[0], cache = sprintf.cache
+ if (!(cache[key] && cache.hasOwnProperty(key))) {
+ cache[key] = sprintf.parse(key)
+ }
+ return sprintf.format.call(null, cache[key], arguments)
+ }
+
+ sprintf.format = function(parse_tree, argv) {
+ var cursor = 1, tree_length = parse_tree.length, node_type = "", arg, output = [], i, k, match, pad, pad_character, pad_length, is_positive = true, sign = ""
+ for (i = 0; i < tree_length; i++) {
+ node_type = get_type(parse_tree[i])
+ if (node_type === "string") {
+ output[output.length] = parse_tree[i]
+ }
+ else if (node_type === "array") {
+ match = parse_tree[i] // convenience purposes only
+ if (match[2]) { // keyword argument
+ arg = argv[cursor]
+ for (k = 0; k < match[2].length; k++) {
+ if (!arg.hasOwnProperty(match[2][k])) {
+ throw new Error(sprintf("[sprintf] property '%s' does not exist", match[2][k]))
+ }
+ arg = arg[match[2][k]]
+ }
+ }
+ else if (match[1]) { // positional argument (explicit)
+ arg = argv[match[1]]
+ }
+ else { // positional argument (implicit)
+ arg = argv[cursor++]
+ }
+
+ if (get_type(arg) == "function") {
+ arg = arg()
+ }
+
+ if (re.not_string.test(match[8]) && re.not_json.test(match[8]) && (get_type(arg) != "number" && isNaN(arg))) {
+ throw new TypeError(sprintf("[sprintf] expecting number but found %s", get_type(arg)))
+ }
+
+ if (re.number.test(match[8])) {
+ is_positive = arg >= 0
+ }
+
+ switch (match[8]) {
+ case "b":
+ arg = arg.toString(2)
+ break
+ case "c":
+ arg = String.fromCharCode(arg)
+ break
+ case "d":
+ case "i":
+ arg = parseInt(arg, 10)
+ break
+ case "j":
+ arg = JSON.stringify(arg, null, match[6] ? parseInt(match[6]) : 0)
+ break
+ case "e":
+ arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential()
+ break
+ case "f":
+ arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg)
+ break
+ case "g":
+ arg = match[7] ? parseFloat(arg).toPrecision(match[7]) : parseFloat(arg)
+ break
+ case "o":
+ arg = arg.toString(8)
+ break
+ case "s":
+ arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg)
+ break
+ case "u":
+ arg = arg >>> 0
+ break
+ case "x":
+ arg = arg.toString(16)
+ break
+ case "X":
+ arg = arg.toString(16).toUpperCase()
+ break
+ }
+ if (re.json.test(match[8])) {
+ output[output.length] = arg
+ }
+ else {
+ if (re.number.test(match[8]) && (!is_positive || match[3])) {
+ sign = is_positive ? "+" : "-"
+ arg = arg.toString().replace(re.sign, "")
+ }
+ else {
+ sign = ""
+ }
+ pad_character = match[4] ? match[4] === "0" ? "0" : match[4].charAt(1) : " "
+ pad_length = match[6] - (sign + arg).length
+ pad = match[6] ? (pad_length > 0 ? str_repeat(pad_character, pad_length) : "") : ""
+ output[output.length] = match[5] ? sign + arg + pad : (pad_character === "0" ? sign + pad + arg : pad + sign + arg)
+ }
+ }
+ }
+ return output.join("")
+ }
+
+ sprintf.cache = {}
+
+ sprintf.parse = function(fmt) {
+ var _fmt = fmt, match = [], parse_tree = [], arg_names = 0
+ while (_fmt) {
+ if ((match = re.text.exec(_fmt)) !== null) {
+ parse_tree[parse_tree.length] = match[0]
+ }
+ else if ((match = re.modulo.exec(_fmt)) !== null) {
+ parse_tree[parse_tree.length] = "%"
+ }
+ else if ((match = re.placeholder.exec(_fmt)) !== null) {
+ if (match[2]) {
+ arg_names |= 1
+ var field_list = [], replacement_field = match[2], field_match = []
+ if ((field_match = re.key.exec(replacement_field)) !== null) {
+ field_list[field_list.length] = field_match[1]
+ while ((replacement_field = replacement_field.substring(field_match[0].length)) !== "") {
+ if ((field_match = re.key_access.exec(replacement_field)) !== null) {
+ field_list[field_list.length] = field_match[1]
+ }
+ else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
+ field_list[field_list.length] = field_match[1]
+ }
+ else {
+ throw new SyntaxError("[sprintf] failed to parse named argument key")
+ }
+ }
+ }
+ else {
+ throw new SyntaxError("[sprintf] failed to parse named argument key")
+ }
+ match[2] = field_list
+ }
+ else {
+ arg_names |= 2
+ }
+ if (arg_names === 3) {
+ throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported")
+ }
+ parse_tree[parse_tree.length] = match
+ }
+ else {
+ throw new SyntaxError("[sprintf] unexpected placeholder")
+ }
+ _fmt = _fmt.substring(match[0].length)
+ }
+ return parse_tree
+ }
+
+ var vsprintf = function(fmt, argv, _argv) {
+ _argv = (argv || []).slice(0)
+ _argv.splice(0, 0, fmt)
+ return sprintf.apply(null, _argv)
+ }
+
+ /**
+ * helpers
+ */
+ function get_type(variable) {
+ return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase()
+ }
+
+ function str_repeat(input, multiplier) {
+ return Array(multiplier + 1).join(input)
+ }
+
+ /**
+ * export to either browser or node.js
+ */
+ if (typeof exports !== "undefined") {
+ exports.sprintf = sprintf
+ exports.vsprintf = vsprintf
+ }
+ else {
+ window.sprintf = sprintf
+ window.vsprintf = vsprintf
+
+ if (typeof define === "function" && define.amd) {
+ define(function() {
+ return {
+ sprintf: sprintf,
+ vsprintf: vsprintf
+ }
+ })
+ }
+ }
+})(typeof window === "undefined" ? this : window);
+
+},{}],175:[function(require,module,exports){
+var hiddenStore = require('./hidden-store.js');
+
+module.exports = createStore;
+
+function createStore() {
+ var key = {};
+
+ return function (obj) {
+ if ((typeof obj !== 'object' || obj === null) &&
+ typeof obj !== 'function'
+ ) {
+ throw new Error('Weakmap-shim: Key must be object')
+ }
+
+ var store = obj.valueOf(key);
+ return store && store.identity === key ?
+ store : hiddenStore(obj, key);
+ };
+}
+
+},{"./hidden-store.js":176}],176:[function(require,module,exports){
+module.exports = hiddenStore;
+
+function hiddenStore(obj, key) {
+ var store = { identity: key };
+ var valueOf = obj.valueOf;
+
+ Object.defineProperty(obj, "valueOf", {
+ value: function (value) {
+ return value !== key ?
+ valueOf.apply(this, arguments) : store;
+ },
+ writable: true
+ });
+
+ return store;
+}
+
+},{}],177:[function(require,module,exports){
+// Original - @Gozola.
+// https://gist.github.com/Gozala/1269991
+// This is a reimplemented version (with a few bug fixes).
+
+var createStore = require('./create-store.js');
+
+module.exports = weakMap;
+
+function weakMap() {
+ var privates = createStore();
+
+ return {
+ 'get': function (key, fallback) {
+ var store = privates(key)
+ return store.hasOwnProperty('value') ?
+ store.value : fallback
+ },
+ 'set': function (key, value) {
+ privates(key).value = value;
+ },
+ 'has': function(key) {
+ return 'value' in privates(key);
+ },
+ 'delete': function (key) {
+ return delete privates(key).value;
+ }
+ }
+}
+
+},{"./create-store.js":175}],178:[function(require,module,exports){
+'use strict'
+
+module.exports = createSpikes2D
+
+function GLSpikes2D(plot) {
+ this.plot = plot
+ this.enable = [true, true, false, false]
+ this.width = [1, 1, 1, 1]
+ this.color = [[0,0,0,1],
+ [0,0,0,1],
+ [0,0,0,1],
+ [0,0,0,1]]
+ this.center = [Infinity, Infinity]
+}
+
+var proto = GLSpikes2D.prototype
+
+proto.update = function(options) {
+ options = options || {}
+ this.enable = (options.enable || [true,true,false,false]).slice()
+ this.width = (options.width || [1,1,1,1]).slice()
+ this.color = (options.color || [
+ [0,0,0,1],
+ [0,0,0,1],
+ [0,0,0,1],
+ [0,0,0,1]]).map(function(x) { return x.slice() })
+ this.center = (options.center || [Infinity,Infinity]).slice()
+ this.plot.setOverlayDirty()
+}
+
+proto.draw = function() {
+ var spikeEnable = this.enable
+ var spikeWidth = this.width
+ var spikeColor = this.color
+ var spikeCenter = this.center
+ var plot = this.plot
+ var line = plot.line
+
+ var dataBox = plot.dataBox
+ var viewPixels = plot.viewBox
+
+ line.bind()
+
+ if(dataBox[0] <= spikeCenter[0] && spikeCenter[0] <= dataBox[2] &&
+ dataBox[1] <= spikeCenter[1] && spikeCenter[1] <= dataBox[3]) {
+
+ var centerX = viewPixels[0] + (spikeCenter[0] - dataBox[0]) / (dataBox[2] - dataBox[0]) * (viewPixels[2] - viewPixels[0])
+ var centerY = viewPixels[1] + (spikeCenter[1] - dataBox[1]) / (dataBox[3] - dataBox[1]) * (viewPixels[3] - viewPixels[1])
+
+ if(spikeEnable[0]) {
+ line.drawLine(
+ centerX, centerY,
+ viewPixels[0], centerY,
+ spikeWidth[0], spikeColor[0])
+ }
+ if(spikeEnable[1]) {
+ line.drawLine(
+ centerX, centerY,
+ centerX, viewPixels[1],
+ spikeWidth[1], spikeColor[1])
+ }
+ if(spikeEnable[2]) {
+ line.drawLine(
+ centerX, centerY,
+ viewPixels[2], centerY,
+ spikeWidth[2], spikeColor[2])
+ }
+ if(spikeEnable[3]) {
+ line.drawLine(
+ centerX, centerY,
+ centerX, viewPixels[3],
+ spikeWidth[3], spikeColor[3])
+ }
+ }
+}
+
+proto.dispose = function() {
+ this.plot.removeOverlay(this)
+}
+
+function createSpikes2D(plot, options) {
+ var spikes = new GLSpikes2D(plot)
+ spikes.update(options)
+ plot.addOverlay(spikes)
+ return spikes
+}
+
+},{}],179:[function(require,module,exports){
+var createShader = require('gl-shader')
+
+
+var vertSrc = "#define GLSLIFY 1\nprecision mediump float;\n\nattribute vec4 uv;\nattribute vec2 f;\nattribute vec3 normal;\n\nuniform mat4 model, view, projection, inverseModel;\nuniform vec3 lightPosition, eyePosition;\n\nvarying float value, kill;\nvarying vec3 worldCoordinate;\nvarying vec2 planeCoordinate;\nvarying vec3 lightDirection, eyeDirection, surfaceNormal;\n\nvoid main() {\n worldCoordinate = vec3(uv.zw, f.x);\n vec4 worldPosition = model * vec4(worldCoordinate, 1.0);\n vec4 clipPosition = projection * view * worldPosition;\n gl_Position = clipPosition;\n value = f.x;\n kill = f.y;\n planeCoordinate = uv.xy;\n \n //Lighting geometry parameters\n vec4 cameraCoordinate = view * worldPosition;\n cameraCoordinate.xyz /= cameraCoordinate.w;\n lightDirection = lightPosition - cameraCoordinate.xyz;\n eyeDirection = eyePosition - cameraCoordinate.xyz;\n surfaceNormal = normalize((vec4(normal,0) * inverseModel).xyz);\n}"
+var fragSrc = "#define GLSLIFY 1\nprecision mediump float;\n\nfloat beckmannDistribution_2_0(float x, float roughness) {\n float NdotH = max(x, 0.0001);\n float cos2Alpha = NdotH * NdotH;\n float tan2Alpha = (cos2Alpha - 1.0) / cos2Alpha;\n float roughness2 = roughness * roughness;\n float denom = 3.141592653589793 * roughness2 * cos2Alpha * cos2Alpha;\n return exp(tan2Alpha / roughness2) / denom;\n}\n\n\n\nfloat beckmannSpecular_1_1(\n vec3 lightDirection,\n vec3 viewDirection,\n vec3 surfaceNormal,\n float roughness) {\n return beckmannDistribution_2_0(dot(surfaceNormal, normalize(lightDirection + viewDirection)), roughness);\n}\n\n\n\nuniform vec3 lowerBound, upperBound;\nuniform float contourTint;\nuniform vec4 contourColor;\nuniform sampler2D colormap;\nuniform vec3 clipBounds[2];\nuniform float roughness, fresnel, kambient, kdiffuse, kspecular, opacity;\n\nvarying float value, kill;\nvarying vec3 worldCoordinate;\nvarying vec3 lightDirection, eyeDirection, surfaceNormal;\n\nvoid main() {\n if(kill > 0.0 ||\n any(lessThan(worldCoordinate, clipBounds[0])) || any(greaterThan(worldCoordinate, clipBounds[1]))) {\n discard;\n }\n\n vec3 N = normalize(surfaceNormal);\n vec3 V = normalize(eyeDirection);\n vec3 L = normalize(lightDirection);\n\n if(gl_FrontFacing) {\n N = -N;\n }\n\n float specular = beckmannSpecular_1_1(L, V, N, roughness);\n float diffuse = min(kambient + kdiffuse * max(dot(N, L), 0.0), 1.0);\n\n float interpValue = (value - lowerBound.z) / (upperBound.z - lowerBound.z);\n vec4 surfaceColor = texture2D(colormap, vec2(interpValue, interpValue));\n vec4 litColor = surfaceColor.a * vec4(diffuse * surfaceColor.rgb + kspecular * vec3(1,1,1) * specular, 1.0);\n\n gl_FragColor = mix(litColor, contourColor, contourTint) * opacity;\n}\n"
+var contourVertSrc = "#define GLSLIFY 1\nprecision mediump float;\n\nattribute vec4 uv;\n\nuniform mat3 permutation;\nuniform mat4 model, view, projection;\nuniform float height, zOffset;\n\nvarying float value, kill;\nvarying vec3 worldCoordinate;\nvarying vec2 planeCoordinate;\nvarying vec3 lightDirection, eyeDirection, surfaceNormal;\n\nvoid main() {\n vec3 dataCoordinate = permutation * vec3(uv.xy, height);\n vec4 worldPosition = model * vec4(dataCoordinate, 1.0);\n\n vec4 clipPosition = projection * view * worldPosition;\n clipPosition.z = clipPosition.z + zOffset;\n\n gl_Position = clipPosition;\n value = dataCoordinate.z;\n kill = -1.0;\n worldCoordinate = dataCoordinate;\n planeCoordinate = uv.zw;\n\n //Don't do lighting for contours\n surfaceNormal = vec3(1,0,0);\n eyeDirection = vec3(0,1,0);\n lightDirection = vec3(0,0,1);\n}\n"
+var pickSrc = "#define GLSLIFY 1\nprecision mediump float;\n\nuniform vec2 shape;\nuniform vec3 clipBounds[2];\nuniform float pickId;\n\nvarying float value, kill;\nvarying vec3 worldCoordinate;\nvarying vec2 planeCoordinate;\nvarying vec3 surfaceNormal;\n\nvec2 splitFloat(float v) {\n float vh = 255.0 * v;\n float upper = floor(vh);\n float lower = fract(vh);\n return vec2(upper / 255.0, floor(lower * 16.0) / 16.0);\n}\n\nvoid main() {\n if(kill > 0.0 || \n any(lessThan(worldCoordinate, clipBounds[0])) || any(greaterThan(worldCoordinate, clipBounds[1]))) {\n discard;\n }\n vec2 ux = splitFloat(planeCoordinate.x / shape.x);\n vec2 uy = splitFloat(planeCoordinate.y / shape.y);\n gl_FragColor = vec4(pickId, ux.x, uy.x, ux.y + (uy.y/16.0));\n}"
+
+exports.createShader = function(gl) {
+ var shader = createShader(gl, vertSrc, fragSrc, null, [
+ {name: 'uv', type: 'vec4'},
+ {name: 'f', type: 'vec2'},
+ {name: 'normal', type: 'vec3'}
+ ])
+ shader.attributes.uv.location = 0
+ shader.attributes.f.location = 1
+ shader.attributes.normal.location = 2
+ return shader
+}
+exports.createPickShader = function(gl) {
+ var shader = createShader(gl, vertSrc, pickSrc, null, [
+ {name: 'uv', type: 'vec4'},
+ {name: 'f', type: 'vec2'},
+ {name: 'normal', type: 'vec3'}
+ ])
+ shader.attributes.uv.location = 0
+ shader.attributes.f.location = 1
+ shader.attributes.normal.location = 2
+ return shader
+}
+exports.createContourShader = function(gl) {
+ var shader = createShader(gl, contourVertSrc, fragSrc, null, [
+ {name: 'uv', type: 'vec4'}
+ ])
+ shader.attributes.uv.location = 0
+ return shader
+}
+exports.createPickContourShader = function(gl) {
+ var shader = createShader(gl, contourVertSrc, pickSrc, null, [
+ {name: 'uv', type: 'vec4'}
+ ])
+ shader.attributes.uv.location = 0
+ return shader
+}
+
+},{"gl-shader":154}],180:[function(require,module,exports){
+arguments[4][20][0].apply(exports,arguments)
+},{"dup":20}],181:[function(require,module,exports){
+'use strict'
+
+module.exports = gradient
+
+var dup = require('dup')
+var cwiseCompiler = require('cwise-compiler')
+
+var TEMPLATE_CACHE = {}
+var GRADIENT_CACHE = {}
+
+var EmptyProc = {
+ body: "",
+ args: [],
+ thisVars: [],
+ localVars: []
+}
+
+var centralDiff = cwiseCompiler({
+ args: [ 'array', 'array', 'array' ],
+ pre: EmptyProc,
+ post: EmptyProc,
+ body: {
+ args: [ {
+ name: 'out',
+ lvalue: true,
+ rvalue: false,
+ count: 1
+ }, {
+ name: 'left',
+ lvalue: false,
+ rvalue: true,
+ count: 1
+ }, {
+ name: 'right',
+ lvalue: false,
+ rvalue: true,
+ count: 1
+ }],
+ body: "out=0.5*(left-right)",
+ thisVars: [],
+ localVars: []
+ },
+ funcName: 'cdiff'
+})
+
+var zeroOut = cwiseCompiler({
+ args: [ 'array' ],
+ pre: EmptyProc,
+ post: EmptyProc,
+ body: {
+ args: [ {
+ name: 'out',
+ lvalue: true,
+ rvalue: false,
+ count: 1
+ }],
+ body: "out=0",
+ thisVars: [],
+ localVars: []
+ },
+ funcName: 'zero'
+})
+
+function generateTemplate(d) {
+ if(d in TEMPLATE_CACHE) {
+ return TEMPLATE_CACHE[d]
+ }
+ var code = []
+ for(var i=0; i= 0) {
+ pickStr.push('0')
+ } else if(facet.indexOf(-(i+1)) >= 0) {
+ pickStr.push('s['+i+']-1')
+ } else {
+ pickStr.push('-1')
+ loStr.push('1')
+ hiStr.push('s['+i+']-2')
+ }
+ }
+ var boundStr = '.lo(' + loStr.join() + ').hi(' + hiStr.join() + ')'
+ if(loStr.length === 0) {
+ boundStr = ''
+ }
+
+ if(cod > 0) {
+ code.push('if(1')
+ for(var i=0; i= 0 || facet.indexOf(-(i+1)) >= 0) {
+ continue
+ }
+ code.push('&&s[', i, ']>2')
+ }
+ code.push('){grad', cod, '(src.pick(', pickStr.join(), ')', boundStr)
+ for(var i=0; i= 0 || facet.indexOf(-(i+1)) >= 0) {
+ continue
+ }
+ code.push(',dst.pick(', pickStr.join(), ',', i, ')', boundStr)
+ }
+ code.push(');')
+ }
+
+ for(var i=0; i1){dst.set(',
+ pickStr.join(), ',', bnd, ',0.5*(src.get(',
+ cPickStr.join(), ')-src.get(',
+ dPickStr.join(), ')))}else{dst.set(',
+ pickStr.join(), ',', bnd, ',0)};')
+ } else {
+ code.push('if(s[', bnd, ']>1){diff(', outStr,
+ ',src.pick(', cPickStr.join(), ')', boundStr,
+ ',src.pick(', dPickStr.join(), ')', boundStr,
+ ');}else{zero(', outStr, ');};')
+ }
+ break
+
+ case 'mirror':
+ if(cod === 0) {
+ code.push('dst.set(', pickStr.join(), ',', bnd, ',0);')
+ } else {
+ code.push('zero(', outStr, ');')
+ }
+ break
+
+ case 'wrap':
+ var aPickStr = pickStr.slice()
+ var bPickStr = pickStr.slice()
+ if(facet[i] < 0) {
+ aPickStr[bnd] = 's[' + bnd + ']-2'
+ bPickStr[bnd] = '0'
+
+ } else {
+ aPickStr[bnd] = 's[' + bnd + ']-1'
+ bPickStr[bnd] = '1'
+ }
+ if(cod === 0) {
+ code.push('if(s[', bnd, ']>2){dst.set(',
+ pickStr.join(), ',', bnd, ',0.5*(src.get(',
+ aPickStr.join(), ')-src.get(',
+ bPickStr.join(), ')))}else{dst.set(',
+ pickStr.join(), ',', bnd, ',0)};')
+ } else {
+ code.push('if(s[', bnd, ']>2){diff(', outStr,
+ ',src.pick(', aPickStr.join(), ')', boundStr,
+ ',src.pick(', bPickStr.join(), ')', boundStr,
+ ');}else{zero(', outStr, ');};')
+ }
+ break
+
+ default:
+ throw new Error('ndarray-gradient: Invalid boundary condition')
+ }
+ }
+
+ if(cod > 0) {
+ code.push('};')
+ }
+ }
+
+ //Enumerate ridges, facets, etc. of hypercube
+ for(var i=0; i<(1<= 1) {
+ return true
+ }
+ for(var i=0; i<3; ++i) {
+ if(this._contourCounts[i].length > 0 || this._dynamicCounts[i] > 0) {
+ return true
+ }
+ }
+ return false
+}
+
+proto.pickSlots = 1
+
+proto.setPickBase = function(id) {
+ this.pickId = id
+}
+
+var ZERO_VEC = [0,0,0]
+
+var PROJECT_DATA = {
+ showSurface: false,
+ showContour: false,
+ projections: [IDENTITY.slice(), IDENTITY.slice(), IDENTITY.slice()],
+ clipBounds: [
+ [[0,0,0], [0,0,0]],
+ [[0,0,0], [0,0,0]],
+ [[0,0,0], [0,0,0]]]
+}
+
+function computeProjectionData(camera, obj) {
+ //Compute cube properties
+ var cubeAxis = (obj.axes && obj.axes.lastCubeProps.axis) || ZERO_VEC
+
+ var showSurface = obj.showSurface
+ var showContour = obj.showContour
+
+ for(var i=0; i<3; ++i) {
+ showSurface = showSurface || obj.surfaceProject[i]
+ for(var j=0; j<3; ++j) {
+ showContour = showContour || obj.contourProject[i][j]
+ }
+ }
+
+ for(var i=0; i<3; ++i) {
+ //Construct projection onto axis
+ var axisSquish = PROJECT_DATA.projections[i]
+ for(var j=0; j<16; ++j) {
+ axisSquish[j] = 0
+ }
+ for(var j=0; j<4; ++j) {
+ axisSquish[5*j] = 1
+ }
+ axisSquish[5*i] = 0
+ axisSquish[12+i] = obj.axesBounds[+(cubeAxis[i]>0)][i]
+ multiply(axisSquish, camera.model, axisSquish)
+
+ var nclipBounds = PROJECT_DATA.clipBounds[i]
+ for(var k=0; k<2; ++k) {
+ for(var j=0; j<3; ++j) {
+ nclipBounds[k][j] = camera.clipBounds[k][j]
+ }
+ }
+ nclipBounds[0][i] = -1e8
+ nclipBounds[1][i] = 1e8
+ }
+
+ PROJECT_DATA.showSurface = showSurface
+ PROJECT_DATA.showContour = showContour
+
+ return PROJECT_DATA
+}
+
+var UNIFORMS = {
+ model: IDENTITY,
+ view: IDENTITY,
+ projection: IDENTITY,
+ inverseModel: IDENTITY.slice(),
+ lowerBound: [0,0,0],
+ upperBound: [0,0,0],
+ colorMap: 0,
+ clipBounds: [[0,0,0], [0,0,0]],
+ height: 0.0,
+ contourTint: 0,
+ contourColor: [0,0,0,1],
+ permutation: [1,0,0,0,1,0,0,0,1],
+ zOffset: -1e-4,
+ kambient: 1,
+ kdiffuse: 1,
+ kspecular: 1,
+ lightPosition: [1000,1000,1000],
+ eyePosition: [0,0,0],
+ roughness: 1,
+ fresnel: 1,
+ opacity: 1
+}
+
+var MATRIX_INVERSE = IDENTITY.slice()
+var DEFAULT_PERM = [1,0,0,0,1,0,0,0,1]
+
+function drawCore(params, transparent) {
+ params = params || {}
+ var gl = this.gl
+
+ gl.disable(gl.CULL_FACE)
+
+ this._colorMap.bind(0)
+
+ var uniforms = UNIFORMS
+ uniforms.model = params.model || IDENTITY
+ uniforms.view = params.view || IDENTITY
+ uniforms.projection = params.projection || IDENTITY
+ uniforms.lowerBound = [this.bounds[0][0], this.bounds[0][1], this.colorBounds[0] || this.bounds[0][2]]
+ uniforms.upperBound = [this.bounds[1][0], this.bounds[1][1], this.colorBounds[1] || this.bounds[1][2]]
+ uniforms.contourColor = this.contourColor[0]
+
+ uniforms.inverseModel = invert(uniforms.inverseModel, uniforms.model)
+
+ for(var i=0; i<2; ++i) {
+ var clipClamped = uniforms.clipBounds[i]
+ for(var j=0; j<3; ++j) {
+ clipClamped[j] = Math.min(Math.max(this.clipBounds[i][j], -1e8), 1e8)
+ }
+ }
+
+ uniforms.kambient = this.ambientLight
+ uniforms.kdiffuse = this.diffuseLight
+ uniforms.kspecular = this.specularLight
+
+ uniforms.shape =
+
+ uniforms.roughness = this.roughness
+ uniforms.fresnel = this.fresnel
+ uniforms.opacity = this.opacity
+
+ uniforms.height = 0.0
+ uniforms.permutation = DEFAULT_PERM
+
+ //Compute camera matrix inverse
+ var invCameraMatrix = MATRIX_INVERSE
+ multiply(invCameraMatrix, uniforms.view, uniforms.model)
+ multiply(invCameraMatrix, uniforms.projection, invCameraMatrix)
+ invert(invCameraMatrix, invCameraMatrix)
+
+ for(var i=0; i<3; ++i) {
+ uniforms.eyePosition[i] = invCameraMatrix[12+i] / invCameraMatrix[15]
+ }
+
+ var w = invCameraMatrix[15]
+ for(var i=0; i<3; ++i) {
+ w += this.lightPosition[i] * invCameraMatrix[4*i+3]
+ }
+ for(var i=0; i<3; ++i) {
+ var s = invCameraMatrix[12+i]
+ for(var j=0; j<3; ++j) {
+ s += invCameraMatrix[4*j+i] * this.lightPosition[j]
+ }
+ uniforms.lightPosition[i] = s / w
+ }
+
+ var projectData = computeProjectionData(uniforms, this)
+
+ if(projectData.showSurface && (transparent === (this.opacity < 1))) {
+ //Set up uniforms
+ this._shader.bind()
+ this._shader.uniforms = uniforms
+
+ //Draw it
+ this._vao.bind()
+
+ if(this.showSurface) {
+ this._vao.draw(gl.TRIANGLES, this._vertexCount)
+ }
+
+ //Draw projections of surface
+ for(var i=0; i<3; ++i) {
+ if(!this.surfaceProject[i]) {
+ continue
+ }
+ this._shader.uniforms.model = projectData.projections[i]
+ this._shader.uniforms.clipBounds = projectData.clipBounds[i]
+ this._vao.draw(gl.TRIANGLES, this._vertexCount)
+ }
+
+ this._vao.unbind()
+ }
+
+ if(projectData.showContour && !transparent) {
+ var shader = this._contourShader
+
+ //Don't apply lighting to contours
+ uniforms.kambient = 1.0
+ uniforms.kdiffuse = 0.0
+ uniforms.kspecular = 0.0
+ uniforms.opacity = 1.0
+
+ shader.bind()
+ shader.uniforms = uniforms
+
+ //Draw contour lines
+ var vao = this._contourVAO
+ vao.bind()
+
+ //Draw contour levels
+ for(var i=0; i<3; ++i) {
+ shader.uniforms.permutation = PERMUTATIONS[i]
+ gl.lineWidth(this.contourWidth[i])
+
+ for(var j=0; j>4)/16.0)/255.0
+ var ix = Math.floor(x)
+ var fx = x - ix
+
+ var y = shape[1] * (selection.value[1] + (selection.value[2]&15)/16.0)/255.0
+ var iy = Math.floor(y)
+ var fy = y - iy
+
+ ix += 1
+ iy += 1
+
+ //Compute xyz coordinate
+ var pos = result.position
+ pos[0] = pos[1] = pos[2] = 0
+ for(var dx=0; dx<2; ++dx) {
+ var s = dx ? fx : 1.0 - fx
+ for(var dy=0; dy<2; ++dy) {
+ var t = dy ? fy : 1.0 - fy
+
+ var r = ix + dx
+ var c = iy + dy
+ var w = s * t
+
+ for(var i=0; i<3; ++i) {
+ pos[i] += this._field[i].get(r,c) * w
+ }
+ }
+ }
+
+ //Find closest level
+ var levelIndex = this._pickResult.level
+ for(var j=0; j<3; ++j) {
+ levelIndex[j] = bsearch.le(this.contourLevels[j], pos[j])
+ if(levelIndex[j] < 0) {
+ if(this.contourLevels[j].length > 0) {
+ levelIndex[j] = 0
+ }
+ } else if(levelIndex[j] < this.contourLevels[j].length-1) {
+ var a = this.contourLevels[j][levelIndex[j]]
+ var b = this.contourLevels[j][levelIndex[j]+1]
+ if(Math.abs(a-pos[j]) > Math.abs(b-pos[j])) {
+ levelIndex[j] += 1
+ }
+ }
+ }
+
+ result.index[0] = fx<0.5 ? ix : (ix+1)
+ result.index[1] = fy<0.5 ? iy : (iy+1)
+
+ result.uv[0] = x/shape[0]
+ result.uv[1] = y/shape[1]
+
+ for(var i=0; i<3; ++i) {
+ result.dataCoordinate[i] = this._field[i].get(result.index[0], result.index[1])
+ }
+
+ return result
+}
+
+function padField(nfield, field) {
+
+ var shape = field.shape.slice()
+ var nshape = nfield.shape.slice()
+
+ //Center
+ ops.assign(nfield.lo(1,1).hi(shape[0], shape[1]), field)
+
+ //Edges
+ ops.assign(nfield.lo(1).hi(shape[0], 1),
+ field.hi(shape[0], 1))
+ ops.assign(nfield.lo(1,nshape[1]-1).hi(shape[0],1),
+ field.lo(0,shape[1]-1).hi(shape[0],1))
+ ops.assign(nfield.lo(0,1).hi(1,shape[1]),
+ field.hi(1))
+ ops.assign(nfield.lo(nshape[0]-1,1).hi(1,shape[1]),
+ field.lo(shape[0]-1))
+ //Corners
+ nfield.set(0,0, field.get(0,0))
+ nfield.set(0,nshape[1]-1, field.get(0,shape[1]-1))
+ nfield.set(nshape[0]-1,0, field.get(shape[0]-1,0))
+ nfield.set(nshape[0]-1,nshape[1]-1, field.get(shape[0]-1,shape[1]-1))
+}
+
+function handleArray(param, ctor) {
+ if(Array.isArray(param)) {
+ return [ ctor(param[0]), ctor(param[1]), ctor(param[2]) ]
+ }
+ return [ ctor(param), ctor(param), ctor(param) ]
+}
+
+function toColor(x) {
+ if(Array.isArray(x)) {
+ if(x.length === 3) {
+ return [x[0], x[1], x[2], 1]
+ }
+ return [x[0], x[1], x[2], x[3]]
+ }
+ return [0,0,0,1]
+}
+
+function handleColor(param) {
+ if(Array.isArray(param)) {
+ if(Array.isArray(param)) {
+ return [ toColor(param[0]),
+ toColor(param[1]),
+ toColor(param[2]) ]
+ } else {
+ var c = toColor(param)
+ return [
+ c.slice(),
+ c.slice(),
+ c.slice() ]
+ }
+ }
+}
+
+proto.update = function(params) {
+ params = params || {}
+
+ this.dirty = true
+
+ if('contourWidth' in params) {
+ this.contourWidth = handleArray(params.contourWidth, Number)
+ }
+ if('showContour' in params) {
+ this.showContour = handleArray(params.showContour, Boolean)
+ }
+ if('showSurface' in params) {
+ this.showSurface = !!params.showSurface
+ }
+ if('contourTint' in params) {
+ this.contourTint = handleArray(params.contourTint, Boolean)
+ }
+ if('contourColor' in params) {
+ this.contourColor = handleColor(params.contourColor)
+ }
+ if('contourProject' in params) {
+ this.contourProject = handleArray(params.contourProject, function(x) {
+ return handleArray(x, Boolean)
+ })
+ }
+ if('surfaceProject' in params) {
+ this.surfaceProject = params.surfaceProject
+ }
+ if('dynamicColor' in params) {
+ this.dynamicColor = handleColor(params.dynamicColor)
+ }
+ if('dynamicTint' in params) {
+ this.dynamicTint = handleArray(params.dynamicTint, Number)
+ }
+ if('dynamicWidth' in params) {
+ this.dynamicWidth = handleArray(params.dynamicWidth, Number)
+ }
+ if('opacity' in params) {
+ this.opacity = params.opacity
+ }
+ if('colorBounds' in params) {
+ this.colorBounds = params.colorBounds
+ }
+
+ var field = params.field || (params.coords && params.coords[2]) || null
+
+ if(!field) {
+ if(this._field[2].shape[0] || this._field[2].shape[2]) {
+ field = this._field[2].lo(1,1).hi(this._field[2].shape[0]-2, this._field[2].shape[1]-2)
+ } else {
+ field = this._field[2].hi(0,0)
+ }
+ }
+
+ //Update field
+ if('field' in params || 'coords' in params) {
+ var fsize = (field.shape[0]+2)*(field.shape[1]+2)
+
+ //Resize if necessary
+ if(fsize > this._field[2].data.length) {
+ pool.freeFloat(this._field[2].data)
+ this._field[2].data = pool.mallocFloat(bits.nextPow2(fsize))
+ }
+
+ //Pad field
+ this._field[2] = ndarray(this._field[2].data, [field.shape[0]+2, field.shape[1]+2])
+ padField(this._field[2], field)
+
+ //Save shape of field
+ this.shape = field.shape.slice()
+ var shape = this.shape
+
+ //Resize coordinate fields if necessary
+ for(var i=0; i<2; ++i) {
+ if(this._field[2].size > this._field[i].data.length) {
+ pool.freeFloat(this._field[i].data)
+ this._field[i].data = pool.mallocFloat(this._field[2].size)
+ }
+ this._field[i] = ndarray(this._field[i].data, [shape[0]+2, shape[1]+2])
+ }
+
+ //Generate x/y coordinates
+ if(params.coords) {
+ var coords = params.coords
+ if(!Array.isArray(coords) || coords.length !== 3) {
+ throw new Error('gl-surface: invalid coordinates for x/y')
+ }
+ for(var i=0; i<2; ++i) {
+ var coord = coords[i]
+ for(var j=0; j<2; ++j) {
+ if(coord.shape[j] !== shape[j]) {
+ throw new Error('gl-surface: coords have incorrect shape')
+ }
+ }
+ padField(this._field[i], coord)
+ }
+ } else if(params.ticks) {
+ var ticks = params.ticks
+ if(!Array.isArray(ticks) || ticks.length !== 2) {
+ throw new Error('gl-surface: invalid ticks')
+ }
+ for(var i=0; i<2; ++i) {
+ var tick = ticks[i]
+ if(Array.isArray(tick) || tick.length) {
+ tick = ndarray(tick)
+ }
+ if(tick.shape[0] !== shape[i]) {
+ throw new Error('gl-surface: invalid tick length')
+ }
+ //Make a copy view of the tick array
+ var tick2 = ndarray(tick.data, shape)
+ tick2.stride[i] = tick.stride[0]
+ tick2.stride[i^1] = 0
+
+ //Fill in field array
+ padField(this._field[i], tick2)
+ }
+ } else {
+ for(var i=0; i<2; ++i) {
+ var offset = [0,0]
+ offset[i] = 1
+ this._field[i] = ndarray(this._field[i].data, [shape[0]+2, shape[1]+2], offset, 0)
+ }
+ this._field[0].set(0,0,0)
+ for(var j=0; j 0) {
+ //If we already added first edge, pop off verts
+ for(var l=0; l<4; ++l) {
+ contourVerts.pop()
+ }
+ vertexCount -= 1
+ }
+ continue edge_loop
+ }
+ }
+ }
+ levelCounts.push(vertexCount)
+ }
+
+ //Store results
+ this._contourOffsets[dim] = levelOffsets
+ this._contourCounts[dim] = levelCounts
+ }
+
+ var floatBuffer = pool.mallocFloat(contourVerts.length)
+ for(var i=0; i maxSize || h < 0 || h > maxSize) {
+ throw new Error('gl-texture2d: Invalid texture size')
+ }
+ tex._shape = [w, h]
+ tex.bind()
+ gl.texImage2D(gl.TEXTURE_2D, 0, tex.format, w, h, 0, tex.format, tex.type, null)
+ tex._mipLevels = [0]
+ return tex
+}
+
+function Texture2D(gl, handle, width, height, format, type) {
+ this.gl = gl
+ this.handle = handle
+ this.format = format
+ this.type = type
+ this._shape = [width, height]
+ this._mipLevels = [0]
+ this._magFilter = gl.NEAREST
+ this._minFilter = gl.NEAREST
+ this._wrapS = gl.CLAMP_TO_EDGE
+ this._wrapT = gl.CLAMP_TO_EDGE
+ this._anisoSamples = 1
+
+ var parent = this
+ var wrapVector = [this._wrapS, this._wrapT]
+ Object.defineProperties(wrapVector, [
+ {
+ get: function() {
+ return parent._wrapS
+ },
+ set: function(v) {
+ return parent.wrapS = v
+ }
+ },
+ {
+ get: function() {
+ return parent._wrapT
+ },
+ set: function(v) {
+ return parent.wrapT = v
+ }
+ }
+ ])
+ this._wrapVector = wrapVector
+
+ var shapeVector = [this._shape[0], this._shape[1]]
+ Object.defineProperties(shapeVector, [
+ {
+ get: function() {
+ return parent._shape[0]
+ },
+ set: function(v) {
+ return parent.width = v
+ }
+ },
+ {
+ get: function() {
+ return parent._shape[1]
+ },
+ set: function(v) {
+ return parent.height = v
+ }
+ }
+ ])
+ this._shapeVector = shapeVector
+}
+
+var proto = Texture2D.prototype
+
+Object.defineProperties(proto, {
+ minFilter: {
+ get: function() {
+ return this._minFilter
+ },
+ set: function(v) {
+ this.bind()
+ var gl = this.gl
+ if(this.type === gl.FLOAT && linearTypes.indexOf(v) >= 0) {
+ if(!gl.getExtension('OES_texture_float_linear')) {
+ v = gl.NEAREST
+ }
+ }
+ if(filterTypes.indexOf(v) < 0) {
+ throw new Error('gl-texture2d: Unknown filter mode ' + v)
+ }
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, v)
+ return this._minFilter = v
+ }
+ },
+ magFilter: {
+ get: function() {
+ return this._magFilter
+ },
+ set: function(v) {
+ this.bind()
+ var gl = this.gl
+ if(this.type === gl.FLOAT && linearTypes.indexOf(v) >= 0) {
+ if(!gl.getExtension('OES_texture_float_linear')) {
+ v = gl.NEAREST
+ }
+ }
+ if(filterTypes.indexOf(v) < 0) {
+ throw new Error('gl-texture2d: Unknown filter mode ' + v)
+ }
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, v)
+ return this._magFilter = v
+ }
+ },
+ mipSamples: {
+ get: function() {
+ return this._anisoSamples
+ },
+ set: function(i) {
+ var psamples = this._anisoSamples
+ this._anisoSamples = Math.max(i, 1)|0
+ if(psamples !== this._anisoSamples) {
+ var ext = gl.getExtension('EXT_texture_filter_anisotropic')
+ if(ext) {
+ this.gl.texParameterf(this.gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, this._anisoSamples)
+ }
+ }
+ return this._anisoSamples
+ }
+ },
+ wrapS: {
+ get: function() {
+ return this._wrapS
+ },
+ set: function(v) {
+ this.bind()
+ if(wrapTypes.indexOf(v) < 0) {
+ throw new Error('gl-texture2d: Unknown wrap mode ' + v)
+ }
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, v)
+ return this._wrapS = v
+ }
+ },
+ wrapT: {
+ get: function() {
+ return this._wrapT
+ },
+ set: function(v) {
+ this.bind()
+ if(wrapTypes.indexOf(v) < 0) {
+ throw new Error('gl-texture2d: Unknown wrap mode ' + v)
+ }
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, v)
+ return this._wrapT = v
+ }
+ },
+ wrap: {
+ get: function() {
+ return this._wrapVector
+ },
+ set: function(v) {
+ if(!Array.isArray(v)) {
+ v = [v,v]
+ }
+ if(v.length !== 2) {
+ throw new Error('gl-texture2d: Must specify wrap mode for rows and columns')
+ }
+ for(var i=0; i<2; ++i) {
+ if(wrapTypes.indexOf(v[i]) < 0) {
+ throw new Error('gl-texture2d: Unknown wrap mode ' + v)
+ }
+ }
+ this._wrapS = v[0]
+ this._wrapT = v[1]
+
+ var gl = this.gl
+ this.bind()
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, this._wrapS)
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, this._wrapT)
+
+ return v
+ }
+ },
+ shape: {
+ get: function() {
+ return this._shapeVector
+ },
+ set: function(x) {
+ if(!Array.isArray(x)) {
+ x = [x|0,x|0]
+ } else {
+ if(x.length !== 2) {
+ throw new Error('gl-texture2d: Invalid texture shape')
+ }
+ }
+ reshapeTexture(this, x[0]|0, x[1]|0)
+ return [x[0]|0, x[1]|0]
+ }
+ },
+ width: {
+ get: function() {
+ return this._shape[0]
+ },
+ set: function(w) {
+ w = w|0
+ reshapeTexture(this, w, this._shape[1])
+ return w
+ }
+ },
+ height: {
+ get: function() {
+ return this._shape[1]
+ },
+ set: function(h) {
+ h = h|0
+ reshapeTexture(this, this._shape[0], h)
+ return h
+ }
+ }
+})
+
+proto.bind = function(unit) {
+ var gl = this.gl
+ if(unit !== undefined) {
+ gl.activeTexture(gl.TEXTURE0 + (unit|0))
+ }
+ gl.bindTexture(gl.TEXTURE_2D, this.handle)
+ if(unit !== undefined) {
+ return (unit|0)
+ }
+ return gl.getParameter(gl.ACTIVE_TEXTURE) - gl.TEXTURE0
+}
+
+proto.dispose = function() {
+ this.gl.deleteTexture(this.handle)
+}
+
+proto.generateMipmap = function() {
+ this.bind()
+ this.gl.generateMipmap(this.gl.TEXTURE_2D)
+
+ //Update mip levels
+ var l = Math.min(this._shape[0], this._shape[1])
+ for(var i=0; l>0; ++i, l>>>=1) {
+ if(this._mipLevels.indexOf(i) < 0) {
+ this._mipLevels.push(i)
+ }
+ }
+}
+
+proto.setPixels = function(data, x_off, y_off, mip_level) {
+ var gl = this.gl
+ this.bind()
+ if(Array.isArray(x_off)) {
+ mip_level = y_off
+ y_off = x_off[1]|0
+ x_off = x_off[0]|0
+ } else {
+ x_off = x_off || 0
+ y_off = y_off || 0
+ }
+ mip_level = mip_level || 0
+ if(data instanceof HTMLCanvasElement ||
+ data instanceof ImageData ||
+ data instanceof HTMLImageElement ||
+ data instanceof HTMLVideoElement) {
+ var needsMip = this._mipLevels.indexOf(mip_level) < 0
+ if(needsMip) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.format, this.type, data)
+ this._mipLevels.push(mip_level)
+ } else {
+ gl.texSubImage2D(gl.TEXTURE_2D, mip_level, x_off, y_off, this.format, this.type, data)
+ }
+ } else if(data.shape && data.stride && data.data) {
+ if(data.shape.length < 2 ||
+ x_off + data.shape[1] > this._shape[1]>>>mip_level ||
+ y_off + data.shape[0] > this._shape[0]>>>mip_level ||
+ x_off < 0 ||
+ y_off < 0) {
+ throw new Error('gl-texture2d: Texture dimensions are out of bounds')
+ }
+ texSubImageArray(gl, x_off, y_off, mip_level, this.format, this.type, this._mipLevels, data)
+ } else {
+ throw new Error('gl-texture2d: Unsupported data type')
+ }
+}
+
+
+function isPacked(shape, stride) {
+ if(shape.length === 3) {
+ return (stride[2] === 1) &&
+ (stride[1] === shape[0]*shape[2]) &&
+ (stride[0] === shape[2])
+ }
+ return (stride[0] === 1) &&
+ (stride[1] === shape[0])
+}
+
+function texSubImageArray(gl, x_off, y_off, mip_level, cformat, ctype, mipLevels, array) {
+ var dtype = array.dtype
+ var shape = array.shape.slice()
+ if(shape.length < 2 || shape.length > 3) {
+ throw new Error('gl-texture2d: Invalid ndarray, must be 2d or 3d')
+ }
+ var type = 0, format = 0
+ var packed = isPacked(shape, array.stride.slice())
+ if(dtype === 'float32') {
+ type = gl.FLOAT
+ } else if(dtype === 'float64') {
+ type = gl.FLOAT
+ packed = false
+ dtype = 'float32'
+ } else if(dtype === 'uint8') {
+ type = gl.UNSIGNED_BYTE
+ } else {
+ type = gl.UNSIGNED_BYTE
+ packed = false
+ dtype = 'uint8'
+ }
+ var channels = 1
+ if(shape.length === 2) {
+ format = gl.LUMINANCE
+ shape = [shape[0], shape[1], 1]
+ array = ndarray(array.data, shape, [array.stride[0], array.stride[1], 1], array.offset)
+ } else if(shape.length === 3) {
+ if(shape[2] === 1) {
+ format = gl.ALPHA
+ } else if(shape[2] === 2) {
+ format = gl.LUMINANCE_ALPHA
+ } else if(shape[2] === 3) {
+ format = gl.RGB
+ } else if(shape[2] === 4) {
+ format = gl.RGBA
+ } else {
+ throw new Error('gl-texture2d: Invalid shape for pixel coords')
+ }
+ channels = shape[2]
+ } else {
+ throw new Error('gl-texture2d: Invalid shape for texture')
+ }
+ //For 1-channel textures allow conversion between formats
+ if((format === gl.LUMINANCE || format === gl.ALPHA) &&
+ (cformat === gl.LUMINANCE || cformat === gl.ALPHA)) {
+ format = cformat
+ }
+ if(format !== cformat) {
+ throw new Error('gl-texture2d: Incompatible texture format for setPixels')
+ }
+ var size = array.size
+ var needsMip = mipLevels.indexOf(mip_level) < 0
+ if(needsMip) {
+ mipLevels.push(mip_level)
+ }
+ if(type === ctype && packed) {
+ //Array data types are compatible, can directly copy into texture
+ if(array.offset === 0 && array.data.length === size) {
+ if(needsMip) {
+ gl.texImage2D(gl.TEXTURE_2D, mip_level, cformat, shape[0], shape[1], 0, cformat, ctype, array.data)
+ } else {
+ gl.texSubImage2D(gl.TEXTURE_2D, mip_level, x_off, y_off, shape[0], shape[1], cformat, ctype, array.data)
+ }
+ } else {
+ if(needsMip) {
+ gl.texImage2D(gl.TEXTURE_2D, mip_level, cformat, shape[0], shape[1], 0, cformat, ctype, array.data.subarray(array.offset, array.offset+size))
+ } else {
+ gl.texSubImage2D(gl.TEXTURE_2D, mip_level, x_off, y_off, shape[0], shape[1], cformat, ctype, array.data.subarray(array.offset, array.offset+size))
+ }
+ }
+ } else {
+ //Need to do type conversion to pack data into buffer
+ var pack_buffer
+ if(ctype === gl.FLOAT) {
+ pack_buffer = pool.mallocFloat32(size)
+ } else {
+ pack_buffer = pool.mallocUint8(size)
+ }
+ var pack_view = ndarray(pack_buffer, shape, [shape[2], shape[2]*shape[0], 1])
+ if(type === gl.FLOAT && ctype === gl.UNSIGNED_BYTE) {
+ convertFloatToUint8(pack_view, array)
+ } else {
+ ops.assign(pack_view, array)
+ }
+ if(needsMip) {
+ gl.texImage2D(gl.TEXTURE_2D, mip_level, cformat, shape[0], shape[1], 0, cformat, ctype, pack_buffer.subarray(0, size))
+ } else {
+ gl.texSubImage2D(gl.TEXTURE_2D, mip_level, x_off, y_off, shape[0], shape[1], cformat, ctype, pack_buffer.subarray(0, size))
+ }
+ if(ctype === gl.FLOAT) {
+ pool.freeFloat32(pack_buffer)
+ } else {
+ pool.freeUint8(pack_buffer)
+ }
+ }
+}
+
+function initTexture(gl) {
+ var tex = gl.createTexture()
+ gl.bindTexture(gl.TEXTURE_2D, tex)
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
+ return tex
+}
+
+function createTextureShape(gl, width, height, format, type) {
+ var maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE)
+ if(width < 0 || width > maxTextureSize || height < 0 || height > maxTextureSize) {
+ throw new Error('gl-texture2d: Invalid texture shape')
+ }
+ if(type === gl.FLOAT && !gl.getExtension('OES_texture_float')) {
+ throw new Error('gl-texture2d: Floating point textures not supported on this platform')
+ }
+ var tex = initTexture(gl)
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, format, type, null)
+ return new Texture2D(gl, tex, width, height, format, type)
+}
+
+function createTextureDOM(gl, element, format, type) {
+ var tex = initTexture(gl)
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, format, type, element)
+ return new Texture2D(gl, tex, element.width|0, element.height|0, format, type)
+}
+
+//Creates a texture from an ndarray
+function createTextureArray(gl, array) {
+ var dtype = array.dtype
+ var shape = array.shape.slice()
+ var maxSize = gl.getParameter(gl.MAX_TEXTURE_SIZE)
+ if(shape[0] < 0 || shape[0] > maxSize || shape[1] < 0 || shape[1] > maxSize) {
+ throw new Error('gl-texture2d: Invalid texture size')
+ }
+ var packed = isPacked(shape, array.stride.slice())
+ var type = 0
+ if(dtype === 'float32') {
+ type = gl.FLOAT
+ } else if(dtype === 'float64') {
+ type = gl.FLOAT
+ packed = false
+ dtype = 'float32'
+ } else if(dtype === 'uint8') {
+ type = gl.UNSIGNED_BYTE
+ } else {
+ type = gl.UNSIGNED_BYTE
+ packed = false
+ dtype = 'uint8'
+ }
+ var format = 0
+ if(shape.length === 2) {
+ format = gl.LUMINANCE
+ shape = [shape[0], shape[1], 1]
+ array = ndarray(array.data, shape, [array.stride[0], array.stride[1], 1], array.offset)
+ } else if(shape.length === 3) {
+ if(shape[2] === 1) {
+ format = gl.ALPHA
+ } else if(shape[2] === 2) {
+ format = gl.LUMINANCE_ALPHA
+ } else if(shape[2] === 3) {
+ format = gl.RGB
+ } else if(shape[2] === 4) {
+ format = gl.RGBA
+ } else {
+ throw new Error('gl-texture2d: Invalid shape for pixel coords')
+ }
+ } else {
+ throw new Error('gl-texture2d: Invalid shape for texture')
+ }
+ if(type === gl.FLOAT && !gl.getExtension('OES_texture_float')) {
+ type = gl.UNSIGNED_BYTE
+ packed = false
+ }
+ var buffer, buf_store
+ var size = array.size
+ if(!packed) {
+ var stride = [shape[2], shape[2]*shape[0], 1]
+ buf_store = pool.malloc(size, dtype)
+ var buf_array = ndarray(buf_store, shape, stride, 0)
+ if((dtype === 'float32' || dtype === 'float64') && type === gl.UNSIGNED_BYTE) {
+ convertFloatToUint8(buf_array, array)
+ } else {
+ ops.assign(buf_array, array)
+ }
+ buffer = buf_store.subarray(0, size)
+ } else if (array.offset === 0 && array.data.length === size) {
+ buffer = array.data
+ } else {
+ buffer = array.data.subarray(array.offset, array.offset + size)
+ }
+ var tex = initTexture(gl)
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, shape[0], shape[1], 0, format, type, buffer)
+ if(!packed) {
+ pool.free(buf_store)
+ }
+ return new Texture2D(gl, tex, shape[0], shape[1], format, type)
+}
+
+function createTexture2D(gl) {
+ if(arguments.length <= 1) {
+ throw new Error('gl-texture2d: Missing arguments for texture2d constructor')
+ }
+ if(!linearTypes) {
+ lazyInitLinearTypes(gl)
+ }
+ if(typeof arguments[1] === 'number') {
+ return createTextureShape(gl, arguments[1], arguments[2], arguments[3]||gl.RGBA, arguments[4]||gl.UNSIGNED_BYTE)
+ }
+ if(Array.isArray(arguments[1])) {
+ return createTextureShape(gl, arguments[1][0]|0, arguments[1][1]|0, arguments[2]||gl.RGBA, arguments[3]||gl.UNSIGNED_BYTE)
+ }
+ if(typeof arguments[1] === 'object') {
+ var obj = arguments[1]
+ if(obj instanceof HTMLCanvasElement ||
+ obj instanceof HTMLImageElement ||
+ obj instanceof HTMLVideoElement ||
+ obj instanceof ImageData) {
+ return createTextureDOM(gl, obj, arguments[2]||gl.RGBA, arguments[3]||gl.UNSIGNED_BYTE)
+ } else if(obj.shape && obj.data && obj.stride) {
+ return createTextureArray(gl, obj)
+ }
+ }
+ throw new Error('gl-texture2d: Invalid arguments for texture2d constructor')
+}
+
+},{"ndarray":208,"ndarray-ops":207,"typedarray-pool":233}],186:[function(require,module,exports){
+"use strict"
+
+function doBind(gl, elements, attributes) {
+ if(elements) {
+ elements.bind()
+ } else {
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null)
+ }
+ var nattribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS)|0
+ if(attributes) {
+ if(attributes.length > nattribs) {
+ throw new Error("gl-vao: Too many vertex attributes")
+ }
+ for(var i=0; i 0) {
+ code.push(",")
+ }
+ code.push("tuple[", i, "]")
+ }
+ code.push(")}return orient")
+ var proc = new Function("test", code.join(""))
+ var test = orient[d+1]
+ if(!test) {
+ test = orient
+ }
+ return proc(test)
+}
+
+var BAKED = []
+
+function Triangulation(dimension, vertices, simplices) {
+ this.dimension = dimension
+ this.vertices = vertices
+ this.simplices = simplices
+ this.interior = simplices.filter(function(c) {
+ return !c.boundary
+ })
+
+ this.tuple = new Array(dimension+1)
+ for(var i=0; i<=dimension; ++i) {
+ this.tuple[i] = this.vertices[i]
+ }
+
+ var o = BAKED[dimension]
+ if(!o) {
+ o = BAKED[dimension] = bakeOrient(dimension)
+ }
+ this.orient = o
+}
+
+var proto = Triangulation.prototype
+
+//Degenerate situation where we are on boundary, but coplanar to face
+proto.handleBoundaryDegeneracy = function(cell, point) {
+ var d = this.dimension
+ var n = this.vertices.length - 1
+ var tuple = this.tuple
+ var verts = this.vertices
+
+ //Dumb solution: Just do dfs from boundary cell until we find any peak, or terminate
+ var toVisit = [ cell ]
+ cell.lastVisited = -n
+ while(toVisit.length > 0) {
+ cell = toVisit.pop()
+ var cellVerts = cell.vertices
+ var cellAdj = cell.adjacent
+ for(var i=0; i<=d; ++i) {
+ var neighbor = cellAdj[i]
+ if(!neighbor.boundary || neighbor.lastVisited <= -n) {
+ continue
+ }
+ var nv = neighbor.vertices
+ for(var j=0; j<=d; ++j) {
+ var vv = nv[j]
+ if(vv < 0) {
+ tuple[j] = point
+ } else {
+ tuple[j] = verts[vv]
+ }
+ }
+ var o = this.orient()
+ if(o > 0) {
+ return neighbor
+ }
+ neighbor.lastVisited = -n
+ if(o === 0) {
+ toVisit.push(neighbor)
+ }
+ }
+ }
+ return null
+}
+
+proto.walk = function(point, random) {
+ //Alias local properties
+ var n = this.vertices.length - 1
+ var d = this.dimension
+ var verts = this.vertices
+ var tuple = this.tuple
+
+ //Compute initial jump cell
+ var initIndex = random ? (this.interior.length * Math.random())|0 : (this.interior.length-1)
+ var cell = this.interior[ initIndex ]
+
+ //Start walking
+outerLoop:
+ while(!cell.boundary) {
+ var cellVerts = cell.vertices
+ var cellAdj = cell.adjacent
+
+ for(var i=0; i<=d; ++i) {
+ tuple[i] = verts[cellVerts[i]]
+ }
+ cell.lastVisited = n
+
+ //Find farthest adjacent cell
+ for(var i=0; i<=d; ++i) {
+ var neighbor = cellAdj[i]
+ if(neighbor.lastVisited >= n) {
+ continue
+ }
+ var prev = tuple[i]
+ tuple[i] = point
+ var o = this.orient()
+ tuple[i] = prev
+ if(o < 0) {
+ cell = neighbor
+ continue outerLoop
+ } else {
+ if(!neighbor.boundary) {
+ neighbor.lastVisited = n
+ } else {
+ neighbor.lastVisited = -n
+ }
+ }
+ }
+ return
+ }
+
+ return cell
+}
+
+proto.addPeaks = function(point, cell) {
+ var n = this.vertices.length - 1
+ var d = this.dimension
+ var verts = this.vertices
+ var tuple = this.tuple
+ var interior = this.interior
+ var simplices = this.simplices
+
+ //Walking finished at boundary, time to add peaks
+ var tovisit = [ cell ]
+
+ //Stretch initial boundary cell into a peak
+ cell.lastVisited = n
+ cell.vertices[cell.vertices.indexOf(-1)] = n
+ cell.boundary = false
+ interior.push(cell)
+
+ //Record a list of all new boundaries created by added peaks so we can glue them together when we are all done
+ var glueFacets = []
+
+ //Do a traversal of the boundary walking outward from starting peak
+ while(tovisit.length > 0) {
+ //Pop off peak and walk over adjacent cells
+ var cell = tovisit.pop()
+ var cellVerts = cell.vertices
+ var cellAdj = cell.adjacent
+ var indexOfN = cellVerts.indexOf(n)
+ if(indexOfN < 0) {
+ continue
+ }
+
+ for(var i=0; i<=d; ++i) {
+ if(i === indexOfN) {
+ continue
+ }
+
+ //For each boundary neighbor of the cell
+ var neighbor = cellAdj[i]
+ if(!neighbor.boundary || neighbor.lastVisited >= n) {
+ continue
+ }
+
+ var nv = neighbor.vertices
+
+ //Test if neighbor is a peak
+ if(neighbor.lastVisited !== -n) {
+ //Compute orientation of p relative to each boundary peak
+ var indexOfNeg1 = 0
+ for(var j=0; j<=d; ++j) {
+ if(nv[j] < 0) {
+ indexOfNeg1 = j
+ tuple[j] = point
+ } else {
+ tuple[j] = verts[nv[j]]
+ }
+ }
+ var o = this.orient()
+
+ //Test if neighbor cell is also a peak
+ if(o > 0) {
+ nv[indexOfNeg1] = n
+ neighbor.boundary = false
+ interior.push(neighbor)
+ tovisit.push(neighbor)
+ neighbor.lastVisited = n
+ continue
+ } else {
+ neighbor.lastVisited = -n
+ }
+ }
+
+ var na = neighbor.adjacent
+
+ //Otherwise, replace neighbor with new face
+ var vverts = cellVerts.slice()
+ var vadj = cellAdj.slice()
+ var ncell = new Simplex(vverts, vadj, true)
+ simplices.push(ncell)
+
+ //Connect to neighbor
+ var opposite = na.indexOf(cell)
+ if(opposite < 0) {
+ continue
+ }
+ na[opposite] = ncell
+ vadj[indexOfN] = neighbor
+
+ //Connect to cell
+ vverts[i] = -1
+ vadj[i] = cell
+ cellAdj[i] = ncell
+
+ //Flip facet
+ ncell.flip()
+
+ //Add to glue list
+ for(var j=0; j<=d; ++j) {
+ var uu = vverts[j]
+ if(uu < 0 || uu === n) {
+ continue
+ }
+ var nface = new Array(d-1)
+ var nptr = 0
+ for(var k=0; k<=d; ++k) {
+ var vv = vverts[k]
+ if(vv < 0 || k === j) {
+ continue
+ }
+ nface[nptr++] = vv
+ }
+ glueFacets.push(new GlueFacet(nface, ncell, j))
+ }
+ }
+ }
+
+ //Glue boundary facets together
+ glueFacets.sort(compareGlue)
+
+ for(var i=0; i+1= 0) {
+ bcell[ptr++] = cv[j]
+ } else {
+ parity = j&1
+ }
+ }
+ if(parity === (d&1)) {
+ var t = bcell[0]
+ bcell[0] = bcell[1]
+ bcell[1] = t
+ }
+ boundary.push(bcell)
+ }
+ }
+ return boundary
+}
+
+function incrementalConvexHull(points, randomSearch) {
+ var n = points.length
+ if(n === 0) {
+ throw new Error("Must have at least d+1 points")
+ }
+ var d = points[0].length
+ if(n <= d) {
+ throw new Error("Must input at least d+1 points")
+ }
+
+ //FIXME: This could be degenerate, but need to select d+1 non-coplanar points to bootstrap process
+ var initialSimplex = points.slice(0, d+1)
+
+ //Make sure initial simplex is positively oriented
+ var o = orient.apply(void 0, initialSimplex)
+ if(o === 0) {
+ throw new Error("Input not in general position")
+ }
+ var initialCoords = new Array(d+1)
+ for(var i=0; i<=d; ++i) {
+ initialCoords[i] = i
+ }
+ if(o < 0) {
+ initialCoords[0] = 1
+ initialCoords[1] = 0
+ }
+
+ //Create initial topological index, glue pointers together (kind of messy)
+ var initialCell = new Simplex(initialCoords, new Array(d+1), false)
+ var boundary = initialCell.adjacent
+ var list = new Array(d+2)
+ for(var i=0; i<=d; ++i) {
+ var verts = initialCoords.slice()
+ for(var j=0; j<=d; ++j) {
+ if(j === i) {
+ verts[j] = -1
+ }
+ }
+ var t = verts[0]
+ verts[0] = verts[1]
+ verts[1] = t
+ var cell = new Simplex(verts, new Array(d+1), true)
+ boundary[i] = cell
+ list[i] = cell
+ }
+ list[d+1] = initialCell
+ for(var i=0; i<=d; ++i) {
+ var verts = boundary[i].vertices
+ var adj = boundary[i].adjacent
+ for(var j=0; j<=d; ++j) {
+ var v = verts[j]
+ if(v < 0) {
+ adj[j] = initialCell
+ continue
+ }
+ for(var k=0; k<=d; ++k) {
+ if(boundary[k].vertices.indexOf(v) < 0) {
+ adj[j] = boundary[k]
+ }
+ }
+ }
+ }
+
+ //Initialize triangles
+ var triangles = new Triangulation(d, initialSimplex, list)
+
+ //Insert remaining points
+ var useRandom = !!randomSearch
+ for(var i=d+1; i> 1
+ , s = compareCells(cells[mid], c)
+ if(s <= 0) {
+ if(s === 0) {
+ r = mid
+ }
+ lo = mid + 1
+ } else if(s > 0) {
+ hi = mid - 1
+ }
+ }
+ return r
+}
+exports.findCell = findCell;
+
+//Builds an index for an n-cell. This is more general than dual, but less efficient
+function incidence(from_cells, to_cells) {
+ var index = new Array(from_cells.length)
+ for(var i=0, il=index.length; i= from_cells.length || compareCells(from_cells[idx], b) !== 0) {
+ break
+ }
+ }
+ }
+ }
+ return index
+}
+exports.incidence = incidence
+
+//Computes the dual of the mesh. This is basically an optimized version of buildIndex for the situation where from_cells is just the list of vertices
+function dual(cells, vertex_count) {
+ if(!vertex_count) {
+ return incidence(unique(skeleton(cells, 0)), cells, 0)
+ }
+ var res = new Array(vertex_count)
+ for(var i=0; i>> k) & 1) {
+ b.push(c[k])
+ }
+ }
+ result.push(b)
+ }
+ }
+ return normalize(result)
+}
+exports.explode = explode
+
+//Enumerates all of the n-cells of a cell complex
+function skeleton(cells, n) {
+ if(n < 0) {
+ return []
+ }
+ var result = []
+ , k0 = (1<<(n+1))-1
+ for(var i=0; i 0) {
+ return 1<<(b-1)
+ }
+ } else if('button' in ev) {
+ var b = ev.button
+ if(b === 1) {
+ return 4
+ } else if(b === 2) {
+ return 2
+ } else if(b >= 0) {
+ return 1<>",
+ rrshift: ">>>"
+}
+;(function(){
+ for(var id in assign_ops) {
+ var op = assign_ops[id]
+ exports[id] = makeOp({
+ args: ["array","array","array"],
+ body: {args:["a","b","c"],
+ body: "a=b"+op+"c"},
+ funcName: id
+ })
+ exports[id+"eq"] = makeOp({
+ args: ["array","array"],
+ body: {args:["a","b"],
+ body:"a"+op+"=b"},
+ rvalue: true,
+ funcName: id+"eq"
+ })
+ exports[id+"s"] = makeOp({
+ args: ["array", "array", "scalar"],
+ body: {args:["a","b","s"],
+ body:"a=b"+op+"s"},
+ funcName: id+"s"
+ })
+ exports[id+"seq"] = makeOp({
+ args: ["array","scalar"],
+ body: {args:["a","s"],
+ body:"a"+op+"=s"},
+ rvalue: true,
+ funcName: id+"seq"
+ })
+ }
+})();
+
+var unary_ops = {
+ not: "!",
+ bnot: "~",
+ neg: "-",
+ recip: "1.0/"
+}
+;(function(){
+ for(var id in unary_ops) {
+ var op = unary_ops[id]
+ exports[id] = makeOp({
+ args: ["array", "array"],
+ body: {args:["a","b"],
+ body:"a="+op+"b"},
+ funcName: id
+ })
+ exports[id+"eq"] = makeOp({
+ args: ["array"],
+ body: {args:["a"],
+ body:"a="+op+"a"},
+ rvalue: true,
+ count: 2,
+ funcName: id+"eq"
+ })
+ }
+})();
+
+var binary_ops = {
+ and: "&&",
+ or: "||",
+ eq: "===",
+ neq: "!==",
+ lt: "<",
+ gt: ">",
+ leq: "<=",
+ geq: ">="
+}
+;(function() {
+ for(var id in binary_ops) {
+ var op = binary_ops[id]
+ exports[id] = makeOp({
+ args: ["array","array","array"],
+ body: {args:["a", "b", "c"],
+ body:"a=b"+op+"c"},
+ funcName: id
+ })
+ exports[id+"s"] = makeOp({
+ args: ["array","array","scalar"],
+ body: {args:["a", "b", "s"],
+ body:"a=b"+op+"s"},
+ funcName: id+"s"
+ })
+ exports[id+"eq"] = makeOp({
+ args: ["array", "array"],
+ body: {args:["a", "b"],
+ body:"a=a"+op+"b"},
+ rvalue:true,
+ count:2,
+ funcName: id+"eq"
+ })
+ exports[id+"seq"] = makeOp({
+ args: ["array", "scalar"],
+ body: {args:["a","s"],
+ body:"a=a"+op+"s"},
+ rvalue:true,
+ count:2,
+ funcName: id+"seq"
+ })
+ }
+})();
+
+var math_unary = [
+ "abs",
+ "acos",
+ "asin",
+ "atan",
+ "ceil",
+ "cos",
+ "exp",
+ "floor",
+ "log",
+ "round",
+ "sin",
+ "sqrt",
+ "tan"
+]
+;(function() {
+ for(var i=0; ithis_s){this_s=-a}else if(a>this_s){this_s=a}", localVars: [], thisVars: ["this_s"]},
+ post: {args:[], localVars:[], thisVars:["this_s"], body:"return this_s"},
+ funcName: "norminf"
+})
+
+exports.norm1 = compile({
+ args:["array"],
+ pre: {args:[], localVars:[], thisVars:["this_s"], body:"this_s=0"},
+ body: {args:[{name:"a", lvalue:false, rvalue:true, count:3}], body: "this_s+=a<0?-a:a", localVars: [], thisVars: ["this_s"]},
+ post: {args:[], localVars:[], thisVars:["this_s"], body:"return this_s"},
+ funcName: "norm1"
+})
+
+exports.sup = compile({
+ args: [ "array" ],
+ pre:
+ { body: "this_h=-Infinity",
+ args: [],
+ thisVars: [ "this_h" ],
+ localVars: [] },
+ body:
+ { body: "if(_inline_1_arg0_>this_h)this_h=_inline_1_arg0_",
+ args: [{"name":"_inline_1_arg0_","lvalue":false,"rvalue":true,"count":2} ],
+ thisVars: [ "this_h" ],
+ localVars: [] },
+ post:
+ { body: "return this_h",
+ args: [],
+ thisVars: [ "this_h" ],
+ localVars: [] }
+ })
+
+exports.inf = compile({
+ args: [ "array" ],
+ pre:
+ { body: "this_h=Infinity",
+ args: [],
+ thisVars: [ "this_h" ],
+ localVars: [] },
+ body:
+ { body: "if(_inline_1_arg0_this_v){this_v=_inline_1_arg1_;for(var _inline_1_k=0;_inline_1_k<_inline_1_arg0_.length;++_inline_1_k){this_i[_inline_1_k]=_inline_1_arg0_[_inline_1_k]}}}",
+ args:[
+ {name:"_inline_1_arg0_",lvalue:false,rvalue:true,count:2},
+ {name:"_inline_1_arg1_",lvalue:false,rvalue:true,count:2}],
+ thisVars:["this_i","this_v"],
+ localVars:["_inline_1_k"]},
+ post:{
+ body:"{return this_i}",
+ args:[],
+ thisVars:["this_i"],
+ localVars:[]}
+})
+
+exports.random = makeOp({
+ args: ["array"],
+ pre: {args:[], body:"this_f=Math.random", thisVars:["this_f"]},
+ body: {args: ["a"], body:"a=this_f()", thisVars:["this_f"]},
+ funcName: "random"
+})
+
+exports.assign = makeOp({
+ args:["array", "array"],
+ body: {args:["a", "b"], body:"a=b"},
+ funcName: "assign" })
+
+exports.assigns = makeOp({
+ args:["array", "scalar"],
+ body: {args:["a", "b"], body:"a=b"},
+ funcName: "assigns" })
+
+
+exports.equals = compile({
+ args:["array", "array"],
+ pre: EmptyProc,
+ body: {args:[{name:"x", lvalue:false, rvalue:true, count:1},
+ {name:"y", lvalue:false, rvalue:true, count:1}],
+ body: "if(x!==y){return false}",
+ localVars: [],
+ thisVars: []},
+ post: {args:[], localVars:[], thisVars:[], body:"return true"},
+ funcName: "equals"
+})
+
+
+
+},{"cwise-compiler":66}],208:[function(require,module,exports){
+var iota = require("iota-array")
+var isBuffer = require("is-buffer")
+
+var hasTypedArrays = ((typeof Float64Array) !== "undefined")
+
+function compare1st(a, b) {
+ return a[0] - b[0]
+}
+
+function order() {
+ var stride = this.stride
+ var terms = new Array(stride.length)
+ var i
+ for(i=0; iMath.abs(this.stride[1]))?[1,0]:[0,1]}})")
+ } else if(dimension === 3) {
+ code.push(
+"var s0=Math.abs(this.stride[0]),s1=Math.abs(this.stride[1]),s2=Math.abs(this.stride[2]);\
+if(s0>s1){\
+if(s1>s2){\
+return [2,1,0];\
+}else if(s0>s2){\
+return [1,2,0];\
+}else{\
+return [1,0,2];\
+}\
+}else if(s0>s2){\
+return [2,0,1];\
+}else if(s2>s1){\
+return [0,1,2];\
+}else{\
+return [0,2,1];\
+}}})")
+ }
+ } else {
+ code.push("ORDER})")
+ }
+ }
+
+ //view.set(i0, ..., v):
+ code.push(
+"proto.set=function "+className+"_set("+args.join(",")+",v){")
+ if(useGetters) {
+ code.push("return this.data.set("+index_str+",v)}")
+ } else {
+ code.push("return this.data["+index_str+"]=v}")
+ }
+
+ //view.get(i0, ...):
+ code.push("proto.get=function "+className+"_get("+args.join(",")+"){")
+ if(useGetters) {
+ code.push("return this.data.get("+index_str+")}")
+ } else {
+ code.push("return this.data["+index_str+"]}")
+ }
+
+ //view.index:
+ code.push(
+ "proto.index=function "+className+"_index(", args.join(), "){return "+index_str+"}")
+
+ //view.hi():
+ code.push("proto.hi=function "+className+"_hi("+args.join(",")+"){return new "+className+"(this.data,"+
+ indices.map(function(i) {
+ return ["(typeof i",i,"!=='number'||i",i,"<0)?this.shape[", i, "]:i", i,"|0"].join("")
+ }).join(",")+","+
+ indices.map(function(i) {
+ return "this.stride["+i + "]"
+ }).join(",")+",this.offset)}")
+
+ //view.lo():
+ var a_vars = indices.map(function(i) { return "a"+i+"=this.shape["+i+"]" })
+ var c_vars = indices.map(function(i) { return "c"+i+"=this.stride["+i+"]" })
+ code.push("proto.lo=function "+className+"_lo("+args.join(",")+"){var b=this.offset,d=0,"+a_vars.join(",")+","+c_vars.join(","))
+ for(var i=0; i=0){\
+d=i"+i+"|0;\
+b+=c"+i+"*d;\
+a"+i+"-=d}")
+ }
+ code.push("return new "+className+"(this.data,"+
+ indices.map(function(i) {
+ return "a"+i
+ }).join(",")+","+
+ indices.map(function(i) {
+ return "c"+i
+ }).join(",")+",b)}")
+
+ //view.step():
+ code.push("proto.step=function "+className+"_step("+args.join(",")+"){var "+
+ indices.map(function(i) {
+ return "a"+i+"=this.shape["+i+"]"
+ }).join(",")+","+
+ indices.map(function(i) {
+ return "b"+i+"=this.stride["+i+"]"
+ }).join(",")+",c=this.offset,d=0,ceil=Math.ceil")
+ for(var i=0; i=0){c=(c+this.stride["+i+"]*i"+i+")|0}else{a.push(this.shape["+i+"]);b.push(this.stride["+i+"])}")
+ }
+ code.push("var ctor=CTOR_LIST[a.length+1];return ctor(this.data,a,b,c)}")
+
+ //Add return statement
+ code.push("return function construct_"+className+"(data,shape,stride,offset){return new "+className+"(data,"+
+ indices.map(function(i) {
+ return "shape["+i+"]"
+ }).join(",")+","+
+ indices.map(function(i) {
+ return "stride["+i+"]"
+ }).join(",")+",offset)}")
+
+ //Compile procedure
+ var procedure = new Function("CTOR_LIST", "ORDER", code.join("\n"))
+ return procedure(CACHED_CONSTRUCTORS[dtype], order)
+}
+
+function arrayDType(data) {
+ if(isBuffer(data)) {
+ return "buffer"
+ }
+ if(hasTypedArrays) {
+ switch(Object.prototype.toString.call(data)) {
+ case "[object Float64Array]":
+ return "float64"
+ case "[object Float32Array]":
+ return "float32"
+ case "[object Int8Array]":
+ return "int8"
+ case "[object Int16Array]":
+ return "int16"
+ case "[object Int32Array]":
+ return "int32"
+ case "[object Uint8Array]":
+ return "uint8"
+ case "[object Uint16Array]":
+ return "uint16"
+ case "[object Uint32Array]":
+ return "uint32"
+ case "[object Uint8ClampedArray]":
+ return "uint8_clamped"
+ }
+ }
+ if(Array.isArray(data)) {
+ return "array"
+ }
+ return "generic"
+}
+
+var CACHED_CONSTRUCTORS = {
+ "float32":[],
+ "float64":[],
+ "int8":[],
+ "int16":[],
+ "int32":[],
+ "uint8":[],
+ "uint16":[],
+ "uint32":[],
+ "array":[],
+ "uint8_clamped":[],
+ "buffer":[],
+ "generic":[]
+}
+
+;(function() {
+ for(var id in CACHED_CONSTRUCTORS) {
+ CACHED_CONSTRUCTORS[id].push(compileConstructor(id, -1))
+ }
+});
+
+function wrappedNDArrayCtor(data, shape, stride, offset) {
+ if(data === undefined) {
+ var ctor = CACHED_CONSTRUCTORS.array[0]
+ return ctor([])
+ } else if(typeof data === "number") {
+ data = [data]
+ }
+ if(shape === undefined) {
+ shape = [ data.length ]
+ }
+ var d = shape.length
+ if(stride === undefined) {
+ stride = new Array(d)
+ for(var i=d-1, sz=1; i>=0; --i) {
+ stride[i] = sz
+ sz *= shape[i]
+ }
+ }
+ if(offset === undefined) {
+ offset = 0
+ for(var i=0; i
+ * License: MIT
+ *
+ * `npm install is-buffer`
+ */
+
+module.exports = function (obj) {
+ return !!(obj != null &&
+ (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor)
+ (obj.constructor &&
+ typeof obj.constructor.isBuffer === 'function' &&
+ obj.constructor.isBuffer(obj))
+ ))
+}
+
+},{}],210:[function(require,module,exports){
+(function (global){
+module.exports =
+ global.performance &&
+ global.performance.now ? function now() {
+ return performance.now()
+ } : Date.now || function now() {
+ return +new Date
+ }
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],211:[function(require,module,exports){
+"use strict"
+
+var determinant = require("robust-determinant")
+
+var NUM_EXPAND = 6
+
+function generateSolver(n) {
+ var funcName = "robustLinearSolve" + n + "d"
+ var code = ["function ", funcName, "(A,b){return ["]
+ for(var i=0; i 0) {
+ code.push(",")
+ }
+ code.push("[")
+ for(var k=0; k 0) {
+ code.push(",")
+ }
+ if(k === i) {
+ code.push("+b[", j, "]")
+ } else {
+ code.push("+A[", j, "][", k, "]")
+ }
+ }
+ code.push("]")
+ }
+ code.push("]),")
+ }
+ code.push("det(A)]}return ", funcName)
+ var proc = new Function("det", code.join(""))
+ if(n < 6) {
+ return proc(determinant[n])
+ }
+ return proc(determinant)
+}
+
+function robustLinearSolve0d() {
+ return [ 0 ]
+}
+
+function robustLinearSolve1d(A, b) {
+ return [ [ b[0] ], [ A[0][0] ] ]
+}
+
+var CACHE = [
+ robustLinearSolve0d,
+ robustLinearSolve1d
+]
+
+function generateDispatch() {
+ while(CACHE.length < NUM_EXPAND) {
+ CACHE.push(generateSolver(CACHE.length))
+ }
+ var procArgs = []
+ var code = ["function dispatchLinearSolve(A,b){switch(A.length){"]
+ for(var i=0; i=0; --i) {
+ var a = Q
+ var b = e[i]
+ Q = a + b
+ var bv = Q - a
+ var q = b - bv
+ if(q) {
+ e[--bottom] = Q
+ Q = q
+ }
+ }
+ var top = 0
+ for(var i=bottom; i>1
+ return ["sum(", generateSum(expr.slice(0, m)), ",", generateSum(expr.slice(m)), ")"].join("")
+ }
+}
+
+function determinant(m) {
+ if(m.length === 2) {
+ return ["sum(prod(", m[0][0], ",", m[1][1], "),prod(-", m[0][1], ",", m[1][0], "))"].join("")
+ } else {
+ var expr = []
+ for(var i=0; i>1
+ return ["sum(", generateSum(expr.slice(0, m)), ",", generateSum(expr.slice(m)), ")"].join("")
+ }
+}
+
+function determinant(m) {
+ if(m.length === 2) {
+ return [["sum(prod(", m[0][0], ",", m[1][1], "),prod(-", m[0][1], ",", m[1][0], "))"].join("")]
+ } else {
+ var expr = []
+ for(var i=0; i 0) {
+ if(r <= 0) {
+ return det
+ } else {
+ s = l + r
+ }
+ } else if(l < 0) {
+ if(r >= 0) {
+ return det
+ } else {
+ s = -(l + r)
+ }
+ } else {
+ return det
+ }
+ var tol = ERRBOUND3 * s
+ if(det >= tol || det <= -tol) {
+ return det
+ }
+ return orientation3Exact(a, b, c)
+ },
+ function orientation4(a,b,c,d) {
+ var adx = a[0] - d[0]
+ var bdx = b[0] - d[0]
+ var cdx = c[0] - d[0]
+ var ady = a[1] - d[1]
+ var bdy = b[1] - d[1]
+ var cdy = c[1] - d[1]
+ var adz = a[2] - d[2]
+ var bdz = b[2] - d[2]
+ var cdz = c[2] - d[2]
+ var bdxcdy = bdx * cdy
+ var cdxbdy = cdx * bdy
+ var cdxady = cdx * ady
+ var adxcdy = adx * cdy
+ var adxbdy = adx * bdy
+ var bdxady = bdx * ady
+ var det = adz * (bdxcdy - cdxbdy)
+ + bdz * (cdxady - adxcdy)
+ + cdz * (adxbdy - bdxady)
+ var permanent = (Math.abs(bdxcdy) + Math.abs(cdxbdy)) * Math.abs(adz)
+ + (Math.abs(cdxady) + Math.abs(adxcdy)) * Math.abs(bdz)
+ + (Math.abs(adxbdy) + Math.abs(bdxady)) * Math.abs(cdz)
+ var tol = ERRBOUND4 * permanent
+ if ((det > tol) || (-det > tol)) {
+ return det
+ }
+ return orientation4Exact(a,b,c,d)
+ }
+]
+
+function slowOrient(args) {
+ var proc = CACHED[args.length]
+ if(!proc) {
+ proc = CACHED[args.length] = orientation(args.length)
+ }
+ return proc.apply(undefined, args)
+}
+
+function generateOrientationProc() {
+ while(CACHED.length <= NUM_EXPAND) {
+ CACHED.push(orientation(CACHED.length))
+ }
+ var args = []
+ var procArgs = ["slow"]
+ for(var i=0; i<=NUM_EXPAND; ++i) {
+ args.push("a" + i)
+ procArgs.push("o" + i)
+ }
+ var code = [
+ "function getOrientation(", args.join(), "){switch(arguments.length){case 0:case 1:return 0;"
+ ]
+ for(var i=2; i<=NUM_EXPAND; ++i) {
+ code.push("case ", i, ":return o", i, "(", args.slice(0, i).join(), ");")
+ }
+ code.push("}var s=new Array(arguments.length);for(var i=0;i= nf)) {
+ a = ei
+ eptr += 1
+ if(eptr < ne) {
+ ei = e[eptr]
+ ea = abs(ei)
+ }
+ } else {
+ a = fi
+ fptr += 1
+ if(fptr < nf) {
+ fi = -f[fptr]
+ fa = abs(fi)
+ }
+ }
+ var x = a + b
+ var bv = x - a
+ var y = b - bv
+ var q0 = y
+ var q1 = x
+ var _x, _bv, _av, _br, _ar
+ while(eptr < ne && fptr < nf) {
+ if(ea < fa) {
+ a = ei
+ eptr += 1
+ if(eptr < ne) {
+ ei = e[eptr]
+ ea = abs(ei)
+ }
+ } else {
+ a = fi
+ fptr += 1
+ if(fptr < nf) {
+ fi = -f[fptr]
+ fa = abs(fi)
+ }
+ }
+ b = q0
+ x = a + b
+ bv = x - a
+ y = b - bv
+ if(y) {
+ g[count++] = y
+ }
+ _x = q1 + x
+ _bv = _x - q1
+ _av = _x - _bv
+ _br = x - _bv
+ _ar = q1 - _av
+ q0 = _ar + _br
+ q1 = _x
+ }
+ while(eptr < ne) {
+ a = ei
+ b = q0
+ x = a + b
+ bv = x - a
+ y = b - bv
+ if(y) {
+ g[count++] = y
+ }
+ _x = q1 + x
+ _bv = _x - q1
+ _av = _x - _bv
+ _br = x - _bv
+ _ar = q1 - _av
+ q0 = _ar + _br
+ q1 = _x
+ eptr += 1
+ if(eptr < ne) {
+ ei = e[eptr]
+ }
+ }
+ while(fptr < nf) {
+ a = fi
+ b = q0
+ x = a + b
+ bv = x - a
+ y = b - bv
+ if(y) {
+ g[count++] = y
+ }
+ _x = q1 + x
+ _bv = _x - q1
+ _av = _x - _bv
+ _br = x - _bv
+ _ar = q1 - _av
+ q0 = _ar + _br
+ q1 = _x
+ fptr += 1
+ if(fptr < nf) {
+ fi = -f[fptr]
+ }
+ }
+ if(q0) {
+ g[count++] = q0
+ }
+ if(q1) {
+ g[count++] = q1
+ }
+ if(!count) {
+ g[count++] = 0.0
+ }
+ g.length = count
+ return g
+}
+},{}],217:[function(require,module,exports){
+"use strict"
+
+module.exports = linearExpansionSum
+
+//Easy case: Add two scalars
+function scalarScalar(a, b) {
+ var x = a + b
+ var bv = x - a
+ var av = x - bv
+ var br = b - bv
+ var ar = a - av
+ var y = ar + br
+ if(y) {
+ return [y, x]
+ }
+ return [x]
+}
+
+function linearExpansionSum(e, f) {
+ var ne = e.length|0
+ var nf = f.length|0
+ if(ne === 1 && nf === 1) {
+ return scalarScalar(e[0], f[0])
+ }
+ var n = ne + nf
+ var g = new Array(n)
+ var count = 0
+ var eptr = 0
+ var fptr = 0
+ var abs = Math.abs
+ var ei = e[eptr]
+ var ea = abs(ei)
+ var fi = f[fptr]
+ var fa = abs(fi)
+ var a, b
+ if(ea < fa) {
+ b = ei
+ eptr += 1
+ if(eptr < ne) {
+ ei = e[eptr]
+ ea = abs(ei)
+ }
+ } else {
+ b = fi
+ fptr += 1
+ if(fptr < nf) {
+ fi = f[fptr]
+ fa = abs(fi)
+ }
+ }
+ if((eptr < ne && ea < fa) || (fptr >= nf)) {
+ a = ei
+ eptr += 1
+ if(eptr < ne) {
+ ei = e[eptr]
+ ea = abs(ei)
+ }
+ } else {
+ a = fi
+ fptr += 1
+ if(fptr < nf) {
+ fi = f[fptr]
+ fa = abs(fi)
+ }
+ }
+ var x = a + b
+ var bv = x - a
+ var y = b - bv
+ var q0 = y
+ var q1 = x
+ var _x, _bv, _av, _br, _ar
+ while(eptr < ne && fptr < nf) {
+ if(ea < fa) {
+ a = ei
+ eptr += 1
+ if(eptr < ne) {
+ ei = e[eptr]
+ ea = abs(ei)
+ }
+ } else {
+ a = fi
+ fptr += 1
+ if(fptr < nf) {
+ fi = f[fptr]
+ fa = abs(fi)
+ }
+ }
+ b = q0
+ x = a + b
+ bv = x - a
+ y = b - bv
+ if(y) {
+ g[count++] = y
+ }
+ _x = q1 + x
+ _bv = _x - q1
+ _av = _x - _bv
+ _br = x - _bv
+ _ar = q1 - _av
+ q0 = _ar + _br
+ q1 = _x
+ }
+ while(eptr < ne) {
+ a = ei
+ b = q0
+ x = a + b
+ bv = x - a
+ y = b - bv
+ if(y) {
+ g[count++] = y
+ }
+ _x = q1 + x
+ _bv = _x - q1
+ _av = _x - _bv
+ _br = x - _bv
+ _ar = q1 - _av
+ q0 = _ar + _br
+ q1 = _x
+ eptr += 1
+ if(eptr < ne) {
+ ei = e[eptr]
+ }
+ }
+ while(fptr < nf) {
+ a = fi
+ b = q0
+ x = a + b
+ bv = x - a
+ y = b - bv
+ if(y) {
+ g[count++] = y
+ }
+ _x = q1 + x
+ _bv = _x - q1
+ _av = _x - _bv
+ _br = x - _bv
+ _ar = q1 - _av
+ q0 = _ar + _br
+ q1 = _x
+ fptr += 1
+ if(fptr < nf) {
+ fi = f[fptr]
+ }
+ }
+ if(q0) {
+ g[count++] = q0
+ }
+ if(q1) {
+ g[count++] = q1
+ }
+ if(!count) {
+ g[count++] = 0.0
+ }
+ g.length = count
+ return g
+}
+},{}],218:[function(require,module,exports){
+'use strict'
+
+module.exports = toSuperScript
+
+var SUPERSCRIPTS = {
+ ' ': ' ',
+ '0': '⁰',
+ '1': '¹',
+ '2': '²',
+ '3': '³',
+ '4': '⁴',
+ '5': '⁵',
+ '6': '⁶',
+ '7': '⁷',
+ '8': '⁸',
+ '9': '⁹',
+ '+': '⁺',
+ '-': '⁻',
+ 'a': 'ᵃ',
+ 'b': 'ᵇ',
+ 'c': 'ᶜ',
+ 'd': 'ᵈ',
+ 'e': 'ᵉ',
+ 'f': 'ᶠ',
+ 'g': 'ᵍ',
+ 'h': 'ʰ',
+ 'i': 'ⁱ',
+ 'j': 'ʲ',
+ 'k': 'ᵏ',
+ 'l': 'ˡ',
+ 'm': 'ᵐ',
+ 'n': 'ⁿ',
+ 'o': 'ᵒ',
+ 'p': 'ᵖ',
+ 'r': 'ʳ',
+ 's': 'ˢ',
+ 't': 'ᵗ',
+ 'u': 'ᵘ',
+ 'v': 'ᵛ',
+ 'w': 'ʷ',
+ 'x': 'ˣ',
+ 'y': 'ʸ',
+ 'z': 'ᶻ'
+}
+
+function toSuperScript(x) {
+ return x.split('').map(function(c) {
+ if(c in SUPERSCRIPTS) {
+ return SUPERSCRIPTS[c]
+ }
+ return ''
+ }).join('')
+}
+
+},{}],219:[function(require,module,exports){
+"use strict"
+
+var pool = require("typedarray-pool")
+
+module.exports = createSurfaceExtractor
+
+//Helper macros
+function array(i) {
+ return "a" + i
+}
+function data(i) {
+ return "d" + i
+}
+function cube(i,bitmask) {
+ return "c" + i + "_" + bitmask
+}
+function shape(i) {
+ return "s" + i
+}
+function stride(i,j) {
+ return "t" + i + "_" + j
+}
+function offset(i) {
+ return "o" + i
+}
+function scalar(i) {
+ return "x" + i
+}
+function pointer(i) {
+ return "p" + i
+}
+function delta(i,bitmask) {
+ return "d" + i + "_" + bitmask
+}
+function index(i) {
+ return "i" + i
+}
+function step(i,j) {
+ return "u" + i + "_" + j
+}
+function pcube(bitmask) {
+ return "b" + bitmask
+}
+function qcube(bitmask) {
+ return "y" + bitmask
+}
+function pdelta(bitmask) {
+ return "e" + bitmask
+}
+function vert(i) {
+ return "v" + i
+}
+var VERTEX_IDS = "V"
+var PHASES = "P"
+var VERTEX_COUNT = "N"
+var POOL_SIZE = "Q"
+var POINTER = "X"
+var TEMPORARY = "T"
+
+function permBitmask(dimension, mask, order) {
+ var r = 0
+ for(var i=0; i 0) {
+ stepVal.push(stride(i, order[j-1]) + "*" + shape(order[j-1]) )
+ }
+ vars.push(step(i,order[j]) + "=(" + stepVal.join("-") + ")|0")
+ }
+ }
+ //Create index variables
+ for(var i=0; i=0; --i) {
+ sizeVariable.push(shape(order[i]))
+ }
+ //Previous phases and vertex_ids
+ vars.push(POOL_SIZE + "=(" + sizeVariable.join("*") + ")|0",
+ PHASES + "=mallocUint32(" + POOL_SIZE + ")",
+ VERTEX_IDS + "=mallocUint32(" + POOL_SIZE + ")",
+ POINTER + "=0")
+ //Create cube variables for phases
+ vars.push(pcube(0) + "=0")
+ for(var j=1; j<(1<=0; --i) {
+ forLoopBegin(i, 0)
+ }
+ var phaseFuncArgs = []
+ for(var i=0; i0; k=(k-1)&subset) {
+ faceArgs.push(VERTEX_IDS + "[" + POINTER + "+" + pdelta(k) + "]")
+ }
+ faceArgs.push(vert(0))
+ for(var k=0; k0){",
+ index(order[i]), "=1;")
+ createLoop(i-1, mask|(1< 0")
+ }
+ if(typeof args.vertex !== "function") {
+ error("Must specify vertex creation function")
+ }
+ if(typeof args.cell !== "function") {
+ error("Must specify cell creation function")
+ }
+ if(typeof args.phase !== "function") {
+ error("Must specify phase function")
+ }
+ var getters = args.getters || []
+ var typesig = new Array(arrays)
+ for(var i=0; i= 0) {
+ typesig[i] = true
+ } else {
+ typesig[i] = false
+ }
+ }
+ return compileSurfaceProcedure(
+ args.vertex,
+ args.cell,
+ args.phase,
+ scalars,
+ order,
+ typesig)
+}
+},{"typedarray-pool":233}],220:[function(require,module,exports){
+// transliterated from the python snippet here:
+// http://en.wikipedia.org/wiki/Lanczos_approximation
+
+var g = 7;
+var p = [
+ 0.99999999999980993,
+ 676.5203681218851,
+ -1259.1392167224028,
+ 771.32342877765313,
+ -176.61502916214059,
+ 12.507343278686905,
+ -0.13857109526572012,
+ 9.9843695780195716e-6,
+ 1.5056327351493116e-7
+];
+
+var g_ln = 607/128;
+var p_ln = [
+ 0.99999999999999709182,
+ 57.156235665862923517,
+ -59.597960355475491248,
+ 14.136097974741747174,
+ -0.49191381609762019978,
+ 0.33994649984811888699e-4,
+ 0.46523628927048575665e-4,
+ -0.98374475304879564677e-4,
+ 0.15808870322491248884e-3,
+ -0.21026444172410488319e-3,
+ 0.21743961811521264320e-3,
+ -0.16431810653676389022e-3,
+ 0.84418223983852743293e-4,
+ -0.26190838401581408670e-4,
+ 0.36899182659531622704e-5
+];
+
+// Spouge approximation (suitable for large arguments)
+function lngamma(z) {
+
+ if(z < 0) return Number('0/0');
+ var x = p_ln[0];
+ for(var i = p_ln.length - 1; i > 0; --i) x += p_ln[i] / (z + i);
+ var t = z + g_ln + 0.5;
+ return .5*Math.log(2*Math.PI)+(z+.5)*Math.log(t)-t+Math.log(x)-Math.log(z);
+}
+
+module.exports = function gamma (z) {
+ if (z < 0.5) {
+ return Math.PI / (Math.sin(Math.PI * z) * gamma(1 - z));
+ }
+ else if(z > 100) return Math.exp(lngamma(z));
+ else {
+ z -= 1;
+ var x = p[0];
+ for (var i = 1; i < g + 2; i++) {
+ x += p[i] / (z + i);
+ }
+ var t = z + g + 0.5;
+
+ return Math.sqrt(2 * Math.PI)
+ * Math.pow(t, z + 0.5)
+ * Math.exp(-t)
+ * x
+ ;
+ }
+};
+
+module.exports.log = lngamma;
+
+},{}],221:[function(require,module,exports){
+"use strict"
+
+module.exports = permutationSign
+
+var BRUTE_FORCE_CUTOFF = 32
+
+var pool = require("typedarray-pool")
+
+function permutationSign(p) {
+ var n = p.length
+ if(n < BRUTE_FORCE_CUTOFF) {
+ //Use quadratic algorithm for small n
+ var sgn = 1
+ for(var i=0; i0; --i) {
+ t = pinv[i]
+ s = p[i]
+ p[i] = p[t]
+ p[t] = s
+ pinv[i] = pinv[s]
+ pinv[s] = t
+ r = (r + s) * i
+ }
+ pool.freeUint32(pinv)
+ pool.freeUint32(p)
+ return r
+}
+
+function unrank(n, r, p) {
+ switch(n) {
+ case 0:
+ if(p) { return p }
+ return []
+ case 1:
+ if(p) {
+ p[0] = 0
+ return p
+ } else {
+ return [0]
+ }
+ case 2:
+ if(p) {
+ if(r) {
+ p[0] = 0
+ p[1] = 1
+ } else {
+ p[0] = 1
+ p[1] = 0
+ }
+ return p
+ } else {
+ return r ? [0,1] : [1,0]
+ }
+ default:
+ break
+ }
+ p = p || new Array(n)
+ var s, t, i, nf=1
+ p[0] = 0
+ for(i=1; i0; --i) {
+ s = (r / nf)|0
+ r = (r - s * nf)|0
+ nf = (nf / i)|0
+ t = p[i]|0
+ p[i] = p[s]|0
+ p[s] = t|0
+ }
+ return p
+}
+
+exports.rank = rank
+exports.unrank = unrank
+
+},{"invert-permutation":223,"typedarray-pool":233}],223:[function(require,module,exports){
+"use strict"
+
+function invertPermutation(pi, result) {
+ result = result || new Array(pi.length)
+ for(var i=0; i= 0) !== (_inline_1_db >= 0)) {\n _inline_1_arg2_.push(_inline_1_arg4_[0] + 0.5 + 0.5 * (_inline_1_da + _inline_1_db) / (_inline_1_da - _inline_1_db))\n }\n }",
+ "args": [{
+ "name": "_inline_1_arg0_",
+ "lvalue": false,
+ "rvalue": true,
+ "count": 1
+ }, {
+ "name": "_inline_1_arg1_",
+ "lvalue": false,
+ "rvalue": true,
+ "count": 1
+ }, {
+ "name": "_inline_1_arg2_",
+ "lvalue": false,
+ "rvalue": true,
+ "count": 1
+ }, {
+ "name": "_inline_1_arg3_",
+ "lvalue": false,
+ "rvalue": true,
+ "count": 2
+ }, {
+ "name": "_inline_1_arg4_",
+ "lvalue": false,
+ "rvalue": true,
+ "count": 1
+ }],
+ "thisVars": [],
+ "localVars": ["_inline_1_da", "_inline_1_db"]
+ },
+ funcName: 'zeroCrossings'
+})
+
+},{"cwise-compiler":66}],226:[function(require,module,exports){
+"use strict"
+
+module.exports = findZeroCrossings
+
+var core = require("./lib/zc-core")
+
+function findZeroCrossings(array, level) {
+ var cross = []
+ level = +level || 0.0
+ core(array.hi(array.shape[0]-1), cross, level)
+ return cross
+}
+},{"./lib/zc-core":225}],227:[function(require,module,exports){
+"use strict"
+
+module.exports = surfaceNets
+
+var generateContourExtractor = require("ndarray-extract-contour")
+var triangulateCube = require("triangulate-hypercube")
+var zeroCrossings = require("zero-crossings")
+
+function buildSurfaceNets(order, dtype) {
+ var dimension = order.length
+ var code = ["'use strict';"]
+ var funcName = "surfaceNets" + order.join("_") + "d" + dtype
+
+ //Contour extraction function
+ code.push(
+ "var contour=genContour({",
+ "order:[", order.join(), "],",
+ "scalarArguments: 3,",
+ "phase:function phaseFunc(p,a,b,c) { return (p > c)|0 },")
+ if(dtype === "generic") {
+ code.push("getters:[0],")
+ }
+
+ //Generate vertex function
+ var cubeArgs = []
+ var extraArgs = []
+ for(var i=0; i>>7){")
+ }
+ for(var i=0; i<1<<(1< 128) {
+ if((i%128)===0) {
+ if(extraFuncs.length > 0) {
+ currentFunc.push("}}")
+ }
+ var efName = "vExtra" + extraFuncs.length
+ code.push("case ", (i>>>7), ":", efName, "(m&0x7f,", extraArgs.join(), ");break;")
+ currentFunc = [
+ "function ", efName, "(m,", extraArgs.join(), "){switch(m){"
+ ]
+ extraFuncs.push(currentFunc)
+ }
+ }
+ currentFunc.push("case ", (i&0x7f), ":")
+ var crossings = new Array(dimension)
+ var denoms = new Array(dimension)
+ var crossingCount = new Array(dimension)
+ var bias = new Array(dimension)
+ var totalCrossings = 0
+ for(var j=0; j j) {
+ continue
+ }
+ if(!(i&(1< 0) {
+ cStr = "+" + crossingCount[k] + "*c"
+ }
+ var weight = 0.5 * (crossings[k].length / totalCrossings)
+ var shift = 0.5 + 0.5 * (bias[k] / totalCrossings)
+ vertexStr.push("d" + k + "-" + shift + "-" + weight + "*(" + crossings[k].join("+") + cStr + ")/(" + denoms[k].join("+") + ")")
+
+ }
+ }
+ currentFunc.push("a.push([", vertexStr.join(), "]);",
+ "break;")
+ }
+ code.push("}},")
+ if(extraFuncs.length > 0) {
+ currentFunc.push("}}")
+ }
+
+ //Create face function
+ var faceArgs = []
+ for(var i=0; i<(1<<(dimension-1)); ++i) {
+ faceArgs.push("v" + i)
+ }
+ faceArgs.push("c0", "c1", "p0", "p1", "a", "b", "c")
+ code.push("cell:function cellFunc(", faceArgs.join(), "){")
+
+ var facets = triangulateCube(dimension-1)
+ code.push("if(p0){b.push(",
+ facets.map(function(f) {
+ return "[" + f.map(function(v) {
+ return "v" + v
+ }) + "]"
+ }).join(), ")}else{b.push(",
+ facets.map(function(f) {
+ var e = f.slice()
+ e.reverse()
+ return "[" + e.map(function(v) {
+ return "v" + v
+ }) + "]"
+ }).join(),
+ ")}}});function ", funcName, "(array,level){var verts=[],cells=[];contour(array,verts,cells,level);return {positions:verts,cells:cells};} return ", funcName, ";")
+
+ for(var i=0; i0) {
+ shapeX += 0.02
+ }
+ }
+
+ var data = new Float32Array(bufferSize)
+ var ptr = 0
+ var xOffset = -0.5 * shapeX
+ for(var i=0; i= 0;
+ var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "name");
+
+ if (needsAlphaFormat) {
+ // Special case for "transparent", all other non-alpha formats
+ // will return rgba when there is transparency.
+ if (format === "name" && this._a === 0) {
+ return this.toName();
+ }
+ return this.toRgbString();
+ }
+ if (format === "rgb") {
+ formattedString = this.toRgbString();
+ }
+ if (format === "prgb") {
+ formattedString = this.toPercentageRgbString();
+ }
+ if (format === "hex" || format === "hex6") {
+ formattedString = this.toHexString();
+ }
+ if (format === "hex3") {
+ formattedString = this.toHexString(true);
+ }
+ if (format === "hex8") {
+ formattedString = this.toHex8String();
+ }
+ if (format === "name") {
+ formattedString = this.toName();
+ }
+ if (format === "hsl") {
+ formattedString = this.toHslString();
+ }
+ if (format === "hsv") {
+ formattedString = this.toHsvString();
+ }
+
+ return formattedString || this.toHexString();
+ },
+ clone: function() {
+ return tinycolor(this.toString());
+ },
+
+ _applyModification: function(fn, args) {
+ var color = fn.apply(null, [this].concat([].slice.call(args)));
+ this._r = color._r;
+ this._g = color._g;
+ this._b = color._b;
+ this.setAlpha(color._a);
+ return this;
+ },
+ lighten: function() {
+ return this._applyModification(lighten, arguments);
+ },
+ brighten: function() {
+ return this._applyModification(brighten, arguments);
+ },
+ darken: function() {
+ return this._applyModification(darken, arguments);
+ },
+ desaturate: function() {
+ return this._applyModification(desaturate, arguments);
+ },
+ saturate: function() {
+ return this._applyModification(saturate, arguments);
+ },
+ greyscale: function() {
+ return this._applyModification(greyscale, arguments);
+ },
+ spin: function() {
+ return this._applyModification(spin, arguments);
+ },
+
+ _applyCombination: function(fn, args) {
+ return fn.apply(null, [this].concat([].slice.call(args)));
+ },
+ analogous: function() {
+ return this._applyCombination(analogous, arguments);
+ },
+ complement: function() {
+ return this._applyCombination(complement, arguments);
+ },
+ monochromatic: function() {
+ return this._applyCombination(monochromatic, arguments);
+ },
+ splitcomplement: function() {
+ return this._applyCombination(splitcomplement, arguments);
+ },
+ triad: function() {
+ return this._applyCombination(triad, arguments);
+ },
+ tetrad: function() {
+ return this._applyCombination(tetrad, arguments);
+ }
+};
+
+// If input is an object, force 1 into "1.0" to handle ratios properly
+// String input requires "1.0" as input, so 1 will be treated as 1
+tinycolor.fromRatio = function(color, opts) {
+ if (typeof color == "object") {
+ var newColor = {};
+ for (var i in color) {
+ if (color.hasOwnProperty(i)) {
+ if (i === "a") {
+ newColor[i] = color[i];
+ }
+ else {
+ newColor[i] = convertToPercentage(color[i]);
+ }
+ }
+ }
+ color = newColor;
+ }
+
+ return tinycolor(color, opts);
+};
+
+// Given a string or object, convert that input to RGB
+// Possible string inputs:
+//
+// "red"
+// "#f00" or "f00"
+// "#ff0000" or "ff0000"
+// "#ff000000" or "ff000000"
+// "rgb 255 0 0" or "rgb (255, 0, 0)"
+// "rgb 1.0 0 0" or "rgb (1, 0, 0)"
+// "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
+// "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
+// "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
+// "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
+// "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
+//
+function inputToRGB(color) {
+
+ var rgb = { r: 0, g: 0, b: 0 };
+ var a = 1;
+ var ok = false;
+ var format = false;
+
+ if (typeof color == "string") {
+ color = stringInputToObject(color);
+ }
+
+ if (typeof color == "object") {
+ if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
+ rgb = rgbToRgb(color.r, color.g, color.b);
+ ok = true;
+ format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
+ }
+ else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
+ color.s = convertToPercentage(color.s);
+ color.v = convertToPercentage(color.v);
+ rgb = hsvToRgb(color.h, color.s, color.v);
+ ok = true;
+ format = "hsv";
+ }
+ else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
+ color.s = convertToPercentage(color.s);
+ color.l = convertToPercentage(color.l);
+ rgb = hslToRgb(color.h, color.s, color.l);
+ ok = true;
+ format = "hsl";
+ }
+
+ if (color.hasOwnProperty("a")) {
+ a = color.a;
+ }
+ }
+
+ a = boundAlpha(a);
+
+ return {
+ ok: ok,
+ format: color.format || format,
+ r: mathMin(255, mathMax(rgb.r, 0)),
+ g: mathMin(255, mathMax(rgb.g, 0)),
+ b: mathMin(255, mathMax(rgb.b, 0)),
+ a: a
+ };
+}
+
+
+// Conversion Functions
+// --------------------
+
+// `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
+//
+
+// `rgbToRgb`
+// Handle bounds / percentage checking to conform to CSS color spec
+//
+// *Assumes:* r, g, b in [0, 255] or [0, 1]
+// *Returns:* { r, g, b } in [0, 255]
+function rgbToRgb(r, g, b){
+ return {
+ r: bound01(r, 255) * 255,
+ g: bound01(g, 255) * 255,
+ b: bound01(b, 255) * 255
+ };
+}
+
+// `rgbToHsl`
+// Converts an RGB color value to HSL.
+// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
+// *Returns:* { h, s, l } in [0,1]
+function rgbToHsl(r, g, b) {
+
+ r = bound01(r, 255);
+ g = bound01(g, 255);
+ b = bound01(b, 255);
+
+ var max = mathMax(r, g, b), min = mathMin(r, g, b);
+ var h, s, l = (max + min) / 2;
+
+ if(max == min) {
+ h = s = 0; // achromatic
+ }
+ else {
+ var d = max - min;
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+ switch(max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+
+ h /= 6;
+ }
+
+ return { h: h, s: s, l: l };
+}
+
+// `hslToRgb`
+// Converts an HSL color value to RGB.
+// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
+// *Returns:* { r, g, b } in the set [0, 255]
+function hslToRgb(h, s, l) {
+ var r, g, b;
+
+ h = bound01(h, 360);
+ s = bound01(s, 100);
+ l = bound01(l, 100);
+
+ function hue2rgb(p, q, t) {
+ if(t < 0) t += 1;
+ if(t > 1) t -= 1;
+ if(t < 1/6) return p + (q - p) * 6 * t;
+ if(t < 1/2) return q;
+ if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
+ return p;
+ }
+
+ if(s === 0) {
+ r = g = b = l; // achromatic
+ }
+ else {
+ var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+ var p = 2 * l - q;
+ r = hue2rgb(p, q, h + 1/3);
+ g = hue2rgb(p, q, h);
+ b = hue2rgb(p, q, h - 1/3);
+ }
+
+ return { r: r * 255, g: g * 255, b: b * 255 };
+}
+
+// `rgbToHsv`
+// Converts an RGB color value to HSV
+// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
+// *Returns:* { h, s, v } in [0,1]
+function rgbToHsv(r, g, b) {
+
+ r = bound01(r, 255);
+ g = bound01(g, 255);
+ b = bound01(b, 255);
+
+ var max = mathMax(r, g, b), min = mathMin(r, g, b);
+ var h, s, v = max;
+
+ var d = max - min;
+ s = max === 0 ? 0 : d / max;
+
+ if(max == min) {
+ h = 0; // achromatic
+ }
+ else {
+ switch(max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h, s: s, v: v };
+}
+
+// `hsvToRgb`
+// Converts an HSV color value to RGB.
+// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
+// *Returns:* { r, g, b } in the set [0, 255]
+ function hsvToRgb(h, s, v) {
+
+ h = bound01(h, 360) * 6;
+ s = bound01(s, 100);
+ v = bound01(v, 100);
+
+ var i = math.floor(h),
+ f = h - i,
+ p = v * (1 - s),
+ q = v * (1 - f * s),
+ t = v * (1 - (1 - f) * s),
+ mod = i % 6,
+ r = [v, q, p, p, t, v][mod],
+ g = [t, v, v, q, p, p][mod],
+ b = [p, p, t, v, v, q][mod];
+
+ return { r: r * 255, g: g * 255, b: b * 255 };
+}
+
+// `rgbToHex`
+// Converts an RGB color to hex
+// Assumes r, g, and b are contained in the set [0, 255]
+// Returns a 3 or 6 character hex
+function rgbToHex(r, g, b, allow3Char) {
+
+ var hex = [
+ pad2(mathRound(r).toString(16)),
+ pad2(mathRound(g).toString(16)),
+ pad2(mathRound(b).toString(16))
+ ];
+
+ // Return a 3 character hex if possible
+ if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
+ return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
+ }
+
+ return hex.join("");
+}
+
+// `rgbaToHex`
+// Converts an RGBA color plus alpha transparency to hex
+// Assumes r, g, b and a are contained in the set [0, 255]
+// Returns an 8 character hex
+function rgbaToHex(r, g, b, a) {
+
+ var hex = [
+ pad2(convertDecimalToHex(a)),
+ pad2(mathRound(r).toString(16)),
+ pad2(mathRound(g).toString(16)),
+ pad2(mathRound(b).toString(16))
+ ];
+
+ return hex.join("");
+}
+
+// `equals`
+// Can be called with any tinycolor input
+tinycolor.equals = function (color1, color2) {
+ if (!color1 || !color2) { return false; }
+ return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
+};
+
+tinycolor.random = function() {
+ return tinycolor.fromRatio({
+ r: mathRandom(),
+ g: mathRandom(),
+ b: mathRandom()
+ });
+};
+
+
+// Modification Functions
+// ----------------------
+// Thanks to less.js for some of the basics here
+//
+
+function desaturate(color, amount) {
+ amount = (amount === 0) ? 0 : (amount || 10);
+ var hsl = tinycolor(color).toHsl();
+ hsl.s -= amount / 100;
+ hsl.s = clamp01(hsl.s);
+ return tinycolor(hsl);
+}
+
+function saturate(color, amount) {
+ amount = (amount === 0) ? 0 : (amount || 10);
+ var hsl = tinycolor(color).toHsl();
+ hsl.s += amount / 100;
+ hsl.s = clamp01(hsl.s);
+ return tinycolor(hsl);
+}
+
+function greyscale(color) {
+ return tinycolor(color).desaturate(100);
+}
+
+function lighten (color, amount) {
+ amount = (amount === 0) ? 0 : (amount || 10);
+ var hsl = tinycolor(color).toHsl();
+ hsl.l += amount / 100;
+ hsl.l = clamp01(hsl.l);
+ return tinycolor(hsl);
+}
+
+function brighten(color, amount) {
+ amount = (amount === 0) ? 0 : (amount || 10);
+ var rgb = tinycolor(color).toRgb();
+ rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));
+ rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));
+ rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));
+ return tinycolor(rgb);
+}
+
+function darken (color, amount) {
+ amount = (amount === 0) ? 0 : (amount || 10);
+ var hsl = tinycolor(color).toHsl();
+ hsl.l -= amount / 100;
+ hsl.l = clamp01(hsl.l);
+ return tinycolor(hsl);
+}
+
+// Spin takes a positive or negative amount within [-360, 360] indicating the change of hue.
+// Values outside of this range will be wrapped into this range.
+function spin(color, amount) {
+ var hsl = tinycolor(color).toHsl();
+ var hue = (mathRound(hsl.h) + amount) % 360;
+ hsl.h = hue < 0 ? 360 + hue : hue;
+ return tinycolor(hsl);
+}
+
+// Combination Functions
+// ---------------------
+// Thanks to jQuery xColor for some of the ideas behind these
+//
+
+function complement(color) {
+ var hsl = tinycolor(color).toHsl();
+ hsl.h = (hsl.h + 180) % 360;
+ return tinycolor(hsl);
+}
+
+function triad(color) {
+ var hsl = tinycolor(color).toHsl();
+ var h = hsl.h;
+ return [
+ tinycolor(color),
+ tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
+ tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
+ ];
+}
+
+function tetrad(color) {
+ var hsl = tinycolor(color).toHsl();
+ var h = hsl.h;
+ return [
+ tinycolor(color),
+ tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
+ tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
+ tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
+ ];
+}
+
+function splitcomplement(color) {
+ var hsl = tinycolor(color).toHsl();
+ var h = hsl.h;
+ return [
+ tinycolor(color),
+ tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
+ tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
+ ];
+}
+
+function analogous(color, results, slices) {
+ results = results || 6;
+ slices = slices || 30;
+
+ var hsl = tinycolor(color).toHsl();
+ var part = 360 / slices;
+ var ret = [tinycolor(color)];
+
+ for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
+ hsl.h = (hsl.h + part) % 360;
+ ret.push(tinycolor(hsl));
+ }
+ return ret;
+}
+
+function monochromatic(color, results) {
+ results = results || 6;
+ var hsv = tinycolor(color).toHsv();
+ var h = hsv.h, s = hsv.s, v = hsv.v;
+ var ret = [];
+ var modification = 1 / results;
+
+ while (results--) {
+ ret.push(tinycolor({ h: h, s: s, v: v}));
+ v = (v + modification) % 1;
+ }
+
+ return ret;
+}
+
+// Utility Functions
+// ---------------------
+
+tinycolor.mix = function(color1, color2, amount) {
+ amount = (amount === 0) ? 0 : (amount || 50);
+
+ var rgb1 = tinycolor(color1).toRgb();
+ var rgb2 = tinycolor(color2).toRgb();
+
+ var p = amount / 100;
+ var w = p * 2 - 1;
+ var a = rgb2.a - rgb1.a;
+
+ var w1;
+
+ if (w * a == -1) {
+ w1 = w;
+ } else {
+ w1 = (w + a) / (1 + w * a);
+ }
+
+ w1 = (w1 + 1) / 2;
+
+ var w2 = 1 - w1;
+
+ var rgba = {
+ r: rgb2.r * w1 + rgb1.r * w2,
+ g: rgb2.g * w1 + rgb1.g * w2,
+ b: rgb2.b * w1 + rgb1.b * w2,
+ a: rgb2.a * p + rgb1.a * (1 - p)
+ };
+
+ return tinycolor(rgba);
+};
+
+
+// Readability Functions
+// ---------------------
+// false
+// tinycolor.isReadable("#000", "#111",{level:"AA",size:"large"}) => false
+tinycolor.isReadable = function(color1, color2, wcag2) {
+ var readability = tinycolor.readability(color1, color2);
+ var wcag2Parms, out;
+
+ out = false;
+
+ wcag2Parms = validateWCAG2Parms(wcag2);
+ switch (wcag2Parms.level + wcag2Parms.size) {
+ case "AAsmall":
+ case "AAAlarge":
+ out = readability >= 4.5;
+ break;
+ case "AAlarge":
+ out = readability >= 3;
+ break;
+ case "AAAsmall":
+ out = readability >= 7;
+ break;
+ }
+ return out;
+
+};
+
+// `mostReadable`
+// Given a base color and a list of possible foreground or background
+// colors for that base, returns the most readable color.
+// Optionally returns Black or White if the most readable color is unreadable.
+// *Example*
+// tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:false}).toHexString(); // "#112255"
+// tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:true}).toHexString(); // "#ffffff"
+// tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"large"}).toHexString(); // "#faf3f3"
+// tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"small"}).toHexString(); // "#ffffff"
+tinycolor.mostReadable = function(baseColor, colorList, args) {
+ var bestColor = null;
+ var bestScore = 0;
+ var readability;
+ var includeFallbackColors, level, size ;
+ args = args || {};
+ includeFallbackColors = args.includeFallbackColors ;
+ level = args.level;
+ size = args.size;
+
+ for (var i= 0; i < colorList.length ; i++) {
+ readability = tinycolor.readability(baseColor, colorList[i]);
+ if (readability > bestScore) {
+ bestScore = readability;
+ bestColor = tinycolor(colorList[i]);
+ }
+ }
+
+ if (tinycolor.isReadable(baseColor, bestColor, {"level":level,"size":size}) || !includeFallbackColors) {
+ return bestColor;
+ }
+ else {
+ args.includeFallbackColors=false;
+ return tinycolor.mostReadable(baseColor,["#fff", "#000"],args);
+ }
+};
+
+
+// Big List of Colors
+// ------------------
+//
+var names = tinycolor.names = {
+ aliceblue: "f0f8ff",
+ antiquewhite: "faebd7",
+ aqua: "0ff",
+ aquamarine: "7fffd4",
+ azure: "f0ffff",
+ beige: "f5f5dc",
+ bisque: "ffe4c4",
+ black: "000",
+ blanchedalmond: "ffebcd",
+ blue: "00f",
+ blueviolet: "8a2be2",
+ brown: "a52a2a",
+ burlywood: "deb887",
+ burntsienna: "ea7e5d",
+ cadetblue: "5f9ea0",
+ chartreuse: "7fff00",
+ chocolate: "d2691e",
+ coral: "ff7f50",
+ cornflowerblue: "6495ed",
+ cornsilk: "fff8dc",
+ crimson: "dc143c",
+ cyan: "0ff",
+ darkblue: "00008b",
+ darkcyan: "008b8b",
+ darkgoldenrod: "b8860b",
+ darkgray: "a9a9a9",
+ darkgreen: "006400",
+ darkgrey: "a9a9a9",
+ darkkhaki: "bdb76b",
+ darkmagenta: "8b008b",
+ darkolivegreen: "556b2f",
+ darkorange: "ff8c00",
+ darkorchid: "9932cc",
+ darkred: "8b0000",
+ darksalmon: "e9967a",
+ darkseagreen: "8fbc8f",
+ darkslateblue: "483d8b",
+ darkslategray: "2f4f4f",
+ darkslategrey: "2f4f4f",
+ darkturquoise: "00ced1",
+ darkviolet: "9400d3",
+ deeppink: "ff1493",
+ deepskyblue: "00bfff",
+ dimgray: "696969",
+ dimgrey: "696969",
+ dodgerblue: "1e90ff",
+ firebrick: "b22222",
+ floralwhite: "fffaf0",
+ forestgreen: "228b22",
+ fuchsia: "f0f",
+ gainsboro: "dcdcdc",
+ ghostwhite: "f8f8ff",
+ gold: "ffd700",
+ goldenrod: "daa520",
+ gray: "808080",
+ green: "008000",
+ greenyellow: "adff2f",
+ grey: "808080",
+ honeydew: "f0fff0",
+ hotpink: "ff69b4",
+ indianred: "cd5c5c",
+ indigo: "4b0082",
+ ivory: "fffff0",
+ khaki: "f0e68c",
+ lavender: "e6e6fa",
+ lavenderblush: "fff0f5",
+ lawngreen: "7cfc00",
+ lemonchiffon: "fffacd",
+ lightblue: "add8e6",
+ lightcoral: "f08080",
+ lightcyan: "e0ffff",
+ lightgoldenrodyellow: "fafad2",
+ lightgray: "d3d3d3",
+ lightgreen: "90ee90",
+ lightgrey: "d3d3d3",
+ lightpink: "ffb6c1",
+ lightsalmon: "ffa07a",
+ lightseagreen: "20b2aa",
+ lightskyblue: "87cefa",
+ lightslategray: "789",
+ lightslategrey: "789",
+ lightsteelblue: "b0c4de",
+ lightyellow: "ffffe0",
+ lime: "0f0",
+ limegreen: "32cd32",
+ linen: "faf0e6",
+ magenta: "f0f",
+ maroon: "800000",
+ mediumaquamarine: "66cdaa",
+ mediumblue: "0000cd",
+ mediumorchid: "ba55d3",
+ mediumpurple: "9370db",
+ mediumseagreen: "3cb371",
+ mediumslateblue: "7b68ee",
+ mediumspringgreen: "00fa9a",
+ mediumturquoise: "48d1cc",
+ mediumvioletred: "c71585",
+ midnightblue: "191970",
+ mintcream: "f5fffa",
+ mistyrose: "ffe4e1",
+ moccasin: "ffe4b5",
+ navajowhite: "ffdead",
+ navy: "000080",
+ oldlace: "fdf5e6",
+ olive: "808000",
+ olivedrab: "6b8e23",
+ orange: "ffa500",
+ orangered: "ff4500",
+ orchid: "da70d6",
+ palegoldenrod: "eee8aa",
+ palegreen: "98fb98",
+ paleturquoise: "afeeee",
+ palevioletred: "db7093",
+ papayawhip: "ffefd5",
+ peachpuff: "ffdab9",
+ peru: "cd853f",
+ pink: "ffc0cb",
+ plum: "dda0dd",
+ powderblue: "b0e0e6",
+ purple: "800080",
+ rebeccapurple: "663399",
+ red: "f00",
+ rosybrown: "bc8f8f",
+ royalblue: "4169e1",
+ saddlebrown: "8b4513",
+ salmon: "fa8072",
+ sandybrown: "f4a460",
+ seagreen: "2e8b57",
+ seashell: "fff5ee",
+ sienna: "a0522d",
+ silver: "c0c0c0",
+ skyblue: "87ceeb",
+ slateblue: "6a5acd",
+ slategray: "708090",
+ slategrey: "708090",
+ snow: "fffafa",
+ springgreen: "00ff7f",
+ steelblue: "4682b4",
+ tan: "d2b48c",
+ teal: "008080",
+ thistle: "d8bfd8",
+ tomato: "ff6347",
+ turquoise: "40e0d0",
+ violet: "ee82ee",
+ wheat: "f5deb3",
+ white: "fff",
+ whitesmoke: "f5f5f5",
+ yellow: "ff0",
+ yellowgreen: "9acd32"
+};
+
+// Make it easy to access colors via `hexNames[hex]`
+var hexNames = tinycolor.hexNames = flip(names);
+
+
+// Utilities
+// ---------
+
+// `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
+function flip(o) {
+ var flipped = { };
+ for (var i in o) {
+ if (o.hasOwnProperty(i)) {
+ flipped[o[i]] = i;
+ }
+ }
+ return flipped;
+}
+
+// Return a valid alpha value [0,1] with all invalid values being set to 1
+function boundAlpha(a) {
+ a = parseFloat(a);
+
+ if (isNaN(a) || a < 0 || a > 1) {
+ a = 1;
+ }
+
+ return a;
+}
+
+// Take input from [0, n] and return it as [0, 1]
+function bound01(n, max) {
+ if (isOnePointZero(n)) { n = "100%"; }
+
+ var processPercent = isPercentage(n);
+ n = mathMin(max, mathMax(0, parseFloat(n)));
+
+ // Automatically convert percentage into number
+ if (processPercent) {
+ n = parseInt(n * max, 10) / 100;
+ }
+
+ // Handle floating point rounding errors
+ if ((math.abs(n - max) < 0.000001)) {
+ return 1;
+ }
+
+ // Convert into [0, 1] range if it isn't already
+ return (n % max) / parseFloat(max);
+}
+
+// Force a number between 0 and 1
+function clamp01(val) {
+ return mathMin(1, mathMax(0, val));
+}
+
+// Parse a base-16 hex value into a base-10 integer
+function parseIntFromHex(val) {
+ return parseInt(val, 16);
+}
+
+// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
+//
+function isOnePointZero(n) {
+ return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
+}
+
+// Check to see if string passed in is a percentage
+function isPercentage(n) {
+ return typeof n === "string" && n.indexOf('%') != -1;
+}
+
+// Force a hex value to have 2 characters
+function pad2(c) {
+ return c.length == 1 ? '0' + c : '' + c;
+}
+
+// Replace a decimal with it's percentage value
+function convertToPercentage(n) {
+ if (n <= 1) {
+ n = (n * 100) + "%";
+ }
+
+ return n;
+}
+
+// Converts a decimal to a hex value
+function convertDecimalToHex(d) {
+ return Math.round(parseFloat(d) * 255).toString(16);
+}
+// Converts a hex value to a decimal
+function convertHexToDecimal(h) {
+ return (parseIntFromHex(h) / 255);
+}
+
+var matchers = (function() {
+
+ //
+ var CSS_INTEGER = "[-\\+]?\\d+%?";
+
+ //
+ var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
+
+ // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
+ var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
+
+ // Actual matching.
+ // Parentheses and commas are optional, but not required.
+ // Whitespace can take the place of commas or opening paren
+ var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
+ var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
+
+ return {
+ rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
+ rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
+ hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
+ hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
+ hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
+ hsva: new RegExp("hsva" + PERMISSIVE_MATCH4),
+ hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
+ hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
+ hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
+ };
+})();
+
+// `stringInputToObject`
+// Permissive string parsing. Take in a number of formats, and output an object
+// based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
+function stringInputToObject(color) {
+
+ color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
+ var named = false;
+ if (names[color]) {
+ color = names[color];
+ named = true;
+ }
+ else if (color == 'transparent') {
+ return { r: 0, g: 0, b: 0, a: 0, format: "name" };
+ }
+
+ // Try to match string input using regular expressions.
+ // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
+ // Just return an object and let the conversion functions handle that.
+ // This way the result will be the same whether the tinycolor is initialized with string or object.
+ var match;
+ if ((match = matchers.rgb.exec(color))) {
+ return { r: match[1], g: match[2], b: match[3] };
+ }
+ if ((match = matchers.rgba.exec(color))) {
+ return { r: match[1], g: match[2], b: match[3], a: match[4] };
+ }
+ if ((match = matchers.hsl.exec(color))) {
+ return { h: match[1], s: match[2], l: match[3] };
+ }
+ if ((match = matchers.hsla.exec(color))) {
+ return { h: match[1], s: match[2], l: match[3], a: match[4] };
+ }
+ if ((match = matchers.hsv.exec(color))) {
+ return { h: match[1], s: match[2], v: match[3] };
+ }
+ if ((match = matchers.hsva.exec(color))) {
+ return { h: match[1], s: match[2], v: match[3], a: match[4] };
+ }
+ if ((match = matchers.hex8.exec(color))) {
+ return {
+ a: convertHexToDecimal(match[1]),
+ r: parseIntFromHex(match[2]),
+ g: parseIntFromHex(match[3]),
+ b: parseIntFromHex(match[4]),
+ format: named ? "name" : "hex8"
+ };
+ }
+ if ((match = matchers.hex6.exec(color))) {
+ return {
+ r: parseIntFromHex(match[1]),
+ g: parseIntFromHex(match[2]),
+ b: parseIntFromHex(match[3]),
+ format: named ? "name" : "hex"
+ };
+ }
+ if ((match = matchers.hex3.exec(color))) {
+ return {
+ r: parseIntFromHex(match[1] + '' + match[1]),
+ g: parseIntFromHex(match[2] + '' + match[2]),
+ b: parseIntFromHex(match[3] + '' + match[3]),
+ format: named ? "name" : "hex"
+ };
+ }
+
+ return false;
+}
+
+function validateWCAG2Parms(parms) {
+ // return valid WCAG2 parms for isReadable.
+ // If input parms are invalid, return {"level":"AA", "size":"small"}
+ var level, size;
+ parms = parms || {"level":"AA", "size":"small"};
+ level = (parms.level || "AA").toUpperCase();
+ size = (parms.size || "small").toLowerCase();
+ if (level !== "AA" && level !== "AAA") {
+ level = "AA";
+ }
+ if (size !== "small" && size !== "large") {
+ size = "small";
+ }
+ return {"level":level, "size":size};
+}
+
+// Node: Export function
+if (typeof module !== "undefined" && module.exports) {
+ module.exports = tinycolor;
+}
+// AMD/requirejs: Define the module
+else if (typeof define === 'function' && define.amd) {
+ define(function () {return tinycolor;});
+}
+// Browser: Expose to window
+else {
+ window.tinycolor = tinycolor;
+}
+
+})();
+
+},{}],230:[function(require,module,exports){
+!function() {
+ var topojson = {
+ version: "1.6.20",
+ mesh: function(topology) { return object(topology, meshArcs.apply(this, arguments)); },
+ meshArcs: meshArcs,
+ merge: function(topology) { return object(topology, mergeArcs.apply(this, arguments)); },
+ mergeArcs: mergeArcs,
+ feature: featureOrCollection,
+ neighbors: neighbors,
+ presimplify: presimplify
+ };
+
+ function stitchArcs(topology, arcs) {
+ var stitchedArcs = {},
+ fragmentByStart = {},
+ fragmentByEnd = {},
+ fragments = [],
+ emptyIndex = -1;
+
+ // Stitch empty arcs first, since they may be subsumed by other arcs.
+ arcs.forEach(function(i, j) {
+ var arc = topology.arcs[i < 0 ? ~i : i], t;
+ if (arc.length < 3 && !arc[1][0] && !arc[1][1]) {
+ t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t;
+ }
+ });
+
+ arcs.forEach(function(i) {
+ var e = ends(i),
+ start = e[0],
+ end = e[1],
+ f, g;
+
+ if (f = fragmentByEnd[start]) {
+ delete fragmentByEnd[f.end];
+ f.push(i);
+ f.end = end;
+ if (g = fragmentByStart[end]) {
+ delete fragmentByStart[g.start];
+ var fg = g === f ? f : f.concat(g);
+ fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg;
+ } else {
+ fragmentByStart[f.start] = fragmentByEnd[f.end] = f;
+ }
+ } else if (f = fragmentByStart[end]) {
+ delete fragmentByStart[f.start];
+ f.unshift(i);
+ f.start = start;
+ if (g = fragmentByEnd[start]) {
+ delete fragmentByEnd[g.end];
+ var gf = g === f ? f : g.concat(f);
+ fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf;
+ } else {
+ fragmentByStart[f.start] = fragmentByEnd[f.end] = f;
+ }
+ } else {
+ f = [i];
+ fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f;
+ }
+ });
+
+ function ends(i) {
+ var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1;
+ if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; });
+ else p1 = arc[arc.length - 1];
+ return i < 0 ? [p1, p0] : [p0, p1];
+ }
+
+ function flush(fragmentByEnd, fragmentByStart) {
+ for (var k in fragmentByEnd) {
+ var f = fragmentByEnd[k];
+ delete fragmentByStart[f.start];
+ delete f.start;
+ delete f.end;
+ f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; });
+ fragments.push(f);
+ }
+ }
+
+ flush(fragmentByEnd, fragmentByStart);
+ flush(fragmentByStart, fragmentByEnd);
+ arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); });
+
+ return fragments;
+ }
+
+ function meshArcs(topology, o, filter) {
+ var arcs = [];
+
+ if (arguments.length > 1) {
+ var geomsByArc = [],
+ geom;
+
+ function arc(i) {
+ var j = i < 0 ? ~i : i;
+ (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom});
+ }
+
+ function line(arcs) {
+ arcs.forEach(arc);
+ }
+
+ function polygon(arcs) {
+ arcs.forEach(line);
+ }
+
+ function geometry(o) {
+ if (o.type === "GeometryCollection") o.geometries.forEach(geometry);
+ else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs);
+ }
+
+ var geometryType = {
+ LineString: line,
+ MultiLineString: polygon,
+ Polygon: polygon,
+ MultiPolygon: function(arcs) { arcs.forEach(polygon); }
+ };
+
+ geometry(o);
+
+ geomsByArc.forEach(arguments.length < 3
+ ? function(geoms) { arcs.push(geoms[0].i); }
+ : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); });
+ } else {
+ for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i);
+ }
+
+ return {type: "MultiLineString", arcs: stitchArcs(topology, arcs)};
+ }
+
+ function mergeArcs(topology, objects) {
+ var polygonsByArc = {},
+ polygons = [],
+ components = [];
+
+ objects.forEach(function(o) {
+ if (o.type === "Polygon") register(o.arcs);
+ else if (o.type === "MultiPolygon") o.arcs.forEach(register);
+ });
+
+ function register(polygon) {
+ polygon.forEach(function(ring) {
+ ring.forEach(function(arc) {
+ (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon);
+ });
+ });
+ polygons.push(polygon);
+ }
+
+ function exterior(ring) {
+ return cartesianRingArea(object(topology, {type: "Polygon", arcs: [ring]}).coordinates[0]) > 0; // TODO allow spherical?
+ }
+
+ polygons.forEach(function(polygon) {
+ if (!polygon._) {
+ var component = [],
+ neighbors = [polygon];
+ polygon._ = 1;
+ components.push(component);
+ while (polygon = neighbors.pop()) {
+ component.push(polygon);
+ polygon.forEach(function(ring) {
+ ring.forEach(function(arc) {
+ polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) {
+ if (!polygon._) {
+ polygon._ = 1;
+ neighbors.push(polygon);
+ }
+ });
+ });
+ });
+ }
+ }
+ });
+
+ polygons.forEach(function(polygon) {
+ delete polygon._;
+ });
+
+ return {
+ type: "MultiPolygon",
+ arcs: components.map(function(polygons) {
+ var arcs = [], n;
+
+ // Extract the exterior (unique) arcs.
+ polygons.forEach(function(polygon) {
+ polygon.forEach(function(ring) {
+ ring.forEach(function(arc) {
+ if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) {
+ arcs.push(arc);
+ }
+ });
+ });
+ });
+
+ // Stitch the arcs into one or more rings.
+ arcs = stitchArcs(topology, arcs);
+
+ // If more than one ring is returned,
+ // at most one of these rings can be the exterior;
+ // this exterior ring has the same winding order
+ // as any exterior ring in the original polygons.
+ if ((n = arcs.length) > 1) {
+ var sgn = exterior(polygons[0][0]);
+ for (var i = 0, t; i < n; ++i) {
+ if (sgn === exterior(arcs[i])) {
+ t = arcs[0], arcs[0] = arcs[i], arcs[i] = t;
+ break;
+ }
+ }
+ }
+
+ return arcs;
+ })
+ };
+ }
+
+ function featureOrCollection(topology, o) {
+ return o.type === "GeometryCollection" ? {
+ type: "FeatureCollection",
+ features: o.geometries.map(function(o) { return feature(topology, o); })
+ } : feature(topology, o);
+ }
+
+ function feature(topology, o) {
+ var f = {
+ type: "Feature",
+ id: o.id,
+ properties: o.properties || {},
+ geometry: object(topology, o)
+ };
+ if (o.id == null) delete f.id;
+ return f;
+ }
+
+ function object(topology, o) {
+ var absolute = transformAbsolute(topology.transform),
+ arcs = topology.arcs;
+
+ function arc(i, points) {
+ if (points.length) points.pop();
+ for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) {
+ points.push(p = a[k].slice());
+ absolute(p, k);
+ }
+ if (i < 0) reverse(points, n);
+ }
+
+ function point(p) {
+ p = p.slice();
+ absolute(p, 0);
+ return p;
+ }
+
+ function line(arcs) {
+ var points = [];
+ for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points);
+ if (points.length < 2) points.push(points[0].slice());
+ return points;
+ }
+
+ function ring(arcs) {
+ var points = line(arcs);
+ while (points.length < 4) points.push(points[0].slice());
+ return points;
+ }
+
+ function polygon(arcs) {
+ return arcs.map(ring);
+ }
+
+ function geometry(o) {
+ var t = o.type;
+ return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)}
+ : t in geometryType ? {type: t, coordinates: geometryType[t](o)}
+ : null;
+ }
+
+ var geometryType = {
+ Point: function(o) { return point(o.coordinates); },
+ MultiPoint: function(o) { return o.coordinates.map(point); },
+ LineString: function(o) { return line(o.arcs); },
+ MultiLineString: function(o) { return o.arcs.map(line); },
+ Polygon: function(o) { return polygon(o.arcs); },
+ MultiPolygon: function(o) { return o.arcs.map(polygon); }
+ };
+
+ return geometry(o);
+ }
+
+ function reverse(array, n) {
+ var t, j = array.length, i = j - n; while (i < --j) t = array[i], array[i++] = array[j], array[j] = t;
+ }
+
+ function bisect(a, x) {
+ var lo = 0, hi = a.length;
+ while (lo < hi) {
+ var mid = lo + hi >>> 1;
+ if (a[mid] < x) lo = mid + 1;
+ else hi = mid;
+ }
+ return lo;
+ }
+
+ function neighbors(objects) {
+ var indexesByArc = {}, // arc index -> array of object indexes
+ neighbors = objects.map(function() { return []; });
+
+ function line(arcs, i) {
+ arcs.forEach(function(a) {
+ if (a < 0) a = ~a;
+ var o = indexesByArc[a];
+ if (o) o.push(i);
+ else indexesByArc[a] = [i];
+ });
+ }
+
+ function polygon(arcs, i) {
+ arcs.forEach(function(arc) { line(arc, i); });
+ }
+
+ function geometry(o, i) {
+ if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); });
+ else if (o.type in geometryType) geometryType[o.type](o.arcs, i);
+ }
+
+ var geometryType = {
+ LineString: line,
+ MultiLineString: polygon,
+ Polygon: polygon,
+ MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); }
+ };
+
+ objects.forEach(geometry);
+
+ for (var i in indexesByArc) {
+ for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) {
+ for (var k = j + 1; k < m; ++k) {
+ var ij = indexes[j], ik = indexes[k], n;
+ if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik);
+ if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij);
+ }
+ }
+ }
+
+ return neighbors;
+ }
+
+ function presimplify(topology, triangleArea) {
+ var absolute = transformAbsolute(topology.transform),
+ relative = transformRelative(topology.transform),
+ heap = minAreaHeap();
+
+ if (!triangleArea) triangleArea = cartesianTriangleArea;
+
+ topology.arcs.forEach(function(arc) {
+ var triangles = [],
+ maxArea = 0,
+ triangle;
+
+ // To store each point’s effective area, we create a new array rather than
+ // extending the passed-in point to workaround a Chrome/V8 bug (getting
+ // stuck in smi mode). For midpoints, the initial effective area of
+ // Infinity will be computed in the next step.
+ for (var i = 0, n = arc.length, p; i < n; ++i) {
+ p = arc[i];
+ absolute(arc[i] = [p[0], p[1], Infinity], i);
+ }
+
+ for (var i = 1, n = arc.length - 1; i < n; ++i) {
+ triangle = arc.slice(i - 1, i + 2);
+ triangle[1][2] = triangleArea(triangle);
+ triangles.push(triangle);
+ heap.push(triangle);
+ }
+
+ for (var i = 0, n = triangles.length; i < n; ++i) {
+ triangle = triangles[i];
+ triangle.previous = triangles[i - 1];
+ triangle.next = triangles[i + 1];
+ }
+
+ while (triangle = heap.pop()) {
+ var previous = triangle.previous,
+ next = triangle.next;
+
+ // If the area of the current point is less than that of the previous point
+ // to be eliminated, use the latter's area instead. This ensures that the
+ // current point cannot be eliminated without eliminating previously-
+ // eliminated points.
+ if (triangle[1][2] < maxArea) triangle[1][2] = maxArea;
+ else maxArea = triangle[1][2];
+
+ if (previous) {
+ previous.next = next;
+ previous[2] = triangle[2];
+ update(previous);
+ }
+
+ if (next) {
+ next.previous = previous;
+ next[0] = triangle[0];
+ update(next);
+ }
+ }
+
+ arc.forEach(relative);
+ });
+
+ function update(triangle) {
+ heap.remove(triangle);
+ triangle[1][2] = triangleArea(triangle);
+ heap.push(triangle);
+ }
+
+ return topology;
+ }
+
+ function cartesianRingArea(ring) {
+ var i = -1,
+ n = ring.length,
+ a,
+ b = ring[n - 1],
+ area = 0;
+
+ while (++i < n) {
+ a = b;
+ b = ring[i];
+ area += a[0] * b[1] - a[1] * b[0];
+ }
+
+ return area / 2;
+ }
+
+ function cartesianTriangleArea(triangle) {
+ var a = triangle[0], b = triangle[1], c = triangle[2];
+ return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]));
+ }
+
+ function compareArea(a, b) {
+ return a[1][2] - b[1][2];
+ }
+
+ function minAreaHeap() {
+ var heap = {},
+ array = [],
+ size = 0;
+
+ heap.push = function(object) {
+ up(array[object._ = size] = object, size++);
+ return size;
+ };
+
+ heap.pop = function() {
+ if (size <= 0) return;
+ var removed = array[0], object;
+ if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0);
+ return removed;
+ };
+
+ heap.remove = function(removed) {
+ var i = removed._, object;
+ if (array[i] !== removed) return; // invalid request
+ if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i);
+ return i;
+ };
+
+ function up(object, i) {
+ while (i > 0) {
+ var j = ((i + 1) >> 1) - 1,
+ parent = array[j];
+ if (compareArea(object, parent) >= 0) break;
+ array[parent._ = i] = parent;
+ array[object._ = i = j] = object;
+ }
+ }
+
+ function down(object, i) {
+ while (true) {
+ var r = (i + 1) << 1,
+ l = r - 1,
+ j = i,
+ child = array[j];
+ if (l < size && compareArea(array[l], child) < 0) child = array[j = l];
+ if (r < size && compareArea(array[r], child) < 0) child = array[j = r];
+ if (j === i) break;
+ array[child._ = i] = child;
+ array[object._ = i = j] = object;
+ }
+ }
+
+ return heap;
+ }
+
+ function transformAbsolute(transform) {
+ if (!transform) return noop;
+ var x0,
+ y0,
+ kx = transform.scale[0],
+ ky = transform.scale[1],
+ dx = transform.translate[0],
+ dy = transform.translate[1];
+ return function(point, i) {
+ if (!i) x0 = y0 = 0;
+ point[0] = (x0 += point[0]) * kx + dx;
+ point[1] = (y0 += point[1]) * ky + dy;
+ };
+ }
+
+ function transformRelative(transform) {
+ if (!transform) return noop;
+ var x0,
+ y0,
+ kx = transform.scale[0],
+ ky = transform.scale[1],
+ dx = transform.translate[0],
+ dy = transform.translate[1];
+ return function(point, i) {
+ if (!i) x0 = y0 = 0;
+ var x1 = (point[0] - dx) / kx | 0,
+ y1 = (point[1] - dy) / ky | 0;
+ point[0] = x1 - x0;
+ point[1] = y1 - y0;
+ x0 = x1;
+ y0 = y1;
+ };
+ }
+
+ function noop() {}
+
+ if (typeof define === "function" && define.amd) define(topojson);
+ else if (typeof module === "object" && module.exports) module.exports = topojson;
+ else this.topojson = topojson;
+}();
+
+},{}],231:[function(require,module,exports){
+"use strict"
+
+module.exports = twoProduct
+
+var SPLITTER = +(Math.pow(2, 27) + 1.0)
+
+function twoProduct(a, b, result) {
+ var x = a * b
+
+ var c = SPLITTER * a
+ var abig = c - a
+ var ahi = c - abig
+ var alo = a - ahi
+
+ var d = SPLITTER * b
+ var bbig = d - b
+ var bhi = d - bbig
+ var blo = b - bhi
+
+ var err1 = x - (ahi * bhi)
+ var err2 = err1 - (alo * bhi)
+ var err3 = err2 - (ahi * blo)
+
+ var y = alo * blo - err3
+
+ if(result) {
+ result[0] = y
+ result[1] = x
+ return result
+ }
+
+ return [ y, x ]
+}
+},{}],232:[function(require,module,exports){
+"use strict"
+
+module.exports = fastTwoSum
+
+function fastTwoSum(a, b, result) {
+ var x = a + b
+ var bv = x - a
+ var av = x - bv
+ var br = b - bv
+ var ar = a - av
+ if(result) {
+ result[0] = ar + br
+ result[1] = x
+ return result
+ }
+ return [ar+br, x]
+}
+},{}],233:[function(require,module,exports){
+(function (global,Buffer){
+'use strict'
+
+var bits = require('bit-twiddle')
+var dup = require('dup')
+
+//Legacy pool support
+if(!global.__TYPEDARRAY_POOL) {
+ global.__TYPEDARRAY_POOL = {
+ UINT8 : dup([32, 0])
+ , UINT16 : dup([32, 0])
+ , UINT32 : dup([32, 0])
+ , INT8 : dup([32, 0])
+ , INT16 : dup([32, 0])
+ , INT32 : dup([32, 0])
+ , FLOAT : dup([32, 0])
+ , DOUBLE : dup([32, 0])
+ , DATA : dup([32, 0])
+ , UINT8C : dup([32, 0])
+ , BUFFER : dup([32, 0])
+ }
+}
+
+var hasUint8C = (typeof Uint8ClampedArray) !== 'undefined'
+var POOL = global.__TYPEDARRAY_POOL
+
+//Upgrade pool
+if(!POOL.UINT8C) {
+ POOL.UINT8C = dup([32, 0])
+}
+if(!POOL.BUFFER) {
+ POOL.BUFFER = dup([32, 0])
+}
+
+//New technique: Only allocate from ArrayBufferView and Buffer
+var DATA = POOL.DATA
+ , BUFFER = POOL.BUFFER
+
+exports.free = function free(array) {
+ if(Buffer.isBuffer(array)) {
+ BUFFER[bits.log2(array.length)].push(array)
+ } else {
+ if(Object.prototype.toString.call(array) !== '[object ArrayBuffer]') {
+ array = array.buffer
+ }
+ if(!array) {
+ return
+ }
+ var n = array.length || array.byteLength
+ var log_n = bits.log2(n)|0
+ DATA[log_n].push(array)
+ }
+}
+
+function freeArrayBuffer(buffer) {
+ if(!buffer) {
+ return
+ }
+ var n = buffer.length || buffer.byteLength
+ var log_n = bits.log2(n)
+ DATA[log_n].push(buffer)
+}
+
+function freeTypedArray(array) {
+ freeArrayBuffer(array.buffer)
+}
+
+exports.freeUint8 =
+exports.freeUint16 =
+exports.freeUint32 =
+exports.freeInt8 =
+exports.freeInt16 =
+exports.freeInt32 =
+exports.freeFloat32 =
+exports.freeFloat =
+exports.freeFloat64 =
+exports.freeDouble =
+exports.freeUint8Clamped =
+exports.freeDataView = freeTypedArray
+
+exports.freeArrayBuffer = freeArrayBuffer
+
+exports.freeBuffer = function freeBuffer(array) {
+ BUFFER[bits.log2(array.length)].push(array)
+}
+
+exports.malloc = function malloc(n, dtype) {
+ if(dtype === undefined || dtype === 'arraybuffer') {
+ return mallocArrayBuffer(n)
+ } else {
+ switch(dtype) {
+ case 'uint8':
+ return mallocUint8(n)
+ case 'uint16':
+ return mallocUint16(n)
+ case 'uint32':
+ return mallocUint32(n)
+ case 'int8':
+ return mallocInt8(n)
+ case 'int16':
+ return mallocInt16(n)
+ case 'int32':
+ return mallocInt32(n)
+ case 'float':
+ case 'float32':
+ return mallocFloat(n)
+ case 'double':
+ case 'float64':
+ return mallocDouble(n)
+ case 'uint8_clamped':
+ return mallocUint8Clamped(n)
+ case 'buffer':
+ return mallocBuffer(n)
+ case 'data':
+ case 'dataview':
+ return mallocDataView(n)
+
+ default:
+ return null
+ }
+ }
+ return null
+}
+
+function mallocArrayBuffer(n) {
+ var n = bits.nextPow2(n)
+ var log_n = bits.log2(n)
+ var d = DATA[log_n]
+ if(d.length > 0) {
+ return d.pop()
+ }
+ return new ArrayBuffer(n)
+}
+exports.mallocArrayBuffer = mallocArrayBuffer
+
+function mallocUint8(n) {
+ return new Uint8Array(mallocArrayBuffer(n), 0, n)
+}
+exports.mallocUint8 = mallocUint8
+
+function mallocUint16(n) {
+ return new Uint16Array(mallocArrayBuffer(2*n), 0, n)
+}
+exports.mallocUint16 = mallocUint16
+
+function mallocUint32(n) {
+ return new Uint32Array(mallocArrayBuffer(4*n), 0, n)
+}
+exports.mallocUint32 = mallocUint32
+
+function mallocInt8(n) {
+ return new Int8Array(mallocArrayBuffer(n), 0, n)
+}
+exports.mallocInt8 = mallocInt8
+
+function mallocInt16(n) {
+ return new Int16Array(mallocArrayBuffer(2*n), 0, n)
+}
+exports.mallocInt16 = mallocInt16
+
+function mallocInt32(n) {
+ return new Int32Array(mallocArrayBuffer(4*n), 0, n)
+}
+exports.mallocInt32 = mallocInt32
+
+function mallocFloat(n) {
+ return new Float32Array(mallocArrayBuffer(4*n), 0, n)
+}
+exports.mallocFloat32 = exports.mallocFloat = mallocFloat
+
+function mallocDouble(n) {
+ return new Float64Array(mallocArrayBuffer(8*n), 0, n)
+}
+exports.mallocFloat64 = exports.mallocDouble = mallocDouble
+
+function mallocUint8Clamped(n) {
+ if(hasUint8C) {
+ return new Uint8ClampedArray(mallocArrayBuffer(n), 0, n)
+ } else {
+ return mallocUint8(n)
+ }
+}
+exports.mallocUint8Clamped = mallocUint8Clamped
+
+function mallocDataView(n) {
+ return new DataView(mallocArrayBuffer(n), 0, n)
+}
+exports.mallocDataView = mallocDataView
+
+function mallocBuffer(n) {
+ n = bits.nextPow2(n)
+ var log_n = bits.log2(n)
+ var cache = BUFFER[log_n]
+ if(cache.length > 0) {
+ return cache.pop()
+ }
+ return new Buffer(n)
+}
+exports.mallocBuffer = mallocBuffer
+
+exports.clearCache = function clearCache() {
+ for(var i=0; i<32; ++i) {
+ POOL.UINT8[i].length = 0
+ POOL.UINT16[i].length = 0
+ POOL.UINT32[i].length = 0
+ POOL.INT8[i].length = 0
+ POOL.INT16[i].length = 0
+ POOL.INT32[i].length = 0
+ POOL.FLOAT[i].length = 0
+ POOL.DOUBLE[i].length = 0
+ POOL.UINT8C[i].length = 0
+ DATA[i].length = 0
+ BUFFER[i].length = 0
+ }
+}
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer)
+},{"bit-twiddle":49,"buffer":50,"dup":72}],234:[function(require,module,exports){
+"use strict"
+
+function unique_pred(list, compare) {
+ var ptr = 1
+ , len = list.length
+ , a=list[0], b=list[0]
+ for(var i=1; i 8192) {
+ throw new Error("vectorize-text: String too long (sorry, this will get fixed later)")
+ }
+ var height = 3 * size
+ if(canvas.height < height) {
+ canvas.height = height
+ }
+
+ context.fillStyle = "#000"
+ context.fillRect(0, 0, canvas.width, canvas.height)
+
+ context.fillStyle = "#fff"
+ context.fillText(str, size, 2*size)
+
+ //Cut pixels from image
+ var pixelData = context.getImageData(0, 0, width, height)
+ var pixels = ndarray(pixelData.data, [height, width, 4])
+
+ return pixels.pick(-1,-1,0).transpose(1,0)
+}
+
+function getContour(pixels, doSimplify) {
+ var contour = surfaceNets(pixels, 128)
+ if(doSimplify) {
+ return simplify(contour.cells, contour.positions, 0.25)
+ }
+ return {
+ edges: contour.cells,
+ positions: contour.positions
+ }
+}
+
+function processPixelsImpl(pixels, options, size, simplify) {
+ //Extract contour
+ var contour = getContour(pixels, simplify)
+
+ //Apply warp to positions
+ var positions = transformPositions(contour.positions, options, size)
+ var edges = contour.edges
+ var flip = "ccw" === options.orientation
+
+ //Clean up the PSLG, resolve self intersections, etc.
+ cleanPSLG(positions, edges)
+
+ //If triangulate flag passed, triangulate the result
+ if(options.polygons || options.polygon || options.polyline) {
+ var result = toPolygonCrappy(edges, positions)
+ var nresult = new Array(result.length)
+ for(var i=0; i 0) {
+ var b = stack.pop()
+ var a = stack.pop()
+
+ //Find opposite pairs
+ var x = -1, y = -1
+ var star = stars[a]
+ for(var i=1; i= 0) {
+ continue
+ }
+
+ //Flip the edge
+ triangulation.flip(a, b)
+
+ //Test flipping neighboring edges
+ testFlip(points, triangulation, stack, x, a, y)
+ testFlip(points, triangulation, stack, a, y, x)
+ testFlip(points, triangulation, stack, y, b, x)
+ testFlip(points, triangulation, stack, b, x, y)
+ }
+}
+
+},{"binary-search-bounds":242,"robust-in-sphere":243}],239:[function(require,module,exports){
+'use strict'
+
+var bsearch = require('binary-search-bounds')
+
+module.exports = classifyFaces
+
+function FaceIndex(cells, neighbor, constraint, flags, active, next, boundary) {
+ this.cells = cells
+ this.neighbor = neighbor
+ this.flags = flags
+ this.constraint = constraint
+ this.active = active
+ this.next = next
+ this.boundary = boundary
+}
+
+var proto = FaceIndex.prototype
+
+function compareCell(a, b) {
+ return a[0] - b[0] ||
+ a[1] - b[1] ||
+ a[2] - b[2]
+}
+
+proto.locate = (function() {
+ var key = [0,0,0]
+ return function(a, b, c) {
+ var x = a, y = b, z = c
+ if(b < c) {
+ if(b < a) {
+ x = b
+ y = c
+ z = a
+ }
+ } else if(c < a) {
+ x = c
+ y = a
+ z = b
+ }
+ if(x < 0) {
+ return -1
+ }
+ key[0] = x
+ key[1] = y
+ key[2] = z
+ return bsearch.eq(this.cells, key, compareCell)
+ }
+})()
+
+function indexCells(triangulation, infinity) {
+ //First get cells and canonicalize
+ var cells = triangulation.cells()
+ var nc = cells.length
+ for(var i=0; i 0 || next.length > 0) {
+ while(active.length > 0) {
+ var t = active.pop()
+ if(flags[t] === -side) {
+ continue
+ }
+ flags[t] = side
+ var c = cells[t]
+ for(var j=0; j<3; ++j) {
+ var f = neighbor[3*t+j]
+ if(f >= 0 && flags[f] === 0) {
+ if(constraint[3*t+j]) {
+ next.push(f)
+ } else {
+ active.push(f)
+ flags[f] = side
+ }
+ }
+ }
+ }
+
+ //Swap arrays and loop
+ var tmp = next
+ next = active
+ active = tmp
+ next.length = 0
+ side = -side
+ }
+
+ var result = filterCells(cells, flags, target)
+ if(infinity) {
+ return result.concat(index.boundary)
+ }
+ return result
+}
+
+},{"binary-search-bounds":242}],240:[function(require,module,exports){
+'use strict'
+
+var bsearch = require('binary-search-bounds')
+var orient = require('robust-orientation')[3]
+
+var EVENT_POINT = 0
+var EVENT_END = 1
+var EVENT_START = 2
+
+module.exports = monotoneTriangulate
+
+//A partial convex hull fragment, made of two unimonotone polygons
+function PartialHull(a, b, idx, lowerIds, upperIds) {
+ this.a = a
+ this.b = b
+ this.idx = idx
+ this.lowerIds = lowerIds
+ this.upperIds = upperIds
+}
+
+//An event in the sweep line procedure
+function Event(a, b, type, idx) {
+ this.a = a
+ this.b = b
+ this.type = type
+ this.idx = idx
+}
+
+//This is used to compare events for the sweep line procedure
+// Points are:
+// 1. sorted lexicographically
+// 2. sorted by type (point < end < start)
+// 3. segments sorted by winding order
+// 4. sorted by index
+function compareEvent(a, b) {
+ var d =
+ (a.a[0] - b.a[0]) ||
+ (a.a[1] - b.a[1]) ||
+ (a.type - b.type)
+ if(d) { return d }
+ if(a.type !== EVENT_POINT) {
+ d = orient(a.a, a.b, b.b)
+ if(d) { return d }
+ }
+ return a.idx - b.idx
+}
+
+function testPoint(hull, p) {
+ return orient(hull.a, hull.b, p)
+}
+
+function addPoint(cells, hulls, points, p, idx) {
+ var lo = bsearch.lt(hulls, p, testPoint)
+ var hi = bsearch.gt(hulls, p, testPoint)
+ for(var i=lo; i 1 && orient(
+ points[lowerIds[m-2]],
+ points[lowerIds[m-1]],
+ p) > 0) {
+ cells.push(
+ [lowerIds[m-1],
+ lowerIds[m-2],
+ idx])
+ m -= 1
+ }
+ lowerIds.length = m
+ lowerIds.push(idx)
+
+ //Insert p into upper hull
+ var upperIds = hull.upperIds
+ var m = upperIds.length
+ while(m > 1 && orient(
+ points[upperIds[m-2]],
+ points[upperIds[m-1]],
+ p) < 0) {
+ cells.push(
+ [upperIds[m-2],
+ upperIds[m-1],
+ idx])
+ m -= 1
+ }
+ upperIds.length = m
+ upperIds.push(idx)
+ }
+}
+
+function findSplit(hull, edge) {
+ var d
+ if(hull.a[0] < edge.a[0]) {
+ d = orient(hull.a, hull.b, edge.a)
+ } else {
+ d = orient(edge.b, edge.a, hull.a)
+ }
+ if(d) { return d }
+ if(edge.b[0] < hull.b[0]) {
+ d = orient(hull.a, hull.b, edge.b)
+ } else {
+ d = orient(edge.b, edge.a, hull.b)
+ }
+ return d || hull.idx - edge.idx
+}
+
+function splitHulls(hulls, points, event) {
+ var splitIdx = bsearch.le(hulls, event, findSplit)
+ var hull = hulls[splitIdx]
+ var upperIds = hull.upperIds
+ var x = upperIds[upperIds.length-1]
+ hull.upperIds = [x]
+ hulls.splice(splitIdx+1, 0,
+ new PartialHull(event.a, event.b, event.idx, [x], upperIds))
+}
+
+
+function mergeHulls(hulls, points, event) {
+ //Swap pointers for merge search
+ var tmp = event.a
+ event.a = event.b
+ event.b = tmp
+ var mergeIdx = bsearch.eq(hulls, event, findSplit)
+ var upper = hulls[mergeIdx]
+ var lower = hulls[mergeIdx-1]
+ lower.upperIds = upper.upperIds
+ hulls.splice(mergeIdx, 1)
+}
+
+
+function monotoneTriangulate(points, edges) {
+
+ var numPoints = points.length
+ var numEdges = edges.length
+
+ var events = []
+
+ //Create point events
+ for(var i=0; i b[0]) {
+ events.push(
+ new Event(b, a, EVENT_START, i),
+ new Event(a, b, EVENT_END, i))
+ }
+ }
+
+ //Sort events
+ events.sort(compareEvent)
+
+ //Initialize hull
+ var minX = events[0].a[0] - (1 + Math.abs(events[0].a[0])) * Math.pow(2, -52)
+ var hull = [ new PartialHull([minX, 1], [minX, 0], -1, [], [], [], []) ]
+
+ //Process events in order
+ var cells = []
+ for(var i=0, numEvents=events.length; i= 0
+ }
+})()
+
+proto.removeTriangle = function(i, j, k) {
+ var stars = this.stars
+ removePair(stars[i], j, k)
+ removePair(stars[j], k, i)
+ removePair(stars[k], i, j)
+}
+
+proto.addTriangle = function(i, j, k) {
+ var stars = this.stars
+ stars[i].push(j, k)
+ stars[j].push(k, i)
+ stars[k].push(i, j)
+}
+
+proto.opposite = function(j, i) {
+ var list = this.stars[i]
+ for(var k=1, n=list.length; k>1
+ return ["sum(", generateSum(expr.slice(0, m)), ",", generateSum(expr.slice(m)), ")"].join("")
+ }
+}
+
+function makeProduct(a, b) {
+ if(a.charAt(0) === "m") {
+ if(b.charAt(0) === "w") {
+ var toks = a.split("[")
+ return ["w", b.substr(1), "m", toks[0].substr(1)].join("")
+ } else {
+ return ["prod(", a, ",", b, ")"].join("")
+ }
+ } else {
+ return makeProduct(b, a)
+ }
+}
+
+function sign(s) {
+ if(s & 1 !== 0) {
+ return "-"
+ }
+ return ""
+}
+
+function determinant(m) {
+ if(m.length === 2) {
+ return [["diff(", makeProduct(m[0][0], m[1][1]), ",", makeProduct(m[1][0], m[0][1]), ")"].join("")]
+ } else {
+ var expr = []
+ for(var i=0; i 0) {
+ return [nextafter(f, -Infinity), f]
+ } else {
+ return [f, f]
+ }
+}
+
+//Convert a list of edges in a pslg to bounding boxes
+function boundEdges(points, edges) {
+ var bounds = new Array(edges.length)
+ for(var i=0; i= floatPoints.length) {
+ return ratPoints[idx-floatPoints.length]
+ }
+ var p = floatPoints[idx]
+ return [ rat(p[0]), rat(p[1]) ]
+ }
+ junctions.sort(function(a, b) {
+ if(a[0] !== b[0]) {
+ return a[0] - b[0]
+ }
+ var u = getPoint(a[1])
+ var v = getPoint(b[1])
+ return ratCmp(u[0], v[0]) || ratCmp(u[1], v[1])
+ })
+
+ //Split edges along junctions
+ for(var i=junctions.length-1; i>=0; --i) {
+ var junction = junctions[i]
+ var e = junction[0]
+
+ var edge = edges[e]
+ var s = edge[0]
+ var t = edge[1]
+
+ //Check if edge is not lexicographically sorted
+ var a = floatPoints[s]
+ var b = floatPoints[t]
+ if(((a[0] - b[0]) || (a[1] - b[1])) < 0) {
+ var tmp = s
+ s = t
+ t = tmp
+ }
+
+ //Split leading edge
+ edge[0] = s
+ var last = edge[1] = junction[1]
+
+ //If we are grouping edges by color, remember to track data
+ var color
+ if(useColor) {
+ color = edge[2]
+ }
+
+ //Split other edges
+ while(i > 0 && junctions[i-1][0] === e) {
+ var junction = junctions[--i]
+ var next = junction[1]
+ if(useColor) {
+ edges.push([last, next, color])
+ } else {
+ edges.push([last, next])
+ }
+ last = next
+ }
+
+ //Add final edge
+ if(useColor) {
+ edges.push([last, t, color])
+ } else {
+ edges.push([last, t])
+ }
+ }
+
+ //Return constructed rational points
+ return ratPoints
+}
+
+//Merge overlapping points
+function dedupPoints(floatPoints, ratPoints, floatBounds) {
+ var numPoints = floatPoints.length + ratPoints.length
+ var uf = new UnionFind(numPoints)
+
+ //Compute rational bounds
+ var bounds = floatBounds
+ for(var i=0; i b[2]) {
+ return 1
+ }
+ return 0
+}
+
+//Remove duplicate edge labels
+function dedupEdges(edges, labels, useColor) {
+ if(edges.length === 0) {
+ return
+ }
+ if(labels) {
+ for(var i=0; i 0 || tjunctions.length > 0)
+ }
+
+ // More iterations necessary
+ return true
+}
+
+//Main loop, runs PSLG clean up until completion
+function cleanPSLG(points, edges, colors) {
+ var modified = false
+
+ //If using colors, augment edges with color data
+ var prevEdges
+ if(colors) {
+ prevEdges = edges
+ var augEdges = new Array(edges.length)
+ for(var i=0; i 0) {
+ a = a.shln(shift)
+ } else if(shift < 0) {
+ b = b.shln(-shift)
+ }
+ return rationalize(a, b)
+}
+
+},{"./div":248,"./is-rat":250,"./lib/is-bn":254,"./lib/num-to-bn":255,"./lib/rationalize":256,"./lib/str-to-bn":257}],250:[function(require,module,exports){
+'use strict'
+
+var isBN = require('./lib/is-bn')
+
+module.exports = isRat
+
+function isRat(x) {
+ return Array.isArray(x) && x.length === 2 && isBN(x[0]) && isBN(x[1])
+}
+
+},{"./lib/is-bn":254}],251:[function(require,module,exports){
+'use strict'
+
+var bn = require('bn.js')
+
+module.exports = sign
+
+function sign(x) {
+ return x.cmp(new bn(0))
+}
+
+},{"bn.js":259}],252:[function(require,module,exports){
+'use strict'
+
+module.exports = bn2num
+
+//TODO: Make this better
+function bn2num(b) {
+ var l = b.length
+ var words = b.words
+ var out = 0
+ if (l === 1) {
+ out = words[0]
+ } else if (l === 2) {
+ out = words[0] + (words[1] * 0x4000000)
+ } else {
+ var out = 0
+ for (var i = 0; i < l; i++) {
+ var w = words[i]
+ out += w * Math.pow(0x4000000, i)
+ }
+ }
+ return b.sign ? -out : out
+}
+
+},{}],253:[function(require,module,exports){
+'use strict'
+
+var db = require('double-bits')
+var ctz = require('bit-twiddle').countTrailingZeros
+
+module.exports = ctzNumber
+
+//Counts the number of trailing zeros
+function ctzNumber(x) {
+ var l = ctz(db.lo(x))
+ if(l < 32) {
+ return l
+ }
+ var h = ctz(db.hi(x))
+ if(h > 20) {
+ return 52
+ }
+ return h + 32
+}
+
+},{"bit-twiddle":49,"double-bits":270}],254:[function(require,module,exports){
+'use strict'
+
+var BN = require('bn.js')
+
+module.exports = isBN
+
+//Test if x is a bignumber
+//FIXME: obviously this is the wrong way to do it
+function isBN(x) {
+ return x && typeof x === 'object' && Boolean(x.words)
+}
+
+},{"bn.js":259}],255:[function(require,module,exports){
+'use strict'
+
+var BN = require('bn.js')
+var db = require('double-bits')
+
+module.exports = num2bn
+
+function num2bn(x) {
+ var e = db.exponent(x)
+ if(e < 52) {
+ return new BN(x)
+ } else {
+ return (new BN(x * Math.pow(2, 52-e))).shln(e-52)
+ }
+}
+
+},{"bn.js":259,"double-bits":270}],256:[function(require,module,exports){
+'use strict'
+
+var num2bn = require('./num-to-bn')
+var sign = require('./bn-sign')
+
+module.exports = rationalize
+
+function rationalize(numer, denom) {
+ var snumer = sign(numer)
+ var sdenom = sign(denom)
+ if(snumer === 0) {
+ return [num2bn(0), num2bn(1)]
+ }
+ if(sdenom === 0) {
+ return [num2bn(0), num2bn(0)]
+ }
+ if(sdenom < 0) {
+ numer = numer.neg()
+ denom = denom.neg()
+ }
+ var d = numer.gcd(denom)
+ if(d.cmpn(1)) {
+ return [ numer.div(d), denom.div(d) ]
+ }
+ return [ numer, denom ]
+}
+
+},{"./bn-sign":251,"./num-to-bn":255}],257:[function(require,module,exports){
+'use strict'
+
+var BN = require('bn.js')
+
+module.exports = str2BN
+
+function str2BN(x) {
+ return new BN(x)
+}
+
+},{"bn.js":259}],258:[function(require,module,exports){
+'use strict'
+
+var rationalize = require('./lib/rationalize')
+
+module.exports = mul
+
+function mul(a, b) {
+ return rationalize(a[0].mul(b[0]), a[1].mul(b[1]))
+}
+
+},{"./lib/rationalize":256}],259:[function(require,module,exports){
+(function (module, exports) {
+
+'use strict';
+
+// Utils
+
+function assert(val, msg) {
+ if (!val)
+ throw new Error(msg || 'Assertion failed');
+}
+
+// Could use `inherits` module, but don't want to move from single file
+// architecture yet.
+function inherits(ctor, superCtor) {
+ ctor.super_ = superCtor;
+ var TempCtor = function () {};
+ TempCtor.prototype = superCtor.prototype;
+ ctor.prototype = new TempCtor();
+ ctor.prototype.constructor = ctor;
+}
+
+// BN
+
+function BN(number, base, endian) {
+ // May be `new BN(bn)` ?
+ if (number !== null &&
+ typeof number === 'object' &&
+ Array.isArray(number.words)) {
+ return number;
+ }
+
+ this.sign = false;
+ this.words = null;
+ this.length = 0;
+
+ // Reduction context
+ this.red = null;
+
+ if (base === 'le' || base === 'be') {
+ endian = base;
+ base = 10;
+ }
+
+ if (number !== null)
+ this._init(number || 0, base || 10, endian || 'be');
+}
+if (typeof module === 'object')
+ module.exports = BN;
+else
+ exports.BN = BN;
+
+BN.BN = BN;
+BN.wordSize = 26;
+
+BN.prototype._init = function init(number, base, endian) {
+ if (typeof number === 'number') {
+ return this._initNumber(number, base, endian);
+ } else if (typeof number === 'object') {
+ return this._initArray(number, base, endian);
+ }
+ if (base === 'hex')
+ base = 16;
+ assert(base === (base | 0) && base >= 2 && base <= 36);
+
+ number = number.toString().replace(/\s+/g, '');
+ var start = 0;
+ if (number[0] === '-')
+ start++;
+
+ if (base === 16)
+ this._parseHex(number, start);
+ else
+ this._parseBase(number, base, start);
+
+ if (number[0] === '-')
+ this.sign = true;
+
+ this.strip();
+
+ if (endian !== 'le')
+ return;
+
+ this._initArray(this.toArray(), base, endian);
+};
+
+BN.prototype._initNumber = function _initNumber(number, base, endian) {
+ if (number < 0) {
+ this.sign = true;
+ number = -number;
+ }
+ if (number < 0x4000000) {
+ this.words = [ number & 0x3ffffff ];
+ this.length = 1;
+ } else if (number < 0x10000000000000) {
+ this.words = [
+ number & 0x3ffffff,
+ (number / 0x4000000) & 0x3ffffff
+ ];
+ this.length = 2;
+ } else {
+ assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
+ this.words = [
+ number & 0x3ffffff,
+ (number / 0x4000000) & 0x3ffffff,
+ 1
+ ];
+ this.length = 3;
+ }
+
+ if (endian !== 'le')
+ return;
+
+ // Reverse the bytes
+ this._initArray(this.toArray(), base, endian);
+};
+
+BN.prototype._initArray = function _initArray(number, base, endian) {
+ // Perhaps a Uint8Array
+ assert(typeof number.length === 'number');
+ if (number.length <= 0) {
+ this.words = [ 0 ];
+ this.length = 1;
+ return this;
+ }
+
+ this.length = Math.ceil(number.length / 3);
+ this.words = new Array(this.length);
+ for (var i = 0; i < this.length; i++)
+ this.words[i] = 0;
+
+ var off = 0;
+ if (endian === 'be') {
+ for (var i = number.length - 1, j = 0; i >= 0; i -= 3) {
+ var w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
+ this.words[j] |= (w << off) & 0x3ffffff;
+ this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
+ off += 24;
+ if (off >= 26) {
+ off -= 26;
+ j++;
+ }
+ }
+ } else if (endian === 'le') {
+ for (var i = 0, j = 0; i < number.length; i += 3) {
+ var w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
+ this.words[j] |= (w << off) & 0x3ffffff;
+ this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
+ off += 24;
+ if (off >= 26) {
+ off -= 26;
+ j++;
+ }
+ }
+ }
+ return this.strip();
+};
+
+function parseHex(str, start, end) {
+ var r = 0;
+ var len = Math.min(str.length, end);
+ for (var i = start; i < len; i++) {
+ var c = str.charCodeAt(i) - 48;
+
+ r <<= 4;
+
+ // 'a' - 'f'
+ if (c >= 49 && c <= 54)
+ r |= c - 49 + 0xa;
+
+ // 'A' - 'F'
+ else if (c >= 17 && c <= 22)
+ r |= c - 17 + 0xa;
+
+ // '0' - '9'
+ else
+ r |= c & 0xf;
+ }
+ return r;
+}
+
+BN.prototype._parseHex = function _parseHex(number, start) {
+ // Create possibly bigger array to ensure that it fits the number
+ this.length = Math.ceil((number.length - start) / 6);
+ this.words = new Array(this.length);
+ for (var i = 0; i < this.length; i++)
+ this.words[i] = 0;
+
+ // Scan 24-bit chunks and add them to the number
+ var off = 0;
+ for (var i = number.length - 6, j = 0; i >= start; i -= 6) {
+ var w = parseHex(number, i, i + 6);
+ this.words[j] |= (w << off) & 0x3ffffff;
+ this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
+ off += 24;
+ if (off >= 26) {
+ off -= 26;
+ j++;
+ }
+ }
+ if (i + 6 !== start) {
+ var w = parseHex(number, start, i + 6);
+ this.words[j] |= (w << off) & 0x3ffffff;
+ this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
+ }
+ this.strip();
+};
+
+function parseBase(str, start, end, mul) {
+ var r = 0;
+ var len = Math.min(str.length, end);
+ for (var i = start; i < len; i++) {
+ var c = str.charCodeAt(i) - 48;
+
+ r *= mul;
+
+ // 'a'
+ if (c >= 49)
+ r += c - 49 + 0xa;
+
+ // 'A'
+ else if (c >= 17)
+ r += c - 17 + 0xa;
+
+ // '0' - '9'
+ else
+ r += c;
+ }
+ return r;
+}
+
+BN.prototype._parseBase = function _parseBase(number, base, start) {
+ // Initialize as zero
+ this.words = [ 0 ];
+ this.length = 1;
+
+ // Find length of limb in base
+ for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base)
+ limbLen++;
+ limbLen--;
+ limbPow = (limbPow / base) | 0;
+
+ var total = number.length - start;
+ var mod = total % limbLen;
+ var end = Math.min(total, total - mod) + start;
+
+ var word = 0;
+ for (var i = start; i < end; i += limbLen) {
+ word = parseBase(number, i, i + limbLen, base);
+
+ this.imuln(limbPow);
+ if (this.words[0] + word < 0x4000000)
+ this.words[0] += word;
+ else
+ this._iaddn(word);
+ }
+
+ if (mod !== 0) {
+ var pow = 1;
+ var word = parseBase(number, i, number.length, base);
+
+ for (var i = 0; i < mod; i++)
+ pow *= base;
+ this.imuln(pow);
+ if (this.words[0] + word < 0x4000000)
+ this.words[0] += word;
+ else
+ this._iaddn(word);
+ }
+};
+
+BN.prototype.copy = function copy(dest) {
+ dest.words = new Array(this.length);
+ for (var i = 0; i < this.length; i++)
+ dest.words[i] = this.words[i];
+ dest.length = this.length;
+ dest.sign = this.sign;
+ dest.red = this.red;
+};
+
+BN.prototype.clone = function clone() {
+ var r = new BN(null);
+ this.copy(r);
+ return r;
+};
+
+// Remove leading `0` from `this`
+BN.prototype.strip = function strip() {
+ while (this.length > 1 && this.words[this.length - 1] === 0)
+ this.length--;
+ return this._normSign();
+};
+
+BN.prototype._normSign = function _normSign() {
+ // -0 = 0
+ if (this.length === 1 && this.words[0] === 0)
+ this.sign = false;
+ return this;
+};
+
+BN.prototype.inspect = function inspect() {
+ return (this.red ? '';
+};
+
+/*
+
+var zeros = [];
+var groupSizes = [];
+var groupBases = [];
+
+var s = '';
+var i = -1;
+while (++i < BN.wordSize) {
+ zeros[i] = s;
+ s += '0';
+}
+groupSizes[0] = 0;
+groupSizes[1] = 0;
+groupBases[0] = 0;
+groupBases[1] = 0;
+var base = 2 - 1;
+while (++base < 36 + 1) {
+ var groupSize = 0;
+ var groupBase = 1;
+ while (groupBase < (1 << BN.wordSize) / base) {
+ groupBase *= base;
+ groupSize += 1;
+ }
+ groupSizes[base] = groupSize;
+ groupBases[base] = groupBase;
+}
+
+*/
+
+var zeros = [
+ '',
+ '0',
+ '00',
+ '000',
+ '0000',
+ '00000',
+ '000000',
+ '0000000',
+ '00000000',
+ '000000000',
+ '0000000000',
+ '00000000000',
+ '000000000000',
+ '0000000000000',
+ '00000000000000',
+ '000000000000000',
+ '0000000000000000',
+ '00000000000000000',
+ '000000000000000000',
+ '0000000000000000000',
+ '00000000000000000000',
+ '000000000000000000000',
+ '0000000000000000000000',
+ '00000000000000000000000',
+ '000000000000000000000000',
+ '0000000000000000000000000'
+];
+
+var groupSizes = [
+ 0, 0,
+ 25, 16, 12, 11, 10, 9, 8,
+ 8, 7, 7, 7, 7, 6, 6,
+ 6, 6, 6, 6, 6, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5
+];
+
+var groupBases = [
+ 0, 0,
+ 33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
+ 43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
+ 16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
+ 6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
+ 24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
+];
+
+BN.prototype.toString = function toString(base, padding) {
+ base = base || 10;
+ if (base === 16 || base === 'hex') {
+ var out = '';
+ var off = 0;
+ var padding = padding | 0 || 1;
+ var carry = 0;
+ for (var i = 0; i < this.length; i++) {
+ var w = this.words[i];
+ var word = (((w << off) | carry) & 0xffffff).toString(16);
+ carry = (w >>> (24 - off)) & 0xffffff;
+ if (carry !== 0 || i !== this.length - 1)
+ out = zeros[6 - word.length] + word + out;
+ else
+ out = word + out;
+ off += 2;
+ if (off >= 26) {
+ off -= 26;
+ i--;
+ }
+ }
+ if (carry !== 0)
+ out = carry.toString(16) + out;
+ while (out.length % padding !== 0)
+ out = '0' + out;
+ if (this.sign)
+ out = '-' + out;
+ return out;
+ } else if (base === (base | 0) && base >= 2 && base <= 36) {
+ // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
+ var groupSize = groupSizes[base];
+ // var groupBase = Math.pow(base, groupSize);
+ var groupBase = groupBases[base];
+ var out = '';
+ var c = this.clone();
+ c.sign = false;
+ while (c.cmpn(0) !== 0) {
+ var r = c.modn(groupBase).toString(base);
+ c = c.idivn(groupBase);
+
+ if (c.cmpn(0) !== 0)
+ out = zeros[groupSize - r.length] + r + out;
+ else
+ out = r + out;
+ }
+ if (this.cmpn(0) === 0)
+ out = '0' + out;
+ if (this.sign)
+ out = '-' + out;
+ return out;
+ } else {
+ assert(false, 'Base should be between 2 and 36');
+ }
+};
+
+BN.prototype.toJSON = function toJSON() {
+ return this.toString(16);
+};
+
+BN.prototype.toArray = function toArray(endian) {
+ this.strip();
+ var res = new Array(this.byteLength());
+ res[0] = 0;
+
+ var q = this.clone();
+ if (endian !== 'le') {
+ // Assume big-endian
+ for (var i = 0; q.cmpn(0) !== 0; i++) {
+ var b = q.andln(0xff);
+ q.ishrn(8);
+
+ res[res.length - i - 1] = b;
+ }
+ } else {
+ // Assume little-endian
+ for (var i = 0; q.cmpn(0) !== 0; i++) {
+ var b = q.andln(0xff);
+ q.ishrn(8);
+
+ res[i] = b;
+ }
+ }
+
+ return res;
+};
+
+if (Math.clz32) {
+ BN.prototype._countBits = function _countBits(w) {
+ return 32 - Math.clz32(w);
+ };
+} else {
+ BN.prototype._countBits = function _countBits(w) {
+ var t = w;
+ var r = 0;
+ if (t >= 0x1000) {
+ r += 13;
+ t >>>= 13;
+ }
+ if (t >= 0x40) {
+ r += 7;
+ t >>>= 7;
+ }
+ if (t >= 0x8) {
+ r += 4;
+ t >>>= 4;
+ }
+ if (t >= 0x02) {
+ r += 2;
+ t >>>= 2;
+ }
+ return r + t;
+ };
+}
+
+BN.prototype._zeroBits = function _zeroBits(w) {
+ // Short-cut
+ if (w === 0)
+ return 26;
+
+ var t = w;
+ var r = 0;
+ if ((t & 0x1fff) === 0) {
+ r += 13;
+ t >>>= 13;
+ }
+ if ((t & 0x7f) === 0) {
+ r += 7;
+ t >>>= 7;
+ }
+ if ((t & 0xf) === 0) {
+ r += 4;
+ t >>>= 4;
+ }
+ if ((t & 0x3) === 0) {
+ r += 2;
+ t >>>= 2;
+ }
+ if ((t & 0x1) === 0)
+ r++;
+ return r;
+};
+
+// Return number of used bits in a BN
+BN.prototype.bitLength = function bitLength() {
+ var hi = 0;
+ var w = this.words[this.length - 1];
+ var hi = this._countBits(w);
+ return (this.length - 1) * 26 + hi;
+};
+
+// Number of trailing zero bits
+BN.prototype.zeroBits = function zeroBits() {
+ if (this.cmpn(0) === 0)
+ return 0;
+
+ var r = 0;
+ for (var i = 0; i < this.length; i++) {
+ var b = this._zeroBits(this.words[i]);
+ r += b;
+ if (b !== 26)
+ break;
+ }
+ return r;
+};
+
+BN.prototype.byteLength = function byteLength() {
+ return Math.ceil(this.bitLength() / 8);
+};
+
+// Return negative clone of `this`
+BN.prototype.neg = function neg() {
+ if (this.cmpn(0) === 0)
+ return this.clone();
+
+ var r = this.clone();
+ r.sign = !this.sign;
+ return r;
+};
+
+
+// Or `num` with `this` in-place
+BN.prototype.ior = function ior(num) {
+ this.sign = this.sign || num.sign;
+
+ while (this.length < num.length)
+ this.words[this.length++] = 0;
+
+ for (var i = 0; i < num.length; i++)
+ this.words[i] = this.words[i] | num.words[i];
+
+ return this.strip();
+};
+
+
+// Or `num` with `this`
+BN.prototype.or = function or(num) {
+ if (this.length > num.length)
+ return this.clone().ior(num);
+ else
+ return num.clone().ior(this);
+};
+
+
+// And `num` with `this` in-place
+BN.prototype.iand = function iand(num) {
+ this.sign = this.sign && num.sign;
+
+ // b = min-length(num, this)
+ var b;
+ if (this.length > num.length)
+ b = num;
+ else
+ b = this;
+
+ for (var i = 0; i < b.length; i++)
+ this.words[i] = this.words[i] & num.words[i];
+
+ this.length = b.length;
+
+ return this.strip();
+};
+
+
+// And `num` with `this`
+BN.prototype.and = function and(num) {
+ if (this.length > num.length)
+ return this.clone().iand(num);
+ else
+ return num.clone().iand(this);
+};
+
+
+// Xor `num` with `this` in-place
+BN.prototype.ixor = function ixor(num) {
+ this.sign = this.sign || num.sign;
+
+ // a.length > b.length
+ var a;
+ var b;
+ if (this.length > num.length) {
+ a = this;
+ b = num;
+ } else {
+ a = num;
+ b = this;
+ }
+
+ for (var i = 0; i < b.length; i++)
+ this.words[i] = a.words[i] ^ b.words[i];
+
+ if (this !== a)
+ for (; i < a.length; i++)
+ this.words[i] = a.words[i];
+
+ this.length = a.length;
+
+ return this.strip();
+};
+
+
+// Xor `num` with `this`
+BN.prototype.xor = function xor(num) {
+ if (this.length > num.length)
+ return this.clone().ixor(num);
+ else
+ return num.clone().ixor(this);
+};
+
+
+// Set `bit` of `this`
+BN.prototype.setn = function setn(bit, val) {
+ assert(typeof bit === 'number' && bit >= 0);
+
+ var off = (bit / 26) | 0;
+ var wbit = bit % 26;
+
+ while (this.length <= off)
+ this.words[this.length++] = 0;
+
+ if (val)
+ this.words[off] = this.words[off] | (1 << wbit);
+ else
+ this.words[off] = this.words[off] & ~(1 << wbit);
+
+ return this.strip();
+};
+
+
+// Add `num` to `this` in-place
+BN.prototype.iadd = function iadd(num) {
+ // negative + positive
+ if (this.sign && !num.sign) {
+ this.sign = false;
+ var r = this.isub(num);
+ this.sign = !this.sign;
+ return this._normSign();
+
+ // positive + negative
+ } else if (!this.sign && num.sign) {
+ num.sign = false;
+ var r = this.isub(num);
+ num.sign = true;
+ return r._normSign();
+ }
+
+ // a.length > b.length
+ var a;
+ var b;
+ if (this.length > num.length) {
+ a = this;
+ b = num;
+ } else {
+ a = num;
+ b = this;
+ }
+
+ var carry = 0;
+ for (var i = 0; i < b.length; i++) {
+ var r = a.words[i] + b.words[i] + carry;
+ this.words[i] = r & 0x3ffffff;
+ carry = r >>> 26;
+ }
+ for (; carry !== 0 && i < a.length; i++) {
+ var r = a.words[i] + carry;
+ this.words[i] = r & 0x3ffffff;
+ carry = r >>> 26;
+ }
+
+ this.length = a.length;
+ if (carry !== 0) {
+ this.words[this.length] = carry;
+ this.length++;
+ // Copy the rest of the words
+ } else if (a !== this) {
+ for (; i < a.length; i++)
+ this.words[i] = a.words[i];
+ }
+
+ return this;
+};
+
+// Add `num` to `this`
+BN.prototype.add = function add(num) {
+ if (num.sign && !this.sign) {
+ num.sign = false;
+ var res = this.sub(num);
+ num.sign = true;
+ return res;
+ } else if (!num.sign && this.sign) {
+ this.sign = false;
+ var res = num.sub(this);
+ this.sign = true;
+ return res;
+ }
+
+ if (this.length > num.length)
+ return this.clone().iadd(num);
+ else
+ return num.clone().iadd(this);
+};
+
+// Subtract `num` from `this` in-place
+BN.prototype.isub = function isub(num) {
+ // this - (-num) = this + num
+ if (num.sign) {
+ num.sign = false;
+ var r = this.iadd(num);
+ num.sign = true;
+ return r._normSign();
+
+ // -this - num = -(this + num)
+ } else if (this.sign) {
+ this.sign = false;
+ this.iadd(num);
+ this.sign = true;
+ return this._normSign();
+ }
+
+ // At this point both numbers are positive
+ var cmp = this.cmp(num);
+
+ // Optimization - zeroify
+ if (cmp === 0) {
+ this.sign = false;
+ this.length = 1;
+ this.words[0] = 0;
+ return this;
+ }
+
+ // a > b
+ var a;
+ var b;
+ if (cmp > 0) {
+ a = this;
+ b = num;
+ } else {
+ a = num;
+ b = this;
+ }
+
+ var carry = 0;
+ for (var i = 0; i < b.length; i++) {
+ var r = a.words[i] - b.words[i] + carry;
+ carry = r >> 26;
+ this.words[i] = r & 0x3ffffff;
+ }
+ for (; carry !== 0 && i < a.length; i++) {
+ var r = a.words[i] + carry;
+ carry = r >> 26;
+ this.words[i] = r & 0x3ffffff;
+ }
+
+ // Copy rest of the words
+ if (carry === 0 && i < a.length && a !== this)
+ for (; i < a.length; i++)
+ this.words[i] = a.words[i];
+ this.length = Math.max(this.length, i);
+
+ if (a !== this)
+ this.sign = true;
+
+ return this.strip();
+};
+
+// Subtract `num` from `this`
+BN.prototype.sub = function sub(num) {
+ return this.clone().isub(num);
+};
+
+/*
+// NOTE: This could be potentionally used to generate loop-less multiplications
+function _genCombMulTo(alen, blen) {
+ var len = alen + blen - 1;
+ var src = [
+ 'var a = this.words, b = num.words, o = out.words, c = 0, w, ' +
+ 'mask = 0x3ffffff, shift = 0x4000000;',
+ 'out.length = ' + len + ';'
+ ];
+ for (var k = 0; k < len; k++) {
+ var minJ = Math.max(0, k - alen + 1);
+ var maxJ = Math.min(k, blen - 1);
+
+ for (var j = minJ; j <= maxJ; j++) {
+ var i = k - j;
+ var mul = 'a[' + i + '] * b[' + j + ']';
+
+ if (j === minJ) {
+ src.push('w = ' + mul + ' + c;');
+ src.push('c = (w / shift) | 0;');
+ } else {
+ src.push('w += ' + mul + ';');
+ src.push('c += (w / shift) | 0;');
+ }
+ src.push('w &= mask;');
+ }
+ src.push('o[' + k + '] = w;');
+ }
+ src.push('if (c !== 0) {',
+ ' o[' + k + '] = c;',
+ ' out.length++;',
+ '}',
+ 'return out;');
+
+ return src.join('\n');
+}
+*/
+
+BN.prototype._smallMulTo = function _smallMulTo(num, out) {
+ out.sign = num.sign !== this.sign;
+ out.length = this.length + num.length;
+
+ var carry = 0;
+ for (var k = 0; k < out.length - 1; k++) {
+ // Sum all words with the same `i + j = k` and accumulate `ncarry`,
+ // note that ncarry could be >= 0x3ffffff
+ var ncarry = carry >>> 26;
+ var rword = carry & 0x3ffffff;
+ var maxJ = Math.min(k, num.length - 1);
+ for (var j = Math.max(0, k - this.length + 1); j <= maxJ; j++) {
+ var i = k - j;
+ var a = this.words[i] | 0;
+ var b = num.words[j] | 0;
+ var r = a * b;
+
+ var lo = r & 0x3ffffff;
+ ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
+ lo = (lo + rword) | 0;
+ rword = lo & 0x3ffffff;
+ ncarry = (ncarry + (lo >>> 26)) | 0;
+ }
+ out.words[k] = rword;
+ carry = ncarry;
+ }
+ if (carry !== 0) {
+ out.words[k] = carry;
+ } else {
+ out.length--;
+ }
+
+ return out.strip();
+};
+
+BN.prototype._bigMulTo = function _bigMulTo(num, out) {
+ out.sign = num.sign !== this.sign;
+ out.length = this.length + num.length;
+
+ var carry = 0;
+ var hncarry = 0;
+ for (var k = 0; k < out.length - 1; k++) {
+ // Sum all words with the same `i + j = k` and accumulate `ncarry`,
+ // note that ncarry could be >= 0x3ffffff
+ var ncarry = hncarry;
+ hncarry = 0;
+ var rword = carry & 0x3ffffff;
+ var maxJ = Math.min(k, num.length - 1);
+ for (var j = Math.max(0, k - this.length + 1); j <= maxJ; j++) {
+ var i = k - j;
+ var a = this.words[i] | 0;
+ var b = num.words[j] | 0;
+ var r = a * b;
+
+ var lo = r & 0x3ffffff;
+ ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
+ lo = (lo + rword) | 0;
+ rword = lo & 0x3ffffff;
+ ncarry = (ncarry + (lo >>> 26)) | 0;
+
+ hncarry += ncarry >>> 26;
+ ncarry &= 0x3ffffff;
+ }
+ out.words[k] = rword;
+ carry = ncarry;
+ ncarry = hncarry;
+ }
+ if (carry !== 0) {
+ out.words[k] = carry;
+ } else {
+ out.length--;
+ }
+
+ return out.strip();
+};
+
+BN.prototype.mulTo = function mulTo(num, out) {
+ var res;
+ if (this.length + num.length < 63)
+ res = this._smallMulTo(num, out);
+ else
+ res = this._bigMulTo(num, out);
+ return res;
+};
+
+// Multiply `this` by `num`
+BN.prototype.mul = function mul(num) {
+ var out = new BN(null);
+ out.words = new Array(this.length + num.length);
+ return this.mulTo(num, out);
+};
+
+// In-place Multiplication
+BN.prototype.imul = function imul(num) {
+ if (this.cmpn(0) === 0 || num.cmpn(0) === 0) {
+ this.words[0] = 0;
+ this.length = 1;
+ return this;
+ }
+
+ var tlen = this.length;
+ var nlen = num.length;
+
+ this.sign = num.sign !== this.sign;
+ this.length = this.length + num.length;
+ this.words[this.length - 1] = 0;
+
+ for (var k = this.length - 2; k >= 0; k--) {
+ // Sum all words with the same `i + j = k` and accumulate `carry`,
+ // note that carry could be >= 0x3ffffff
+ var carry = 0;
+ var rword = 0;
+ var maxJ = Math.min(k, nlen - 1);
+ for (var j = Math.max(0, k - tlen + 1); j <= maxJ; j++) {
+ var i = k - j;
+ var a = this.words[i];
+ var b = num.words[j];
+ var r = a * b;
+
+ var lo = r & 0x3ffffff;
+ carry += (r / 0x4000000) | 0;
+ lo += rword;
+ rword = lo & 0x3ffffff;
+ carry += lo >>> 26;
+ }
+ this.words[k] = rword;
+ this.words[k + 1] += carry;
+ carry = 0;
+ }
+
+ // Propagate overflows
+ var carry = 0;
+ for (var i = 1; i < this.length; i++) {
+ var w = this.words[i] + carry;
+ this.words[i] = w & 0x3ffffff;
+ carry = w >>> 26;
+ }
+
+ return this.strip();
+};
+
+BN.prototype.imuln = function imuln(num) {
+ assert(typeof num === 'number');
+
+ // Carry
+ var carry = 0;
+ for (var i = 0; i < this.length; i++) {
+ var w = this.words[i] * num;
+ var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
+ carry >>= 26;
+ carry += (w / 0x4000000) | 0;
+ // NOTE: lo is 27bit maximum
+ carry += lo >>> 26;
+ this.words[i] = lo & 0x3ffffff;
+ }
+
+ if (carry !== 0) {
+ this.words[i] = carry;
+ this.length++;
+ }
+
+ return this;
+};
+
+BN.prototype.muln = function muln(num) {
+ return this.clone().imuln(num);
+};
+
+// `this` * `this`
+BN.prototype.sqr = function sqr() {
+ return this.mul(this);
+};
+
+// `this` * `this` in-place
+BN.prototype.isqr = function isqr() {
+ return this.mul(this);
+};
+
+// Shift-left in-place
+BN.prototype.ishln = function ishln(bits) {
+ assert(typeof bits === 'number' && bits >= 0);
+ var r = bits % 26;
+ var s = (bits - r) / 26;
+ var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
+
+ if (r !== 0) {
+ var carry = 0;
+ for (var i = 0; i < this.length; i++) {
+ var newCarry = this.words[i] & carryMask;
+ var c = (this.words[i] - newCarry) << r;
+ this.words[i] = c | carry;
+ carry = newCarry >>> (26 - r);
+ }
+ if (carry) {
+ this.words[i] = carry;
+ this.length++;
+ }
+ }
+
+ if (s !== 0) {
+ for (var i = this.length - 1; i >= 0; i--)
+ this.words[i + s] = this.words[i];
+ for (var i = 0; i < s; i++)
+ this.words[i] = 0;
+ this.length += s;
+ }
+
+ return this.strip();
+};
+
+// Shift-right in-place
+// NOTE: `hint` is a lowest bit before trailing zeroes
+// NOTE: if `extended` is present - it will be filled with destroyed bits
+BN.prototype.ishrn = function ishrn(bits, hint, extended) {
+ assert(typeof bits === 'number' && bits >= 0);
+ var h;
+ if (hint)
+ h = (hint - (hint % 26)) / 26;
+ else
+ h = 0;
+
+ var r = bits % 26;
+ var s = Math.min((bits - r) / 26, this.length);
+ var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
+ var maskedWords = extended;
+
+ h -= s;
+ h = Math.max(0, h);
+
+ // Extended mode, copy masked part
+ if (maskedWords) {
+ for (var i = 0; i < s; i++)
+ maskedWords.words[i] = this.words[i];
+ maskedWords.length = s;
+ }
+
+ if (s === 0) {
+ // No-op, we should not move anything at all
+ } else if (this.length > s) {
+ this.length -= s;
+ for (var i = 0; i < this.length; i++)
+ this.words[i] = this.words[i + s];
+ } else {
+ this.words[0] = 0;
+ this.length = 1;
+ }
+
+ var carry = 0;
+ for (var i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
+ var word = this.words[i];
+ this.words[i] = (carry << (26 - r)) | (word >>> r);
+ carry = word & mask;
+ }
+
+ // Push carried bits as a mask
+ if (maskedWords && carry !== 0)
+ maskedWords.words[maskedWords.length++] = carry;
+
+ if (this.length === 0) {
+ this.words[0] = 0;
+ this.length = 1;
+ }
+
+ this.strip();
+
+ return this;
+};
+
+// Shift-left
+BN.prototype.shln = function shln(bits) {
+ return this.clone().ishln(bits);
+};
+
+// Shift-right
+BN.prototype.shrn = function shrn(bits) {
+ return this.clone().ishrn(bits);
+};
+
+// Test if n bit is set
+BN.prototype.testn = function testn(bit) {
+ assert(typeof bit === 'number' && bit >= 0);
+ var r = bit % 26;
+ var s = (bit - r) / 26;
+ var q = 1 << r;
+
+ // Fast case: bit is much higher than all existing words
+ if (this.length <= s) {
+ return false;
+ }
+
+ // Check bit and return
+ var w = this.words[s];
+
+ return !!(w & q);
+};
+
+// Return only lowers bits of number (in-place)
+BN.prototype.imaskn = function imaskn(bits) {
+ assert(typeof bits === 'number' && bits >= 0);
+ var r = bits % 26;
+ var s = (bits - r) / 26;
+
+ assert(!this.sign, 'imaskn works only with positive numbers');
+
+ if (r !== 0)
+ s++;
+ this.length = Math.min(s, this.length);
+
+ if (r !== 0) {
+ var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
+ this.words[this.length - 1] &= mask;
+ }
+
+ return this.strip();
+};
+
+// Return only lowers bits of number
+BN.prototype.maskn = function maskn(bits) {
+ return this.clone().imaskn(bits);
+};
+
+// Add plain number `num` to `this`
+BN.prototype.iaddn = function iaddn(num) {
+ assert(typeof num === 'number');
+ if (num < 0)
+ return this.isubn(-num);
+
+ // Possible sign change
+ if (this.sign) {
+ if (this.length === 1 && this.words[0] < num) {
+ this.words[0] = num - this.words[0];
+ this.sign = false;
+ return this;
+ }
+
+ this.sign = false;
+ this.isubn(num);
+ this.sign = true;
+ return this;
+ }
+
+ // Add without checks
+ return this._iaddn(num);
+};
+
+BN.prototype._iaddn = function _iaddn(num) {
+ this.words[0] += num;
+
+ // Carry
+ for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
+ this.words[i] -= 0x4000000;
+ if (i === this.length - 1)
+ this.words[i + 1] = 1;
+ else
+ this.words[i + 1]++;
+ }
+ this.length = Math.max(this.length, i + 1);
+
+ return this;
+};
+
+// Subtract plain number `num` from `this`
+BN.prototype.isubn = function isubn(num) {
+ assert(typeof num === 'number');
+ if (num < 0)
+ return this.iaddn(-num);
+
+ if (this.sign) {
+ this.sign = false;
+ this.iaddn(num);
+ this.sign = true;
+ return this;
+ }
+
+ this.words[0] -= num;
+
+ // Carry
+ for (var i = 0; i < this.length && this.words[i] < 0; i++) {
+ this.words[i] += 0x4000000;
+ this.words[i + 1] -= 1;
+ }
+
+ return this.strip();
+};
+
+BN.prototype.addn = function addn(num) {
+ return this.clone().iaddn(num);
+};
+
+BN.prototype.subn = function subn(num) {
+ return this.clone().isubn(num);
+};
+
+BN.prototype.iabs = function iabs() {
+ this.sign = false;
+
+ return this;
+};
+
+BN.prototype.abs = function abs() {
+ return this.clone().iabs();
+};
+
+BN.prototype._ishlnsubmul = function _ishlnsubmul(num, mul, shift) {
+ // Bigger storage is needed
+ var len = num.length + shift;
+ var i;
+ if (this.words.length < len) {
+ var t = new Array(len);
+ for (var i = 0; i < this.length; i++)
+ t[i] = this.words[i];
+ this.words = t;
+ } else {
+ i = this.length;
+ }
+
+ // Zeroify rest
+ this.length = Math.max(this.length, len);
+ for (; i < this.length; i++)
+ this.words[i] = 0;
+
+ var carry = 0;
+ for (var i = 0; i < num.length; i++) {
+ var w = this.words[i + shift] + carry;
+ var right = num.words[i] * mul;
+ w -= right & 0x3ffffff;
+ carry = (w >> 26) - ((right / 0x4000000) | 0);
+ this.words[i + shift] = w & 0x3ffffff;
+ }
+ for (; i < this.length - shift; i++) {
+ var w = this.words[i + shift] + carry;
+ carry = w >> 26;
+ this.words[i + shift] = w & 0x3ffffff;
+ }
+
+ if (carry === 0)
+ return this.strip();
+
+ // Subtraction overflow
+ assert(carry === -1);
+ carry = 0;
+ for (var i = 0; i < this.length; i++) {
+ var w = -this.words[i] + carry;
+ carry = w >> 26;
+ this.words[i] = w & 0x3ffffff;
+ }
+ this.sign = true;
+
+ return this.strip();
+};
+
+BN.prototype._wordDiv = function _wordDiv(num, mode) {
+ var shift = this.length - num.length;
+
+ var a = this.clone();
+ var b = num;
+
+ // Normalize
+ var bhi = b.words[b.length - 1];
+ var bhiBits = this._countBits(bhi);
+ shift = 26 - bhiBits;
+ if (shift !== 0) {
+ b = b.shln(shift);
+ a.ishln(shift);
+ bhi = b.words[b.length - 1];
+ }
+
+ // Initialize quotient
+ var m = a.length - b.length;
+ var q;
+
+ if (mode !== 'mod') {
+ q = new BN(null);
+ q.length = m + 1;
+ q.words = new Array(q.length);
+ for (var i = 0; i < q.length; i++)
+ q.words[i] = 0;
+ }
+
+ var diff = a.clone()._ishlnsubmul(b, 1, m);
+ if (!diff.sign) {
+ a = diff;
+ if (q)
+ q.words[m] = 1;
+ }
+
+ for (var j = m - 1; j >= 0; j--) {
+ var qj = a.words[b.length + j] * 0x4000000 + a.words[b.length + j - 1];
+
+ // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
+ // (0x7ffffff)
+ qj = Math.min((qj / bhi) | 0, 0x3ffffff);
+
+ a._ishlnsubmul(b, qj, j);
+ while (a.sign) {
+ qj--;
+ a.sign = false;
+ a._ishlnsubmul(b, 1, j);
+ if (a.cmpn(0) !== 0)
+ a.sign = !a.sign;
+ }
+ if (q)
+ q.words[j] = qj;
+ }
+ if (q)
+ q.strip();
+ a.strip();
+
+ // Denormalize
+ if (mode !== 'div' && shift !== 0)
+ a.ishrn(shift);
+ return { div: q ? q : null, mod: a };
+};
+
+BN.prototype.divmod = function divmod(num, mode) {
+ assert(num.cmpn(0) !== 0);
+
+ if (this.sign && !num.sign) {
+ var res = this.neg().divmod(num, mode);
+ var div;
+ var mod;
+ if (mode !== 'mod')
+ div = res.div.neg();
+ if (mode !== 'div')
+ mod = res.mod.cmpn(0) === 0 ? res.mod : num.sub(res.mod);
+ return {
+ div: div,
+ mod: mod
+ };
+ } else if (!this.sign && num.sign) {
+ var res = this.divmod(num.neg(), mode);
+ var div;
+ if (mode !== 'mod')
+ div = res.div.neg();
+ return { div: div, mod: res.mod };
+ } else if (this.sign && num.sign) {
+ return this.neg().divmod(num.neg(), mode);
+ }
+
+ // Both numbers are positive at this point
+
+ // Strip both numbers to approximate shift value
+ if (num.length > this.length || this.cmp(num) < 0)
+ return { div: new BN(0), mod: this };
+
+ // Very short reduction
+ if (num.length === 1) {
+ if (mode === 'div')
+ return { div: this.divn(num.words[0]), mod: null };
+ else if (mode === 'mod')
+ return { div: null, mod: new BN(this.modn(num.words[0])) };
+ return {
+ div: this.divn(num.words[0]),
+ mod: new BN(this.modn(num.words[0]))
+ };
+ }
+
+ return this._wordDiv(num, mode);
+};
+
+// Find `this` / `num`
+BN.prototype.div = function div(num) {
+ return this.divmod(num, 'div').div;
+};
+
+// Find `this` % `num`
+BN.prototype.mod = function mod(num) {
+ return this.divmod(num, 'mod').mod;
+};
+
+// Find Round(`this` / `num`)
+BN.prototype.divRound = function divRound(num) {
+ var dm = this.divmod(num);
+
+ // Fast case - exact division
+ if (dm.mod.cmpn(0) === 0)
+ return dm.div;
+
+ var mod = dm.div.sign ? dm.mod.isub(num) : dm.mod;
+
+ var half = num.shrn(1);
+ var r2 = num.andln(1);
+ var cmp = mod.cmp(half);
+
+ // Round down
+ if (cmp < 0 || r2 === 1 && cmp === 0)
+ return dm.div;
+
+ // Round up
+ return dm.div.sign ? dm.div.isubn(1) : dm.div.iaddn(1);
+};
+
+BN.prototype.modn = function modn(num) {
+ assert(num <= 0x3ffffff);
+ var p = (1 << 26) % num;
+
+ var acc = 0;
+ for (var i = this.length - 1; i >= 0; i--)
+ acc = (p * acc + this.words[i]) % num;
+
+ return acc;
+};
+
+// In-place division by number
+BN.prototype.idivn = function idivn(num) {
+ assert(num <= 0x3ffffff);
+
+ var carry = 0;
+ for (var i = this.length - 1; i >= 0; i--) {
+ var w = this.words[i] + carry * 0x4000000;
+ this.words[i] = (w / num) | 0;
+ carry = w % num;
+ }
+
+ return this.strip();
+};
+
+BN.prototype.divn = function divn(num) {
+ return this.clone().idivn(num);
+};
+
+BN.prototype.egcd = function egcd(p) {
+ assert(!p.sign);
+ assert(p.cmpn(0) !== 0);
+
+ var x = this;
+ var y = p.clone();
+
+ if (x.sign)
+ x = x.mod(p);
+ else
+ x = x.clone();
+
+ // A * x + B * y = x
+ var A = new BN(1);
+ var B = new BN(0);
+
+ // C * x + D * y = y
+ var C = new BN(0);
+ var D = new BN(1);
+
+ var g = 0;
+
+ while (x.isEven() && y.isEven()) {
+ x.ishrn(1);
+ y.ishrn(1);
+ ++g;
+ }
+
+ var yp = y.clone();
+ var xp = x.clone();
+
+ while (x.cmpn(0) !== 0) {
+ while (x.isEven()) {
+ x.ishrn(1);
+ if (A.isEven() && B.isEven()) {
+ A.ishrn(1);
+ B.ishrn(1);
+ } else {
+ A.iadd(yp).ishrn(1);
+ B.isub(xp).ishrn(1);
+ }
+ }
+
+ while (y.isEven()) {
+ y.ishrn(1);
+ if (C.isEven() && D.isEven()) {
+ C.ishrn(1);
+ D.ishrn(1);
+ } else {
+ C.iadd(yp).ishrn(1);
+ D.isub(xp).ishrn(1);
+ }
+ }
+
+ if (x.cmp(y) >= 0) {
+ x.isub(y);
+ A.isub(C);
+ B.isub(D);
+ } else {
+ y.isub(x);
+ C.isub(A);
+ D.isub(B);
+ }
+ }
+
+ return {
+ a: C,
+ b: D,
+ gcd: y.ishln(g)
+ };
+};
+
+// This is reduced incarnation of the binary EEA
+// above, designated to invert members of the
+// _prime_ fields F(p) at a maximal speed
+BN.prototype._invmp = function _invmp(p) {
+ assert(!p.sign);
+ assert(p.cmpn(0) !== 0);
+
+ var a = this;
+ var b = p.clone();
+
+ if (a.sign)
+ a = a.mod(p);
+ else
+ a = a.clone();
+
+ var x1 = new BN(1);
+ var x2 = new BN(0);
+
+ var delta = b.clone();
+
+ while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
+ while (a.isEven()) {
+ a.ishrn(1);
+ if (x1.isEven())
+ x1.ishrn(1);
+ else
+ x1.iadd(delta).ishrn(1);
+ }
+ while (b.isEven()) {
+ b.ishrn(1);
+ if (x2.isEven())
+ x2.ishrn(1);
+ else
+ x2.iadd(delta).ishrn(1);
+ }
+ if (a.cmp(b) >= 0) {
+ a.isub(b);
+ x1.isub(x2);
+ } else {
+ b.isub(a);
+ x2.isub(x1);
+ }
+ }
+ if (a.cmpn(1) === 0)
+ return x1;
+ else
+ return x2;
+};
+
+BN.prototype.gcd = function gcd(num) {
+ if (this.cmpn(0) === 0)
+ return num.clone();
+ if (num.cmpn(0) === 0)
+ return this.clone();
+
+ var a = this.clone();
+ var b = num.clone();
+ a.sign = false;
+ b.sign = false;
+
+ // Remove common factor of two
+ for (var shift = 0; a.isEven() && b.isEven(); shift++) {
+ a.ishrn(1);
+ b.ishrn(1);
+ }
+
+ do {
+ while (a.isEven())
+ a.ishrn(1);
+ while (b.isEven())
+ b.ishrn(1);
+
+ var r = a.cmp(b);
+ if (r < 0) {
+ // Swap `a` and `b` to make `a` always bigger than `b`
+ var t = a;
+ a = b;
+ b = t;
+ } else if (r === 0 || b.cmpn(1) === 0) {
+ break;
+ }
+
+ a.isub(b);
+ } while (true);
+
+ return b.ishln(shift);
+};
+
+// Invert number in the field F(num)
+BN.prototype.invm = function invm(num) {
+ return this.egcd(num).a.mod(num);
+};
+
+BN.prototype.isEven = function isEven() {
+ return (this.words[0] & 1) === 0;
+};
+
+BN.prototype.isOdd = function isOdd() {
+ return (this.words[0] & 1) === 1;
+};
+
+// And first word and num
+BN.prototype.andln = function andln(num) {
+ return this.words[0] & num;
+};
+
+// Increment at the bit position in-line
+BN.prototype.bincn = function bincn(bit) {
+ assert(typeof bit === 'number');
+ var r = bit % 26;
+ var s = (bit - r) / 26;
+ var q = 1 << r;
+
+ // Fast case: bit is much higher than all existing words
+ if (this.length <= s) {
+ for (var i = this.length; i < s + 1; i++)
+ this.words[i] = 0;
+ this.words[s] |= q;
+ this.length = s + 1;
+ return this;
+ }
+
+ // Add bit and propagate, if needed
+ var carry = q;
+ for (var i = s; carry !== 0 && i < this.length; i++) {
+ var w = this.words[i];
+ w += carry;
+ carry = w >>> 26;
+ w &= 0x3ffffff;
+ this.words[i] = w;
+ }
+ if (carry !== 0) {
+ this.words[i] = carry;
+ this.length++;
+ }
+ return this;
+};
+
+BN.prototype.cmpn = function cmpn(num) {
+ var sign = num < 0;
+ if (sign)
+ num = -num;
+
+ if (this.sign && !sign)
+ return -1;
+ else if (!this.sign && sign)
+ return 1;
+
+ num &= 0x3ffffff;
+ this.strip();
+
+ var res;
+ if (this.length > 1) {
+ res = 1;
+ } else {
+ var w = this.words[0];
+ res = w === num ? 0 : w < num ? -1 : 1;
+ }
+ if (this.sign)
+ res = -res;
+ return res;
+};
+
+// Compare two numbers and return:
+// 1 - if `this` > `num`
+// 0 - if `this` == `num`
+// -1 - if `this` < `num`
+BN.prototype.cmp = function cmp(num) {
+ if (this.sign && !num.sign)
+ return -1;
+ else if (!this.sign && num.sign)
+ return 1;
+
+ var res = this.ucmp(num);
+ if (this.sign)
+ return -res;
+ else
+ return res;
+};
+
+// Unsigned comparison
+BN.prototype.ucmp = function ucmp(num) {
+ // At this point both numbers have the same sign
+ if (this.length > num.length)
+ return 1;
+ else if (this.length < num.length)
+ return -1;
+
+ var res = 0;
+ for (var i = this.length - 1; i >= 0; i--) {
+ var a = this.words[i];
+ var b = num.words[i];
+
+ if (a === b)
+ continue;
+ if (a < b)
+ res = -1;
+ else if (a > b)
+ res = 1;
+ break;
+ }
+ return res;
+};
+
+//
+// A reduce context, could be using montgomery or something better, depending
+// on the `m` itself.
+//
+BN.red = function red(num) {
+ return new Red(num);
+};
+
+BN.prototype.toRed = function toRed(ctx) {
+ assert(!this.red, 'Already a number in reduction context');
+ assert(!this.sign, 'red works only with positives');
+ return ctx.convertTo(this)._forceRed(ctx);
+};
+
+BN.prototype.fromRed = function fromRed() {
+ assert(this.red, 'fromRed works only with numbers in reduction context');
+ return this.red.convertFrom(this);
+};
+
+BN.prototype._forceRed = function _forceRed(ctx) {
+ this.red = ctx;
+ return this;
+};
+
+BN.prototype.forceRed = function forceRed(ctx) {
+ assert(!this.red, 'Already a number in reduction context');
+ return this._forceRed(ctx);
+};
+
+BN.prototype.redAdd = function redAdd(num) {
+ assert(this.red, 'redAdd works only with red numbers');
+ return this.red.add(this, num);
+};
+
+BN.prototype.redIAdd = function redIAdd(num) {
+ assert(this.red, 'redIAdd works only with red numbers');
+ return this.red.iadd(this, num);
+};
+
+BN.prototype.redSub = function redSub(num) {
+ assert(this.red, 'redSub works only with red numbers');
+ return this.red.sub(this, num);
+};
+
+BN.prototype.redISub = function redISub(num) {
+ assert(this.red, 'redISub works only with red numbers');
+ return this.red.isub(this, num);
+};
+
+BN.prototype.redShl = function redShl(num) {
+ assert(this.red, 'redShl works only with red numbers');
+ return this.red.shl(this, num);
+};
+
+BN.prototype.redMul = function redMul(num) {
+ assert(this.red, 'redMul works only with red numbers');
+ this.red._verify2(this, num);
+ return this.red.mul(this, num);
+};
+
+BN.prototype.redIMul = function redIMul(num) {
+ assert(this.red, 'redMul works only with red numbers');
+ this.red._verify2(this, num);
+ return this.red.imul(this, num);
+};
+
+BN.prototype.redSqr = function redSqr() {
+ assert(this.red, 'redSqr works only with red numbers');
+ this.red._verify1(this);
+ return this.red.sqr(this);
+};
+
+BN.prototype.redISqr = function redISqr() {
+ assert(this.red, 'redISqr works only with red numbers');
+ this.red._verify1(this);
+ return this.red.isqr(this);
+};
+
+// Square root over p
+BN.prototype.redSqrt = function redSqrt() {
+ assert(this.red, 'redSqrt works only with red numbers');
+ this.red._verify1(this);
+ return this.red.sqrt(this);
+};
+
+BN.prototype.redInvm = function redInvm() {
+ assert(this.red, 'redInvm works only with red numbers');
+ this.red._verify1(this);
+ return this.red.invm(this);
+};
+
+// Return negative clone of `this` % `red modulo`
+BN.prototype.redNeg = function redNeg() {
+ assert(this.red, 'redNeg works only with red numbers');
+ this.red._verify1(this);
+ return this.red.neg(this);
+};
+
+BN.prototype.redPow = function redPow(num) {
+ assert(this.red && !num.red, 'redPow(normalNum)');
+ this.red._verify1(this);
+ return this.red.pow(this, num);
+};
+
+// Prime numbers with efficient reduction
+var primes = {
+ k256: null,
+ p224: null,
+ p192: null,
+ p25519: null
+};
+
+// Pseudo-Mersenne prime
+function MPrime(name, p) {
+ // P = 2 ^ N - K
+ this.name = name;
+ this.p = new BN(p, 16);
+ this.n = this.p.bitLength();
+ this.k = new BN(1).ishln(this.n).isub(this.p);
+
+ this.tmp = this._tmp();
+}
+
+MPrime.prototype._tmp = function _tmp() {
+ var tmp = new BN(null);
+ tmp.words = new Array(Math.ceil(this.n / 13));
+ return tmp;
+};
+
+MPrime.prototype.ireduce = function ireduce(num) {
+ // Assumes that `num` is less than `P^2`
+ // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
+ var r = num;
+ var rlen;
+
+ do {
+ this.split(r, this.tmp);
+ r = this.imulK(r);
+ r = r.iadd(this.tmp);
+ rlen = r.bitLength();
+ } while (rlen > this.n);
+
+ var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
+ if (cmp === 0) {
+ r.words[0] = 0;
+ r.length = 1;
+ } else if (cmp > 0) {
+ r.isub(this.p);
+ } else {
+ r.strip();
+ }
+
+ return r;
+};
+
+MPrime.prototype.split = function split(input, out) {
+ input.ishrn(this.n, 0, out);
+};
+
+MPrime.prototype.imulK = function imulK(num) {
+ return num.imul(this.k);
+};
+
+function K256() {
+ MPrime.call(
+ this,
+ 'k256',
+ 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
+}
+inherits(K256, MPrime);
+
+K256.prototype.split = function split(input, output) {
+ // 256 = 9 * 26 + 22
+ var mask = 0x3fffff;
+
+ var outLen = Math.min(input.length, 9);
+ for (var i = 0; i < outLen; i++)
+ output.words[i] = input.words[i];
+ output.length = outLen;
+
+ if (input.length <= 9) {
+ input.words[0] = 0;
+ input.length = 1;
+ return;
+ }
+
+ // Shift by 9 limbs
+ var prev = input.words[9];
+ output.words[output.length++] = prev & mask;
+
+ for (var i = 10; i < input.length; i++) {
+ var next = input.words[i];
+ input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
+ prev = next;
+ }
+ input.words[i - 10] = prev >>> 22;
+ input.length -= 9;
+};
+
+K256.prototype.imulK = function imulK(num) {
+ // K = 0x1000003d1 = [ 0x40, 0x3d1 ]
+ num.words[num.length] = 0;
+ num.words[num.length + 1] = 0;
+ num.length += 2;
+
+ // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
+ var hi;
+ var lo = 0;
+ for (var i = 0; i < num.length; i++) {
+ var w = num.words[i];
+ hi = w * 0x40;
+ lo += w * 0x3d1;
+ hi += (lo / 0x4000000) | 0;
+ lo &= 0x3ffffff;
+
+ num.words[i] = lo;
+
+ lo = hi;
+ }
+
+ // Fast length reduction
+ if (num.words[num.length - 1] === 0) {
+ num.length--;
+ if (num.words[num.length - 1] === 0)
+ num.length--;
+ }
+ return num;
+};
+
+function P224() {
+ MPrime.call(
+ this,
+ 'p224',
+ 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
+}
+inherits(P224, MPrime);
+
+function P192() {
+ MPrime.call(
+ this,
+ 'p192',
+ 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
+}
+inherits(P192, MPrime);
+
+function P25519() {
+ // 2 ^ 255 - 19
+ MPrime.call(
+ this,
+ '25519',
+ '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
+}
+inherits(P25519, MPrime);
+
+P25519.prototype.imulK = function imulK(num) {
+ // K = 0x13
+ var carry = 0;
+ for (var i = 0; i < num.length; i++) {
+ var hi = num.words[i] * 0x13 + carry;
+ var lo = hi & 0x3ffffff;
+ hi >>>= 26;
+
+ num.words[i] = lo;
+ carry = hi;
+ }
+ if (carry !== 0)
+ num.words[num.length++] = carry;
+ return num;
+};
+
+// Exported mostly for testing purposes, use plain name instead
+BN._prime = function prime(name) {
+ // Cached version of prime
+ if (primes[name])
+ return primes[name];
+
+ var prime;
+ if (name === 'k256')
+ prime = new K256();
+ else if (name === 'p224')
+ prime = new P224();
+ else if (name === 'p192')
+ prime = new P192();
+ else if (name === 'p25519')
+ prime = new P25519();
+ else
+ throw new Error('Unknown prime ' + name);
+ primes[name] = prime;
+
+ return prime;
+};
+
+//
+// Base reduction engine
+//
+function Red(m) {
+ if (typeof m === 'string') {
+ var prime = BN._prime(m);
+ this.m = prime.p;
+ this.prime = prime;
+ } else {
+ this.m = m;
+ this.prime = null;
+ }
+}
+
+Red.prototype._verify1 = function _verify1(a) {
+ assert(!a.sign, 'red works only with positives');
+ assert(a.red, 'red works only with red numbers');
+};
+
+Red.prototype._verify2 = function _verify2(a, b) {
+ assert(!a.sign && !b.sign, 'red works only with positives');
+ assert(a.red && a.red === b.red,
+ 'red works only with red numbers');
+};
+
+Red.prototype.imod = function imod(a) {
+ if (this.prime)
+ return this.prime.ireduce(a)._forceRed(this);
+ return a.mod(this.m)._forceRed(this);
+};
+
+Red.prototype.neg = function neg(a) {
+ var r = a.clone();
+ r.sign = !r.sign;
+ return r.iadd(this.m)._forceRed(this);
+};
+
+Red.prototype.add = function add(a, b) {
+ this._verify2(a, b);
+
+ var res = a.add(b);
+ if (res.cmp(this.m) >= 0)
+ res.isub(this.m);
+ return res._forceRed(this);
+};
+
+Red.prototype.iadd = function iadd(a, b) {
+ this._verify2(a, b);
+
+ var res = a.iadd(b);
+ if (res.cmp(this.m) >= 0)
+ res.isub(this.m);
+ return res;
+};
+
+Red.prototype.sub = function sub(a, b) {
+ this._verify2(a, b);
+
+ var res = a.sub(b);
+ if (res.cmpn(0) < 0)
+ res.iadd(this.m);
+ return res._forceRed(this);
+};
+
+Red.prototype.isub = function isub(a, b) {
+ this._verify2(a, b);
+
+ var res = a.isub(b);
+ if (res.cmpn(0) < 0)
+ res.iadd(this.m);
+ return res;
+};
+
+Red.prototype.shl = function shl(a, num) {
+ this._verify1(a);
+ return this.imod(a.shln(num));
+};
+
+Red.prototype.imul = function imul(a, b) {
+ this._verify2(a, b);
+ return this.imod(a.imul(b));
+};
+
+Red.prototype.mul = function mul(a, b) {
+ this._verify2(a, b);
+ return this.imod(a.mul(b));
+};
+
+Red.prototype.isqr = function isqr(a) {
+ return this.imul(a, a);
+};
+
+Red.prototype.sqr = function sqr(a) {
+ return this.mul(a, a);
+};
+
+Red.prototype.sqrt = function sqrt(a) {
+ if (a.cmpn(0) === 0)
+ return a.clone();
+
+ var mod3 = this.m.andln(3);
+ assert(mod3 % 2 === 1);
+
+ // Fast case
+ if (mod3 === 3) {
+ var pow = this.m.add(new BN(1)).ishrn(2);
+ var r = this.pow(a, pow);
+ return r;
+ }
+
+ // Tonelli-Shanks algorithm (Totally unoptimized and slow)
+ //
+ // Find Q and S, that Q * 2 ^ S = (P - 1)
+ var q = this.m.subn(1);
+ var s = 0;
+ while (q.cmpn(0) !== 0 && q.andln(1) === 0) {
+ s++;
+ q.ishrn(1);
+ }
+ assert(q.cmpn(0) !== 0);
+
+ var one = new BN(1).toRed(this);
+ var nOne = one.redNeg();
+
+ // Find quadratic non-residue
+ // NOTE: Max is such because of generalized Riemann hypothesis.
+ var lpow = this.m.subn(1).ishrn(1);
+ var z = this.m.bitLength();
+ z = new BN(2 * z * z).toRed(this);
+ while (this.pow(z, lpow).cmp(nOne) !== 0)
+ z.redIAdd(nOne);
+
+ var c = this.pow(z, q);
+ var r = this.pow(a, q.addn(1).ishrn(1));
+ var t = this.pow(a, q);
+ var m = s;
+ while (t.cmp(one) !== 0) {
+ var tmp = t;
+ for (var i = 0; tmp.cmp(one) !== 0; i++)
+ tmp = tmp.redSqr();
+ assert(i < m);
+ var b = this.pow(c, new BN(1).ishln(m - i - 1));
+
+ r = r.redMul(b);
+ c = b.redSqr();
+ t = t.redMul(c);
+ m = i;
+ }
+
+ return r;
+};
+
+Red.prototype.invm = function invm(a) {
+ var inv = a._invmp(this.m);
+ if (inv.sign) {
+ inv.sign = false;
+ return this.imod(inv).redNeg();
+ } else {
+ return this.imod(inv);
+ }
+};
+
+Red.prototype.pow = function pow(a, num) {
+ var w = [];
+
+ if (num.cmpn(0) === 0)
+ return new BN(1);
+
+ var q = num.clone();
+
+ while (q.cmpn(0) !== 0) {
+ w.push(q.andln(1));
+ q.ishrn(1);
+ }
+
+ // Skip leading zeroes
+ var res = a;
+ for (var i = 0; i < w.length; i++, res = this.sqr(res))
+ if (w[i] !== 0)
+ break;
+
+ if (++i < w.length) {
+ for (var q = this.sqr(res); i < w.length; i++, q = this.sqr(q)) {
+ if (w[i] === 0)
+ continue;
+ res = this.mul(res, q);
+ }
+ }
+
+ return res;
+};
+
+Red.prototype.convertTo = function convertTo(num) {
+ var r = num.mod(this.m);
+ if (r === num)
+ return r.clone();
+ else
+ return r;
+};
+
+Red.prototype.convertFrom = function convertFrom(num) {
+ var res = num.clone();
+ res.red = null;
+ return res;
+};
+
+//
+// Montgomery method engine
+//
+
+BN.mont = function mont(num) {
+ return new Mont(num);
+};
+
+function Mont(m) {
+ Red.call(this, m);
+
+ this.shift = this.m.bitLength();
+ if (this.shift % 26 !== 0)
+ this.shift += 26 - (this.shift % 26);
+ this.r = new BN(1).ishln(this.shift);
+ this.r2 = this.imod(this.r.sqr());
+ this.rinv = this.r._invmp(this.m);
+
+ this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
+ this.minv.sign = true;
+ this.minv = this.minv.mod(this.r);
+}
+inherits(Mont, Red);
+
+Mont.prototype.convertTo = function convertTo(num) {
+ return this.imod(num.shln(this.shift));
+};
+
+Mont.prototype.convertFrom = function convertFrom(num) {
+ var r = this.imod(num.mul(this.rinv));
+ r.red = null;
+ return r;
+};
+
+Mont.prototype.imul = function imul(a, b) {
+ if (a.cmpn(0) === 0 || b.cmpn(0) === 0) {
+ a.words[0] = 0;
+ a.length = 1;
+ return a;
+ }
+
+ var t = a.imul(b);
+ var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
+ var u = t.isub(c).ishrn(this.shift);
+ var res = u;
+ if (u.cmp(this.m) >= 0)
+ res = u.isub(this.m);
+ else if (u.cmpn(0) < 0)
+ res = u.iadd(this.m);
+
+ return res._forceRed(this);
+};
+
+Mont.prototype.mul = function mul(a, b) {
+ if (a.cmpn(0) === 0 || b.cmpn(0) === 0)
+ return new BN(0)._forceRed(this);
+
+ var t = a.mul(b);
+ var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
+ var u = t.isub(c).ishrn(this.shift);
+ var res = u;
+ if (u.cmp(this.m) >= 0)
+ res = u.isub(this.m);
+ else if (u.cmpn(0) < 0)
+ res = u.iadd(this.m);
+
+ return res._forceRed(this);
+};
+
+Mont.prototype.invm = function invm(a) {
+ // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
+ var res = this.imod(a._invmp(this.m).mul(this.r2));
+ return res._forceRed(this);
+};
+
+})(typeof module === 'undefined' || module, this);
+
+},{}],260:[function(require,module,exports){
+'use strict'
+
+var bnsign = require('./lib/bn-sign')
+
+module.exports = sign
+
+function sign(x) {
+ return bnsign(x[0]) * bnsign(x[1])
+}
+
+},{"./lib/bn-sign":251}],261:[function(require,module,exports){
+'use strict'
+
+var rationalize = require('./lib/rationalize')
+
+module.exports = sub
+
+function sub(a, b) {
+ return rationalize(a[0].mul(b[1]).sub(a[1].mul(b[0])), a[1].mul(b[1]))
+}
+
+},{"./lib/rationalize":256}],262:[function(require,module,exports){
+'use strict'
+
+var bn2num = require('./lib/bn-to-num')
+var ctz = require('./lib/ctz')
+
+module.exports = roundRat
+
+//Round a rational to the closest float
+function roundRat(f) {
+ var a = f[0]
+ var b = f[1]
+ if(a.cmpn(0) === 0) {
+ return 0
+ }
+ var h = a.divmod(b)
+ var iv = h.div
+ var x = bn2num(iv)
+ var ir = h.mod
+ if(ir.cmpn(0) === 0) {
+ return x
+ }
+ if(x) {
+ var s = ctz(x) + 4
+ var y = bn2num(ir.shln(s).divRound(b))
+
+ // flip the sign of y if x is negative
+ if (x<0) {
+ y = -y;
+ }
+
+ return x + y * Math.pow(2, -s)
+ } else {
+ var ybits = b.bitLength() - ir.bitLength() + 53
+ var y = bn2num(ir.shln(ybits).divRound(b))
+ if(ybits < 1023) {
+ return y * Math.pow(2, -ybits)
+ }
+ y *= Math.pow(2, -1023)
+ return y * Math.pow(2, 1023-ybits)
+ }
+}
+
+},{"./lib/bn-to-num":252,"./lib/ctz":253}],263:[function(require,module,exports){
+'use strict'
+
+module.exports = boxIntersectWrapper
+
+var pool = require('typedarray-pool')
+var sweep = require('./lib/sweep')
+var boxIntersectIter = require('./lib/intersect')
+
+function boxEmpty(d, box) {
+ for(var j=0; j>>1
+ if(d <= 0) {
+ return
+ }
+
+ var retval
+
+ //Convert red boxes
+ var redList = pool.mallocDouble(2*d*n)
+ var redIds = pool.mallocInt32(n)
+ n = convertBoxes(red, d, redList, redIds)
+
+ if(n > 0) {
+ if(d === 1 && full) {
+ //Special case: 1d complete
+ sweep.init(n)
+ retval = sweep.sweepComplete(
+ d, visit,
+ 0, n, redList, redIds,
+ 0, n, redList, redIds)
+ } else {
+
+ //Convert blue boxes
+ var blueList = pool.mallocDouble(2*d*m)
+ var blueIds = pool.mallocInt32(m)
+ m = convertBoxes(blue, d, blueList, blueIds)
+
+ if(m > 0) {
+ sweep.init(n+m)
+
+ if(d === 1) {
+ //Special case: 1d bipartite
+ retval = sweep.sweepBipartite(
+ d, visit,
+ 0, n, redList, redIds,
+ 0, m, blueList, blueIds)
+ } else {
+ //General case: d>1
+ retval = boxIntersectIter(
+ d, visit, full,
+ n, redList, redIds,
+ m, blueList, blueIds)
+ }
+
+ pool.free(blueList)
+ pool.free(blueIds)
+ }
+ }
+
+ pool.free(redList)
+ pool.free(redIds)
+ }
+
+ return retval
+}
+
+
+var RESULT
+
+function appendItem(i,j) {
+ RESULT.push([i,j])
+}
+
+function intersectFullArray(x) {
+ RESULT = []
+ boxIntersect(x, x, appendItem, true)
+ return RESULT
+}
+
+function intersectBipartiteArray(x, y) {
+ RESULT = []
+ boxIntersect(x, y, appendItem, false)
+ return RESULT
+}
+
+//User-friendly wrapper, handle full input and no-visitor cases
+function boxIntersectWrapper(arg0, arg1, arg2) {
+ var result
+ switch(arguments.length) {
+ case 1:
+ return intersectFullArray(arg0)
+ case 2:
+ if(typeof arg1 === 'function') {
+ return boxIntersect(arg0, arg0, arg1, true)
+ } else {
+ return intersectBipartiteArray(arg0, arg1)
+ }
+ case 3:
+ return boxIntersect(arg0, arg1, arg2, false)
+ default:
+ throw new Error('box-intersect: Invalid arguments')
+ }
+}
+},{"./lib/intersect":265,"./lib/sweep":269,"typedarray-pool":233}],264:[function(require,module,exports){
+'use strict'
+
+var DIMENSION = 'd'
+var AXIS = 'ax'
+var VISIT = 'vv'
+var FLIP = 'fp'
+
+var ELEM_SIZE = 'es'
+
+var RED_START = 'rs'
+var RED_END = 're'
+var RED_BOXES = 'rb'
+var RED_INDEX = 'ri'
+var RED_PTR = 'rp'
+
+var BLUE_START = 'bs'
+var BLUE_END = 'be'
+var BLUE_BOXES = 'bb'
+var BLUE_INDEX = 'bi'
+var BLUE_PTR = 'bp'
+
+var RETVAL = 'rv'
+
+var INNER_LABEL = 'Q'
+
+var ARGS = [
+ DIMENSION,
+ AXIS,
+ VISIT,
+ RED_START,
+ RED_END,
+ RED_BOXES,
+ RED_INDEX,
+ BLUE_START,
+ BLUE_END,
+ BLUE_BOXES,
+ BLUE_INDEX
+]
+
+function generateBruteForce(redMajor, flip, full) {
+ var funcName = 'bruteForce' +
+ (redMajor ? 'Red' : 'Blue') +
+ (flip ? 'Flip' : '') +
+ (full ? 'Full' : '')
+
+ var code = ['function ', funcName, '(', ARGS.join(), '){',
+ 'var ', ELEM_SIZE, '=2*', DIMENSION, ';']
+
+ var redLoop =
+ 'for(var i=' + RED_START + ',' + RED_PTR + '=' + ELEM_SIZE + '*' + RED_START + ';' +
+ 'i<' + RED_END +';' +
+ '++i,' + RED_PTR + '+=' + ELEM_SIZE + '){' +
+ 'var x0=' + RED_BOXES + '[' + AXIS + '+' + RED_PTR + '],' +
+ 'x1=' + RED_BOXES + '[' + AXIS + '+' + RED_PTR + '+' + DIMENSION + '],' +
+ 'xi=' + RED_INDEX + '[i];'
+
+ var blueLoop =
+ 'for(var j=' + BLUE_START + ',' + BLUE_PTR + '=' + ELEM_SIZE + '*' + BLUE_START + ';' +
+ 'j<' + BLUE_END + ';' +
+ '++j,' + BLUE_PTR + '+=' + ELEM_SIZE + '){' +
+ 'var y0=' + BLUE_BOXES + '[' + AXIS + '+' + BLUE_PTR + '],' +
+ (full ? 'y1=' + BLUE_BOXES + '[' + AXIS + '+' + BLUE_PTR + '+' + DIMENSION + '],' : '') +
+ 'yi=' + BLUE_INDEX + '[j];'
+
+ if(redMajor) {
+ code.push(redLoop, INNER_LABEL, ':', blueLoop)
+ } else {
+ code.push(blueLoop, INNER_LABEL, ':', redLoop)
+ }
+
+ if(full) {
+ code.push('if(y1' +
+ BLUE_END + '-' + BLUE_START + '){')
+
+ if(full) {
+ invoke(true, false)
+ code.push('}else{')
+ invoke(false, false)
+ } else {
+ code.push('if(' + FLIP + '){')
+ invoke(true, true)
+ code.push('}else{')
+ invoke(true, false)
+ code.push('}}else{if(' + FLIP + '){')
+ invoke(false, true)
+ code.push('}else{')
+ invoke(false, false)
+ code.push('}')
+ }
+ code.push('}}return ' + funcName)
+
+ var codeStr = prefix.join('') + code.join('')
+ var proc = new Function(codeStr)
+ return proc()
+}
+
+
+exports.partial = bruteForcePlanner(false)
+exports.full = bruteForcePlanner(true)
+},{}],265:[function(require,module,exports){
+'use strict'
+
+module.exports = boxIntersectIter
+
+var pool = require('typedarray-pool')
+var bits = require('bit-twiddle')
+var bruteForce = require('./brute')
+var bruteForcePartial = bruteForce.partial
+var bruteForceFull = bruteForce.full
+var sweep = require('./sweep')
+var findMedian = require('./median')
+var genPartition = require('./partition')
+
+//Twiddle parameters
+var BRUTE_FORCE_CUTOFF = 128 //Cut off for brute force search
+var SCAN_CUTOFF = (1<<22) //Cut off for two way scan
+var SCAN_COMPLETE_CUTOFF = (1<<22)
+
+//Partition functions
+var partitionInteriorContainsInterval = genPartition(
+ '!(lo>=p0)&&!(p1>=hi)',
+ ['p0', 'p1'])
+
+var partitionStartEqual = genPartition(
+ 'lo===p0',
+ ['p0'])
+
+var partitionStartLessThan = genPartition(
+ 'lo 0) {
+ top -= 1
+
+ var iptr = top * IFRAME_SIZE
+ var axis = BOX_ISTACK[iptr]
+ var redStart = BOX_ISTACK[iptr+1]
+ var redEnd = BOX_ISTACK[iptr+2]
+ var blueStart = BOX_ISTACK[iptr+3]
+ var blueEnd = BOX_ISTACK[iptr+4]
+ var state = BOX_ISTACK[iptr+5]
+
+ var dptr = top * DFRAME_SIZE
+ var lo = BOX_DSTACK[dptr]
+ var hi = BOX_DSTACK[dptr+1]
+
+ //Unpack state info
+ var flip = (state & 1)
+ var full = !!(state & 16)
+
+ //Unpack indices
+ var red = xBoxes
+ var redIndex = xIndex
+ var blue = yBoxes
+ var blueIndex = yIndex
+ if(flip) {
+ red = yBoxes
+ redIndex = yIndex
+ blue = xBoxes
+ blueIndex = xIndex
+ }
+
+ if(state & 2) {
+ redEnd = partitionStartLessThan(
+ d, axis,
+ redStart, redEnd, red, redIndex,
+ hi)
+ if(redStart >= redEnd) {
+ continue
+ }
+ }
+ if(state & 4) {
+ redStart = partitionEndLessThanEqual(
+ d, axis,
+ redStart, redEnd, red, redIndex,
+ lo)
+ if(redStart >= redEnd) {
+ continue
+ }
+ }
+
+ var redCount = redEnd - redStart
+ var blueCount = blueEnd - blueStart
+
+ if(full) {
+ if(d * redCount * (redCount + blueCount) < SCAN_COMPLETE_CUTOFF) {
+ retval = sweep.scanComplete(
+ d, axis, visit,
+ redStart, redEnd, red, redIndex,
+ blueStart, blueEnd, blue, blueIndex)
+ if(retval !== void 0) {
+ return retval
+ }
+ continue
+ }
+ } else {
+ if(d * Math.min(redCount, blueCount) < BRUTE_FORCE_CUTOFF) {
+ //If input small, then use brute force
+ retval = bruteForcePartial(
+ d, axis, visit, flip,
+ redStart, redEnd, red, redIndex,
+ blueStart, blueEnd, blue, blueIndex)
+ if(retval !== void 0) {
+ return retval
+ }
+ continue
+ } else if(d * redCount * blueCount < SCAN_CUTOFF) {
+ //If input medium sized, then use sweep and prune
+ retval = sweep.scanBipartite(
+ d, axis, visit, flip,
+ redStart, redEnd, red, redIndex,
+ blueStart, blueEnd, blue, blueIndex)
+ if(retval !== void 0) {
+ return retval
+ }
+ continue
+ }
+ }
+
+ //First, find all red intervals whose interior contains (lo,hi)
+ var red0 = partitionInteriorContainsInterval(
+ d, axis,
+ redStart, redEnd, red, redIndex,
+ lo, hi)
+
+ //Lower dimensional case
+ if(redStart < red0) {
+
+ if(d * (red0 - redStart) < BRUTE_FORCE_CUTOFF) {
+ //Special case for small inputs: use brute force
+ retval = bruteForceFull(
+ d, axis+1, visit,
+ redStart, red0, red, redIndex,
+ blueStart, blueEnd, blue, blueIndex)
+ if(retval !== void 0) {
+ return retval
+ }
+ } else if(axis === d-2) {
+ if(flip) {
+ retval = sweep.sweepBipartite(
+ d, visit,
+ blueStart, blueEnd, blue, blueIndex,
+ redStart, red0, red, redIndex)
+ } else {
+ retval = sweep.sweepBipartite(
+ d, visit,
+ redStart, red0, red, redIndex,
+ blueStart, blueEnd, blue, blueIndex)
+ }
+ if(retval !== void 0) {
+ return retval
+ }
+ } else {
+ iterPush(top++,
+ axis+1,
+ redStart, red0,
+ blueStart, blueEnd,
+ flip,
+ -Infinity, Infinity)
+ iterPush(top++,
+ axis+1,
+ blueStart, blueEnd,
+ redStart, red0,
+ flip^1,
+ -Infinity, Infinity)
+ }
+ }
+
+ //Divide and conquer phase
+ if(red0 < redEnd) {
+
+ //Cut blue into 3 parts:
+ //
+ // Points < mid point
+ // Points = mid point
+ // Points > mid point
+ //
+ var blue0 = findMedian(
+ d, axis,
+ blueStart, blueEnd, blue, blueIndex)
+ var mid = blue[elemSize * blue0 + axis]
+ var blue1 = partitionStartEqual(
+ d, axis,
+ blue0, blueEnd, blue, blueIndex,
+ mid)
+
+ //Right case
+ if(blue1 < blueEnd) {
+ iterPush(top++,
+ axis,
+ red0, redEnd,
+ blue1, blueEnd,
+ (flip|4) + (full ? 16 : 0),
+ mid, hi)
+ }
+
+ //Left case
+ if(blueStart < blue0) {
+ iterPush(top++,
+ axis,
+ red0, redEnd,
+ blueStart, blue0,
+ (flip|2) + (full ? 16 : 0),
+ lo, mid)
+ }
+
+ //Center case (the hard part)
+ if(blue0 + 1 === blue1) {
+ //Optimization: Range with exactly 1 point, use a brute force scan
+ if(full) {
+ retval = onePointFull(
+ d, axis, visit,
+ red0, redEnd, red, redIndex,
+ blue0, blue, blueIndex[blue0])
+ } else {
+ retval = onePointPartial(
+ d, axis, visit, flip,
+ red0, redEnd, red, redIndex,
+ blue0, blue, blueIndex[blue0])
+ }
+ if(retval !== void 0) {
+ return retval
+ }
+ } else if(blue0 < blue1) {
+ var red1
+ if(full) {
+ //If full intersection, need to handle special case
+ red1 = partitionContainsPoint(
+ d, axis,
+ red0, redEnd, red, redIndex,
+ mid)
+ if(red0 < red1) {
+ var redX = partitionStartEqual(
+ d, axis,
+ red0, red1, red, redIndex,
+ mid)
+ if(axis === d-2) {
+ //Degenerate sweep intersection:
+ // [red0, redX] with [blue0, blue1]
+ if(red0 < redX) {
+ retval = sweep.sweepComplete(
+ d, visit,
+ red0, redX, red, redIndex,
+ blue0, blue1, blue, blueIndex)
+ if(retval !== void 0) {
+ return retval
+ }
+ }
+
+ //Normal sweep intersection:
+ // [redX, red1] with [blue0, blue1]
+ if(redX < red1) {
+ retval = sweep.sweepBipartite(
+ d, visit,
+ redX, red1, red, redIndex,
+ blue0, blue1, blue, blueIndex)
+ if(retval !== void 0) {
+ return retval
+ }
+ }
+ } else {
+ if(red0 < redX) {
+ iterPush(top++,
+ axis+1,
+ red0, redX,
+ blue0, blue1,
+ 16,
+ -Infinity, Infinity)
+ }
+ if(redX < red1) {
+ iterPush(top++,
+ axis+1,
+ redX, red1,
+ blue0, blue1,
+ 0,
+ -Infinity, Infinity)
+ iterPush(top++,
+ axis+1,
+ blue0, blue1,
+ redX, red1,
+ 1,
+ -Infinity, Infinity)
+ }
+ }
+ }
+ } else {
+ if(flip) {
+ red1 = partitionContainsPointProper(
+ d, axis,
+ red0, redEnd, red, redIndex,
+ mid)
+ } else {
+ red1 = partitionContainsPoint(
+ d, axis,
+ red0, redEnd, red, redIndex,
+ mid)
+ }
+ if(red0 < red1) {
+ if(axis === d-2) {
+ if(flip) {
+ retval = sweep.sweepBipartite(
+ d, visit,
+ blue0, blue1, blue, blueIndex,
+ red0, red1, red, redIndex)
+ } else {
+ retval = sweep.sweepBipartite(
+ d, visit,
+ red0, red1, red, redIndex,
+ blue0, blue1, blue, blueIndex)
+ }
+ } else {
+ iterPush(top++,
+ axis+1,
+ red0, red1,
+ blue0, blue1,
+ flip,
+ -Infinity, Infinity)
+ iterPush(top++,
+ axis+1,
+ blue0, blue1,
+ red0, red1,
+ flip^1,
+ -Infinity, Infinity)
+ }
+ }
+ }
+ }
+ }
+ }
+}
+},{"./brute":264,"./median":266,"./partition":267,"./sweep":269,"bit-twiddle":49,"typedarray-pool":233}],266:[function(require,module,exports){
+'use strict'
+
+module.exports = findMedian
+
+var genPartition = require('./partition')
+
+var partitionStartLessThan = genPartition('lostart && boxes[ptr+axis] > x;
+ --j, ptr-=elemSize) {
+ //Swap
+ var aPtr = ptr
+ var bPtr = ptr+elemSize
+ for(var k=0; k>> 1)
+ var elemSize = 2*d
+ var pivot = mid
+ var value = boxes[elemSize*mid+axis]
+
+ while(lo < hi) {
+ if(hi - lo < PARTITION_THRESHOLD) {
+ insertionSort(d, axis, lo, hi, boxes, ids)
+ value = boxes[elemSize*mid+axis]
+ break
+ }
+
+ //Select pivot using median-of-3
+ var count = hi - lo
+ var pivot0 = (Math.random()*count+lo)|0
+ var value0 = boxes[elemSize*pivot0 + axis]
+ var pivot1 = (Math.random()*count+lo)|0
+ var value1 = boxes[elemSize*pivot1 + axis]
+ var pivot2 = (Math.random()*count+lo)|0
+ var value2 = boxes[elemSize*pivot2 + axis]
+ if(value0 <= value1) {
+ if(value2 >= value1) {
+ pivot = pivot1
+ value = value1
+ } else if(value0 >= value2) {
+ pivot = pivot0
+ value = value0
+ } else {
+ pivot = pivot2
+ value = value2
+ }
+ } else {
+ if(value1 >= value2) {
+ pivot = pivot1
+ value = value1
+ } else if(value2 >= value0) {
+ pivot = pivot0
+ value = value0
+ } else {
+ pivot = pivot2
+ value = value2
+ }
+ }
+
+ //Swap pivot to end of array
+ var aPtr = elemSize * (hi-1)
+ var bPtr = elemSize * pivot
+ for(var i=0; i= 0) {
+ reads.push('lo=e[k+n]')
+ }
+ if(predicate.indexOf('hi') >= 0) {
+ reads.push('hi=e[k+o]')
+ }
+ fargs.push(
+ code.replace('_', reads.join())
+ .replace('$', predicate))
+ return Function.apply(void 0, fargs)
+}
+},{}],268:[function(require,module,exports){
+'use strict';
+
+//This code is extracted from ndarray-sort
+//It is inlined here as a temporary workaround
+
+module.exports = wrapper;
+
+var INSERT_SORT_CUTOFF = 32
+
+function wrapper(data, n0) {
+ if (n0 <= 4*INSERT_SORT_CUTOFF) {
+ insertionSort(0, n0 - 1, data);
+ } else {
+ quickSort(0, n0 - 1, data);
+ }
+}
+
+function insertionSort(left, right, data) {
+ var ptr = 2*(left+1)
+ for(var i=left+1; i<=right; ++i) {
+ var a = data[ptr++]
+ var b = data[ptr++]
+ var j = i
+ var jptr = ptr-2
+ while(j-- > left) {
+ var x = data[jptr-2]
+ var y = data[jptr-1]
+ if(x < a) {
+ break
+ } else if(x === a && y < b) {
+ break
+ }
+ data[jptr] = x
+ data[jptr+1] = y
+ jptr -= 2
+ }
+ data[jptr] = a
+ data[jptr+1] = b
+ }
+}
+
+function swap(i, j, data) {
+ i *= 2
+ j *= 2
+ var x = data[i]
+ var y = data[i+1]
+ data[i] = data[j]
+ data[i+1] = data[j+1]
+ data[j] = x
+ data[j+1] = y
+}
+
+function move(i, j, data) {
+ i *= 2
+ j *= 2
+ data[i] = data[j]
+ data[i+1] = data[j+1]
+}
+
+function rotate(i, j, k, data) {
+ i *= 2
+ j *= 2
+ k *= 2
+ var x = data[i]
+ var y = data[i+1]
+ data[i] = data[j]
+ data[i+1] = data[j+1]
+ data[j] = data[k]
+ data[j+1] = data[k+1]
+ data[k] = x
+ data[k+1] = y
+}
+
+function shufflePivot(i, j, px, py, data) {
+ i *= 2
+ j *= 2
+ data[i] = data[j]
+ data[j] = px
+ data[i+1] = data[j+1]
+ data[j+1] = py
+}
+
+function compare(i, j, data) {
+ i *= 2
+ j *= 2
+ var x = data[i],
+ y = data[j]
+ if(x < y) {
+ return false
+ } else if(x === y) {
+ return data[i+1] > data[j+1]
+ }
+ return true
+}
+
+function comparePivot(i, y, b, data) {
+ i *= 2
+ var x = data[i]
+ if(x < y) {
+ return true
+ } else if(x === y) {
+ return data[i+1] < b
+ }
+ return false
+}
+
+function quickSort(left, right, data) {
+ var sixth = (right - left + 1) / 6 | 0,
+ index1 = left + sixth,
+ index5 = right - sixth,
+ index3 = left + right >> 1,
+ index2 = index3 - sixth,
+ index4 = index3 + sixth,
+ el1 = index1,
+ el2 = index2,
+ el3 = index3,
+ el4 = index4,
+ el5 = index5,
+ less = left + 1,
+ great = right - 1,
+ tmp = 0
+ if(compare(el1, el2, data)) {
+ tmp = el1
+ el1 = el2
+ el2 = tmp
+ }
+ if(compare(el4, el5, data)) {
+ tmp = el4
+ el4 = el5
+ el5 = tmp
+ }
+ if(compare(el1, el3, data)) {
+ tmp = el1
+ el1 = el3
+ el3 = tmp
+ }
+ if(compare(el2, el3, data)) {
+ tmp = el2
+ el2 = el3
+ el3 = tmp
+ }
+ if(compare(el1, el4, data)) {
+ tmp = el1
+ el1 = el4
+ el4 = tmp
+ }
+ if(compare(el3, el4, data)) {
+ tmp = el3
+ el3 = el4
+ el4 = tmp
+ }
+ if(compare(el2, el5, data)) {
+ tmp = el2
+ el2 = el5
+ el5 = tmp
+ }
+ if(compare(el2, el3, data)) {
+ tmp = el2
+ el2 = el3
+ el3 = tmp
+ }
+ if(compare(el4, el5, data)) {
+ tmp = el4
+ el4 = el5
+ el5 = tmp
+ }
+
+ var pivot1X = data[2*el2]
+ var pivot1Y = data[2*el2+1]
+ var pivot2X = data[2*el4]
+ var pivot2Y = data[2*el4+1]
+
+ var ptr0 = 2 * el1;
+ var ptr2 = 2 * el3;
+ var ptr4 = 2 * el5;
+ var ptr5 = 2 * index1;
+ var ptr6 = 2 * index3;
+ var ptr7 = 2 * index5;
+ for (var i1 = 0; i1 < 2; ++i1) {
+ var x = data[ptr0+i1];
+ var y = data[ptr2+i1];
+ var z = data[ptr4+i1];
+ data[ptr5+i1] = x;
+ data[ptr6+i1] = y;
+ data[ptr7+i1] = z;
+ }
+
+ move(index2, left, data)
+ move(index4, right, data)
+ for (var k = less; k <= great; ++k) {
+ if (comparePivot(k, pivot1X, pivot1Y, data)) {
+ if (k !== less) {
+ swap(k, less, data)
+ }
+ ++less;
+ } else {
+ if (!comparePivot(k, pivot2X, pivot2Y, data)) {
+ while (true) {
+ if (!comparePivot(great, pivot2X, pivot2Y, data)) {
+ if (--great < k) {
+ break;
+ }
+ continue;
+ } else {
+ if (comparePivot(great, pivot1X, pivot1Y, data)) {
+ rotate(k, less, great, data)
+ ++less;
+ --great;
+ } else {
+ swap(k, great, data)
+ --great;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ shufflePivot(left, less-1, pivot1X, pivot1Y, data)
+ shufflePivot(right, great+1, pivot2X, pivot2Y, data)
+ if (less - 2 - left <= INSERT_SORT_CUTOFF) {
+ insertionSort(left, less - 2, data);
+ } else {
+ quickSort(left, less - 2, data);
+ }
+ if (right - (great + 2) <= INSERT_SORT_CUTOFF) {
+ insertionSort(great + 2, right, data);
+ } else {
+ quickSort(great + 2, right, data);
+ }
+ if (great - less <= INSERT_SORT_CUTOFF) {
+ insertionSort(less, great, data);
+ } else {
+ quickSort(less, great, data);
+ }
+}
+},{}],269:[function(require,module,exports){
+'use strict'
+
+module.exports = {
+ init: sqInit,
+ sweepBipartite: sweepBipartite,
+ sweepComplete: sweepComplete,
+ scanBipartite: scanBipartite,
+ scanComplete: scanComplete
+}
+
+var pool = require('typedarray-pool')
+var bits = require('bit-twiddle')
+var isort = require('./sort')
+
+//Flag for blue
+var BLUE_FLAG = (1<<28)
+
+//1D sweep event queue stuff (use pool to save space)
+var INIT_CAPACITY = 1024
+var RED_SWEEP_QUEUE = pool.mallocInt32(INIT_CAPACITY)
+var RED_SWEEP_INDEX = pool.mallocInt32(INIT_CAPACITY)
+var BLUE_SWEEP_QUEUE = pool.mallocInt32(INIT_CAPACITY)
+var BLUE_SWEEP_INDEX = pool.mallocInt32(INIT_CAPACITY)
+var COMMON_SWEEP_QUEUE = pool.mallocInt32(INIT_CAPACITY)
+var COMMON_SWEEP_INDEX = pool.mallocInt32(INIT_CAPACITY)
+var SWEEP_EVENTS = pool.mallocDouble(INIT_CAPACITY * 8)
+
+//Reserves memory for the 1D sweep data structures
+function sqInit(count) {
+ var rcount = bits.nextPow2(count)
+ if(RED_SWEEP_QUEUE.length < rcount) {
+ pool.free(RED_SWEEP_QUEUE)
+ RED_SWEEP_QUEUE = pool.mallocInt32(rcount)
+ }
+ if(RED_SWEEP_INDEX.length < rcount) {
+ pool.free(RED_SWEEP_INDEX)
+ RED_SWEEP_INDEX = pool.mallocInt32(rcount)
+ }
+ if(BLUE_SWEEP_QUEUE.length < rcount) {
+ pool.free(BLUE_SWEEP_QUEUE)
+ BLUE_SWEEP_QUEUE = pool.mallocInt32(rcount)
+ }
+ if(BLUE_SWEEP_INDEX.length < rcount) {
+ pool.free(BLUE_SWEEP_INDEX)
+ BLUE_SWEEP_INDEX = pool.mallocInt32(rcount)
+ }
+ if(COMMON_SWEEP_QUEUE.length < rcount) {
+ pool.free(COMMON_SWEEP_QUEUE)
+ COMMON_SWEEP_QUEUE = pool.mallocInt32(rcount)
+ }
+ if(COMMON_SWEEP_INDEX.length < rcount) {
+ pool.free(COMMON_SWEEP_INDEX)
+ COMMON_SWEEP_INDEX = pool.mallocInt32(rcount)
+ }
+ var eventLength = 8 * rcount
+ if(SWEEP_EVENTS.length < eventLength) {
+ pool.free(SWEEP_EVENTS)
+ SWEEP_EVENTS = pool.mallocDouble(eventLength)
+ }
+}
+
+//Remove an item from the active queue in O(1)
+function sqPop(queue, index, count, item) {
+ var idx = index[item]
+ var top = queue[count-1]
+ queue[idx] = top
+ index[top] = idx
+}
+
+//Insert an item into the active queue in O(1)
+function sqPush(queue, index, count, item) {
+ queue[count] = item
+ index[item] = count
+}
+
+//Recursion base case: use 1D sweep algorithm
+function sweepBipartite(
+ d, visit,
+ redStart, redEnd, red, redIndex,
+ blueStart, blueEnd, blue, blueIndex) {
+
+ //store events as pairs [coordinate, idx]
+ //
+ // red create: -(idx+1)
+ // red destroy: idx
+ // blue create: -(idx+BLUE_FLAG)
+ // blue destroy: idx+BLUE_FLAG
+ //
+ var ptr = 0
+ var elemSize = 2*d
+ var istart = d-1
+ var iend = elemSize-1
+
+ for(var i=redStart; iright
+ var n = ptr >>> 1
+ isort(SWEEP_EVENTS, n)
+
+ var redActive = 0
+ var blueActive = 0
+ for(var i=0; i= BLUE_FLAG) {
+ //blue destroy event
+ e = (e-BLUE_FLAG)|0
+ sqPop(BLUE_SWEEP_QUEUE, BLUE_SWEEP_INDEX, blueActive--, e)
+ } else if(e >= 0) {
+ //red destroy event
+ sqPop(RED_SWEEP_QUEUE, RED_SWEEP_INDEX, redActive--, e)
+ } else if(e <= -BLUE_FLAG) {
+ //blue create event
+ e = (-e-BLUE_FLAG)|0
+ for(var j=0; jright
+ var n = ptr >>> 1
+ isort(SWEEP_EVENTS, n)
+
+ var redActive = 0
+ var blueActive = 0
+ var commonActive = 0
+ for(var i=0; i>1) === (SWEEP_EVENTS[2*i+3]>>1)) {
+ color = 2
+ i += 1
+ }
+
+ if(e < 0) {
+ //Create event
+ var id = -(e>>1) - 1
+
+ //Intersect with common
+ for(var j=0; j>1) - 1
+ if(color === 0) {
+ //Red
+ sqPop(RED_SWEEP_QUEUE, RED_SWEEP_INDEX, redActive--, id)
+ } else if(color === 1) {
+ //Blue
+ sqPop(BLUE_SWEEP_QUEUE, BLUE_SWEEP_INDEX, blueActive--, id)
+ } else if(color === 2) {
+ //Both
+ sqPop(COMMON_SWEEP_QUEUE, COMMON_SWEEP_INDEX, commonActive--, id)
+ }
+ }
+ }
+}
+
+//Sweep and prune/scanline algorithm:
+// Scan along axis, detect intersections
+// Brute force all boxes along axis
+function scanBipartite(
+ d, axis, visit, flip,
+ redStart, redEnd, red, redIndex,
+ blueStart, blueEnd, blue, blueIndex) {
+
+ var ptr = 0
+ var elemSize = 2*d
+ var istart = axis
+ var iend = axis+d
+
+ var redShift = 1
+ var blueShift = 1
+ if(flip) {
+ blueShift = BLUE_FLAG
+ } else {
+ redShift = BLUE_FLAG
+ }
+
+ for(var i=redStart; iright
+ var n = ptr >>> 1
+ isort(SWEEP_EVENTS, n)
+
+ var redActive = 0
+ for(var i=0; i= BLUE_FLAG) {
+ isRed = !flip
+ idx -= BLUE_FLAG
+ } else {
+ isRed = !!flip
+ idx -= 1
+ }
+ if(isRed) {
+ sqPush(RED_SWEEP_QUEUE, RED_SWEEP_INDEX, redActive++, idx)
+ } else {
+ var blueId = blueIndex[idx]
+ var bluePtr = elemSize * idx
+
+ var b0 = blue[bluePtr+axis+1]
+ var b1 = blue[bluePtr+axis+1+d]
+
+red_loop:
+ for(var j=0; jright
+ var n = ptr >>> 1
+ isort(SWEEP_EVENTS, n)
+
+ var redActive = 0
+ for(var i=0; i= BLUE_FLAG) {
+ RED_SWEEP_QUEUE[redActive++] = idx - BLUE_FLAG
+ } else {
+ idx -= 1
+ var blueId = blueIndex[idx]
+ var bluePtr = elemSize * idx
+
+ var b0 = blue[bluePtr+axis+1]
+ var b1 = blue[bluePtr+axis+1+d]
+
+red_loop:
+ for(var j=0; j=0; --j) {
+ if(RED_SWEEP_QUEUE[j] === idx) {
+ for(var k=j+1; k>> 31
+}
+
+module.exports.exponent = function(n) {
+ var b = module.exports.hi(n)
+ return ((b<<1) >>> 21) - 1023
+}
+
+module.exports.fraction = function(n) {
+ var lo = module.exports.lo(n)
+ var hi = module.exports.hi(n)
+ var b = hi & ((1<<20) - 1)
+ if(hi & 0x7ff00000) {
+ b += (1<<20)
+ }
+ return [lo, b]
+}
+
+module.exports.denormalized = function(n) {
+ var hi = module.exports.hi(n)
+ return !(hi & 0x7ff00000)
+}
+}).call(this,require("buffer").Buffer)
+},{"buffer":50}],271:[function(require,module,exports){
+"use strict"
+
+var doubleBits = require("double-bits")
+
+var SMALLEST_DENORM = Math.pow(2, -1074)
+var UINT_MAX = (-1)>>>0
+
+module.exports = nextafter
+
+function nextafter(x, y) {
+ if(isNaN(x) || isNaN(y)) {
+ return NaN
+ }
+ if(x === y) {
+ return x
+ }
+ if(x === 0) {
+ if(y < 0) {
+ return -SMALLEST_DENORM
+ } else {
+ return SMALLEST_DENORM
+ }
+ }
+ var hi = doubleBits.hi(x)
+ var lo = doubleBits.lo(x)
+ if((y > x) === (x > 0)) {
+ if(lo === UINT_MAX) {
+ hi += 1
+ lo = 0
+ } else {
+ lo += 1
+ }
+ } else {
+ if(lo === 0) {
+ lo = UINT_MAX
+ hi -= 1
+ } else {
+ lo -= 1
+ }
+ }
+ return doubleBits.pack(lo, hi)
+}
+},{"double-bits":270}],272:[function(require,module,exports){
+'use strict'
+
+var bnadd = require('big-rat/add')
+
+module.exports = add
+
+function add(a, b) {
+ var n = a.length
+ var r = new Array(n)
+ for(var i=0; i 0 && y0 > 0) || (x0 < 0 && y0 < 0)) {
+ return false
+ }
+
+ var x1 = orient(b0, a0, a1)
+ var y1 = orient(b1, a0, a1)
+ if((x1 > 0 && y1 > 0) || (x1 < 0 && y1 < 0)) {
+ return false
+ }
+
+ //Check for degenerate collinear case
+ if(x0 === 0 && y0 === 0 && x1 === 0 && y1 === 0) {
+ return checkCollinear(a0, a1, b0, b1)
+ }
+
+ return true
+}
+},{"robust-orientation":214}],277:[function(require,module,exports){
+arguments[4][193][0].apply(exports,arguments)
+},{"dup":193}],278:[function(require,module,exports){
+'use strict'
+
+module.exports = trimLeaves
+
+var e2a = require('edges-to-adjacency-list')
+
+function trimLeaves(edges, positions) {
+ var adj = e2a(edges, positions.length)
+ var live = new Array(positions.length)
+ var nbhd = new Array(positions.length)
+
+ var dead = []
+ for(var i=0; i 0) {
+ var v = dead.pop()
+ live[v] = false
+ var n = adj[v]
+ for(var i=0; i 0) {
+ nextCell = adj[i][b][0]
+ nextDir = i
+ break
+ }
+ }
+ nextVertex = nextCell[nextDir^1]
+
+ for(var dir=0; dir<2; ++dir) {
+ var nbhd = adj[dir][b]
+ for(var k=0; k