mapillary-js
Version:
WebGL JavaScript library for displaying street level imagery from mapillary.com
1,480 lines (1,208 loc) • 3.03 MB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Mapillary = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
'use strict';
var Queue = require('tinyqueue');
module.exports = polylabel;
module.exports.default = polylabel;
function polylabel(polygon, precision, debug) {
precision = precision || 1.0;
// find the bounding box of the outer ring
var minX, minY, maxX, maxY;
for (var i = 0; i < polygon[0].length; i++) {
var p = polygon[0][i];
if (!i || p[0] < minX) minX = p[0];
if (!i || p[1] < minY) minY = p[1];
if (!i || p[0] > maxX) maxX = p[0];
if (!i || p[1] > maxY) maxY = p[1];
}
var width = maxX - minX;
var height = maxY - minY;
var cellSize = Math.min(width, height);
var h = cellSize / 2;
// a priority queue of cells in order of their "potential" (max distance to polygon)
var cellQueue = new Queue(null, compareMax);
if (cellSize === 0) return [minX, minY];
// cover polygon with initial cells
for (var x = minX; x < maxX; x += cellSize) {
for (var y = minY; y < maxY; y += cellSize) {
cellQueue.push(new Cell(x + h, y + h, h, polygon));
}
}
// take centroid as the first best guess
var bestCell = getCentroidCell(polygon);
// special case for rectangular polygons
var bboxCell = new Cell(minX + width / 2, minY + height / 2, 0, polygon);
if (bboxCell.d > bestCell.d) bestCell = bboxCell;
var numProbes = cellQueue.length;
while (cellQueue.length) {
// pick the most promising cell from the queue
var cell = cellQueue.pop();
// update the best cell if we found a better one
if (cell.d > bestCell.d) {
bestCell = cell;
if (debug) console.log('found best %d after %d probes', Math.round(1e4 * cell.d) / 1e4, numProbes);
}
// do not drill down further if there's no chance of a better solution
if (cell.max - bestCell.d <= precision) continue;
// split the cell into four cells
h = cell.h / 2;
cellQueue.push(new Cell(cell.x - h, cell.y - h, h, polygon));
cellQueue.push(new Cell(cell.x + h, cell.y - h, h, polygon));
cellQueue.push(new Cell(cell.x - h, cell.y + h, h, polygon));
cellQueue.push(new Cell(cell.x + h, cell.y + h, h, polygon));
numProbes += 4;
}
if (debug) {
console.log('num probes: ' + numProbes);
console.log('best distance: ' + bestCell.d);
}
return [bestCell.x, bestCell.y];
}
function compareMax(a, b) {
return b.max - a.max;
}
function Cell(x, y, h, polygon) {
this.x = x; // cell center x
this.y = y; // cell center y
this.h = h; // half the cell size
this.d = pointToPolygonDist(x, y, polygon); // distance from cell center to polygon
this.max = this.d + this.h * Math.SQRT2; // max distance to polygon within a cell
}
// signed distance from point to polygon outline (negative if point is outside)
function pointToPolygonDist(x, y, polygon) {
var inside = false;
var minDistSq = Infinity;
for (var k = 0; k < polygon.length; k++) {
var ring = polygon[k];
for (var i = 0, len = ring.length, j = len - 1; i < len; j = i++) {
var a = ring[i];
var b = ring[j];
if ((a[1] > y !== b[1] > y) &&
(x < (b[0] - a[0]) * (y - a[1]) / (b[1] - a[1]) + a[0])) inside = !inside;
minDistSq = Math.min(minDistSq, getSegDistSq(x, y, a, b));
}
}
return (inside ? 1 : -1) * Math.sqrt(minDistSq);
}
// get polygon centroid
function getCentroidCell(polygon) {
var area = 0;
var x = 0;
var y = 0;
var points = polygon[0];
for (var i = 0, len = points.length, j = len - 1; i < len; j = i++) {
var a = points[i];
var b = points[j];
var f = a[0] * b[1] - b[0] * a[1];
x += (a[0] + b[0]) * f;
y += (a[1] + b[1]) * f;
area += f * 3;
}
if (area === 0) return new Cell(points[0][0], points[0][1], 0, polygon);
return new Cell(x / area, y / area, 0, polygon);
}
// get squared distance from a point to a segment
function getSegDistSq(px, py, a, b) {
var x = a[0];
var y = a[1];
var dx = b[0] - x;
var dy = b[1] - y;
if (dx !== 0 || dy !== 0) {
var t = ((px - x) * dx + (py - y) * dy) / (dx * dx + dy * dy);
if (t > 1) {
x = b[0];
y = b[1];
} else if (t > 0) {
x += dx * t;
y += dy * t;
}
}
dx = px - x;
dy = py - y;
return dx * dx + dy * dy;
}
},{"tinyqueue":243}],2:[function(require,module,exports){
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Ported from Webkit
* http://svn.webkit.org/repository/webkit/trunk/Source/WebCore/platform/graphics/UnitBezier.h
*/
module.exports = UnitBezier;
function UnitBezier(p1x, p1y, p2x, p2y) {
// Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1).
this.cx = 3.0 * p1x;
this.bx = 3.0 * (p2x - p1x) - this.cx;
this.ax = 1.0 - this.cx - this.bx;
this.cy = 3.0 * p1y;
this.by = 3.0 * (p2y - p1y) - this.cy;
this.ay = 1.0 - this.cy - this.by;
this.p1x = p1x;
this.p1y = p2y;
this.p2x = p2x;
this.p2y = p2y;
}
UnitBezier.prototype.sampleCurveX = function(t) {
// `ax t^3 + bx t^2 + cx t' expanded using Horner's rule.
return ((this.ax * t + this.bx) * t + this.cx) * t;
};
UnitBezier.prototype.sampleCurveY = function(t) {
return ((this.ay * t + this.by) * t + this.cy) * t;
};
UnitBezier.prototype.sampleCurveDerivativeX = function(t) {
return (3.0 * this.ax * t + 2.0 * this.bx) * t + this.cx;
};
UnitBezier.prototype.solveCurveX = function(x, epsilon) {
if (typeof epsilon === 'undefined') epsilon = 1e-6;
var t0, t1, t2, x2, i;
// First try a few iterations of Newton's method -- normally very fast.
for (t2 = x, i = 0; i < 8; i++) {
x2 = this.sampleCurveX(t2) - x;
if (Math.abs(x2) < epsilon) return t2;
var d2 = this.sampleCurveDerivativeX(t2);
if (Math.abs(d2) < 1e-6) break;
t2 = t2 - x2 / d2;
}
// Fall back to the bisection method for reliability.
t0 = 0.0;
t1 = 1.0;
t2 = x;
if (t2 < t0) return t0;
if (t2 > t1) return t1;
while (t0 < t1) {
x2 = this.sampleCurveX(t2);
if (Math.abs(x2 - x) < epsilon) return t2;
if (x > x2) {
t0 = t2;
} else {
t1 = t2;
}
t2 = (t1 - t0) * 0.5 + t0;
}
// Failure.
return t2;
};
UnitBezier.prototype.solve = function(x, epsilon) {
return this.sampleCurveY(this.solveCurveX(x, epsilon));
};
},{}],3:[function(require,module,exports){
},{}],4:[function(require,module,exports){
/*!
* Cross-Browser Split 1.1.1
* Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
* Available under the MIT License
* ECMAScript compliant, uniform cross-browser split method
*/
/**
* Splits a string into an array of strings using a regex or string separator. Matches of the
* separator are not included in the result array. However, if `separator` is a regex that contains
* capturing groups, backreferences are spliced into the result each time `separator` is matched.
* Fixes browser bugs compared to the native `String.prototype.split` and can be used reliably
* cross-browser.
* @param {String} str String to split.
* @param {RegExp|String} separator Regex or string to use for separating the string.
* @param {Number} [limit] Maximum number of items to include in the result array.
* @returns {Array} Array of substrings.
* @example
*
* // Basic use
* split('a b c d', ' ');
* // -> ['a', 'b', 'c', 'd']
*
* // With limit
* split('a b c d', ' ', 2);
* // -> ['a', 'b']
*
* // Backreferences in result array
* split('..word1 word2..', /([a-z]+)(\d+)/i);
* // -> ['..', 'word', '1', ' ', 'word', '2', '..']
*/
module.exports = (function split(undef) {
var nativeSplit = String.prototype.split,
compliantExecNpcg = /()??/.exec("")[1] === undef,
// NPCG: nonparticipating capturing group
self;
self = function(str, separator, limit) {
// If `separator` is not a regex, use `nativeSplit`
if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
return nativeSplit.call(str, separator, limit);
}
var output = [],
flags = (separator.ignoreCase ? "i" : "") + (separator.multiline ? "m" : "") + (separator.extended ? "x" : "") + // Proposed for ES6
(separator.sticky ? "y" : ""),
// Firefox 3+
lastLastIndex = 0,
// Make `global` and avoid `lastIndex` issues by working with a copy
separator = new RegExp(separator.source, flags + "g"),
separator2, match, lastIndex, lastLength;
str += ""; // Type-convert
if (!compliantExecNpcg) {
// Doesn't need flags gy, but they don't hurt
separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
}
/* Values for `limit`, per the spec:
* If undefined: 4294967295 // Math.pow(2, 32) - 1
* If 0, Infinity, or NaN: 0
* If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
* If negative number: 4294967296 - Math.floor(Math.abs(limit))
* If other: Type-convert, then use the above rules
*/
limit = limit === undef ? -1 >>> 0 : // Math.pow(2, 32) - 1
limit >>> 0; // ToUint32(limit)
while (match = separator.exec(str)) {
// `separator.lastIndex` is not reliable cross-browser
lastIndex = match.index + match[0].length;
if (lastIndex > lastLastIndex) {
output.push(str.slice(lastLastIndex, match.index));
// Fix browsers whose `exec` methods don't consistently return `undefined` for
// nonparticipating capturing groups
if (!compliantExecNpcg && match.length > 1) {
match[0].replace(separator2, function() {
for (var i = 1; i < arguments.length - 2; i++) {
if (arguments[i] === undef) {
match[i] = undef;
}
}
});
}
if (match.length > 1 && match.index < str.length) {
Array.prototype.push.apply(output, match.slice(1));
}
lastLength = match[0].length;
lastLastIndex = lastIndex;
if (output.length >= limit) {
break;
}
}
if (separator.lastIndex === match.index) {
separator.lastIndex++; // Avoid an infinite loop
}
}
if (lastLastIndex === str.length) {
if (lastLength || !separator.test("")) {
output.push("");
}
} else {
output.push(str.slice(lastLastIndex));
}
return output.length > limit ? output.slice(0, limit) : output;
};
return self;
})();
},{}],5:[function(require,module,exports){
'use strict';
module.exports = earcut;
module.exports.default = earcut;
function earcut(data, holeIndices, dim) {
dim = dim || 2;
var hasHoles = holeIndices && holeIndices.length,
outerLen = hasHoles ? holeIndices[0] * dim : data.length,
outerNode = linkedList(data, 0, outerLen, dim, true),
triangles = [];
if (!outerNode || outerNode.next === outerNode.prev) return triangles;
var minX, minY, maxX, maxY, x, y, invSize;
if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);
// if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
if (data.length > 80 * dim) {
minX = maxX = data[0];
minY = maxY = data[1];
for (var i = dim; i < outerLen; i += dim) {
x = data[i];
y = data[i + 1];
if (x < minX) minX = x;
if (y < minY) minY = y;
if (x > maxX) maxX = x;
if (y > maxY) maxY = y;
}
// minX, minY and invSize are later used to transform coords into integers for z-order calculation
invSize = Math.max(maxX - minX, maxY - minY);
invSize = invSize !== 0 ? 1 / invSize : 0;
}
earcutLinked(outerNode, triangles, dim, minX, minY, invSize);
return triangles;
}
// create a circular doubly linked list from polygon points in the specified winding order
function linkedList(data, start, end, dim, clockwise) {
var i, last;
if (clockwise === (signedArea(data, start, end, dim) > 0)) {
for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);
} else {
for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);
}
if (last && equals(last, last.next)) {
removeNode(last);
last = last.next;
}
return last;
}
// eliminate colinear or duplicate points
function filterPoints(start, end) {
if (!start) return start;
if (!end) end = start;
var p = start,
again;
do {
again = false;
if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
removeNode(p);
p = end = p.prev;
if (p === p.next) break;
again = true;
} else {
p = p.next;
}
} while (again || p !== end);
return end;
}
// main ear slicing loop which triangulates a polygon (given as a linked list)
function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
if (!ear) return;
// interlink polygon nodes in z-order
if (!pass && invSize) indexCurve(ear, minX, minY, invSize);
var stop = ear,
prev, next;
// iterate through ears, slicing them one by one
while (ear.prev !== ear.next) {
prev = ear.prev;
next = ear.next;
if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
// cut off the triangle
triangles.push(prev.i / dim);
triangles.push(ear.i / dim);
triangles.push(next.i / dim);
removeNode(ear);
// skipping the next vertex leads to less sliver triangles
ear = next.next;
stop = next.next;
continue;
}
ear = next;
// if we looped through the whole remaining polygon and can't find any more ears
if (ear === stop) {
// try filtering points and slicing again
if (!pass) {
earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);
// if this didn't work, try curing all small self-intersections locally
} else if (pass === 1) {
ear = cureLocalIntersections(filterPoints(ear), triangles, dim);
earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);
// as a last resort, try splitting the remaining polygon into two
} else if (pass === 2) {
splitEarcut(ear, triangles, dim, minX, minY, invSize);
}
break;
}
}
}
// check whether a polygon node forms a valid ear with adjacent nodes
function isEar(ear) {
var a = ear.prev,
b = ear,
c = ear.next;
if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
// now make sure we don't have other points inside the potential ear
var p = ear.next.next;
while (p !== ear.prev) {
if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
area(p.prev, p, p.next) >= 0) return false;
p = p.next;
}
return true;
}
function isEarHashed(ear, minX, minY, invSize) {
var a = ear.prev,
b = ear,
c = ear.next;
if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
// triangle bbox; min & max are calculated like this for speed
var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),
minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),
maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),
maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);
// z-order range for the current triangle bbox;
var minZ = zOrder(minTX, minTY, minX, minY, invSize),
maxZ = zOrder(maxTX, maxTY, minX, minY, invSize);
var p = ear.prevZ,
n = ear.nextZ;
// look for points inside the triangle in both directions
while (p && p.z >= minZ && n && n.z <= maxZ) {
if (p !== ear.prev && p !== ear.next &&
pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
area(p.prev, p, p.next) >= 0) return false;
p = p.prevZ;
if (n !== ear.prev && n !== ear.next &&
pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) &&
area(n.prev, n, n.next) >= 0) return false;
n = n.nextZ;
}
// look for remaining points in decreasing z-order
while (p && p.z >= minZ) {
if (p !== ear.prev && p !== ear.next &&
pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
area(p.prev, p, p.next) >= 0) return false;
p = p.prevZ;
}
// look for remaining points in increasing z-order
while (n && n.z <= maxZ) {
if (n !== ear.prev && n !== ear.next &&
pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) &&
area(n.prev, n, n.next) >= 0) return false;
n = n.nextZ;
}
return true;
}
// go through all polygon nodes and cure small local self-intersections
function cureLocalIntersections(start, triangles, dim) {
var p = start;
do {
var a = p.prev,
b = p.next.next;
if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
triangles.push(a.i / dim);
triangles.push(p.i / dim);
triangles.push(b.i / dim);
// remove two nodes involved
removeNode(p);
removeNode(p.next);
p = start = b;
}
p = p.next;
} while (p !== start);
return filterPoints(p);
}
// try splitting polygon into two and triangulate them independently
function splitEarcut(start, triangles, dim, minX, minY, invSize) {
// look for a valid diagonal that divides the polygon into two
var a = start;
do {
var b = a.next.next;
while (b !== a.prev) {
if (a.i !== b.i && isValidDiagonal(a, b)) {
// split the polygon in two by the diagonal
var c = splitPolygon(a, b);
// filter colinear points around the cuts
a = filterPoints(a, a.next);
c = filterPoints(c, c.next);
// run earcut on each half
earcutLinked(a, triangles, dim, minX, minY, invSize);
earcutLinked(c, triangles, dim, minX, minY, invSize);
return;
}
b = b.next;
}
a = a.next;
} while (a !== start);
}
// link every hole into the outer loop, producing a single-ring polygon without holes
function eliminateHoles(data, holeIndices, outerNode, dim) {
var queue = [],
i, len, start, end, list;
for (i = 0, len = holeIndices.length; i < len; i++) {
start = holeIndices[i] * dim;
end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
list = linkedList(data, start, end, dim, false);
if (list === list.next) list.steiner = true;
queue.push(getLeftmost(list));
}
queue.sort(compareX);
// process holes from left to right
for (i = 0; i < queue.length; i++) {
eliminateHole(queue[i], outerNode);
outerNode = filterPoints(outerNode, outerNode.next);
}
return outerNode;
}
function compareX(a, b) {
return a.x - b.x;
}
// find a bridge between vertices that connects hole with an outer ring and and link it
function eliminateHole(hole, outerNode) {
outerNode = findHoleBridge(hole, outerNode);
if (outerNode) {
var b = splitPolygon(outerNode, hole);
// filter collinear points around the cuts
filterPoints(outerNode, outerNode.next);
filterPoints(b, b.next);
}
}
// David Eberly's algorithm for finding a bridge between hole and outer polygon
function findHoleBridge(hole, outerNode) {
var p = outerNode,
hx = hole.x,
hy = hole.y,
qx = -Infinity,
m;
// find a segment intersected by a ray from the hole's leftmost point to the left;
// segment's endpoint with lesser x will be potential connection point
do {
if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
if (x <= hx && x > qx) {
qx = x;
if (x === hx) {
if (hy === p.y) return p;
if (hy === p.next.y) return p.next;
}
m = p.x < p.next.x ? p : p.next;
}
}
p = p.next;
} while (p !== outerNode);
if (!m) return null;
if (hx === qx) return m; // hole touches outer segment; pick leftmost endpoint
// look for points inside the triangle of hole point, segment intersection and endpoint;
// if there are no points found, we have a valid connection;
// otherwise choose the point of the minimum angle with the ray as connection point
var stop = m,
mx = m.x,
my = m.y,
tanMin = Infinity,
tan;
p = m;
do {
if (hx >= p.x && p.x >= mx && hx !== p.x &&
pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
tan = Math.abs(hy - p.y) / (hx - p.x); // tangential
if (locallyInside(p, hole) &&
(tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) {
m = p;
tanMin = tan;
}
}
p = p.next;
} while (p !== stop);
return m;
}
// whether sector in vertex m contains sector in vertex p in the same coordinates
function sectorContainsSector(m, p) {
return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
}
// interlink polygon nodes in z-order
function indexCurve(start, minX, minY, invSize) {
var p = start;
do {
if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize);
p.prevZ = p.prev;
p.nextZ = p.next;
p = p.next;
} while (p !== start);
p.prevZ.nextZ = null;
p.prevZ = null;
sortLinked(p);
}
// Simon Tatham's linked list merge sort algorithm
// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
function sortLinked(list) {
var i, p, q, e, tail, numMerges, pSize, qSize,
inSize = 1;
do {
p = list;
list = null;
tail = null;
numMerges = 0;
while (p) {
numMerges++;
q = p;
pSize = 0;
for (i = 0; i < inSize; i++) {
pSize++;
q = q.nextZ;
if (!q) break;
}
qSize = inSize;
while (pSize > 0 || (qSize > 0 && q)) {
if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
e = p;
p = p.nextZ;
pSize--;
} else {
e = q;
q = q.nextZ;
qSize--;
}
if (tail) tail.nextZ = e;
else list = e;
e.prevZ = tail;
tail = e;
}
p = q;
}
tail.nextZ = null;
inSize *= 2;
} while (numMerges > 1);
return list;
}
// z-order of a point given coords and inverse of the longer side of data bbox
function zOrder(x, y, minX, minY, invSize) {
// coords are transformed into non-negative 15-bit integer range
x = 32767 * (x - minX) * invSize;
y = 32767 * (y - minY) * invSize;
x = (x | (x << 8)) & 0x00FF00FF;
x = (x | (x << 4)) & 0x0F0F0F0F;
x = (x | (x << 2)) & 0x33333333;
x = (x | (x << 1)) & 0x55555555;
y = (y | (y << 8)) & 0x00FF00FF;
y = (y | (y << 4)) & 0x0F0F0F0F;
y = (y | (y << 2)) & 0x33333333;
y = (y | (y << 1)) & 0x55555555;
return x | (y << 1);
}
// find the leftmost node of a polygon ring
function getLeftmost(start) {
var p = start,
leftmost = start;
do {
if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) leftmost = p;
p = p.next;
} while (p !== start);
return leftmost;
}
// check if a point lies within a convex triangle
function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&
(ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&
(bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;
}
// check if a diagonal between two polygon nodes is valid (lies in polygon interior)
function isValidDiagonal(a, b) {
return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges
(locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible
(area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors
equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case
}
// signed area of a triangle
function area(p, q, r) {
return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
}
// check if two points are equal
function equals(p1, p2) {
return p1.x === p2.x && p1.y === p2.y;
}
// check if two segments intersect
function intersects(p1, q1, p2, q2) {
var o1 = sign(area(p1, q1, p2));
var o2 = sign(area(p1, q1, q2));
var o3 = sign(area(p2, q2, p1));
var o4 = sign(area(p2, q2, q1));
if (o1 !== o2 && o3 !== o4) return true; // general case
if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1
if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1
if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2
if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2
return false;
}
// for collinear points p, q, r, check if point q lies on segment pr
function onSegment(p, q, r) {
return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
}
function sign(num) {
return num > 0 ? 1 : num < 0 ? -1 : 0;
}
// check if a polygon diagonal intersects any polygon segments
function intersectsPolygon(a, b) {
var p = a;
do {
if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&
intersects(p, p.next, a, b)) return true;
p = p.next;
} while (p !== a);
return false;
}
// check if a polygon diagonal is locally inside the polygon
function locallyInside(a, b) {
return area(a.prev, a, a.next) < 0 ?
area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :
area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
}
// check if the middle point of a polygon diagonal is inside the polygon
function middleInside(a, b) {
var p = a,
inside = false,
px = (a.x + b.x) / 2,
py = (a.y + b.y) / 2;
do {
if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y &&
(px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))
inside = !inside;
p = p.next;
} while (p !== a);
return inside;
}
// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
// if one belongs to the outer ring and another to a hole, it merges it into a single ring
function splitPolygon(a, b) {
var a2 = new Node(a.i, a.x, a.y),
b2 = new Node(b.i, b.x, b.y),
an = a.next,
bp = b.prev;
a.next = b;
b.prev = a;
a2.next = an;
an.prev = a2;
b2.next = a2;
a2.prev = b2;
bp.next = b2;
b2.prev = bp;
return b2;
}
// create a node and optionally link it with previous one (in a circular doubly linked list)
function insertNode(i, x, y, last) {
var p = new Node(i, x, y);
if (!last) {
p.prev = p;
p.next = p;
} else {
p.next = last.next;
p.prev = last;
last.next.prev = p;
last.next = p;
}
return p;
}
function removeNode(p) {
p.next.prev = p.prev;
p.prev.next = p.next;
if (p.prevZ) p.prevZ.nextZ = p.nextZ;
if (p.nextZ) p.nextZ.prevZ = p.prevZ;
}
function Node(i, x, y) {
// vertex index in coordinates array
this.i = i;
// vertex coordinates
this.x = x;
this.y = y;
// previous and next vertex nodes in a polygon ring
this.prev = null;
this.next = null;
// z-order curve value
this.z = null;
// previous and next nodes in z-order
this.prevZ = null;
this.nextZ = null;
// indicates whether this is a steiner point
this.steiner = false;
}
// return a percentage difference between the polygon area and its triangulation area;
// used to verify correctness of triangulation
earcut.deviation = function (data, holeIndices, dim, triangles) {
var hasHoles = holeIndices && holeIndices.length;
var outerLen = hasHoles ? holeIndices[0] * dim : data.length;
var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));
if (hasHoles) {
for (var i = 0, len = holeIndices.length; i < len; i++) {
var start = holeIndices[i] * dim;
var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
polygonArea -= Math.abs(signedArea(data, start, end, dim));
}
}
var trianglesArea = 0;
for (i = 0; i < triangles.length; i += 3) {
var a = triangles[i] * dim;
var b = triangles[i + 1] * dim;
var c = triangles[i + 2] * dim;
trianglesArea += Math.abs(
(data[a] - data[c]) * (data[b + 1] - data[a + 1]) -
(data[a] - data[b]) * (data[c + 1] - data[a + 1]));
}
return polygonArea === 0 && trianglesArea === 0 ? 0 :
Math.abs((trianglesArea - polygonArea) / polygonArea);
};
function signedArea(data, start, end, dim) {
var sum = 0;
for (var i = start, j = end - dim; i < end; i += dim) {
sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
j = i;
}
return sum;
}
// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts
earcut.flatten = function (data) {
var dim = data[0][0].length,
result = {vertices: [], holes: [], dimensions: dim},
holeIndex = 0;
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data[i].length; j++) {
for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);
}
if (i > 0) {
holeIndex += data[i - 1].length;
result.holes.push(holeIndex);
}
}
return result;
};
},{}],6:[function(require,module,exports){
'use strict';
var OneVersionConstraint = require('individual/one-version');
var MY_VERSION = '7';
OneVersionConstraint('ev-store', MY_VERSION);
var hashKey = '__EV_STORE_KEY@' + MY_VERSION;
module.exports = EvStore;
function EvStore(elem) {
var hash = elem[hashKey];
if (!hash) {
hash = elem[hashKey] = {};
}
return hash;
}
},{"individual/one-version":16}],7:[function(require,module,exports){
'use strict';
var request = require('./request');
var buildQueryObject = require('./buildQueryObject');
var isArray = Array.isArray;
function simpleExtend(obj, obj2) {
var prop;
for (prop in obj2) {
obj[prop] = obj2[prop];
}
return obj;
}
function XMLHttpSource(jsongUrl, config) {
this._jsongUrl = jsongUrl;
if (typeof config === 'number') {
var newConfig = {
timeout: config
};
config = newConfig;
}
this._config = simpleExtend({
timeout: 15000,
headers: {}
}, config || {});
}
XMLHttpSource.prototype = {
// because javascript
constructor: XMLHttpSource,
/**
* buildQueryObject helper
*/
buildQueryObject: buildQueryObject,
/**
* @inheritDoc DataSource#get
*/
get: function httpSourceGet(pathSet) {
var method = 'GET';
var queryObject = this.buildQueryObject(this._jsongUrl, method, {
paths: pathSet,
method: 'get'
});
var config = simpleExtend(queryObject, this._config);
// pass context for onBeforeRequest callback
var context = this;
return request(method, config, context);
},
/**
* @inheritDoc DataSource#set
*/
set: function httpSourceSet(jsongEnv) {
var method = 'POST';
var queryObject = this.buildQueryObject(this._jsongUrl, method, {
jsonGraph: jsongEnv,
method: 'set'
});
var config = simpleExtend(queryObject, this._config);
config.headers["Content-Type"] = "application/x-www-form-urlencoded";
// pass context for onBeforeRequest callback
var context = this;
return request(method, config, context);
},
/**
* @inheritDoc DataSource#call
*/
call: function httpSourceCall(callPath, args, pathSuffix, paths) {
// arguments defaults
args = args || [];
pathSuffix = pathSuffix || [];
paths = paths || [];
var method = 'POST';
var queryData = [];
queryData.push('method=call');
queryData.push('callPath=' + encodeURIComponent(JSON.stringify(callPath)));
queryData.push('arguments=' + encodeURIComponent(JSON.stringify(args)));
queryData.push('pathSuffixes=' + encodeURIComponent(JSON.stringify(pathSuffix)));
queryData.push('paths=' + encodeURIComponent(JSON.stringify(paths)));
var queryObject = this.buildQueryObject(this._jsongUrl, method, queryData.join('&'));
var config = simpleExtend(queryObject, this._config);
config.headers["Content-Type"] = "application/x-www-form-urlencoded";
// pass context for onBeforeRequest callback
var context = this;
return request(method, config, context);
}
};
// ES6 modules
XMLHttpSource.XMLHttpSource = XMLHttpSource;
XMLHttpSource['default'] = XMLHttpSource;
// commonjs
module.exports = XMLHttpSource;
},{"./buildQueryObject":8,"./request":11}],8:[function(require,module,exports){
'use strict';
module.exports = function buildQueryObject(url, method, queryData) {
var qData = [];
var keys;
var data = {url: url};
var isQueryParamUrl = url.indexOf('?') !== -1;
var startUrl = (isQueryParamUrl) ? '&' : '?';
if (typeof queryData === 'string') {
qData.push(queryData);
} else {
keys = Object.keys(queryData);
keys.forEach(function (k) {
var value = (typeof queryData[k] === 'object') ? JSON.stringify(queryData[k]) : queryData[k];
qData.push(k + '=' + encodeURIComponent(value));
});
}
if (method === 'GET') {
data.url += startUrl + qData.join('&');
} else {
data.data = qData.join('&');
}
return data;
};
},{}],9:[function(require,module,exports){
(function (global){
'use strict';
// Get CORS support even for older IE
module.exports = function getCORSRequest() {
var xhr = new global.XMLHttpRequest();
if ('withCredentials' in xhr) {
return xhr;
} else if (!!global.XDomainRequest) {
return new XDomainRequest();
} else {
throw new Error('CORS is not supported by your browser');
}
};
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],10:[function(require,module,exports){
(function (global){
'use strict';
module.exports = function getXMLHttpRequest() {
var progId,
progIds,
i;
if (global.XMLHttpRequest) {
return new global.XMLHttpRequest();
} else {
try {
progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
for (i = 0; i < 3; i++) {
try {
progId = progIds[i];
if (new global.ActiveXObject(progId)) {
break;
}
} catch(e) { }
}
return new global.ActiveXObject(progId);
} catch (e) {
throw new Error('XMLHttpRequest is not supported by your browser');
}
}
};
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],11:[function(require,module,exports){
'use strict';
var getXMLHttpRequest = require('./getXMLHttpRequest');
var getCORSRequest = require('./getCORSRequest');
var hasOwnProp = Object.prototype.hasOwnProperty;
var noop = function() {};
function Observable() {}
Observable.create = function(subscribe) {
var o = new Observable();
o.subscribe = function(onNext, onError, onCompleted) {
var observer;
var disposable;
if (typeof onNext === 'function') {
observer = {
onNext: onNext,
onError: (onError || noop),
onCompleted: (onCompleted || noop)
};
} else {
observer = onNext;
}
disposable = subscribe(observer);
if (typeof disposable === 'function') {
return {
dispose: disposable
};
} else {
return disposable;
}
};
return o;
};
function request(method, options, context) {
return Observable.create(function requestObserver(observer) {
var config = {
method: method || 'GET',
crossDomain: false,
async: true,
headers: {},
responseType: 'json'
};
var xhr,
isDone,
headers,
header,
prop;
for (prop in options) {
if (hasOwnProp.call(options, prop)) {
config[prop] = options[prop];
}
}
// Add request with Headers
if (!config.crossDomain && !config.headers['X-Requested-With']) {
config.headers['X-Requested-With'] = 'XMLHttpRequest';
}
// allow the user to mutate the config open
if (context.onBeforeRequest != null) {
context.onBeforeRequest(config);
}
// create xhr
try {
xhr = config.crossDomain ? getCORSRequest() : getXMLHttpRequest();
} catch (err) {
observer.onError(err);
}
try {
// Takes the url and opens the connection
if (config.user) {
xhr.open(config.method, config.url, config.async, config.user, config.password);
} else {
xhr.open(config.method, config.url, config.async);
}
// Sets timeout information
xhr.timeout = config.timeout;
// Anything but explicit false results in true.
xhr.withCredentials = config.withCredentials !== false;
// Fills the request headers
headers = config.headers;
for (header in headers) {
if (hasOwnProp.call(headers, header)) {
xhr.setRequestHeader(header, headers[header]);
}
}
if (config.responseType) {
try {
xhr.responseType = config.responseType;
} catch (e) {
// WebKit added support for the json responseType value on 09/03/2013
// https://bugs.webkit.org/show_bug.cgi?id=73648. Versions of Safari prior to 7 are
// known to throw when setting the value "json" as the response type. Other older
// browsers implementing the responseType
//
// The json response type can be ignored if not supported, because JSON payloads are
// parsed on the client-side regardless.
if (config.responseType !== 'json') {
throw e;
}
}
}
xhr.onreadystatechange = function onreadystatechange(e) {
// Complete
if (xhr.readyState === 4) {
if (!isDone) {
isDone = true;
onXhrLoad(observer, xhr, e);
}
}
};
// Timeout
xhr.ontimeout = function ontimeout(e) {
if (!isDone) {
isDone = true;
onXhrError(observer, xhr, 'timeout error', e);
}
};
// Send Request
xhr.send(config.data);
} catch (e) {
observer.onError(e);
}
// Dispose
return function dispose() {
// Doesn't work in IE9
if (!isDone && xhr.readyState !== 4) {
isDone = true;
xhr.abort();
}
};//Dispose
});
}
/*
* General handling of ultimate failure (after appropriate retries)
*/
function _handleXhrError(observer, textStatus, errorThrown) {
// IE9: cross-domain request may be considered errors
if (!errorThrown) {
errorThrown = new Error(textStatus);
}
observer.onError(errorThrown);
}
function onXhrLoad(observer, xhr, e) {
var responseData,
responseObject,
responseType;
// If there's no observer, the request has been (or is being) cancelled.
if (xhr && observer) {
responseType = xhr.responseType;
// responseText is the old-school way of retrieving response (supported by IE8 & 9)
// response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
responseData = ('response' in xhr) ? xhr.response : xhr.responseText;
// normalize IE9 bug (http://bugs.jquery.com/ticket/1450)
var status = (xhr.status === 1223) ? 204 : xhr.status;
if (status >= 200 && status <= 399) {
try {
if (responseType !== 'json') {
responseData = JSON.parse(responseData || '');
}
if (typeof responseData === 'string') {
responseData = JSON.parse(responseData || '');
}
} catch (e) {
_handleXhrError(observer, 'invalid json', e);
}
observer.onNext(responseData);
observer.onCompleted();
return;
} else if (status === 401 || status === 403 || status === 407) {
return _handleXhrError(observer, responseData);
} else if (status === 410) {
// TODO: Retry ?
return _handleXhrError(observer, responseData);
} else if (status === 408 || status === 504) {
// TODO: Retry ?
return _handleXhrError(observer, responseData);
} else {
return _handleXhrError(observer, responseData || ('Response code ' + status));
}//if
}//if
}//onXhrLoad
function onXhrError(observer, xhr, status, e) {
_handleXhrError(observer, status || xhr.statusText || 'request error', e);
}
module.exports = request;
},{"./getCORSRequest":9,"./getXMLHttpRequest":10}],12:[function(require,module,exports){
(function (global){
!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.falcor=t()}}(function(){var t;return function e(t,n,r){function o(s,u){if(!n[s]){if(!t[s]){var a="function"==typeof require&&require;if(!u&&a)return a(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var p=n[s]={exports:{}};t[s][0].call(p.exports,function(e){var n=t[s][1][e];return o(n?n:e)},p,p.exports,e,t,n,r)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;s<r.length;s++)o(r[s]);return o}({1:[function(t,e,n){var r=t(32),o=t(130);r.atom=o.atom,r.ref=o.ref,r.error=o.error,r.pathValue=o.pathValue,r.HttpDataSource=t(125),e.exports=r},{125:125,130:130,32:32}],2:[function(t,e,n){function r(t){var e=t||{};this._root=e._root||new o(e),this._path=e.path||e._path||[],this._scheduler=e.scheduler||e._scheduler||new l,this._source=e.source||e._source,this._request=e.request||e._request||new s(this,this._scheduler),this._ID=N++,"number"==typeof e.maxSize?this._maxSize=e.maxSize:this._maxSize=e._maxSize||r.prototype._maxSize,"number"==typeof e.collectRatio?this._collectRatio=e.collectRatio:this._collectRatio=e._collectRatio||r.prototype._collectRatio,(e.boxed||e.hasOwnProperty("_boxed"))&&(this._boxed=e.boxed||e._boxed),(e.materialized||e.hasOwnProperty("_materialized"))&&(this._materialized=e.materialized||e._materialized),"boolean"==typeof e.treatErrorsAsValues?this._treatErrorsAsValues=e.treatErrorsAsValues:e.hasOwnProperty("_treatErrorsAsValues")&&(this._treatErrorsAsValues=e._treatErrorsAsValues),e.cache&&this.setCache(e.cache)}var o=t(4),i=t(3),s=t(55),u=t(64),a=t(65),c=t(61),p=t(63),h=t(73),f=t(75),l=t(74),d=t(81),v=t(84),y=t(49),b=t(134),m=t(88),g=t(100),w=t(96),x=t(102),_=t(98),S=t(99),E=t(77),C=t(76),A=t(130),N=0,k=t(116),O=function(){},P=t(14),j=t(19),D={pathValue:!0,pathSyntax:!0,json:!0,jsonGraph:!0},q=t(72);e.exports=r,r.ref=A.ref,r.atom=A.atom,r.error=A.error,r.pathValue=A.pathValue,r.prototype.constructor=r,r.prototype._materialized=!1,r.prototype._boxed=!1,r.prototype._progressive=!1,r.prototype._treatErrorsAsValues=!1,r.prototype._maxSize=Math.pow(2,53)-1,r.prototype._collectRatio=.75,r.prototype.get=t(71),r.prototype._getWithPaths=t(70),r.prototype.set=function(){var t=k(arguments,D,"set");return t!==!0?new u(function(e){e.onError(t)}):this._set.apply(this,arguments)},r.prototype.preload=function(){var t=k(arguments,q,"preload");if(t!==!0)return new u(function(e){e.onError(t)});var e=Array.prototype.slice.call(arguments),n=this;return new u(function(t){return n.get.apply(n,e).subscribe(function(){},function(e){t.onError(e)},function(){t.onCompleted()})})},r.prototype._set=function(){var t,e=-1,n=arguments.length,r=arguments[n-1];for(w(r)?n-=1:r=void 0,t=new Array(n);++e<n;)t[e]=arguments[e];return a.create(this,t,r)},r.prototype.call=function(){var t,e=-1,n=arguments.length;for(t=new Array(n);++e<n;){var r=arguments[e];t[e]=r;var o=typeof r;if(e>1&&!Array.isArray(r)||0===e&&!Array.isArray(r)&&"string"!==o||1===e&&!Array.isArray(r)&&!x(r))return new u(function(t){t.onError(new Error("Invalid argument"))})}return c.create(this,t)},r.prototype.invalidate=function(){var t,e=-1,n=arguments.length,r=arguments[n-1];for(t=new Array(n);++e<n;)if(t[e]=b.fromPath(arguments[e]),"object"!=typeof t[e])throw new Error("Invalid argument");p.create(this,t,r).subscribe(O,function(t){throw t})},r.prototype.deref=t(5),r.prototype.getValue=t(16),r.prototype.setValue=t(79),r.prototype._getValueSync=t(24),r.prototype._setValueSync=t(80),r.prototype._derefSync=t(6),r.prototype.setCache=function(t){var e=this._root.cache;if(t!==e){var n=this._root,r=this._path;this._path=[],this._root.cache={},"undefined"!=typeof e&&y(n,n.expired,m(e),0),S(t)?C(this,[t]):_(t)?E(this,[t]):g(t)&&E(this,[{json:t}]),this._path=r}else"undefined"==typeof e&&(this._root.cache={});return this},r.prototype.getCache=function(){var t=v(arguments);if(0===t.length)return P(this._root.cache);var e=[{}],n=this._path;return j.getWithPathsAsJSONGraph(this,t,e),this._path=n,e[0].jsonGraph},r.prototype.getVersion=function(t){var e=t&&b.fromPath(t)||[];if(Array.isArray(e)===!1)throw new Error("Model#getVersion must be called with an Array path.");return this._path.length&&(e=this._path.concat(e)),this._getVersion(this,e)},r.prototype._syncCheck=function(t){if(Boolean(this._source)&&this._root.syncRefCount<=0&&this._root.unsafeMode===!1)throw new Error("Model#"+t+" may only be called within the context of a request selector.");return!0},r.prototype._clone=function(t){var e=new r(this);for(var n in t){var o=t[n];"delete"===o?delete e[n]:e[n]=o}return e.setCache=void 0,e},r.prototype.batch=function(t){var e=t;"number"==typeof e?e=new f(Math.round(Math.abs(e))):e&&e.schedule||(e=new h);var n=this._clone();return n._request=new s(n,e),n},r.prototype.unbatch=function(){var t=this._clone();return t._request=new s(t,new l),t},r.prototype.treatErrorsAsValues=function(){return this._clone({_treatErrorsAsValues:!0})},r.prototype.asDataSource=function(){return new i(this)},r.prototype._materialize=function(){return this._clone({_mate