mapbox-gl
Version:
A WebGL interactive maps library
1,634 lines (1,614 loc) • 1.44 MB
JavaScript
/* Mapbox GL JS is licensed under the 3-Clause BSD License. Full text of license: https://github.com/mapbox/mapbox-gl-js/blob/v1.2.0/LICENSE.txt */
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.mapboxgl = factory());
}(this, function () { 'use strict';
/* eslint-disable */
var shared, worker, mapboxgl;
// define gets called three times: one for each chunk. we rely on the order
// they're imported to know which is which
function define(_, chunk) {
if (!shared) {
shared = chunk;
} else if (!worker) {
worker = chunk;
} else {
var workerBundleString = 'var sharedChunk = {}; (' + shared + ')(sharedChunk); (' + worker + ')(sharedChunk);'
var sharedChunk = {};
shared(sharedChunk);
mapboxgl = chunk(sharedChunk);
mapboxgl.workerUrl = window.URL.createObjectURL(new Blob([workerBundleString], { type: 'text/javascript' }));
}
}
define(['exports'], function (exports) { 'use strict';
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var version = "1.2.0";
var unitbezier = UnitBezier;
function UnitBezier(p1x, p1y, p2x, p2y) {
this.cx = 3 * p1x;
this.bx = 3 * (p2x - p1x) - this.cx;
this.ax = 1 - this.cx - this.bx;
this.cy = 3 * p1y;
this.by = 3 * (p2y - p1y) - this.cy;
this.ay = 1 - this.cy - this.by;
this.p1x = p1x;
this.p1y = p2y;
this.p2x = p2x;
this.p2y = p2y;
}
UnitBezier.prototype.sampleCurveX = function (t) {
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 * this.ax * t + 2 * this.bx) * t + this.cx;
};
UnitBezier.prototype.solveCurveX = function (x, epsilon) {
if (typeof epsilon === 'undefined') {
epsilon = 0.000001;
}
var t0, t1, t2, x2, i;
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) < 0.000001) {
break;
}
t2 = t2 - x2 / d2;
}
t0 = 0;
t1 = 1;
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;
}
return t2;
};
UnitBezier.prototype.solve = function (x, epsilon) {
return this.sampleCurveY(this.solveCurveX(x, epsilon));
};
var pointGeometry = Point;
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype = {
clone: function () {
return new Point(this.x, this.y);
},
add: function (p) {
return this.clone()._add(p);
},
sub: function (p) {
return this.clone()._sub(p);
},
multByPoint: function (p) {
return this.clone()._multByPoint(p);
},
divByPoint: function (p) {
return this.clone()._divByPoint(p);
},
mult: function (k) {
return this.clone()._mult(k);
},
div: function (k) {
return this.clone()._div(k);
},
rotate: function (a) {
return this.clone()._rotate(a);
},
rotateAround: function (a, p) {
return this.clone()._rotateAround(a, p);
},
matMult: function (m) {
return this.clone()._matMult(m);
},
unit: function () {
return this.clone()._unit();
},
perp: function () {
return this.clone()._perp();
},
round: function () {
return this.clone()._round();
},
mag: function () {
return Math.sqrt(this.x * this.x + this.y * this.y);
},
equals: function (other) {
return this.x === other.x && this.y === other.y;
},
dist: function (p) {
return Math.sqrt(this.distSqr(p));
},
distSqr: function (p) {
var dx = p.x - this.x, dy = p.y - this.y;
return dx * dx + dy * dy;
},
angle: function () {
return Math.atan2(this.y, this.x);
},
angleTo: function (b) {
return Math.atan2(this.y - b.y, this.x - b.x);
},
angleWith: function (b) {
return this.angleWithSep(b.x, b.y);
},
angleWithSep: function (x, y) {
return Math.atan2(this.x * y - this.y * x, this.x * x + this.y * y);
},
_matMult: function (m) {
var x = m[0] * this.x + m[1] * this.y, y = m[2] * this.x + m[3] * this.y;
this.x = x;
this.y = y;
return this;
},
_add: function (p) {
this.x += p.x;
this.y += p.y;
return this;
},
_sub: function (p) {
this.x -= p.x;
this.y -= p.y;
return this;
},
_mult: function (k) {
this.x *= k;
this.y *= k;
return this;
},
_div: function (k) {
this.x /= k;
this.y /= k;
return this;
},
_multByPoint: function (p) {
this.x *= p.x;
this.y *= p.y;
return this;
},
_divByPoint: function (p) {
this.x /= p.x;
this.y /= p.y;
return this;
},
_unit: function () {
this._div(this.mag());
return this;
},
_perp: function () {
var y = this.y;
this.y = this.x;
this.x = -y;
return this;
},
_rotate: function (angle) {
var cos = Math.cos(angle), sin = Math.sin(angle), x = cos * this.x - sin * this.y, y = sin * this.x + cos * this.y;
this.x = x;
this.y = y;
return this;
},
_rotateAround: function (angle, p) {
var cos = Math.cos(angle), sin = Math.sin(angle), x = p.x + cos * (this.x - p.x) - sin * (this.y - p.y), y = p.y + sin * (this.x - p.x) + cos * (this.y - p.y);
this.x = x;
this.y = y;
return this;
},
_round: function () {
this.x = Math.round(this.x);
this.y = Math.round(this.y);
return this;
}
};
Point.convert = function (a) {
if (a instanceof Point) {
return a;
}
if (Array.isArray(a)) {
return new Point(a[0], a[1]);
}
return a;
};
function deepEqual(a, b) {
if (Array.isArray(a)) {
if (!Array.isArray(b) || a.length !== b.length) {
return false;
}
for (var i = 0; i < a.length; i++) {
if (!deepEqual(a[i], b[i])) {
return false;
}
}
return true;
}
if (typeof a === 'object' && a !== null && b !== null) {
if (!(typeof b === 'object')) {
return false;
}
var keys = Object.keys(a);
if (keys.length !== Object.keys(b).length) {
return false;
}
for (var key in a) {
if (!deepEqual(a[key], b[key])) {
return false;
}
}
return true;
}
return a === b;
}
function easeCubicInOut(t) {
if (t <= 0) {
return 0;
}
if (t >= 1) {
return 1;
}
var t2 = t * t, t3 = t2 * t;
return 4 * (t < 0.5 ? t3 : 3 * (t - t2) + t3 - 0.75);
}
function bezier(p1x, p1y, p2x, p2y) {
var bezier = new unitbezier(p1x, p1y, p2x, p2y);
return function (t) {
return bezier.solve(t);
};
}
var ease = bezier(0.25, 0.1, 0.25, 1);
function clamp(n, min, max) {
return Math.min(max, Math.max(min, n));
}
function wrap(n, min, max) {
var d = max - min;
var w = ((n - min) % d + d) % d + min;
return w === min ? max : w;
}
function asyncAll(array, fn, callback) {
if (!array.length) {
return callback(null, []);
}
var remaining = array.length;
var results = new Array(array.length);
var error = null;
array.forEach(function (item, i) {
fn(item, function (err, result) {
if (err) {
error = err;
}
results[i] = result;
if (--remaining === 0) {
callback(error, results);
}
});
});
}
function values(obj) {
var result = [];
for (var k in obj) {
result.push(obj[k]);
}
return result;
}
function keysDifference(obj, other) {
var difference = [];
for (var i in obj) {
if (!(i in other)) {
difference.push(i);
}
}
return difference;
}
function extend(dest) {
var sources = [], len = arguments.length - 1;
while (len-- > 0)
sources[len] = arguments[len + 1];
for (var i = 0, list = sources; i < list.length; i += 1) {
var src = list[i];
for (var k in src) {
dest[k] = src[k];
}
}
return dest;
}
function pick(src, properties) {
var result = {};
for (var i = 0; i < properties.length; i++) {
var k = properties[i];
if (k in src) {
result[k] = src[k];
}
}
return result;
}
var id = 1;
function uniqueId() {
return id++;
}
function uuid() {
function b(a) {
return a ? (a ^ Math.random() * 16 >> a / 4).toString(16) : ([10000000] + -[1000] + -4000 + -8000 + -100000000000).replace(/[018]/g, b);
}
return b();
}
function validateUuid(str) {
return str ? /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(str) : false;
}
function bindAll(fns, context) {
fns.forEach(function (fn) {
if (!context[fn]) {
return;
}
context[fn] = context[fn].bind(context);
});
}
function endsWith(string, suffix) {
return string.indexOf(suffix, string.length - suffix.length) !== -1;
}
function mapObject(input, iterator, context) {
var output = {};
for (var key in input) {
output[key] = iterator.call(context || this, input[key], key, input);
}
return output;
}
function filterObject(input, iterator, context) {
var output = {};
for (var key in input) {
if (iterator.call(context || this, input[key], key, input)) {
output[key] = input[key];
}
}
return output;
}
function clone(input) {
if (Array.isArray(input)) {
return input.map(clone);
} else if (typeof input === 'object' && input) {
return mapObject(input, clone);
} else {
return input;
}
}
function arraysIntersect(a, b) {
for (var l = 0; l < a.length; l++) {
if (b.indexOf(a[l]) >= 0) {
return true;
}
}
return false;
}
var warnOnceHistory = {};
function warnOnce(message) {
if (!warnOnceHistory[message]) {
if (typeof console !== 'undefined') {
console.warn(message);
}
warnOnceHistory[message] = true;
}
}
function isCounterClockwise(a, b, c) {
return (c.y - a.y) * (b.x - a.x) > (b.y - a.y) * (c.x - a.x);
}
function calculateSignedArea(ring) {
var sum = 0;
for (var i = 0, len = ring.length, j = len - 1, p1 = void 0, p2 = void 0; i < len; j = i++) {
p1 = ring[i];
p2 = ring[j];
sum += (p2.x - p1.x) * (p1.y + p2.y);
}
return sum;
}
function sphericalToCartesian(ref) {
var r = ref[0];
var azimuthal = ref[1];
var polar = ref[2];
azimuthal += 90;
azimuthal *= Math.PI / 180;
polar *= Math.PI / 180;
return {
x: r * Math.cos(azimuthal) * Math.sin(polar),
y: r * Math.sin(azimuthal) * Math.sin(polar),
z: r * Math.cos(polar)
};
}
function parseCacheControl(cacheControl) {
var re = /(?:^|(?:\s*\,\s*))([^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)(?:\=(?:([^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)|(?:\"((?:[^"\\]|\\.)*)\")))?/g;
var header = {};
cacheControl.replace(re, function ($0, $1, $2, $3) {
var value = $2 || $3;
header[$1] = value ? value.toLowerCase() : true;
return '';
});
if (header['max-age']) {
var maxAge = parseInt(header['max-age'], 10);
if (isNaN(maxAge)) {
delete header['max-age'];
} else {
header['max-age'] = maxAge;
}
}
return header;
}
function storageAvailable(type) {
try {
var storage = self[type];
storage.setItem('_mapbox_test_', 1);
storage.removeItem('_mapbox_test_');
return true;
} catch (e) {
return false;
}
}
function b64EncodeUnicode(str) {
return self.btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
return String.fromCharCode(Number('0x' + p1));
}));
}
function b64DecodeUnicode(str) {
return decodeURIComponent(self.atob(str).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
}
var now = self.performance && self.performance.now ? self.performance.now.bind(self.performance) : Date.now.bind(Date);
var raf = self.requestAnimationFrame || self.mozRequestAnimationFrame || self.webkitRequestAnimationFrame || self.msRequestAnimationFrame;
var cancel = self.cancelAnimationFrame || self.mozCancelAnimationFrame || self.webkitCancelAnimationFrame || self.msCancelAnimationFrame;
var linkEl;
var reducedMotionQuery;
var exported = {
now: now,
frame: function frame(fn) {
var frame = raf(fn);
return {
cancel: function () {
return cancel(frame);
}
};
},
getImageData: function getImageData(img) {
var canvas = self.document.createElement('canvas');
var context = canvas.getContext('2d');
if (!context) {
throw new Error('failed to create canvas 2d context');
}
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0, img.width, img.height);
return context.getImageData(0, 0, img.width, img.height);
},
resolveURL: function resolveURL(path) {
if (!linkEl) {
linkEl = self.document.createElement('a');
}
linkEl.href = path;
return linkEl.href;
},
hardwareConcurrency: self.navigator.hardwareConcurrency || 4,
get devicePixelRatio() {
return self.devicePixelRatio;
},
get prefersReducedMotion() {
if (!self.matchMedia) {
return false;
}
if (reducedMotionQuery == null) {
reducedMotionQuery = self.matchMedia('(prefers-reduced-motion: reduce)');
}
return reducedMotionQuery.matches;
}
};
var config = {
API_URL: 'https://api.mapbox.com',
get EVENTS_URL() {
if (!this.API_URL) {
return null;
}
if (this.API_URL.indexOf('https://api.mapbox.cn') === 0) {
return 'https://events.mapbox.cn/events/v2';
} else if (this.API_URL.indexOf('https://api.mapbox.com') === 0) {
return 'https://events.mapbox.com/events/v2';
} else {
return null;
}
},
FEEDBACK_URL: 'https://apps.mapbox.com/feedback',
REQUIRE_ACCESS_TOKEN: true,
ACCESS_TOKEN: null,
MAX_PARALLEL_IMAGE_REQUESTS: 16
};
var exported$1 = {
supported: false,
testSupport: testSupport
};
var glForTesting;
var webpCheckComplete = false;
var webpImgTest;
var webpImgTestOnloadComplete = false;
if (self.document) {
webpImgTest = self.document.createElement('img');
webpImgTest.onload = function () {
if (glForTesting) {
testWebpTextureUpload(glForTesting);
}
glForTesting = null;
webpImgTestOnloadComplete = true;
};
webpImgTest.onerror = function () {
webpCheckComplete = true;
glForTesting = null;
};
webpImgTest.src = 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAQAAAAfQ//73v/+BiOh/AAA=';
}
function testSupport(gl) {
if (webpCheckComplete || !webpImgTest) {
return;
}
if (webpImgTestOnloadComplete) {
testWebpTextureUpload(gl);
} else {
glForTesting = gl;
}
}
function testWebpTextureUpload(gl) {
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
try {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, webpImgTest);
if (gl.isContextLost()) {
return;
}
exported$1.supported = true;
} catch (e) {
}
gl.deleteTexture(texture);
webpCheckComplete = true;
}
var SKU_ID = '01';
function createSkuToken() {
var TOKEN_VERSION = '1';
var base62chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
var sessionRandomizer = '';
for (var i = 0; i < 10; i++) {
sessionRandomizer += base62chars[Math.floor(Math.random() * 62)];
}
var expiration = 12 * 60 * 60 * 1000;
var token = [
TOKEN_VERSION,
SKU_ID,
sessionRandomizer
].join('');
var tokenExpiresAt = Date.now() + expiration;
return {
token: token,
tokenExpiresAt: tokenExpiresAt
};
}
var RequestManager = function RequestManager(transformRequestFn, customAccessToken) {
this._transformRequestFn = transformRequestFn;
this._customAccessToken = customAccessToken;
this._createSkuToken();
};
RequestManager.prototype._createSkuToken = function _createSkuToken() {
var skuToken = createSkuToken();
this._skuToken = skuToken.token;
this._skuTokenExpiresAt = skuToken.tokenExpiresAt;
};
RequestManager.prototype._isSkuTokenExpired = function _isSkuTokenExpired() {
return Date.now() > this._skuTokenExpiresAt;
};
RequestManager.prototype.transformRequest = function transformRequest(url, type) {
if (this._transformRequestFn) {
return this._transformRequestFn(url, type) || { url: url };
}
return { url: url };
};
RequestManager.prototype.normalizeStyleURL = function normalizeStyleURL(url, accessToken) {
if (!isMapboxURL(url)) {
return url;
}
var urlObject = parseUrl(url);
urlObject.path = '/styles/v1' + urlObject.path;
return this._makeAPIURL(urlObject, this._customAccessToken || accessToken);
};
RequestManager.prototype.normalizeGlyphsURL = function normalizeGlyphsURL(url, accessToken) {
if (!isMapboxURL(url)) {
return url;
}
var urlObject = parseUrl(url);
urlObject.path = '/fonts/v1' + urlObject.path;
return this._makeAPIURL(urlObject, this._customAccessToken || accessToken);
};
RequestManager.prototype.normalizeSourceURL = function normalizeSourceURL(url, accessToken) {
if (!isMapboxURL(url)) {
return url;
}
var urlObject = parseUrl(url);
urlObject.path = '/v4/' + urlObject.authority + '.json';
urlObject.params.push('secure');
return this._makeAPIURL(urlObject, this._customAccessToken || accessToken);
};
RequestManager.prototype.normalizeSpriteURL = function normalizeSpriteURL(url, format, extension, accessToken) {
var urlObject = parseUrl(url);
if (!isMapboxURL(url)) {
urlObject.path += '' + format + extension;
return formatUrl(urlObject);
}
urlObject.path = '/styles/v1' + urlObject.path + '/sprite' + format + extension;
return this._makeAPIURL(urlObject, this._customAccessToken || accessToken);
};
RequestManager.prototype.normalizeTileURL = function normalizeTileURL(tileURL, sourceURL, tileSize) {
if (this._isSkuTokenExpired()) {
this._createSkuToken();
}
if (!sourceURL || !isMapboxURL(sourceURL)) {
return tileURL;
}
var urlObject = parseUrl(tileURL);
var imageExtensionRe = /(\.(png|jpg)\d*)(?=$)/;
var tileURLAPIPrefixRe = /^.+\/v4\//;
var suffix = exported.devicePixelRatio >= 2 || tileSize === 512 ? '@2x' : '';
var extension = exported$1.supported ? '.webp' : '$1';
urlObject.path = urlObject.path.replace(imageExtensionRe, '' + suffix + extension);
urlObject.path = urlObject.path.replace(tileURLAPIPrefixRe, '/');
urlObject.path = '/v4' + urlObject.path;
if (config.REQUIRE_ACCESS_TOKEN && (config.ACCESS_TOKEN || this._customAccessToken) && this._skuToken) {
urlObject.params.push('sku=' + this._skuToken);
}
return this._makeAPIURL(urlObject, this._customAccessToken);
};
RequestManager.prototype.canonicalizeTileURL = function canonicalizeTileURL(url) {
var version = '/v4/';
var extensionRe = /\.[\w]+$/;
var urlObject = parseUrl(url);
if (!urlObject.path.match(/(^\/v4\/)/) || !urlObject.path.match(extensionRe)) {
return url;
}
var result = 'mapbox://tiles/';
result += urlObject.path.replace(version, '');
var params = urlObject.params.filter(function (p) {
return !p.match(/^access_token=/);
});
if (params.length) {
result += '?' + params.join('&');
}
return result;
};
RequestManager.prototype.canonicalizeTileset = function canonicalizeTileset(tileJSON, sourceURL) {
if (!isMapboxURL(sourceURL)) {
return tileJSON.tiles || [];
}
var canonical = [];
for (var i = 0, list = tileJSON.tiles; i < list.length; i += 1) {
var url = list[i];
var canonicalUrl = this.canonicalizeTileURL(url);
canonical.push(canonicalUrl);
}
return canonical;
};
RequestManager.prototype._makeAPIURL = function _makeAPIURL(urlObject, accessToken) {
var help = 'See https://www.mapbox.com/api-documentation/#access-tokens-and-token-scopes';
var apiUrlObject = parseUrl(config.API_URL);
urlObject.protocol = apiUrlObject.protocol;
urlObject.authority = apiUrlObject.authority;
if (apiUrlObject.path !== '/') {
urlObject.path = '' + apiUrlObject.path + urlObject.path;
}
if (!config.REQUIRE_ACCESS_TOKEN) {
return formatUrl(urlObject);
}
accessToken = accessToken || config.ACCESS_TOKEN;
if (!accessToken) {
throw new Error('An API access token is required to use Mapbox GL. ' + help);
}
if (accessToken[0] === 's') {
throw new Error('Use a public access token (pk.*) with Mapbox GL, not a secret access token (sk.*). ' + help);
}
urlObject.params = urlObject.params.filter(function (d) {
return d.indexOf('access_token') === -1;
});
urlObject.params.push('access_token=' + accessToken);
return formatUrl(urlObject);
};
function isMapboxURL(url) {
return url.indexOf('mapbox:') === 0;
}
var mapboxHTTPURLRe = /^((https?:)?\/\/)?([^\/]+\.)?mapbox\.c(n|om)(\/|\?|$)/i;
function isMapboxHTTPURL(url) {
return mapboxHTTPURLRe.test(url);
}
function hasCacheDefeatingSku(url) {
return url.indexOf('sku=') > 0 && isMapboxHTTPURL(url);
}
var urlRe = /^(\w+):\/\/([^/?]*)(\/[^?]+)?\??(.+)?/;
function parseUrl(url) {
var parts = url.match(urlRe);
if (!parts) {
throw new Error('Unable to parse URL object');
}
return {
protocol: parts[1],
authority: parts[2],
path: parts[3] || '/',
params: parts[4] ? parts[4].split('&') : []
};
}
function formatUrl(obj) {
var params = obj.params.length ? '?' + obj.params.join('&') : '';
return obj.protocol + '://' + obj.authority + obj.path + params;
}
var telemEventKey = 'mapbox.eventData';
function parseAccessToken(accessToken) {
if (!accessToken) {
return null;
}
var parts = accessToken.split('.');
if (!parts || parts.length !== 3) {
return null;
}
try {
var jsonData = JSON.parse(b64DecodeUnicode(parts[1]));
return jsonData;
} catch (e) {
return null;
}
}
var TelemetryEvent = function TelemetryEvent(type) {
this.type = type;
this.anonId = null;
this.eventData = {};
this.queue = [];
this.pendingRequest = null;
};
TelemetryEvent.prototype.getStorageKey = function getStorageKey(domain) {
var tokenData = parseAccessToken(config.ACCESS_TOKEN);
var u = '';
if (tokenData && tokenData['u']) {
u = b64EncodeUnicode(tokenData['u']);
} else {
u = config.ACCESS_TOKEN || '';
}
return domain ? telemEventKey + '.' + domain + ':' + u : telemEventKey + ':' + u;
};
TelemetryEvent.prototype.fetchEventData = function fetchEventData() {
var isLocalStorageAvailable = storageAvailable('localStorage');
var storageKey = this.getStorageKey();
var uuidKey = this.getStorageKey('uuid');
if (isLocalStorageAvailable) {
try {
var data = self.localStorage.getItem(storageKey);
if (data) {
this.eventData = JSON.parse(data);
}
var uuid = self.localStorage.getItem(uuidKey);
if (uuid) {
this.anonId = uuid;
}
} catch (e) {
warnOnce('Unable to read from LocalStorage');
}
}
};
TelemetryEvent.prototype.saveEventData = function saveEventData() {
var isLocalStorageAvailable = storageAvailable('localStorage');
var storageKey = this.getStorageKey();
var uuidKey = this.getStorageKey('uuid');
if (isLocalStorageAvailable) {
try {
self.localStorage.setItem(uuidKey, this.anonId);
if (Object.keys(this.eventData).length >= 1) {
self.localStorage.setItem(storageKey, JSON.stringify(this.eventData));
}
} catch (e) {
warnOnce('Unable to write to LocalStorage');
}
}
};
TelemetryEvent.prototype.processRequests = function processRequests(_) {
};
TelemetryEvent.prototype.postEvent = function postEvent(timestamp, additionalPayload, callback, customAccessToken) {
var this$1 = this;
if (!config.EVENTS_URL) {
return;
}
var eventsUrlObject = parseUrl(config.EVENTS_URL);
eventsUrlObject.params.push('access_token=' + (customAccessToken || config.ACCESS_TOKEN || ''));
var payload = {
event: this.type,
created: new Date(timestamp).toISOString(),
sdkIdentifier: 'mapbox-gl-js',
sdkVersion: version,
skuId: SKU_ID,
userId: this.anonId
};
var finalPayload = additionalPayload ? extend(payload, additionalPayload) : payload;
var request = {
url: formatUrl(eventsUrlObject),
headers: { 'Content-Type': 'text/plain' },
body: JSON.stringify([finalPayload])
};
this.pendingRequest = postData(request, function (error) {
this$1.pendingRequest = null;
callback(error);
this$1.saveEventData();
this$1.processRequests(customAccessToken);
});
};
TelemetryEvent.prototype.queueRequest = function queueRequest(event, customAccessToken) {
this.queue.push(event);
this.processRequests(customAccessToken);
};
var MapLoadEvent = function (TelemetryEvent) {
function MapLoadEvent() {
TelemetryEvent.call(this, 'map.load');
this.success = {};
this.skuToken = '';
}
if (TelemetryEvent)
MapLoadEvent.__proto__ = TelemetryEvent;
MapLoadEvent.prototype = Object.create(TelemetryEvent && TelemetryEvent.prototype);
MapLoadEvent.prototype.constructor = MapLoadEvent;
MapLoadEvent.prototype.postMapLoadEvent = function postMapLoadEvent(tileUrls, mapId, skuToken, customAccessToken) {
this.skuToken = skuToken;
if (config.EVENTS_URL && customAccessToken || config.ACCESS_TOKEN && Array.isArray(tileUrls) && tileUrls.some(function (url) {
return isMapboxURL(url) || isMapboxHTTPURL(url);
})) {
this.queueRequest({
id: mapId,
timestamp: Date.now()
}, customAccessToken);
}
};
MapLoadEvent.prototype.processRequests = function processRequests(customAccessToken) {
var this$1 = this;
if (this.pendingRequest || this.queue.length === 0) {
return;
}
var ref = this.queue.shift();
var id = ref.id;
var timestamp = ref.timestamp;
if (id && this.success[id]) {
return;
}
if (!this.anonId) {
this.fetchEventData();
}
if (!validateUuid(this.anonId)) {
this.anonId = uuid();
}
this.postEvent(timestamp, { skuToken: this.skuToken }, function (err) {
if (!err) {
if (id) {
this$1.success[id] = true;
}
}
}, customAccessToken);
};
return MapLoadEvent;
}(TelemetryEvent);
var TurnstileEvent = function (TelemetryEvent) {
function TurnstileEvent(customAccessToken) {
TelemetryEvent.call(this, 'appUserTurnstile');
this._customAccessToken = customAccessToken;
}
if (TelemetryEvent)
TurnstileEvent.__proto__ = TelemetryEvent;
TurnstileEvent.prototype = Object.create(TelemetryEvent && TelemetryEvent.prototype);
TurnstileEvent.prototype.constructor = TurnstileEvent;
TurnstileEvent.prototype.postTurnstileEvent = function postTurnstileEvent(tileUrls, customAccessToken) {
if (config.EVENTS_URL && config.ACCESS_TOKEN && Array.isArray(tileUrls) && tileUrls.some(function (url) {
return isMapboxURL(url) || isMapboxHTTPURL(url);
})) {
this.queueRequest(Date.now(), customAccessToken);
}
};
TurnstileEvent.prototype.processRequests = function processRequests(customAccessToken) {
var this$1 = this;
if (this.pendingRequest || this.queue.length === 0) {
return;
}
if (!this.anonId || !this.eventData.lastSuccess || !this.eventData.tokenU) {
this.fetchEventData();
}
var tokenData = parseAccessToken(config.ACCESS_TOKEN);
var tokenU = tokenData ? tokenData['u'] : config.ACCESS_TOKEN;
var dueForEvent = tokenU !== this.eventData.tokenU;
if (!validateUuid(this.anonId)) {
this.anonId = uuid();
dueForEvent = true;
}
var nextUpdate = this.queue.shift();
if (this.eventData.lastSuccess) {
var lastUpdate = new Date(this.eventData.lastSuccess);
var nextDate = new Date(nextUpdate);
var daysElapsed = (nextUpdate - this.eventData.lastSuccess) / (24 * 60 * 60 * 1000);
dueForEvent = dueForEvent || daysElapsed >= 1 || daysElapsed < -1 || lastUpdate.getDate() !== nextDate.getDate();
} else {
dueForEvent = true;
}
if (!dueForEvent) {
return this.processRequests();
}
this.postEvent(nextUpdate, { 'enabled.telemetry': false }, function (err) {
if (!err) {
this$1.eventData.lastSuccess = nextUpdate;
this$1.eventData.tokenU = tokenU;
}
}, customAccessToken);
};
return TurnstileEvent;
}(TelemetryEvent);
var turnstileEvent_ = new TurnstileEvent();
var postTurnstileEvent = turnstileEvent_.postTurnstileEvent.bind(turnstileEvent_);
var mapLoadEvent_ = new MapLoadEvent();
var postMapLoadEvent = mapLoadEvent_.postMapLoadEvent.bind(mapLoadEvent_);
var CACHE_NAME = 'mapbox-tiles';
var cacheLimit = 500;
var cacheCheckThreshold = 50;
var MIN_TIME_UNTIL_EXPIRY = 1000 * 60 * 7;
var responseConstructorSupportsReadableStream;
function prepareBody(response, callback) {
if (responseConstructorSupportsReadableStream === undefined) {
try {
new Response(new ReadableStream());
responseConstructorSupportsReadableStream = true;
} catch (e) {
responseConstructorSupportsReadableStream = false;
}
}
if (responseConstructorSupportsReadableStream) {
callback(response.body);
} else {
response.blob().then(callback);
}
}
function cachePut(request, response, requestTime) {
if (!self.caches) {
return;
}
var options = {
status: response.status,
statusText: response.statusText,
headers: new self.Headers()
};
response.headers.forEach(function (v, k) {
return options.headers.set(k, v);
});
var cacheControl = parseCacheControl(response.headers.get('Cache-Control') || '');
if (cacheControl['no-store']) {
return;
}
if (cacheControl['max-age']) {
options.headers.set('Expires', new Date(requestTime + cacheControl['max-age'] * 1000).toUTCString());
}
var timeUntilExpiry = new Date(options.headers.get('Expires')).getTime() - requestTime;
if (timeUntilExpiry < MIN_TIME_UNTIL_EXPIRY) {
return;
}
prepareBody(response, function (body) {
var clonedResponse = new self.Response(body, options);
self.caches.open(CACHE_NAME).then(function (cache) {
return cache.put(stripQueryParameters(request.url), clonedResponse);
});
});
}
function stripQueryParameters(url) {
var start = url.indexOf('?');
return start < 0 ? url : url.slice(0, start);
}
function cacheGet(request, callback) {
if (!self.caches) {
return callback(null);
}
var strippedURL = stripQueryParameters(request.url);
self.caches.open(CACHE_NAME).catch(callback).then(function (cache) {
cache.match(strippedURL).catch(callback).then(function (response) {
var fresh = isFresh(response);
cache.delete(strippedURL);
if (fresh) {
cache.put(strippedURL, response.clone());
}
callback(null, response, fresh);
});
});
}
function isFresh(response) {
if (!response) {
return false;
}
var expires = new Date(response.headers.get('Expires'));
var cacheControl = parseCacheControl(response.headers.get('Cache-Control') || '');
return expires > Date.now() && !cacheControl['no-cache'];
}
var globalEntryCounter = Infinity;
function cacheEntryPossiblyAdded(dispatcher) {
globalEntryCounter++;
if (globalEntryCounter > cacheCheckThreshold) {
dispatcher.send('enforceCacheSizeLimit', cacheLimit);
globalEntryCounter = 0;
}
}
function enforceCacheSizeLimit(limit) {
if (!self.caches) {
return;
}
self.caches.open(CACHE_NAME).then(function (cache) {
cache.keys().then(function (keys) {
for (var i = 0; i < keys.length - limit; i++) {
cache.delete(keys[i]);
}
});
});
}
function clearTileCache(callback) {
var promise = self.caches.delete(CACHE_NAME);
if (callback) {
promise.catch(callback).then(function () {
return callback();
});
}
}
function setCacheLimits(limit, checkThreshold) {
cacheLimit = limit;
cacheCheckThreshold = checkThreshold;
}
var ResourceType = {
Unknown: 'Unknown',
Style: 'Style',
Source: 'Source',
Tile: 'Tile',
Glyphs: 'Glyphs',
SpriteImage: 'SpriteImage',
SpriteJSON: 'SpriteJSON',
Image: 'Image'
};
if (typeof Object.freeze == 'function') {
Object.freeze(ResourceType);
}
var AJAXError = function (Error) {
function AJAXError(message, status, url) {
if (status === 401 && isMapboxHTTPURL(url)) {
message += ': you may have provided an invalid Mapbox access token. See https://www.mapbox.com/api-documentation/#access-tokens-and-token-scopes';
}
Error.call(this, message);
this.status = status;
this.url = url;
this.name = this.constructor.name;
this.message = message;
}
if (Error)
AJAXError.__proto__ = Error;
AJAXError.prototype = Object.create(Error && Error.prototype);
AJAXError.prototype.constructor = AJAXError;
AJAXError.prototype.toString = function toString() {
return this.name + ': ' + this.message + ' (' + this.status + '): ' + this.url;
};
return AJAXError;
}(Error);
function isWorker() {
return typeof WorkerGlobalScope !== 'undefined' && typeof self !== 'undefined' && self instanceof WorkerGlobalScope;
}
var getReferrer = isWorker() ? function () {
return self.worker && self.worker.referrer;
} : function () {
var origin = self.location.origin;
if (origin && origin !== 'null' && origin !== 'file://') {
return origin + self.location.pathname;
}
};
function makeFetchRequest(requestParameters, callback) {
var controller = new self.AbortController();
var request = new self.Request(requestParameters.url, {
method: requestParameters.method || 'GET',
body: requestParameters.body,
credentials: requestParameters.credentials,
headers: requestParameters.headers,
referrer: getReferrer(),
signal: controller.signal
});
var complete = false;
var aborted = false;
var cacheIgnoringSearch = hasCacheDefeatingSku(request.url);
if (requestParameters.type === 'json') {
request.headers.set('Accept', 'application/json');
}
var validateOrFetch = function (err, cachedResponse, responseIsFresh) {
if (aborted) {
return;
}
if (err) {
if (err.message !== 'SecurityError') {
warnOnce(err);
}
}
if (cachedResponse && responseIsFresh) {
return finishRequest(cachedResponse);
}
var requestTime = Date.now();
self.fetch(request).then(function (response) {
if (response.ok) {
var cacheableResponse = cacheIgnoringSearch ? response.clone() : null;
return finishRequest(response, cacheableResponse, requestTime);
} else {
return callback(new AJAXError(response.statusText, response.status, requestParameters.url));
}
}).catch(function (error) {
if (error.code === 20) {
return;
}
callback(new Error(error.message));
});
};
var finishRequest = function (response, cacheableResponse, requestTime) {
(requestParameters.type === 'arrayBuffer' ? response.arrayBuffer() : requestParameters.type === 'json' ? response.json() : response.text()).then(function (result) {
if (aborted) {
return;
}
if (cacheableResponse && requestTime) {
cachePut(request, cacheableResponse, requestTime);
}
complete = true;
callback(null, result, response.headers.get('Cache-Control'), response.headers.get('Expires'));
}).catch(function (err) {
return callback(new Error(err.message));
});
};
if (cacheIgnoringSearch) {
cacheGet(request, validateOrFetch);
} else {
validateOrFetch(null, null);
}
return {
cancel: function () {
aborted = true;
if (!complete) {
controller.abort();
}
}
};
}
function makeXMLHttpRequest(requestParameters, callback) {
var xhr = new self.XMLHttpRequest();
xhr.open(requestParameters.method || 'GET', requestParameters.url, true);
if (requestParameters.type === 'arrayBuffer') {
xhr.responseType = 'arraybuffer';
}
for (var k in requestParameters.headers) {
xhr.setRequestHeader(k, requestParameters.headers[k]);
}
if (requestParameters.type === 'json') {
xhr.setRequestHeader('Accept', 'application/json');
}
xhr.withCredentials = requestParameters.credentials === 'include';
xhr.onerror = function () {
callback(new Error(xhr.statusText));
};
xhr.onload = function () {
if ((xhr.status >= 200 && xhr.status < 300 || xhr.status === 0) && xhr.response !== null) {
var data = xhr.response;
if (requestParameters.type === 'json') {
try {
data = JSON.parse(xhr.response);
} catch (err) {
return callback(err);
}
}
callback(null, data, xhr.getResponseHeader('Cache-Control'), xhr.getResponseHeader('Expires'));
} else {
callback(new AJAXError(xhr.statusText, xhr.status, requestParameters.url));
}
};
xhr.send(requestParameters.body);
return {
cancel: function () {
return xhr.abort();
}
};
}
var makeRequest = function (requestParameters, callback) {
if (!/^file:/.test(requestParameters.url)) {
if (self.fetch && self.Request && self.AbortController && self.Request.prototype.hasOwnProperty('signal')) {
return makeFetchRequest(requestParameters, callback);
}
if (isWorker() && self.worker && self.worker.actor) {
return self.worker.actor.send('getResource', requestParameters, callback);
}
}
return makeXMLHttpRequest(requestParameters, callback);
};
var getJSON = function (requestParameters, callback) {
return makeRequest(extend(requestParameters, { type: 'json' }), callback);
};
var getArrayBuffer = function (requestParameters, callback) {
return makeRequest(extend(requestParameters, { type: 'arrayBuffer' }), callback);
};
var postData = function (requestParameters, callback) {
return makeRequest(extend(requestParameters, { method: 'POST' }), callback);
};
function sameOrigin(url) {
var a = self.document.createElement('a');
a.href = url;
return a.protocol === self.document.location.protocol && a.host === self.document.location.host;
}
var transparentPngUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII=';
var imageQueue, numImageRequests;
var resetImageRequestQueue = function () {
imageQueue = [];
numImageRequests = 0;
};
resetImageRequestQueue();
var getImage = function (requestParameters, callback) {
if (numImageRequests >= config.MAX_PARALLEL_IMAGE_REQUESTS) {
var queued = {
requestParameters: requestParameters,
callback: callback,
cancelled: false,
cancel: function cancel() {
this.cancelled = true;
}
};
imageQueue.push(queued);
return queued;
}
numImageRequests++;
var advanced = false;
var advanceImageRequestQueue = function () {
if (advanced) {
return;
}
advanced = true;
numImageRequests--;
while (imageQueue.length && numImageRequests < config.MAX_PARALLEL_IMAGE_REQUESTS) {
var request = imageQueue.shift();
var requestParameters = request.requestParameters;
var callback = request.callback;
var cancelled = request.cancelled;
if (!cancelled) {
request.cancel = getImage(requestParameters, callback).cancel;
}
}
};
var request = getArrayBuffer(requestParameters, function (err, data, cacheControl, expires) {
advanceImageRequestQueue();
if (err) {
callback(err);
} else if (data) {
var img = new self.Image();
var URL = self.URL || self.webkitURL;
img.onload = function () {
callback(null, img);
URL.revokeObjectURL(img.src);
};
img.onerror = function () {
return callback(new Error('Could not load image. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported.'));
};
var blob = new self.Blob([new Uint8Array(data)], { type: 'image/png' });
img.cacheControl = cacheControl;
img.expires = expires;
img.src = data.byteLength ? URL.createObjectURL(blob) : transparentPngUrl;
}
});
return {
cancel: function () {
request.cancel();
advanceImageRequestQueue();
}
};
};
var getVideo = function (urls, callback) {
var video = self.document.createElement('video');
video.muted = true;
video.onloadstart = function () {
callback(null, video);
};
for (var i = 0; i < urls.length; i++) {
var s = self.document.createElement('source');
if (!sameOrigin(urls[i])) {
video.crossOrigin = 'Anonymous';
}
s.src = urls[i];
video.appendChild(s);
}
return {
cancel: function () {
}
};
};
function _addEventListener(type, listener, listenerList) {
var listenerExists = listenerList[type] && listenerList[type].indexOf(listener) !== -1;
if (!listenerExists) {
listenerList[type] = listenerList[type] || [];
listenerList[type].push(listener);
}
}
function _removeEventListener(type, listener, listenerList) {
if (listenerList && listenerList[type]) {
var index = listenerList[type].indexOf(listener);
if (index !== -1) {
listenerList[type].splice(index, 1);
}
}
}
var Event = function Event(type, data) {
if (data === void 0)
data = {};
extend(this, data);
this.type = type;
};
var ErrorEvent = function (Event) {
function ErrorEvent(error, data) {
if (data === void 0)
data = {};
Event.call(this, 'error', extend({ error: error }, data));
}
if (Event)
ErrorEvent.__proto__ = Event;
ErrorEvent.prototype = Object.create(Event && Event.prototype);
ErrorEvent.prototype.constructor = ErrorEvent;
return ErrorEvent;
}(Event);
var Evented = function Evented() {
};
Evented.prototype.on = function on(type, listener) {
this._listeners = this._listeners || {};
_addEventListener(type, listener, this._listeners);
return this;
};
Evented.prototype.off = function off(type, listener) {
_removeEventListener(type, listener, this._listeners);
_removeEventListener(type, listener, this._oneTimeListeners);
return this;
};
Evented.prototype.once = function once(type, listener) {
this._oneTimeListeners = this._oneTimeListeners || {};
_addEventListener(type, listener, this._oneTimeListeners);
return this;
};
Evented.prototype.fire = function fire(event, properties) {
if (typeof event === 'string') {
event = new Event(event, properties || {});
}
var type = event.type;
if (this.listens(type)) {
event.target = this;
var listeners = this._listeners && this._listeners[type] ? this._listeners[type].slice() : [];
for (var i = 0, list = listeners; i < list.length; i += 1) {
var listener = list[i];
listener.call(this, event);
}
var oneTimeListeners = this._oneTimeListeners && this._oneTimeListeners[type] ? this._oneTimeListeners[type].slice() : [];
for (var i$1 = 0, list$1 = oneTimeListeners; i$1 < list$1.length; i$1 += 1) {
var listener$1 = list$1[i$1];
_removeEventListener(type, listener$1, this._oneTimeListeners);
listener$1.call(this, event);
}
var parent = this._eventedParent;
if (parent) {
extend(event, typeof this._eventedParentData === 'function' ? this._eventedParentData() : this._eventedParentData);
parent.fire(event);
}
} else if (event instanceof ErrorEvent) {
console.error(event.error);
}
return this;
};
Evented.prototype.listens = function listens(type) {
return this._listeners && this._listeners[type] && this._listeners[type].length > 0 || this._oneTimeListeners && this._oneTimeListeners[type] && this._oneTimeListeners[type].length > 0 || this._eventedParent && this._eventedParent.listens(type);
};
Evented.prototype.setEventedParent = function setEventedParent(parent, data) {
this._eventedParent = parent;
this._eventedParentData = data;
return this;
};
var $version = 8;
var $root = {
version: {
required: true,
type: "enum",
values: [
8
]
},
name: {
type: "string"
},
metadata: {
type: "*"
},
center: {
type: "array",
value: "number"
},
zoom: {
type: "number"
},
bearing: {
type: "number",
"default": 0,
period: 360,
units: "degrees"
},
pitch: {
type: "number",
"default": 0,
units: "degrees"
},
light: {
type: "light"
},
sources: {
required: true,
type: "sources"
},
sprite: {
type: "string"
},
glyphs: {
type: "string"
},
transition: {
type: "transition"
},
layers: {
required: true,
type: "array",
value: "layer"
}
};
var sources = {
"*": {
type: "source"
}
};
var source = [
"source_vector",
"source_raster",
"source_raster_dem",
"source_geojson",
"source_video",
"source_image"
];
var source_vector = {
type: {
required: true,
type: "enum",
values: {
vector: {
}
}
},
url: {
type: "string"
},
tiles: {
type: "array",
value: "string"
},
bounds: {
type: "array",
value: "number",
length: 4,
"default": [
-180,
-85.051129,
180,
85.051129
]
},
scheme: {
type: "enum",
values: {
xyz: {
},
tms: {
}
},
"default": "xyz"
},
minzoom: {
type: "number",
"default": 0
},
maxzoom: {
type: "number",
"default": 22
},
attribution: {
type: "string"
},
"*": {
type: "*"
}
};
var source_raster = {
type: {
required: true,
type: "enum",
values: {
raster: {
}
}
},
url: {
type: "string"
},
tiles: {
type: "array",
value: "string"
},
bounds: {
type: "array",
value: "number",
length: 4,
"default": [
-180,
-85.051129,
180,
85.051129
]
},
minzoom: {
type: "number",
"default": 0
},
maxzoom: {
type: "number",
"default": 22
},
tileSize: {
type: "number",
"default": 512,
units: "pixels"
},
scheme: {
type: "enum",
values: {
xyz: {
},
tms: {
}
},
"default": "xyz"
},
attribution: {
type: "string"
},
"*": {
type: "*"
}
};
var source_raster_dem = {
type: {
required: true,
type: "enum",
values: {
"raster-dem": {
}
}
},
url: {
type: "string"
},
t