(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o // Runs a SPARQL query, converting it to // https://query.wikidata.org/bigdata/namespace/wdq/sparql?format=json&query=... this._validateExternalService(urlParts, sanitizedHost, opt.url); if (!urlParts.query || !urlParts.query.query) { throw new Error('wikidatasparql: missing query parameter in: ' + opt.url); } // Only keep the "query" parameter urlParts.query = {query: urlParts.query.query}; urlParts.pathname = '/bigdata/namespace/wdq/sparql'; opt.headers = this.objExtender(opt.headers || {}, {'Accept': 'application/sparql-results+json'}); break; case 'geoshape:': case 'geoline:': // geoshape:///?ids=Q16,Q30 or geoshape:///?query=... // Get geoshapes data from OSM database by supplying Wikidata IDs // https://maps.wikimedia.org/shape?ids=Q16,Q30 // 'geoline:' is an identical service, except that it returns lines instead of polygons this._validateExternalService(urlParts, sanitizedHost, opt.url, 'geoshape:'); if (!urlParts.query || (!urlParts.query.ids && !urlParts.query.query)) { throw new Error(opt.graphProtocol + ' missing ids or query parameter in: ' + opt.url); } // the query object is not modified urlParts.pathname = '/' + removeColon(opt.graphProtocol); break; case 'mapsnapshot:': // mapsnapshot:///?width=__&height=__&zoom=__&lat=__&lon=__ [&style=__] // Converts it into a snapshot image request for Kartotherian: // https://maps.wikimedia.org/img/{style},{zoom},{lat},{lon},{width}x{height}[@{scale}x].{format} // (scale will be set to 2, and format to png) if (!urlParts.query) { throw new Error('mapsnapshot: missing required parameters'); } validate(urlParts, 'width', 1, 4096); validate(urlParts, 'height', 1, 4096); validate(urlParts, 'zoom', 0, 22); validate(urlParts, 'lat', -90, 90, true); validate(urlParts, 'lon', -180, 180, true); var query = urlParts.query; if (query.style && !/^[-_0-9a-z]+$/.test(query.style)) { throw new Error('mapsnapshot: if style is given, it must be letters/numbers/dash/underscores only'); } // Uses the same configuration as geoshape service, so reuse settings this._validateExternalService(urlParts, sanitizedHost, opt.url, 'geoshape:'); urlParts.pathname = '/img/' + (query.style || 'osm-intl') + ',' + query.zoom + ',' + query.lat + ',' + query.lon + ',' + query.width + 'x' + query.height + '@2x.png'; urlParts.query = {}; // deleting it would cause errors in mw.Uri() break; default: throw new Error('Unknown protocol ' + opt.url); } } return this.formatUrl(urlParts, opt); */ return opt.url; }; function validate(urlParts, name, min, max, isFloat) { var value = urlParts.query[name]; if (value === undefined) { throw new Error(urlParts.protocol + ' parameter ' + name + ' is not set'); } if (!(isFloat ? /^-?[0-9]+\.?[0-9]*$/ : /^-?[0-9]+$/).test(value)) { throw new Error(urlParts.protocol + ' parameter ' + name + ' is not a number'); } value = isFloat ? parseFloat(value) : parseInt(value); if (value < min || value > max) { throw new Error(urlParts.protocol + ' parameter ' + name + ' is not valid'); } } VegaWrapper.prototype._validateExternalService = function _validateExternalService(urlParts, sanitizedHost, url, protocolOverride) { var protocol = protocolOverride || urlParts.protocol, domains = this._getProtocolDomains(protocol); if (!domains) { throw new Error(protocol + ': protocol is disabled: ' + url); } if (urlParts.isRelativeHost) { urlParts.host = domains[0]; urlParts.protocol = this.sanitizeHost(urlParts.host).protocol; } else { urlParts.protocol = sanitizedHost.protocol; } if (!this.testHost(protocol, urlParts.host)) { throw new Error(protocol + ': URL must either be relative (' + protocol + '///...), or use one of the allowed hosts: ' + url); } }; /** * Performs post-processing of the data requested by the graph's spec */ VegaWrapper.prototype.dataParser = function dataParser(error, data, opt, callback) { if (!error) { try { data = this.parseDataOrThrow(data, opt); } catch (e) { error = e; } } if (error) data = undefined; callback(error, data); }; /** * Parses the response from MW Api, throwing an error or logging warnings */ VegaWrapper.prototype.parseMWApiResponse = function parseMWApiResponse(data) { data = JSON.parse(data); if (data.error) { throw new Error('API error: ' + JSON.stringify(data.error)); } if (data.warnings) { this.logger('API warnings: ' + JSON.stringify(data.warnings)); } return data; }; /** * Performs post-processing of the data requested by the graph's spec, and throw on error */ VegaWrapper.prototype.parseDataOrThrow = function parseDataOrThrow(data, opt) { switch (opt.xowa_protocol) { // XOWA: use opt.xowa_protocol case 'wikiapi:': data = this.parseMWApiResponse(data); break; case 'wikiraw:': // XOWA: comment out call to MW API; Xograph will make call to xo_server; DATE:2018-03-13 /* data = this.parseMWApiResponse(data); try { data = data.query.pages[0].revisions[0].content; } catch (e) { throw new Error('Page content not available ' + opt.url); } */ break; case null: case 'tabular:': case 'map:': data = this.parseMWApiResponse(data).jsondata; var metadata = [{ description: data.description, license_code: data.license.code, license_text: data.license.text, license_url: data.license.url, sources: data.sources }]; if (opt.xowa_protocol === 'tabular:') { var fields = data.schema.fields.map(function (v) { return v.name; }); data = { meta: metadata, fields: data.schema.fields, data: data.data.map(function (v) { var row = {}, i; for (i = 0; i < fields.length; i++) { // Need to copy nulls too -- Vega has no easy way to test for undefined row[fields[i]] = v[i]; } return row; }) } } else { metadata[0].zoom = data.zoom; metadata[0].latitude = data.latitude; metadata[0].longitude = data.longitude; data = { meta: metadata, data: data.data }; } break; case 'wikidatasparql:': data = JSON.parse(data); if (!data.results || !Array.isArray(data.results.bindings)) { throw new Error('SPARQL query result does not have "results.bindings"'); } data = data.results.bindings.map(function (row) { var key, result = {}; for (key in row) { if (row.hasOwnProperty(key)) { result[key] = parseWikidataValue(row[key]); } } return result; }); break; } return data; }; /** * Throw an error when called */ function alwaysFail() { throw new Error('Disabled'); } },{"domain-validator":2,"wd-type-parser":4}],4:[function(require,module,exports){ 'use strict'; /* global module */ module.exports = parseWikidataValue; /** * Given a value object as returned from Wikidata Query Service, returns a simplified value * @param {object} value Original object as sent by the Wikidata query service * @param {string} value.type SPARQL data type (literal, uri) * @param {string} value.datatype XMLSchema data type * @param {*} value.value The actual value sent by the Wikidata query service * @param {boolean=} ignoreUnknown if false, will return value.value even if it cannot be recognized * @return {*} */ function parseWikidataValue(value, ignoreUnknown) { var temp; if (!value || !value.type || value.value === undefined) { return undefined; } switch (value.type) { case 'literal': switch (value.datatype) { case 'http://www.w3.org/2001/XMLSchema#double': case 'http://www.w3.org/2001/XMLSchema#float': case 'http://www.w3.org/2001/XMLSchema#decimal': case 'http://www.w3.org/2001/XMLSchema#integer': case 'http://www.w3.org/2001/XMLSchema#long': case 'http://www.w3.org/2001/XMLSchema#int': case 'http://www.w3.org/2001/XMLSchema#short': case 'http://www.w3.org/2001/XMLSchema#nonNegativeInteger': case 'http://www.w3.org/2001/XMLSchema#positiveInteger': case 'http://www.w3.org/2001/XMLSchema#unsignedLong': case 'http://www.w3.org/2001/XMLSchema#unsignedInt': case 'http://www.w3.org/2001/XMLSchema#unsignedShort': case 'http://www.w3.org/2001/XMLSchema#nonPositiveInteger': case 'http://www.w3.org/2001/XMLSchema#negativeInteger': temp = parseFloat(value.value); if (temp.toString() === value.value) { // use number only if it is fully round-tripable back to string // TBD: this might be overcautios, and would cause more problems than solve return temp; } break; case 'http://www.opengis.net/ont/geosparql#wktLiteral': // Point(-64.2 -36.62) -- (longitude latitude) temp = /^Point\(([-0-9.]+) ([-0-9.]+)\)$/.exec(value.value); if (temp) { return [parseFloat(temp[1]), parseFloat(temp[2])]; } break; } break; case 'uri': // "http://www.wikidata.org/entity/Q12345" -> "Q12345" temp = /^http:\/\/www\.wikidata\.org\/entity\/(Q[1-9][0-9]*)$/.exec(value.value); if (temp) { return temp[1]; } break; } return ignoreUnknown ? undefined : value.value; } },{}]},{},[1]);