diff --git a/.gitignore b/.gitignore index 9fea7be..dd4c15e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ *~ .vagrant www/include/config_dev.php -www/include/secrets_dev.php +www/include/config_local*.php www/include/secrets*.php www/test*.php tests/coverage.state diff --git a/Makefile b/Makefile index 0505a40..2673dc8 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,9 @@ templates: secret: php -q ./bin/generate_secret.php +countries: + php -q ./bin/mk_countries.php + setup: if test ! -f www/include/secrets.php; then cp www/include/secrets.php.example www/include/secrets.php; fi ubuntu/setup-ubuntu.sh @@ -29,12 +32,20 @@ setup-nossl: ubuntu/setup-db.sh wof_api wof_api ubuntu/setup-apache-conf.sh nossl -mapzen: styleguide mapzenjs refill +mapzen: styleguide favicons mapzenjs refill styleguide: - if test -e www/css/mapzen.styleguide.css; then cp www/css/mapzen.styleguide.css www/css/mapzen.styleguide.css.bak; fi curl -s -o www/css/mapzen.styleguide.css https://mapzen.com/common/styleguide/styles/styleguide.css + curl -s -o www/css/mapzen.website.css https://mapzen.com/common/styleguide/styles/website.css curl -s -o www/javascript/mapzen.styleguide.min.js https://mapzen.com/common/styleguide/scripts/mapzen-styleguide.min.js + curl -s -o www/common/styleguide/images/background/contour_darkpurple2_lg.png https://mapzen.com/common/styleguide/images/background/contour_darkpurple2_lg.png + +favicons: + curl -s -o www/images/favicons/apple-touch-icon.png https://mapzen.com/common/styleguide/images/favicons/apple-touch-icon.png + curl -s -o www/images/favicons/favicon-16x16.png https://mapzen.com/common/styleguide/images/favicons/favicon-16x16.png + curl -s -o www/images/favicons/favicon-32x32.png https://mapzen.com/common/styleguide/images/favicons/favicon-32x32.png + curl -s -o www/images/favicons/manifest.json https://mapzen.com/common/styleguide/images/favicons/manifest.json + curl -s -o www/images/favicons/safari-pinned-tab.svg https://mapzen.com/common/styleguide/images/favicons/safari-pinned-tab.svg tangram: curl -s -o www/javascript/tangram.js https://mapzen.com/tangram/tangram.debug.js @@ -44,12 +55,14 @@ refill: curl -s -o www/tangram/refill-style.zip https://mapzen.com/carto/refill-style/refill-style.zip mapzenjs: - curl -s -o www/css/mapzen.js.css https://mapzen.com/js/mapzen.css - curl -s -o www/javascript/mapzen.js https://mapzen.com/js/mapzen.js - curl -s -o www/javascript/mapzen.min.js https://mapzen.com/js/mapzen.min.js + #curl -s -o www/css/mapzen.js.css https://mapzen.com/js/mapzen.css + #curl -s -o www/javascript/mapzen.js https://mapzen.com/js/mapzen.js + #curl -s -o www/javascript/mapzen.min.js https://mapzen.com/js/mapzen.min.js whosonfirstjs: curl -s -o www/javascript/mapzen.whosonfirst.uri.js https://raw.githubusercontent.com/whosonfirst/js-mapzen-whosonfirst/master/src/mapzen.whosonfirst.uri.js + curl -s -o www/javascript/mapzen.places.api.js https://raw.githubusercontent.com/whosonfirst/js-mapzen-whosonfirst/master/src/mapzen.places.api.js + curl -s -o www/javascript/mapzen.whosonfirst.geojson.js https://raw.githubusercontent.com/whosonfirst/js-mapzen-whosonfirst/master/src/mapzen.whosonfirst.geojson.js chrome: curl -s -o www/css/mapzen.whosonfirst.chrome.css https://raw.githubusercontent.com/whosonfirst/css-mapzen-whosonfirst/master/css/mapzen.whosonfirst.chrome.css @@ -57,12 +70,31 @@ chrome: curl -s -o www/javascript/mapzen.whosonfirst.chrome.init.js https://raw.githubusercontent.com/whosonfirst/js-mapzen-whosonfirst/master/src/mapzen.whosonfirst.chrome.init.js whosonfirst: + curl -s -o www/include/lib_whosonfirst_brands_sizes.php https://raw.githubusercontent.com/whosonfirst/flamework-whosonfirst/master/www/include/lib_whosonfirst_brands_sizes.php + curl -s -o www/include/lib_whosonfirst_brands_sizes_spec.php https://raw.githubusercontent.com/whosonfirst/flamework-whosonfirst/master/www/include/lib_whosonfirst_brands_sizes_spec.php curl -s -o www/include/lib_whosonfirst_placetypes.php https://raw.githubusercontent.com/whosonfirst/flamework-whosonfirst/master/www/include/lib_whosonfirst_placetypes.php curl -s -o www/include/lib_whosonfirst_placetypes_spec.php https://raw.githubusercontent.com/whosonfirst/flamework-whosonfirst/master/www/include/lib_whosonfirst_placetypes_spec.php curl -s -o www/include/lib_whosonfirst_sources.php https://raw.githubusercontent.com/whosonfirst/flamework-whosonfirst/master/www/include/lib_whosonfirst_sources.php curl -s -o www/include/lib_whosonfirst_sources_spec.php https://raw.githubusercontent.com/whosonfirst/flamework-whosonfirst/master/www/include/lib_whosonfirst_sources_spec.php curl -s -o www/include/lib_whosonfirst_uri.php https://raw.githubusercontent.com/whosonfirst/flamework-whosonfirst/master/www/include/lib_whosonfirst_uri.php +leaflet-locate: + curl -s -o www/javascript/L.Control.Locate.min.js https://raw.githubusercontent.com/domoritz/leaflet-locatecontrol/gh-pages/dist/L.Control.Locate.min.js + curl -s -o www/javascript/L.Control.Locate.js https://raw.githubusercontent.com/domoritz/leaflet-locatecontrol/gh-pages/src/L.Control.Locate.js + curl -s -o www/css/L.Control.Locate.css https://raw.githubusercontent.com/domoritz/leaflet-locatecontrol/gh-pages/dist/L.Control.Locate.css + curl -s -o www/css/L.Control.Locate.min.css https://raw.githubusercontent.com/domoritz/leaflet-locatecontrol/gh-pages/dist/L.Control.Locate.min.css + +LEAFLET_MARKERCLUSTER_VERSION = 1.1.0 +leaflet-markercluster: + curl -s -L -o /tmp/leaflet-markercluster.zip https://github.com/Leaflet/Leaflet.markercluster/archive/v$(LEAFLET_MARKERCLUSTER_VERSION).zip + unzip -q /tmp/leaflet-markercluster.zip -d /tmp + cp /tmp/Leaflet.markercluster-$(LEAFLET_MARKERCLUSTER_VERSION)/dist/leaflet.markercluster.js www/javascript/leaflet.markercluster.min.js + cp /tmp/Leaflet.markercluster-$(LEAFLET_MARKERCLUSTER_VERSION)/dist/leaflet.markercluster-src.js www/javascript/leaflet.markercluster.js + cp /tmp/Leaflet.markercluster-$(LEAFLET_MARKERCLUSTER_VERSION)/dist/MarkerCluster.css www/css/leaflet.markercluster.css + cp /tmp/Leaflet.markercluster-$(LEAFLET_MARKERCLUSTER_VERSION)/dist/MarkerCluster.Default.css www/css/leaflet.markercluster.default.css + rm -rf /tmp/Leaflet.markercluster-$(LEAFLET_MARKERCLUSTER_VERSION) + rm /tmp/leaflet-markercluster.zip + dev-to-master: git checkout master git pull origin dev diff --git a/bin/disable_site.sh b/bin/disable_site.sh index 130ed28..e45dcc9 100755 --- a/bin/disable_site.sh +++ b/bin/disable_site.sh @@ -10,8 +10,10 @@ PROJECT=`dirname $BIN` WWW="${PROJECT}/www" INCLUDE="${WWW}/include" -CONFIG="${INCLUDE}/config.php" -${PERL} -p -i -e "s/\['cfg'\]\['site_disabled'\]\s*=\s*[^;];/['cfg']['site_disabled'] = 1;/" ${CONFIG} +for CONFIG in `ls -a ${INCLUDE}/config.php ${INCLUDE}/config_local*.php` +do + ${PERL} -p -i -e "s/\['cfg'\]\['site_disabled'\]\s*=\s*[^;];/['cfg']['site_disabled'] = 1;/" ${CONFIG} +done exit 0 diff --git a/bin/enable_site.sh b/bin/enable_site.sh index 7372dbe..eb5f356 100755 --- a/bin/enable_site.sh +++ b/bin/enable_site.sh @@ -12,6 +12,9 @@ WWW="${PROJECT}/www" INCLUDE="${WWW}/include" CONFIG="${INCLUDE}/config.php" -${PERL} -p -i -e "s/\['cfg'\]\['site_disabled'\]\s*=\s*[^;];/['cfg']['site_disabled'] = 0;/" ${CONFIG} +for CONFIG in `ls -a ${INCLUDE}/config.php ${INCLUDE}/config_local*.php` +do + ${PERL} -p -i -e "s/\['cfg'\]\['site_disabled'\]\s*=\s*[^;];/['cfg']['site_disabled'] = 0;/" ${CONFIG} +done exit 0 diff --git a/bin/mk_countries.php b/bin/mk_countries.php new file mode 100644 index 0000000..9152bb7 --- /dev/null +++ b/bin/mk_countries.php @@ -0,0 +1,63 @@ + 500 + ); + + $php = '<' . '?php'; + $now = date('Y-m-d H:i:s'); + + $head = << $esc_id, + 'wof:name' => $place['wof:name'] + ); + $country = << array( + 'wof:id' => $esc_id, + 'wof:name' => '$esc_name' + ), + +END; + fwrite($fh, $country); + } + + $foot = <<. -# -# The installation procedure is covered at -# . -# -# Elasticsearch comes with reasonable defaults for most settings, -# so you can try it out without bothering with configuration. -# -# Most of the time, these defaults are just fine for running a production -# cluster. If you're fine-tuning your cluster, or wondering about the -# effect of certain configuration option, please _do ask_ on the -# mailing list or IRC channel [http://elasticsearch.org/community]. - -# Any element in the configuration can be replaced with environment variables -# by placing them in ${...} notation. For example: -# -#node.rack: ${RACK_ENV_VAR} - -# For information on supported formats and syntax for the config file, see -# - - -################################### Cluster ################################### - -# Cluster name identifies your cluster for auto-discovery. If you're running -# multiple clusters on the same network, make sure you're using unique names. -# -cluster.name: whosonfirst - - -#################################### Node ##################################### - -# Node names are generated dynamically on startup, so you're relieved -# from configuring them manually. You can tie this node to a specific name: -# -node.name: "Who's On First" -index.number_of_shards: 1 -index.number_of_replicas: 0 - -# Every node can be configured to allow or deny being eligible as the master, -# and to allow or deny to store the data. -# -# Allow this node to be eligible as a master node (enabled by default): -# -#node.master: true -# -# Allow this node to store data (enabled by default): -# -#node.data: true - -# You can exploit these settings to design advanced cluster topologies. -# -# 1. You want this node to never become a master node, only to hold data. -# This will be the "workhorse" of your cluster. -# -#node.master: false -#node.data: true -# -# 2. You want this node to only serve as a master: to not store any data and -# to have free resources. This will be the "coordinator" of your cluster. -# -#node.master: true -#node.data: false -# -# 3. You want this node to be neither master nor data node, but -# to act as a "search load balancer" (fetching data from nodes, -# aggregating results, etc.) -# -#node.master: false -#node.data: false - -# Use the Cluster Health API [http://localhost:9200/_cluster/health], the -# Node Info API [http://localhost:9200/_nodes] or GUI tools -# such as , -# , -# and -# to inspect the cluster state. - -# A node can have generic attributes associated with it, which can later be used -# for customized shard allocation filtering, or allocation awareness. An attribute -# is a simple key value pair, similar to node.key: value, here is an example: -# -#node.rack: rack314 - -# By default, multiple nodes are allowed to start from the same installation location -# to disable it, set the following: -#node.max_local_storage_nodes: 1 - - -#################################### Index #################################### - -# You can set a number of options (such as shard/replica options, mapping -# or analyzer definitions, translog settings, ...) for indices globally, -# in this file. -# -# Note, that it makes more sense to configure index settings specifically for -# a certain index, either when creating it or by using the index templates API. -# -# See and -# -# for more information. - -# Set the number of shards (splits) of an index (5 by default): -# -#index.number_of_shards: 5 - -# Set the number of replicas (additional copies) of an index (1 by default): -# -#index.number_of_replicas: 1 - -# Note, that for development on a local machine, with small indices, it usually -# makes sense to "disable" the distributed features: -# -#index.number_of_shards: 1 -#index.number_of_replicas: 0 - -# These settings directly affect the performance of index and search operations -# in your cluster. Assuming you have enough machines to hold shards and -# replicas, the rule of thumb is: -# -# 1. Having more *shards* enhances the _indexing_ performance and allows to -# _distribute_ a big index across machines. -# 2. Having more *replicas* enhances the _search_ performance and improves the -# cluster _availability_. -# -# The "number_of_shards" is a one-time setting for an index. -# -# The "number_of_replicas" can be increased or decreased anytime, -# by using the Index Update Settings API. -# -# Elasticsearch takes care about load balancing, relocating, gathering the -# results from nodes, etc. Experiment with different settings to fine-tune -# your setup. - -# Use the Index Status API () to inspect -# the index status. - - -#################################### Paths #################################### - -# Path to directory containing configuration (this file and logging.yml): -# -#path.conf: /path/to/conf - -# Path to directory where to store index data allocated for this node. -# -#path.data: /path/to/data -# -# Can optionally include more than one location, causing data to be striped across -# the locations (a la RAID 0) on a file level, favouring locations with most free -# space on creation. For example: -# -#path.data: /path/to/data1,/path/to/data2 - -# Path to temporary files: -# -#path.work: /path/to/work - -# Path to log files: -# -#path.logs: /path/to/logs - -# Path to where plugins are installed: -# -#path.plugins: /path/to/plugins - - -#################################### Plugin ################################### - -# If a plugin listed here is not installed for current node, the node will not start. -# -#plugin.mandatory: mapper-attachments,lang-groovy - - -################################### Memory #################################### - -# Elasticsearch performs poorly when JVM starts swapping: you should ensure that -# it _never_ swaps. -# -# Set this property to true to lock the memory: -# -#bootstrap.mlockall: true - -# Make sure that the ES_MIN_MEM and ES_MAX_MEM environment variables are set -# to the same value, and that the machine has enough memory to allocate -# for Elasticsearch, leaving enough memory for the operating system itself. -# -# You should also make sure that the Elasticsearch process is allowed to lock -# the memory, eg. by using `ulimit -l unlimited`. - - -############################## Network And HTTP ############################### - -# Elasticsearch, by default, binds itself to the 0.0.0.0 address, and listens -# on port [9200-9300] for HTTP traffic and on port [9300-9400] for node-to-node -# communication. (the range means that if the port is busy, it will automatically -# try the next port). - -# Set the bind address specifically (IPv4 or IPv6): -# -#network.bind_host: 192.168.0.1 - -# Set the address other nodes will use to communicate with this node. If not -# set, it is automatically derived. It must point to an actual IP address. -# -#network.publish_host: 192.168.0.1 - -# Set both 'bind_host' and 'publish_host': -# -#network.host: 192.168.0.1 - -# Set a custom port for the node to node communication (9300 by default): -# -#transport.tcp.port: 9300 - -# Enable compression for all communication between nodes (disabled by default): -# -#transport.tcp.compress: true - -# Set a custom port to listen for HTTP traffic: -# -#http.port: 9200 - -# Set a custom allowed content length: -# -#http.max_content_length: 100mb - -# Disable HTTP completely: -# -#http.enabled: false - - -################################### Gateway ################################### - -# The gateway allows for persisting the cluster state between full cluster -# restarts. Every change to the state (such as adding an index) will be stored -# in the gateway, and when the cluster starts up for the first time, -# it will read its state from the gateway. - -# There are several types of gateway implementations. For more information, see -# . - -# The default gateway type is the "local" gateway (recommended): -# -#gateway.type: local - -# Settings below control how and when to start the initial recovery process on -# a full cluster restart (to reuse as much local data as possible when using shared -# gateway). - -# Allow recovery process after N nodes in a cluster are up: -# -#gateway.recover_after_nodes: 1 - -# Set the timeout to initiate the recovery process, once the N nodes -# from previous setting are up (accepts time value): -# -#gateway.recover_after_time: 5m - -# Set how many nodes are expected in this cluster. Once these N nodes -# are up (and recover_after_nodes is met), begin recovery process immediately -# (without waiting for recover_after_time to expire): -# -#gateway.expected_nodes: 2 - - -############################# Recovery Throttling ############################# - -# These settings allow to control the process of shards allocation between -# nodes during initial recovery, replica allocation, rebalancing, -# or when adding and removing nodes. - -# Set the number of concurrent recoveries happening on a node: -# -# 1. During the initial recovery -# -#cluster.routing.allocation.node_initial_primaries_recoveries: 4 -# -# 2. During adding/removing nodes, rebalancing, etc -# -#cluster.routing.allocation.node_concurrent_recoveries: 2 - -# Set to throttle throughput when recovering (eg. 100mb, by default 20mb): -# -#indices.recovery.max_bytes_per_sec: 20mb - -# Set to limit the number of open concurrent streams when -# recovering a shard from a peer: -# -#indices.recovery.concurrent_streams: 5 - - -################################## Discovery ################################## - -# Discovery infrastructure ensures nodes can be found within a cluster -# and master node is elected. Multicast discovery is the default. - -# Set to ensure a node sees N other master eligible nodes to be considered -# operational within the cluster. This should be set to a quorum/majority of -# the master-eligible nodes in the cluster. -# -#discovery.zen.minimum_master_nodes: 1 - -# Set the time to wait for ping responses from other nodes when discovering. -# Set this option to a higher value on a slow or congested network -# to minimize discovery failures: -# -#discovery.zen.ping.timeout: 3s - -# For more information, see -# - -# Unicast discovery allows to explicitly control which nodes will be used -# to discover the cluster. It can be used when multicast is not present, -# or to restrict the cluster communication-wise. -# -# 1. Disable multicast discovery (enabled by default): -# -#discovery.zen.ping.multicast.enabled: false -# -# 2. Configure an initial list of master nodes in the cluster -# to perform discovery when new nodes (master or data) are started: -# -#discovery.zen.ping.unicast.hosts: ["host1", "host2:port"] - -# EC2 discovery allows to use AWS EC2 API in order to perform discovery. -# -# You have to install the cloud-aws plugin for enabling the EC2 discovery. -# -# For more information, see -# -# -# See -# for a step-by-step tutorial. - -# GCE discovery allows to use Google Compute Engine API in order to perform discovery. -# -# You have to install the cloud-gce plugin for enabling the GCE discovery. -# -# For more information, see . - -# Azure discovery allows to use Azure API in order to perform discovery. -# -# You have to install the cloud-azure plugin for enabling the Azure discovery. -# -# For more information, see . - -################################## Slow Log ################################## - -# Shard level query and fetch threshold logging. - -#index.search.slowlog.threshold.query.warn: 10s -#index.search.slowlog.threshold.query.info: 5s -#index.search.slowlog.threshold.query.debug: 2s -#index.search.slowlog.threshold.query.trace: 500ms - -#index.search.slowlog.threshold.fetch.warn: 1s -#index.search.slowlog.threshold.fetch.info: 800ms -#index.search.slowlog.threshold.fetch.debug: 500ms -#index.search.slowlog.threshold.fetch.trace: 200ms - -#index.indexing.slowlog.threshold.index.warn: 10s -#index.indexing.slowlog.threshold.index.info: 5s -#index.indexing.slowlog.threshold.index.debug: 2s -#index.indexing.slowlog.threshold.index.trace: 500ms - -################################## GC Logging ################################ - -#monitor.jvm.gc.young.warn: 1000ms -#monitor.jvm.gc.young.info: 700ms -#monitor.jvm.gc.young.debug: 400ms - -#monitor.jvm.gc.old.warn: 10s -#monitor.jvm.gc.old.info: 5s -#monitor.jvm.gc.old.debug: 2s - -################################## Security ################################ - -# Uncomment if you want to enable JSONP as a valid return transport on the -# http server. With this enabled, it may pose a security risk, so disabling -# it unless you need it is recommended (it is disabled by default). -# -#http.jsonp.enable: true diff --git a/docs/errors.md b/docs/errors.md index 4ae4dd9..3631c3c 100644 --- a/docs/errors.md +++ b/docs/errors.md @@ -1,4 +1,4 @@ -In addition to any already [assigned HTTP status codes](https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml) The Who's On First API assigns specific meaning to certain codes and defines the following additional status codes for representing errors or a failure scenario, across all API methods: +In addition to any already [assigned HTTP status codes](https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml) The Mapzen Places API assigns specific meaning to certain codes and defines the following additional status codes for representing errors or a failure scenario, across all API methods: ### Mapzen errors diff --git a/docs/formats.md b/docs/formats.md index c837987..aa952a2 100644 --- a/docs/formats.md +++ b/docs/formats.md @@ -11,7 +11,7 @@ The default response format is [JSON](formats.md#json). #### Example request ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getInfoMulti&api_key=your-mapzen-api-key&ids=101712565,101712563&format=chicken' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.getInfoMulti&api_key=your-mapzen-api-key&ids=101712565,101712563&format=chicken' ``` #### Example response @@ -55,7 +55,7 @@ CSV (Comma Separated Value) #### Example request ``` -curl -X GET 'https://whosonfirst-api.mapzen.com?method=whosonfirst.places.search&api_key=your-mapzen-api-key&q=poutine&page=1&per_page=1&format=csv' +curl -X GET 'https://places.mapzen.com/v1?method=mapzen.places.search&api_key=your-mapzen-api-key&q=poutine&page=1&per_page=1&format=csv' ``` #### Example response @@ -67,7 +67,7 @@ curl -X GET 'https://whosonfirst-api.mapzen.com?method=whosonfirst.places.search < Date: Tue, 28 Feb 2017 21:13:37 GMT < Status: 200 OK < X-api-pagination-cursor: -< X-api-pagination-next-query: method=whosonfirst.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2&format=csv +< X-api-pagination-next-query: method=mapzen.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2&format=csv < X-api-pagination-page: 1 < X-api-pagination-pages: 13 < X-api-pagination-per-page: 1 @@ -93,7 +93,7 @@ GeoJSON is a data-interchange format based on JavaScript. For more details, cons #### Example request ``` -curl -X GET 'https://whosonfirst-api.mapzen.com?method=whosonfirst.places.getInfoMulti&api_key=your-mapzen-api-key&&ids=101712565,101712563&format=geojson' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.getInfoMulti&api_key=your-mapzen-api-key&&ids=101712565,101712563&format=geojson' ``` #### Example response @@ -173,7 +173,7 @@ JSON (JavaScript Object Notation) is a data-interchange format based on JavaScri #### Example request ``` -curl -X GET 'https://whosonfirst-api.mapzen.com?method=whosonfirst.places.search&api_key=your-mapzen-api-key&q=poutine&page=1&per_page=1&format=json' +curl -X GET 'https://places.mapzen.com/v1/?method=whosonfirst.places.search&api_key=your-mapzen-api-key&q=poutine&page=1&per_page=1&format=json' ``` #### Example response @@ -185,7 +185,7 @@ curl -X GET 'https://whosonfirst-api.mapzen.com?method=whosonfirst.places.search < Date: Tue, 28 Feb 2017 22:29:49 GMT < Status: 200 OK < X-api-pagination-cursor: -< X-api-pagination-next-query: method=whosonfirst.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2 +< X-api-pagination-next-query: method=mapzen.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2 < X-api-pagination-page: 1 < X-api-pagination-pages: 13 < X-api-pagination-per-page: 1 @@ -195,7 +195,7 @@ curl -X GET 'https://whosonfirst-api.mapzen.com?method=whosonfirst.places.search < { "cursor": null, - "next_query": "method=whosonfirst.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2", + "next_query": "method=mapzen.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2", "page": 1, "pages": 13, "per_page": 1, @@ -227,7 +227,7 @@ As in a Who's On First "meta" file. A meta file is really just a CSV file with a #### Example request ``` -curl -X GET 'https://whosonfirst-api.mapzen.com?method=whosonfirst.places.search&api_key=your-mapzen-api-key&q=poutine&page=1&per_page=1&format=meta' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.search&api_key=your-mapzen-api-key&q=poutine&page=1&per_page=1&format=meta' ``` #### Example response @@ -239,7 +239,7 @@ curl -X GET 'https://whosonfirst-api.mapzen.com?method=whosonfirst.places.search < Date: Tue, 28 Feb 2017 22:25:13 GMT < Status: 200 OK < X-api-pagination-cursor: -< X-api-pagination-next-query: method=whosonfirst.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2&format=meta +< X-api-pagination-next-query: method=mapzen.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2&format=meta < X-api-pagination-page: 1 < X-api-pagination-pages: 13 < X-api-pagination-per-page: 1 diff --git a/docs/index.md b/docs/index.md index 4dbd58c..ecc5abd 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,9 +1,9 @@ -The Who's On First API allows developers (and robots) programmatic access to query and retrieve Who's On First data via a [REST-ish](#cgi) interface. +The Mapzen Places API allows developers (and robots) programmatic access to query and retrieve Who's On First data via a [REST-ish](#cgi) interface. API methods are dispatched over `HTTP` with one or more query parameters and data is returned in response as [JSON](formats.md#json) by default but you may also specify [CSV](formats.md#csv) or Who's On First's own [meta](formats.md#meta) formatted responses for certain [API methods](methods.md). -The endpoint for the Who's On First API is: **[https://whosonfirst-api.mapzen.com/](https://whosonfirst-api.mapzen.com/)** +The endpoint for the Mapzen Places API is: **[https://places.mapzen.com/v1/](https://places.mapzen.com/v1/)** All errors are returned using [HTTP status codes](errors.md) in the `400-599` range. @@ -18,12 +18,12 @@ Which is to say: The point is for _the thing to work_ but there are probably sti Also some methods are "more beta" than others. These methods are flagged as being `experimental` which means that both either their inputs or their outputs _may_ change without warning. We'll try not to introduce any backwards incompatible changes but you should approach these API methods defensively. -Finally the API is not feature complete yet. The easiest way to think about the Who's On First API is to look at the Who's On First [Spelunker]() website and imagine that anything you can do there to search and navigate all those places should also be possible via the API. As of this writing it is not but we'll get there. If there is anything currently missing that you'd like or need to do sooner than later [send up a flare](https://twitter.co/alloftheplaces) and we'll see about adding it to the list. +Finally the API is not feature complete yet. The easiest way to think about the Mapzen Places API is to look at the Who's On First [Spelunker](https://whosonfirst.mapzen.com/spelunker/) website and imagine that anything you can do there to search and navigate all those places should also be possible via the API. As of this writing it is not but we'll get there. If there is anything currently missing that you'd like or need to do sooner than later [send up a flare](https://twitter.co/alloftheplaces) and we'll see about adding it to the list. ### API Keys -To use the Who's On First API, you should [first obtain a free developer API key](https://mapzen.com/documentation/overview/). +To use the Mapzen Places API, you should [first obtain a free developer API key](https://mapzen.com/documentation/overview/). ### Rate limits diff --git a/docs/methods.md b/docs/methods.md index faaac5f..a6c3ab1 100644 --- a/docs/methods.md +++ b/docs/methods.md @@ -29,7 +29,7 @@ This API method does not define any custom error codes. For the list of error co ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=api.spec.errors&api_key=your-mapzen-api-key' +curl -X GET 'https://places.mapzen.com/v1/?method=api.spec.errors&api_key=your-mapzen-api-key' { "errors": [ @@ -70,7 +70,7 @@ This API method does not define any custom error codes. For the list of error co ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=api.spec.formats&api_key=your-mapzen-api-key' +curl -X GET 'https://places.mapzen.com/v1/?method=api.spec.formats&api_key=your-mapzen-api-key' { "formats": [ @@ -108,52 +108,33 @@ This API method does not define any custom error codes. For the list of error co ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=api.spec.methods&api_key=your-mapzen-api-key' +curl -X GET 'https://places.mapzen.com/v1/?method=api.spec.methods&api_key=your-mapzen-api-key' { "methods": [ { - "name": "whosonfirst.concordances.getById", + "name": "api.spec.methods", "method": "GET", - "description": "Return a Who's On First record (and all its concordances) by another source identifier.", + "description": "Return the list of available API response methods.", "requires_auth": 0, "parameters": [ - { - "name": "id", - "description": "The ID of concordance you are looking for", - "required": 1, - "example": "3534" - }, - { - "name": "source", - "description": "The source prefix of the concordance you are looking for", - "required": 1, - "example": "gp:id" - } + + ], + "errors": [ + ], - "errors": { - "432": { - "message": "Missing 'id' parameter" - }, - "433": { - "message": "Missing 'source' parameter" - }, - "513": { - "message": "Failed to retrieve concordance" - } - }, "extras": 0, - "paginated": 1, - "pagination": "plain", + "paginated": 0, "disallow_formats": [ + "csv", "geojson", "meta" ] }, { - "name": "whosonfirst.concordances.getSources", + "name": "api.spec.errors", "method": "GET", - "description": "List all the sources that Who's On First holds hands with.", + "description": "Return the list of API error responses common to all methods.", "requires_auth": 0, "parameters": [ @@ -162,9 +143,9 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=api.spec.methods&api_key ], "extras": 0, - "paginated": 1, - "pagination": "plain", + "paginated": 0, "disallow_formats": [ + "csv", "geojson", "meta" ] @@ -204,7 +185,7 @@ This API method does not define any custom error codes. For the list of error co ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=api.test.echo&api_key=your-mapzen-api-key' +curl -X GET 'https://places.mapzen.com/v1/?method=api.test.echo&api_key=your-mapzen-api-key' { "stat": "ok" @@ -234,19 +215,19 @@ This API method does not define any custom error codes. For the list of error co ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=api.test.error&api_key=your-mapzen-api-key' +curl -X GET 'https://places.mapzen.com/v1/?method=api.test.error&api_key=your-mapzen-api-key' null ``` -### whosonfirst.concordances +### mapzen.places.concordances -* [whosonfirst.concordances.getById](#whosonfirst.concordances.getById) -* [whosonfirst.concordances.getSources](#whosonfirst.concordances.getSources) +* [mapzen.places.concordances.getById](#mapzen.places.concordances.getById) +* [mapzen.places.concordances.getSources](#mapzen.places.concordances.getSources) - -#### whosonfirst.concordances.getById + +#### mapzen.places.concordances.getById Return a Who's On First record (and all its concordances) by another source identifier. @@ -279,7 +260,7 @@ In addition to [default error codes](errors.md) common to all methods this API m ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.concordances.getById&api_key=your-mapzen-api-key&id=3534&source=gp:id&per_page=1' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.concordances.getById&api_key=your-mapzen-api-key&id=3534&source=gp:id&per_page=1' { "concordances": [ @@ -308,8 +289,8 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.concordances } ``` - -#### whosonfirst.concordances.getSources + +#### mapzen.places.concordances.getSources List all the sources that Who's On First holds hands with. @@ -334,7 +315,7 @@ This API method does not define any custom error codes. For the list of error co ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.concordances.getSources&api_key=your-mapzen-api-key&per_page=1' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.concordances.getSources&api_key=your-mapzen-api-key&per_page=1' { "sources": [ @@ -343,7 +324,7 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.concordances "concordances": 20584083 } ], - "next_query": "method=whosonfirst.concordances.getSources&per_page=1&page=2", + "next_query": "method=mapzen.places.concordances.getSources&per_page=1&page=2", "total": 31, "page": 1, "per_page": 1, @@ -354,96 +335,21 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.concordances ``` -### whosonfirst.pelias - -* [whosonfirst.pelias.search](#whosonfirst.pelias.search) - - -#### whosonfirst.pelias.search - -Query Who's On First using the Pelias API - -##### Arguments - -| Argument | Description | Example | Required | -| :--- | :--- | :--- | :--- | -| `api_key` | A valid [Mapzen API key](https://mapzen.com/developers/) | your-mapzen-api-key | yes | -| `text` | A valid query string. This is the equivalent of the WOF 'names' parameter. | JFK | no | -| `size` | The number of results per query. This is the equivalent of the WOF 'per_page' parameter. | 10 | no | -| `layers` | Ensure records match this placetype. This is equivalent to the WOF 'placetype' parameter. | borough | no | -| `boundary.country` | Ensure places belong to this ISO country code. This is equivalent to the WOF 'iso' parameter. | ch | no | -| `q` | A valid query string. This is the equivalent of the Pelias 'text' parameter. | JFK | no | -| `placetype` | Ensure records match this placetype. This is equivalent to the Pelias 'layers' parameter. | neighbourhood | no | -| `iso` | Ensure places belong to this ISO country code. This is equivalent to the Pelias 'boundary.country' parameter. | fr | no | -| `query_field` | Scope the query alternate names (alt), variant names (variant), preferred names (preferred), wof:name values (name) or all the names (names). Valid options are: alt, name, names, preferred, variant. If left empty then the query will be performed across all WOF properties. | alt | no | -| `extras` | A comma-separated list of additional fields to include with each result. Valid fields are anything that might be found at the top level of WOF properties dictionary. You can also fetch all the fields for a given namespace by passing its prefix followed by a colon (for example `mz:`) | mz:uri | no | -| `cursor` | This method sometimes uses cursor-based pagination so this argument is the pointer returned by the last API response, in the `cursor` property. | _cXVl...c7MDs=_ | no | -| `page` | The default is 1. If this API method returns a non-empty `cursor` property as part of its response that means you should switch to using cursor-based pagination for all subsequent queries. Alternately you can simply rely on the `next_query` property to determine which parameters to include with your next request. Unfortunately it's complicated because databases are, after all these years, still complicated. Please consult the [pagination documentation](pagination.md) for details. | 1 | no | -| `per_page` | The default is 100 and the maximum is 500. | 100 | no | -| `format` | The format in which to return the data. Normally supported formats are [chicken](formats.md#chicken), [csv](formats.md#csv), [geojson](formats.md#geojson), [json](formats.md#json), [meta](formats.md#meta) however the following output formats are **disallowed** for this API method: [csv](formats.md#csv), [meta](formats.md#meta). The default format is [json](formats.md#json). | json | no | - -##### Error codes - -In addition to [default error codes](errors.md) common to all methods this API method defines the following additional error codes: - -| Error code | Error message | -| :--- | :--- | -| `432` | Unsupported Pelias API parameter | -| `433` | Multiple placetypes not supported (yet) | -| `434` | Invalid placetype | -| `435` | Invalid 'min_latitude' parameter | -| `436` | Invalid 'max_longitude' parameter | -| `437` | Invalid 'max_latitude' parameter | -| `438` | Invalid 'max_longitude' parameter | -| `439` | One or more missing parameters in bounding box query | -| `440` | Invalid output format | -| `441` | Invalid Pelias API version | -| `442` | Invalid (WOF) query field | -| `513` | Failed to perform lookup | - -##### Notes - -* Although neither the 'text' or 'q' parameters are required individually you must pass at least one of them. -* If both a Pelias API and its equivalent WOF parameter are passed the WOF parameter will take precendence. For example if you search for '?text=JFK&q=poutine' the API will only search for 'poutine'. -* The following Pelias API parameters are currently unsupported: boundary.circle.lat, boundary.circle.lon, boundary.circle.radius, boundary.rect.min_lat, boundary.rect.min_lon, boundary.rect.max_lat, boundary.rect.max_lon, focus.point.lat, focus.point.lon, sources -* The following output formats are **disallowed** for this API method: [csv](formats.md#csv), [meta](formats.md#meta) -* This API method uses [mixed](pagination.md#mixed) or [next-query](pagination.md#next-query) pagination. Please consult the [pagination documentation](pagination.md) for details. - -##### Example - -``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.pelias.search&api_key=your-mapzen-api-key&text=JFK&size=10&layers=borough&boundary.rect.min_lat=25.84&boundary.rect.min_lon=-106.65&boundary.rect.max_lat=36.5&boundary.rect.max_lon=-93.51&boundary.country=ch&q=JFK&placetype=neighbourhood&iso=fr&min_latitude=25.84&min_longitude=-106.65&max_latitude=36.5&max_longitude=-93.51&query_field=alt&per_page=1' - -{ - "places": [ - - ], - "next_query": null, - "total": 0, - "page": 1, - "per_page": 1, - "pages": 0, - "cursor": null, - "stat": "ok" -} -``` - - -### whosonfirst.places +### mapzen.places -* [whosonfirst.places.getByLatLon](#whosonfirst.places.getByLatLon) -* [whosonfirst.places.getDescendants](#whosonfirst.places.getDescendants) -* [whosonfirst.places.getHierarchiesByLatLon](#whosonfirst.places.getHierarchiesByLatLon) -* [whosonfirst.places.getInfo](#whosonfirst.places.getInfo) -* [whosonfirst.places.getInfoMulti](#whosonfirst.places.getInfoMulti) -* [whosonfirst.places.getIntersects](#whosonfirst.places.getIntersects) -* [whosonfirst.places.getNearby](#whosonfirst.places.getNearby) -* [whosonfirst.places.getParentByLatLon](#whosonfirst.places.getParentByLatLon) _experimental_ -* [whosonfirst.places.getRandom](#whosonfirst.places.getRandom) -* [whosonfirst.places.search](#whosonfirst.places.search) +* [mapzen.places.getByLatLon](#mapzen.places.getByLatLon) +* [mapzen.places.getDescendants](#mapzen.places.getDescendants) +* [mapzen.places.getHierarchiesByLatLon](#mapzen.places.getHierarchiesByLatLon) +* [mapzen.places.getInfo](#mapzen.places.getInfo) +* [mapzen.places.getInfoMulti](#mapzen.places.getInfoMulti) +* [mapzen.places.getIntersects](#mapzen.places.getIntersects) +* [mapzen.places.getNearby](#mapzen.places.getNearby) +* [mapzen.places.getParentByLatLon](#mapzen.places.getParentByLatLon) _experimental_ +* [mapzen.places.getRandom](#mapzen.places.getRandom) +* [mapzen.places.search](#mapzen.places.search) - -#### whosonfirst.places.getByLatLon + +#### mapzen.places.getByLatLon Return Who's On First places intersecting a latitude and longitude @@ -478,22 +384,22 @@ In addition to [default error codes](errors.md) common to all methods this API m ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getByLatLon&api_key=your-mapzen-api-key&latitude=37.766633&longitude=-122.417693&placetype=neighbourhood' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.getByLatLon&api_key=your-mapzen-api-key&latitude=37.766633&longitude=-122.417693&placetype=neighbourhood' { "places": [ { - "wof:id": 85887443, - "wof:parent_id": "85922583", - "wof:name": "Mission District", + "wof:id": 85834637, + "wof:parent_id": "1108830809", + "wof:name": "Inner Mission", "wof:placetype": "neighbourhood", "wof:country": "US", "wof:repo": "whosonfirst-data" }, { - "wof:id": 85834637, - "wof:parent_id": "1108830809", - "wof:name": "Inner Mission", + "wof:id": 85887443, + "wof:parent_id": "85922583", + "wof:name": "Mission District", "wof:placetype": "neighbourhood", "wof:country": "US", "wof:repo": "whosonfirst-data" @@ -503,8 +409,8 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getBy } ``` - -#### whosonfirst.places.getDescendants + +#### mapzen.places.getDescendants Return all the descendants for a Who's On First ID. @@ -561,31 +467,24 @@ In addition to [default error codes](errors.md) common to all methods this API m ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getDescendants&api_key=your-mapzen-api-key&id=420780703&per_page=1' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.getDescendants&api_key=your-mapzen-api-key&id=420780703&name=Gowanus Heights&names=SF&alt=Paris&preferred=বেইজিং&variant=💩&placetype=microhood&exclude_placetype=venue&tags=diner&category=&iso=CA&country_id=85633147®ion_id=85669831&locality_id=101736545&neighbourhood_id=102112179&brand_id=1126128733&concordance=loc:id&is_current=1&is_ceased=1&is_deprecated=1&is_superseded=1&is_superseding=1&has_brand=1&exclude=nullisland&include=deprecated&min_lastmod=1493855252&max_lastmod=1496783757&per_page=1' { "places": [ - { - "wof:id": 169473107, - "wof:parent_id": "420780703", - "wof:name": "Alfa Consulting", - "wof:placetype": "venue", - "wof:country": "US", - "wof:repo": "whosonfirst-data-venue-us-ca" - } + ], - "next_query": "method=whosonfirst.places.getDescendants&id=420780703&per_page=1&cursor=cXVlcnlUaGVuRmV0Y2g7NTszNjUwMzg0OlFUam1ETWxKU3pta0hZTHgxMmVEdmc7MzY1MDM4NTpRVGptRE1sSlN6bWtIWUx4MTJlRHZnOzM2NTAzODY6UVRqbURNbEpTem1rSFlMeDEyZUR2ZzszNjUwMzg3OlFUam1ETWxKU3pta0hZTHgxMmVEdmc7MzY1MDM4ODpRVGptRE1sSlN6bWtIWUx4MTJlRHZnOzA7", - "total": 120, - "page": null, - "pages": 120, + "next_query": null, + "total": 0, + "page": 1, "per_page": 1, - "cursor": "cXVlcnlUaGVuRmV0Y2g7NTszNjUwMzg0OlFUam1ETWxKU3pta0hZTHgxMmVEdmc7MzY1MDM4NTpRVGptRE1sSlN6bWtIWUx4MTJlRHZnOzM2NTAzODY6UVRqbURNbEpTem1rSFlMeDEyZUR2ZzszNjUwMzg3OlFUam1ETWxKU3pta0hZTHgxMmVEdmc7MzY1MDM4ODpRVGptRE1sSlN6bWtIWUx4MTJlRHZnOzA7", + "pages": 0, + "cursor": null, "stat": "ok" } ``` - -#### whosonfirst.places.getHierarchiesByLatLon + +#### mapzen.places.getHierarchiesByLatLon Return the closest set of ancestors (hierarchies) for a latitude and longitude @@ -624,11 +523,11 @@ In addition to [default error codes](errors.md) common to all methods this API m ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getHierarchiesByLatLon&api_key=your-mapzen-api-key&latitude=LATITUDE&longitude=LONGITUDE&spr=SPR&placetype=PLACETYPE' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.getHierarchiesByLatLon&api_key=your-mapzen-api-key&latitude=LATITUDE&longitude=LONGITUDE&spr=SPR&placetype=PLACETYPE' ``` - -#### whosonfirst.places.getInfo + +#### mapzen.places.getInfo Return a Who's On First record by ID. @@ -654,7 +553,7 @@ In addition to [default error codes](errors.md) common to all methods this API m ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getInfo&api_key=your-mapzen-api-key&id=420561633' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.getInfo&api_key=your-mapzen-api-key&id=420561633' { "place": { @@ -669,8 +568,8 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getIn } ``` - -#### whosonfirst.places.getInfoMulti + +#### mapzen.places.getInfoMulti Return multiple Who's On First records by ID. @@ -697,7 +596,7 @@ In addition to [default error codes](errors.md) common to all methods this API m ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getInfoMulti&api_key=your-mapzen-api-key&ids=101712565,101712563' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.getInfoMulti&api_key=your-mapzen-api-key&ids=101712565,101712563' { "places": [ @@ -722,8 +621,8 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getIn } ``` - -#### whosonfirst.places.getIntersects + +#### mapzen.places.getIntersects Return all the Who's On First places intersecting a bounding box. @@ -765,7 +664,7 @@ In addition to [default error codes](errors.md) common to all methods this API m ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getIntersects&api_key=your-mapzen-api-key&min_latitude=37.78807088&min_longitude=-122.34374508&max_latitude=37.85749665&max_longitude=-122.25585446&placetype=venue&is_current=1&is_ceased=1&is_deprecated=1&is_superseded=1&is_superseding=1&per_page=1' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.getIntersects&api_key=your-mapzen-api-key&min_latitude=37.78807088&min_longitude=-122.34374508&max_latitude=37.85749665&max_longitude=-122.25585446&placetype=venue&is_current=1&is_ceased=1&is_deprecated=1&is_superseded=1&is_superseding=1&per_page=1' { "places": [ @@ -781,8 +680,8 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getIn } ``` - -#### whosonfirst.places.getNearby + +#### mapzen.places.getNearby Return all the Who's On First records near a point. @@ -821,7 +720,7 @@ In addition to [default error codes](errors.md) common to all methods this API m ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getNearby&api_key=your-mapzen-api-key&latitude=40.784165&longitude=-73.958110&radius=25&placetype=venue&is_current=1&is_ceased=1&is_deprecated=1&is_superseded=1&is_superseding=1&per_page=1' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.getNearby&api_key=your-mapzen-api-key&latitude=40.784165&longitude=-73.958110&radius=25&placetype=venue&is_current=1&is_ceased=1&is_deprecated=1&is_superseded=1&is_superseding=1&per_page=1' { "places": [ @@ -837,8 +736,8 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getNe } ``` - -#### whosonfirst.places.getParentByLatLon + +#### mapzen.places.getParentByLatLon Return Who's On First parent ID for a latitude and longitude and placetype @@ -875,7 +774,7 @@ In addition to [default error codes](errors.md) common to all methods this API m ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getParentByLatLon&api_key=your-mapzen-api-key&latitude=35.655065&longitude=139.369640&placetype=neighbourhood' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.getParentByLatLon&api_key=your-mapzen-api-key&latitude=35.655065&longitude=139.369640&placetype=neighbourhood' { "place": { @@ -885,8 +784,8 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getPa } ``` - -#### whosonfirst.places.getRandom + +#### mapzen.places.getRandom Return a random Who's On First record. @@ -910,23 +809,23 @@ In addition to [default error codes](errors.md) common to all methods this API m ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getRandom&api_key=your-mapzen-api-key' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.getRandom&api_key=your-mapzen-api-key' { "place": { - "wof:id": 85782551, - "wof:parent_id": "-1", - "wof:name": "Veerapandianpattinam", - "wof:placetype": "neighbourhood", - "wof:country": "IN", + "wof:id": 1092076933, + "wof:parent_id": "85680321", + "wof:name": "Sauce", + "wof:placetype": "county", + "wof:country": "UY", "wof:repo": "whosonfirst-data" }, "stat": "ok" } ``` - -#### whosonfirst.places.search + +#### mapzen.places.search Query for Who's On First records. @@ -982,43 +881,226 @@ In addition to [default error codes](errors.md) common to all methods this API m ##### Notes * This API method uses [mixed](pagination.md#mixed) or [next-query](pagination.md#next-query) pagination. Please consult the [pagination documentation](pagination.md) for details. -* Please note that this method _is not a geocoder_. We already have one of those [and you should use that](https://mapzen.com/documentation/search/) instead if geocoding a string is what you're after. ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.search&api_key=your-mapzen-api-key&q=poutine&per_page=1' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.search&api_key=your-mapzen-api-key&q=poutine&name=Gowanus Heights&names=SF&alt=Paris&preferred=বেইজিং&variant=💩&placetype=microhood&exclude_placetype=venue&tags=diner&category=&iso=CA&country_id=85633147®ion_id=85669831&locality_id=101736545&neighbourhood_id=102112179&brand_id=1126128733&concordance=loc:id&is_current=1&is_ceased=1&is_deprecated=1&is_superseded=1&is_superseding=1&has_brand=1&exclude=nullisland&include=deprecated&min_lastmod=1493855252&max_lastmod=1496783757&per_page=1' + +{ + "places": [ + + ], + "next_query": null, + "total": 0, + "page": 1, + "per_page": 1, + "pages": 0, + "cursor": null, + "stat": "ok" +} +``` + + +### mapzen.places.pelias + +* [mapzen.places.pelias.autocomplete](#mapzen.places.pelias.autocomplete) +* [mapzen.places.pelias.search](#mapzen.places.pelias.search) + + +#### mapzen.places.pelias.autocomplete + +Query Who's On First using the Pelias autocomplete API + +##### Arguments + +| Argument | Description | Example | Required | +| :--- | :--- | :--- | :--- | +| `api_key` | A valid [Mapzen API key](https://mapzen.com/developers/) | your-mapzen-api-key | yes | +| `text` | A valid query string. | Gowanu | yes | +| `extras` | A comma-separated list of additional fields to include with each result. Valid fields are anything that might be found at the top level of WOF properties dictionary. You can also fetch all the fields for a given namespace by passing its prefix followed by a colon (for example `mz:`) | mz:uri | no | +| `format` | The format in which to return the data. Normally supported formats are [chicken](formats.md#chicken), [csv](formats.md#csv), [geojson](formats.md#geojson), [json](formats.md#json), [meta](formats.md#meta) however the following output formats are **disallowed** for this API method: [csv](formats.md#csv), [meta](formats.md#meta). The default format is [json](formats.md#json). | json | no | + +##### Error codes + +This API method does not define any custom error codes. For the list of error codes common to all API methods please consult the [default error codes](errors.md) documentation. + +##### Notes + +* As of this writing this API method will return zero results by design. WOF does not currently support autocomplete and this method is necessary to keep the Mapzen.JS search widget happy. +* The following output formats are **disallowed** for this API method: [csv](formats.md#csv), [meta](formats.md#meta) + +##### Example + +``` +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.pelias.autocomplete&api_key=your-mapzen-api-key&text=Gowanu' { "places": [ { - "wof:id": 975139507, - "wof:parent_id": "-1", - "wof:name": "Poutine Restau-Bar Enr", + "wof:id": 85865587, + "wof:parent_id": "421205765", + "wof:name": "Gowanus", + "wof:placetype": "neighbourhood", + "wof:country": "US", + "wof:repo": "whosonfirst-data" + }, + { + "wof:id": 353784235, + "wof:parent_id": "-3", + "wof:name": "Gowanus Nursery", + "wof:placetype": "venue", + "wof:country": "US", + "wof:repo": "whosonfirst-data-venue-us-ny" + }, + { + "wof:id": 370860425, + "wof:parent_id": "-3", + "wof:name": "Gowanus Laundromat", + "wof:placetype": "venue", + "wof:country": "US", + "wof:repo": "whosonfirst-data-venue-us-ny" + }, + { + "wof:id": 337285451, + "wof:parent_id": "85892923", + "wof:name": "Gowanus Nursery", + "wof:placetype": "venue", + "wof:country": "US", + "wof:repo": "whosonfirst-data-venue-us-ny" + }, + { + "wof:id": 102061079, + "wof:parent_id": "421205765", + "wof:name": "Gowanus Heights", + "wof:placetype": "neighbourhood", + "wof:country": "US", + "wof:repo": "whosonfirst-data" + }, + { + "wof:id": 185662657, + "wof:parent_id": "102061079", + "wof:name": "Gowanus Canal", + "wof:placetype": "venue", + "wof:country": "US", + "wof:repo": "whosonfirst-data-venue-us-ny" + }, + { + "wof:id": 185645989, + "wof:parent_id": "85865587", + "wof:name": "Gowanus Ballroom", + "wof:placetype": "venue", + "wof:country": "US", + "wof:repo": "whosonfirst-data-venue-us-ny" + }, + { + "wof:id": 571487473, + "wof:parent_id": "420782915", + "wof:name": "Gowanus Canal Community Devmnt", + "wof:placetype": "venue", + "wof:country": "US", + "wof:repo": "whosonfirst-data-venue-us-ny" + }, + { + "wof:id": 269610847, + "wof:parent_id": "-3", + "wof:name": "Ny City Gowanus Houses", + "wof:placetype": "venue", + "wof:country": "US", + "wof:repo": "whosonfirst-data-venue-us-ny" + }, + { + "wof:id": 286656437, + "wof:parent_id": "-3", + "wof:name": "NYC Housing Gowanus Houses", "wof:placetype": "venue", - "wof:country": "CA", - "wof:repo": "whosonfirst-data-venue-ca" + "wof:country": "US", + "wof:repo": "whosonfirst-data-venue-us-ny" } ], - "next_query": "method=whosonfirst.places.search&q=poutine&per_page=1&cursor=cXVlcnlUaGVuRmV0Y2g7NTszNjUwMzk5OlFUam1ETWxKU3pta0hZTHgxMmVEdmc7MzY1MDQwMDpRVGptRE1sSlN6bWtIWUx4MTJlRHZnOzM2NTA0MDI6UVRqbURNbEpTem1rSFlMeDEyZUR2ZzszNjUwNDAxOlFUam1ETWxKU3pta0hZTHgxMmVEdmc7MzY1MDQzNDo4a19EVFpOM1RWU09uNm5xNjQ4djJ3OzA7", - "total": 16, - "page": null, - "pages": 16, + "stat": "ok" +} +``` + + +#### mapzen.places.pelias.search + +Query Who's On First using the Pelias API + +##### Arguments + +| Argument | Description | Example | Required | +| :--- | :--- | :--- | :--- | +| `api_key` | A valid [Mapzen API key](https://mapzen.com/developers/) | your-mapzen-api-key | yes | +| `text` | A valid query string. This is the equivalent of the WOF 'names' parameter. | JFK | no | +| `size` | The number of results per query. This is the equivalent of the WOF 'per_page' parameter. | 10 | no | +| `layers` | Ensure records match this placetype. This is equivalent to the WOF 'placetype' parameter. | borough | no | +| `boundary.country` | Ensure places belong to this ISO country code. This is equivalent to the WOF 'iso' parameter. | ch | no | +| `q` | A valid query string. This is the equivalent of the Pelias 'text' parameter. | JFK | no | +| `placetype` | Ensure records match this placetype. This is equivalent to the Pelias 'layers' parameter. | neighbourhood | no | +| `iso` | Ensure places belong to this ISO country code. This is equivalent to the Pelias 'boundary.country' parameter. | fr | no | +| `query_field` | Scope the query alternate names (alt), variant names (variant), preferred names (preferred), wof:name values (name) or all the names (names). Valid options are: alt, name, names, preferred, variant. If left empty then the query will be performed across all WOF properties. | alt | no | +| `extras` | A comma-separated list of additional fields to include with each result. Valid fields are anything that might be found at the top level of WOF properties dictionary. You can also fetch all the fields for a given namespace by passing its prefix followed by a colon (for example `mz:`) | mz:uri | no | +| `cursor` | This method sometimes uses cursor-based pagination so this argument is the pointer returned by the last API response, in the `cursor` property. | _cXVl...c7MDs=_ | no | +| `page` | The default is 1. If this API method returns a non-empty `cursor` property as part of its response that means you should switch to using cursor-based pagination for all subsequent queries. Alternately you can simply rely on the `next_query` property to determine which parameters to include with your next request. Unfortunately it's complicated because databases are, after all these years, still complicated. Please consult the [pagination documentation](pagination.md) for details. | 1 | no | +| `per_page` | The default is 100 and the maximum is 500. | 100 | no | +| `format` | The format in which to return the data. Normally supported formats are [chicken](formats.md#chicken), [csv](formats.md#csv), [geojson](formats.md#geojson), [json](formats.md#json), [meta](formats.md#meta) however the following output formats are **disallowed** for this API method: [csv](formats.md#csv), [meta](formats.md#meta). The default format is [json](formats.md#json). | json | no | + +##### Error codes + +In addition to [default error codes](errors.md) common to all methods this API method defines the following additional error codes: + +| Error code | Error message | +| :--- | :--- | +| `432` | Unsupported Pelias API parameter | +| `433` | Multiple placetypes not supported (yet) | +| `434` | Invalid placetype | +| `435` | Invalid 'min_latitude' parameter | +| `436` | Invalid 'max_longitude' parameter | +| `437` | Invalid 'max_latitude' parameter | +| `438` | Invalid 'max_longitude' parameter | +| `439` | One or more missing parameters in bounding box query | +| `440` | Invalid output format | +| `441` | Invalid Pelias API version | +| `442` | Invalid (WOF) query field | +| `513` | Failed to perform lookup | + +##### Notes + +* Although neither the 'text' or 'q' parameters are required individually you must pass at least one of them. +* If both a Pelias API and its equivalent WOF parameter are passed the WOF parameter will take precendence. For example if you search for '?text=JFK&q=poutine' the API will only search for 'poutine'. +* The following Pelias API parameters are currently unsupported: boundary.circle.lat, boundary.circle.lon, boundary.circle.radius, boundary.rect.min_lat, boundary.rect.min_lon, boundary.rect.max_lat, boundary.rect.max_lon, focus.point.lat, focus.point.lon, sources +* The following output formats are **disallowed** for this API method: [csv](formats.md#csv), [meta](formats.md#meta) +* This API method uses [mixed](pagination.md#mixed) or [next-query](pagination.md#next-query) pagination. Please consult the [pagination documentation](pagination.md) for details. + +##### Example + +``` +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.pelias.search&api_key=your-mapzen-api-key&text=JFK&size=10&layers=borough&boundary.rect.min_lat=25.84&boundary.rect.min_lon=-106.65&boundary.rect.max_lat=36.5&boundary.rect.max_lon=-93.51&boundary.country=ch&q=JFK&placetype=neighbourhood&iso=fr&min_latitude=25.84&min_longitude=-106.65&max_latitude=36.5&max_longitude=-93.51&query_field=alt&per_page=1' + +{ + "places": [ + + ], + "next_query": null, + "total": 0, + "page": 1, "per_page": 1, - "cursor": "cXVlcnlUaGVuRmV0Y2g7NTszNjUwMzk5OlFUam1ETWxKU3pta0hZTHgxMmVEdmc7MzY1MDQwMDpRVGptRE1sSlN6bWtIWUx4MTJlRHZnOzM2NTA0MDI6UVRqbURNbEpTem1rSFlMeDEyZUR2ZzszNjUwNDAxOlFUam1ETWxKU3pta0hZTHgxMmVEdmc7MzY1MDQzNDo4a19EVFpOM1RWU09uNm5xNjQ4djJ3OzA7", + "pages": 0, + "cursor": null, "stat": "ok" } ``` -### whosonfirst.placetypes +### mapzen.places.placetypes -* [whosonfirst.placetypes.getInfo](#whosonfirst.placetypes.getInfo) -* [whosonfirst.placetypes.getList](#whosonfirst.placetypes.getList) -* [whosonfirst.placetypes.getRoles](#whosonfirst.placetypes.getRoles) +* [mapzen.places.placetypes.getInfo](#mapzen.places.placetypes.getInfo) +* [mapzen.places.placetypes.getList](#mapzen.places.placetypes.getList) +* [mapzen.places.placetypes.getRoles](#mapzen.places.placetypes.getRoles) - -#### whosonfirst.placetypes.getInfo + +#### mapzen.places.placetypes.getInfo Return details for a Who's On First placetype. @@ -1048,7 +1130,7 @@ In addition to [default error codes](errors.md) common to all methods this API m ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.placetypes.getInfo&api_key=your-mapzen-api-key&id=102322043&name=disputed' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.placetypes.getInfo&api_key=your-mapzen-api-key&id=102322043&name=disputed' { "placetype": { @@ -1063,8 +1145,8 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.placetypes.g } ``` - -#### whosonfirst.placetypes.getList + +#### mapzen.places.placetypes.getList Return a list of Who's On First placetypes. @@ -1091,7 +1173,7 @@ In addition to [default error codes](errors.md) common to all methods this API m ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.placetypes.getList&api_key=your-mapzen-api-key&role=common' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.placetypes.getList&api_key=your-mapzen-api-key&role=common' { "placetypes": [ @@ -1099,8 +1181,8 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.placetypes.g "id": 102312307, "name": "country", "parents": [ - "empire", - "continent" + "continent", + "empire" ], "role": "common" }, @@ -1111,18 +1193,58 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.placetypes.g "planet" ], "role": "common" - } - ], - "stat": "ok" -} -``` -_This example response has been truncated for the sake of brevity._ - - -#### whosonfirst.placetypes.getRoles - -Return a list of Who's On First placetype roles. - + }, + { + "id": 102312311, + "name": "region", + "parents": [ + "macroregion", + "dependency", + "disputed", + "country" + ], + "role": "common" + }, + { + "id": 102312317, + "name": "locality", + "parents": [ + "localadmin", + "county", + "region" + ], + "role": "common" + }, + { + "id": 102312319, + "name": "neighbourhood", + "parents": [ + "macrohood", + "borough", + "locality" + ], + "role": "common" + }, + { + "id": 102312319, + "name": "neighborhood", + "parents": [ + "macrohood", + "borough", + "locality" + ], + "role": "common" + } + ], + "stat": "ok" +} +``` + + +#### mapzen.places.placetypes.getRoles + +Return a list of Who's On First placetype roles. + ##### Arguments | Argument | Description | Example | Required | @@ -1141,7 +1263,7 @@ This API method does not define any custom error codes. For the list of error co ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.placetypes.getRoles&api_key=your-mapzen-api-key' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.placetypes.getRoles&api_key=your-mapzen-api-key' { "roles": [ @@ -1154,12 +1276,12 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.placetypes.g ``` -### whosonfirst.repos +### mapzen.places.repos -* [whosonfirst.repos.getByLatLon](#whosonfirst.repos.getByLatLon) +* [mapzen.places.repos.getByLatLon](#mapzen.places.repos.getByLatLon) - -#### whosonfirst.repos.getByLatLon + +#### mapzen.places.repos.getByLatLon Return a Who's On First repo name for a latitude and longitude. @@ -1199,7 +1321,7 @@ In addition to [default error codes](errors.md) common to all methods this API m ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.repos.getByLatLon&api_key=your-mapzen-api-key&latitude=37.766633&longitude=-122.417693&placetype=venue&is_current=1&is_ceased=1&is_deprecated=1&is_superseded=1&is_superseding=1' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.repos.getByLatLon&api_key=your-mapzen-api-key&latitude=37.766633&longitude=-122.417693&placetype=venue&is_current=1&is_ceased=1&is_deprecated=1&is_superseded=1&is_superseding=1' { "repo": "whosonfirst-data-venue-us-ca", @@ -1209,14 +1331,14 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.repos.getByL ``` -### whosonfirst.sources +### mapzen.places.sources -* [whosonfirst.sources.getInfo](#whosonfirst.sources.getInfo) -* [whosonfirst.sources.getList](#whosonfirst.sources.getList) -* [whosonfirst.sources.getPrefixes](#whosonfirst.sources.getPrefixes) +* [mapzen.places.sources.getInfo](#mapzen.places.sources.getInfo) +* [mapzen.places.sources.getList](#mapzen.places.sources.getList) +* [mapzen.places.sources.getPrefixes](#mapzen.places.sources.getPrefixes) - -#### whosonfirst.sources.getInfo + +#### mapzen.places.sources.getInfo Return details for a Who's On First source. @@ -1246,7 +1368,7 @@ In addition to [default error codes](errors.md) common to all methods this API m ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.sources.getInfo&api_key=your-mapzen-api-key&id=840464301&prefix=loc' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.sources.getInfo&api_key=your-mapzen-api-key&id=840464301&prefix=loc' { "source": { @@ -1265,8 +1387,8 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.sources.getI } ``` - -#### whosonfirst.sources.getList + +#### mapzen.places.sources.getList Return the list of Who's On First sources. @@ -1288,7 +1410,7 @@ This API method does not define any custom error codes. For the list of error co ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.sources.getList&api_key=your-mapzen-api-key' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.sources.getList&api_key=your-mapzen-api-key' { "sources": [ @@ -1315,15 +1437,1434 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.sources.getL "name": "acgov", "prefix": "acgov", "url": "https:\/\/data.acgov.org\/" + }, + { + "description": "Purveyors of fine freeware since 1972. On the net since 1991.", + "fullname": "Acme Laboratories", + "id": 1108961115, + "key": "id", + "license": "https:\/\/acme.com\/license.html", + "license_text": "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.", + "license_type": "BSD (modified)", + "name": "acme", + "prefix": "acme", + "url": "https:\/\/acme.com\/" + }, + { + "description": "Property prefix.", + "fullname": "addr", + "id": 1108832191, + "key": "id", + "license": "N\/A", + "license_text": "", + "license_type": "N\/A", + "name": "addr", + "prefix": "addr", + "url": "" + }, + { + "description": "Layers are viewable from the link in the url field as Buurten (microhoods), Buurtcombinaties (neighbourhoods), and Stadsdelen en Haven (boroughs). Open source information as well as downloadable datasets are available from the link in the license field.", + "fullname": "Amsterdam Open Datakaart", + "id": 1108802967, + "key": "", + "license": "https:\/\/kaart.amsterdam.nl\/datasets", + "license_text": "", + "license_type": "", + "name": "amsgis", + "prefix": "amsgis", + "url": "https:\/\/kaart.amsterdam.nl" + }, + { + "description": "Open Data portal for the City of Buenos Aires, Argentina.", + "fullname": "Ciudad Aut\u00f3noma de Buenos Aires, Iniciativa de Datos P\u00fablicos y Transparencia", + "id": 1108969549, + "key": "", + "license": "https:\/\/data.buenosaires.gob.ar\/tyc", + "license_text": "La reutilizaci\u00f3n autorizada puede incluir la copia, difusi\u00f3n, modificaci\u00f3n, adaptaci\u00f3n, extracci\u00f3n, reordenamiento y combinaci\u00f3n de la informaci\u00f3n contenida en el sitio ... Debe citarse la fuente de los documentos objeto de la reutilizaci\u00f3n.", + "license_type": "CC BY", + "name": "arg-caba", + "prefix": "arg-caba", + "url": "https:\/\/data.buenosaires.gob.ar\/dataset\/barrios" + }, + { + "description": "", + "fullname": "data.gv.at", + "id": 823312445, + "key": "", + "license": "http:\/\/creativecommons.org\/licenses\/by\/3.0\/at\/", + "license_text": "You are free to Share, copy and redistribute the material in any medium or format. Adapt, remix, transform, and build upon the material for any purpose, even commercially. The licensor cannot revoke these freedoms as long as you follow the license terms.", + "license_type": "CC BY 3.0", + "name": "atgov", + "prefix": "atgov", + "url": "https:\/\/www.data.gv.at" + }, + { + "description": "Neighborhoods within the City of Atlanta.", + "fullname": "Atlanta Department of Planning and Community Development", + "id": 1108797031, + "key": "", + "license": "https:\/\/www.arcgis.com\/home\/item.html?id=716f417a1990446389ef7fd2c381d09f", + "license_text": "Share, copy and redistribute the material in any medium or format. Adapt, remix, transform, and build upon the material for any purpose, even commercially.", + "license_type": "CC BY 4.0", + "name": "atldpcd", + "prefix": "atldpcd", + "url": "http:\/\/dpcd.coaplangis.opendata.arcgis.com\/datasets\/neighborhoods" + }, + { + "description": "The ABS is Australia's national statistical agency, providing trusted official statistics on a wide range of economic, social, population and environmental matters of importance to Australia.", + "fullname": "Australian Bureau of Statistics", + "id": 1108693461, + "key": "", + "license": "http:\/\/www.abs.gov.au\/websitedbs\/D3310114.nsf\/Home\/%A9+Copyright?opendocument", + "license_text": "Unless otherwise noted, all material on this website, except the ABS logo, the Commonwealth Coat of Arms, and any material protected by a trade mark, is licensed under a Creative Commons Attribution 2.5 Australia licence.", + "license_type": "CC BY 2.5 AU", + "name": "ausstat", + "prefix": "ausstat", + "url": "http:\/\/www.abs.gov.au\/AUSSTATS\/abs@.nsf\/DetailsPage\/1270.0.55.003July%202011?OpenDocument" + }, + { + "description": "", + "fullname": "Austria Open Data", + "id": 1108839435, + "key": "id", + "license": "http:\/\/creativecommons.org\/licenses\/by\/3.0\/at\/", + "license_text": "The data in our catalog are freely available under CC BY 3.0 or CC0 license. The catalog can be sorted according to topic areas. The exact data guidelines can be found in the individual data sets.", + "license_type": "CC BY 3.0", + "name": "Austria Open Data", + "prefix": "austriaod", + "url": "https:\/\/www.data.gv.at\/katalog\/dataset\/c33d36b0-f184-4f2a-89cc-839ca7fcf88a" + }, + { + "description": "Azavea is a civic technology firm based in Philadelphia. Azavea applies geospatial technology for civic and social impact.", + "fullname": "Azavea, Inc.", + "id": 1108721357, + "key": "", + "license": "https:\/\/www.opendataphilly.org\/dataset\/philadelphia-neighborhoods", + "license_text": "You are free to: Share, copy and redistribute the material in any medium or format. Adapt, remix, transform, and build upon the material for any purpose, even commercially.", + "license_type": "CC BY 3.0 US", + "name": "azavea", + "prefix": "azavea", + "url": "https:\/\/www.opendataphilly.org\/dataset\/philadelphia-neighborhoods\/resource\/06e8d380-821f-44ce-8718-a0f2f7902318" + }, + { + "description": "City of Baltimore Open Data Portal. This website is operated by the Mayor and City Council of Baltimore (the 'City') and the data is provided as a service to the public.", + "fullname": "Baltimore Mayor's Office of Information Technology", + "id": 1108794385, + "key": "", + "license": "https:\/\/data.baltimorecity.gov\/Geographic\/Baltimore-Study-Area\/cdrh-gpzc\/about", + "license_text": "THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ('CCPL' OR 'LICENSE'). THE WORK IS PROTECTED BY COPYRIGHT AND\/OR OTHER APPLICABLE LAW.", + "license_type": "Attribution 3.0 Unported", + "name": "baltomoit", + "prefix": "baltomoit", + "url": "https:\/\/data.baltimorecity.gov\/Geographic\/Baltimore-Study-Area\/cdrh-gpzc" + }, + { + "description": "Geopunt is the central Flesmish gateway to geographic government information. The geoportal makes geographical information accessible to government agencies, citizens, organizations and companies.", + "fullname": "Voorlopig Referentiebestand Gemeentegrenzen", + "id": 857004783, + "key": "id", + "license": "http:\/\/www.geopunt.be\/nl\/over-geopunt\/disclaimer", + "license_text": "The licensee is given the non-exclusive, worldwide right to reuse the product for each legitimate purpose, including reproducing, transmitting, publishing, adapting and commercial exploitation of the product.", + "license_type": "Free Open Data License Flanders v.1.0", + "name": "begov", + "prefix": "begov", + "url": "http:\/\/www.geopunt.be\/download?container=referentiebestand-gemeenten&title=Voorlopig%20referentiebestand%20gemeentegrenzen" + }, + { + "description": "Burrito Justice - La Lengua, San Francisco, CA.", + "fullname": "Burrito Justice", + "id": 404734205, + "key": "id", + "license": "http:\/\/burritojustice.com", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", + "license_type": "CC0", + "name": "burritojustice", + "prefix": "bj", + "url": "http:\/\/burritojustice.com\/la-lengua\/" + }, + { + "description": "Neighborhood boundaries are created based on zip code, zoning district boundaries and census tract boundaries. This GIS data layer was produced by the BRA Office of Digital Cartography and GIS.", + "fullname": "Boston Redevelopment Authority", + "id": 1108694665, + "key": "", + "license": "https:\/\/data.cityofboston.gov\/City-Services\/Boston-Neighborhood-Shapefiles\/af56-j7tb", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", + "license_type": "CC0", + "name": "bra", + "prefix": "bra", + "url": "https:\/\/data.cityofboston.gov\/" + }, + { + "description": "Crowdsourced by the locals: http:\/\/geosprocket.blogspot.com\/2012\/10\/results-of-burlington-neighborhoods.html", + "fullname": "Burlington VT Neighborhoods Project", + "id": 404734212, + "key": "id", + "license": "http:\/\/geosprocket.blogspot.com\/2012\/10\/results-of-burlington-neighborhoods.html", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", + "license_type": "CC0 equivalent", + "name": "btvneighborhoods", + "prefix": "btv", + "url": "https:\/\/gist.github.com\/wboykinm\/dfe44481d8ff759c4f1afea223a7c070" + }, + { + "description": "Neighbourhood data for the City of Cambrige, MA.", + "fullname": "City of Cambridge Geographic Information System Department", + "id": 1108713437, + "key": "", + "license": "https:\/\/data.cambridgema.gov\/download\/tif9-pmiw\/application\/pdf", + "license_text": "Any user of Data distributed by the City may modify, use and publish such Data without charge.", + "license_type": "CC BY", + "name": "camgov", + "prefix": "camgov", + "url": "http:\/\/www.cambridgema.gov\/GIS\/gisdatadictionary\/Boundary\/BOUNDARY_CDDNeighborhoods" + }, + { + "description": "Open municipal boundary data provided by the Alberta Open Government program.", + "fullname": "Alberta Open Government - Municipal Boundaries", + "id": 1108974149, + "key": "", + "license": "https:\/\/open.alberta.ca\/documentation\/ogp-licence", + "license_text": "Copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose...Acknowledge the source of the Information by including any attribution statement specified by the Information Provider(s) and, where possible, provide a link to this licence...", + "license_type": "Open Government Licence - Alberta", + "name": "can-abog", + "prefix": "can-abog", + "url": "https:\/\/open.alberta.ca\/opendata\/property-municipal-boundaries" + }, + { + "description": "Open Data Portal for Burnaby, B.C.", + "fullname": "City of Burnaby GIS Department", + "id": 1108914995, + "key": "", + "license": "https:\/\/www.burnaby.ca\/opendata\/licence.html", + "license_text": "you are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", + "license_type": "Open Government License, British Columbia, v2.0", + "name": "can-bbygov", + "prefix": "can-bbygov", + "url": "http:\/\/data.burnaby.ca\/datasets\/0023da089ff746bfb688e2531d1f2beb_9" + }, + { + "description": "Community boundary data generated by the City of Calgary Department of Corporate Analytics and Innovation for use in community planning.", + "fullname": "City of Calgary, Corporate Analytics and Innovation", + "id": 1108963891, + "key": "", + "license": "https:\/\/data.calgary.ca\/stories\/s\/u45n-7awa", + "license_text": "Copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose...Acknowledge the source of the Information by including any attribution statement specified by the Information Provider(s) and, where possible, provide a link to this license.", + "license_type": "Open Government License - City of Calgary", + "name": "can-calcai", + "prefix": "can-calcai", + "url": "https:\/\/data.calgary.ca\/Base-Maps\/Community-Boundaries\/ab7m-fwn6" + }, + { + "description": "Open Data Portal for the District of North Vancouver.", + "fullname": "District of North Vancouver Government", + "id": 1108906765, + "key": "", + "license": "http:\/\/geoweb.dnv.org\/data\/metadata.php?dataset=RegNeighbourhood", + "license_text": "you are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", + "license_type": "Open Government License, British Columbia, v2.0", + "name": "can-dnvgov", + "prefix": "can-dnvgov", + "url": "http:\/\/geoweb.dnv.org\/Products\/Data\/SHP\/RegNeighbourhood_shp.zip" + }, + { + "description": "Neighbourhood\/Ward data provided by the City of Edmonton Department of Sustainable Development.", + "fullname": "City of Edmonton Department of Sustainable Development", + "id": 1108970467, + "key": "", + "license": "https:\/\/www.edmonton.ca\/city_government\/documents\/Web-version2.1-OpenDataAgreement.pdf", + "license_text": "The City of Edmonton (the City) grants you a worldwide, royalty-free, non-exclusive licence to use, modify, and distribute the datasets in all current and future media and formats for any lawful purpose, including for commercial purposes. You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the datasets in any medium, mode or format for any lawful purpose.", + "license_type": "Open Government License - Edmonton", + "name": "can-edmdsd", + "prefix": "can-edmdsd", + "url": "https:\/\/data.edmonton.ca\/Geospatial-Boundaries\/City-of-Edmonton-Neighbourhood-Boundaries-with-War\/jfvj-x253" + }, + { + "description": "Community portrait data created by the city of Gatineau for use in planning and sustainable development (Data provided by request from ).", + "fullname": "Gatineau Service de l'urbanisme et du developpement durable (SUDD)", + "id": 1126109975, + "key": "", + "license": "http:\/\/www3.gatineau.ca\/Infoterritoire\/WebInterface\/help\/fr\/Content\/1_About\/1_About_FR.htm", + "license_text": "Confirmed open source availability by Maurin Dabbadie of the Gatineau Department of Planning and Sustainable Development on 2017-06-07 .", + "license_type": "CC BY equivalent", + "name": "can-gatsudd", + "prefix": "can-gatsudd", + "url": "http:\/\/www3.gatineau.ca\/Infoterritoire\/WebInterface\/views\/index.aspx" + }, + { + "description": "The collaborative crossroads in Quebec open data.", + "fullname": "Laval Service de l'urbanisme", + "id": 1108960971, + "key": "", + "license": "https:\/\/www.donneesquebec.ca\/fr\/licence\/#cc-by", + "license_text": "This license allows other people to distribute, remix, arrange and adapt your work, even for commercial purposes, as long as you are credited with the original creation by quoting your name.", + "license_type": "CC BY", + "name": "can-lvlsu", + "prefix": "can-lvlsu", + "url": "https:\/\/www.donneesquebec.ca\/recherche\/fr\/dataset\/limites-des-anciennes-municipalites" + }, + { + "description": "Open Data portal for the Ville de Montreal.", + "fullname": "Montreal Service de la Mise en Valeur du Territoire", + "id": 1108906761, + "key": "", + "license": "https:\/\/creativecommons.org\/licenses\/by\/4.0\/", + "license_text": "You are free to Share, copy and redistribute the material in any medium or format and Adapt, remix, transform, and build upon the material for any purpose, even commercially. ", + "license_type": "CC BY 4.0", + "name": "can-mtlsmvt", + "prefix": "can-mtlsmvt", + "url": "http:\/\/donnees.ville.montreal.qc.ca\/dataset\/quartiers" + }, + { + "description": "Open Data portal for the City of New Westminster, BC.", + "fullname": "City of New Westminster Development Services Department", + "id": 1108916059, + "key": "", + "license": "http:\/\/opendata.newwestcity.ca\/licence", + "license_text": "You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", + "license_type": "OGL - City of New Westminster", + "name": "can-nwds", + "prefix": "can-nwds", + "url": "http:\/\/opendata.newwestcity.ca\/datasets\/neighbourhoods" + }, + { + "description": "Custom neighbourhood data provided by the Ottawa Neighbourhood Study organization for community enrichment.", + "fullname": "Ottawa Neighbourhood Study (ONS)", + "id": 1108973847, + "key": "", + "license": "http:\/\/neighbourhoodstudy.ca\/ons-terms-of-use\/", + "license_text": "....publicly available and accessible data...must give ONS credit for each use or reproduction of the datasets...", + "license_type": "CC BY equivalent", + "name": "can-ons", + "prefix": "can-ons", + "url": "Data provided by request at http:\/\/neighbourhoodstudy.ca\/contact\/" + }, + { + "description": "Neighbourhood (district) data provided by Quebec City.", + "fullname": "Quebec City Open Data Portal", + "id": 1126115707, + "key": "", + "license": "http:\/\/donnees.ville.quebec.qc.ca\/licence.aspx", + "license_text": "...copy and redistribute the material in any medium or format...remix, transform, and build upon the material for any purpose, even commercially...You must give appropriate credit, provide a link to the license, and indicate if changes were made.", + "license_type": "CC BY 4.0", + "name": "can-qcodp", + "prefix": "can-qcodp", + "url": "http:\/\/donnees.ville.quebec.qc.ca\/donne_details.aspx?jdid=9" + }, + { + "description": "Boundaries provided by the City of Regina to delineate community associations.", + "fullname": "City of Regina Open Data - Community Associations", + "id": 1126113619, + "key": "", + "license": "http:\/\/www.regina.ca\/residents\/open-government\/open-government-licence\/", + "license_text": "Copy, modify, publish, translate, adapt, distribute or otherwise use the data sets in any medium, mode or format for any lawful purpose... Acknowledge the source of the Information by including any attribution statement specified by the Information Provider and, where possible, provide a link to this licence.", + "license_type": "Open Government Licence - City of Regina", + "name": "can-rodca", + "prefix": "can-rodca", + "url": "http:\/\/open.regina.ca\/dataset\/community-associations" + }, + { + "description": "Neighbourhood regions provided by the city of Saskatoon, used for demographic purposes.", + "fullname": "City of Saskatoon Open Data Portal - Neighbourhood Areas", + "id": 1126113989, + "key": "", + "license": "http:\/\/opendata-saskatoon.cloudapp.net\/TermsOfUse\/TermsOfUse", + "license_text": "...a broad license to use the currently published data on the City of Saskatoon website (\u201cInformation\u201d) for your own analysis and applications...appreciate credit for provision of the Information, this is not a strict requirement.", + "license_type": "CC0 equivalent", + "name": "can-saskodp", + "prefix": "can-saskodp", + "url": "http:\/\/opendata-saskatoon.cloudapp.net\/DataBrowser\/SaskatoonOpenDataCatalogueBeta\/NeighbourhoodArea#param=NOFILTER--DataView--Results" + }, + { + "description": "Open data portal for the City of Surrey, BC.", + "fullname": "City of Surrey GIS Section", + "id": 1108951549, + "key": "", + "license": "http:\/\/data.surrey.ca\/pages\/open-government-licence-surrey", + "license_text": "You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", + "license_type": "OGL - City of Surrey", + "name": "can-surgis", + "prefix": "can-surgis", + "url": "https:\/\/data.surrey.ca\/dataset\/surrey-city-boundary" + }, + { + "description": "Neighbourhood boundary data provided by the City of Victoria Open Data Catalogue.", + "fullname": "City of Victoria Open Data Catalogue", + "id": 1126129879, + "key": "", + "license": "http:\/\/www.victoria.ca\/EN\/main\/online-services\/open-data-catalogue\/open-data-licence.html", + "license_text": "Copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose...Acknowledge the source of the Information by including any attribution statement specified by the Information Provider and, where possible, provide a link to this licence.", + "license_type": "Open Government Licence \u2013 City of Victoria", + "name": "can-vicodc", + "prefix": "can-vicodc", + "url": "http:\/\/www.victoria.ca\/EN\/main\/online-services\/open-data-catalogue.html" + }, + { + "description": "Neighbourhood planning districts provided by the City of Winnipeg on their open data portal.", + "fullname": "City of Winnipeg Department of Planning, Property, and Development", + "id": 1108968171, + "key": "", + "license": "https:\/\/data.winnipeg.ca\/open-data-licence", + "license_text": "Copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose...Acknowledge the source of the Information by including any attribution statement specified by the Information Provider(s) and, where possible, provide a link to this licence.", + "license_type": "Open Government License - Winnipeg", + "name": "can-wpgppd", + "prefix": "can-wpgppd", + "url": "https:\/\/data.winnipeg.ca\/City-Planning\/Neighbourhood\/fen6-iygi" + }, + { + "description": "Datasets can be found under the shapefile or geodatabase directories, sorted by precision and location.", + "fullname": "Natural Resources Canada, CanVec Hydrographic Features", + "id": 1108962077, + "key": "", + "license": "http:\/\/open.canada.ca\/en\/open-government-licence-canada", + "license_text": "You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", + "license_type": "Open Government Licence, Canada", + "name": "canvec-hydro", + "prefix": "canvec-hydro", + "url": "http:\/\/open.canada.ca\/data\/en\/dataset\/9d96e8c9-22fe-4ad2-b5e8-94a6991b744b" + }, + { + "description": "This data portal consists of a register containing information about and references to data sets by Dutch authorities.", + "fullname": "Centraal Bureau voor de Statistiek", + "id": 1108804789, + "key": "", + "license": "https:\/\/data.overheid.nl\/data\/dataset\/wijk-en-buurtkaart-2016-versie-1", + "license_text": "With this license, a re-user is free to share, copy, distribute and transmit the dataset through any medium or file format. The dataset may be edited and may be used for commercial purposes. A reference to the creator of the data is required.", + "license_type": "CC BY 3.0", + "name": "cbsnl", + "prefix": "cbsnl", + "url": "https:\/\/data.overheid.nl\/data\/dataset\/wijk-en-buurtkaart-2016-versie-1\/resource\/7f32452a-f035-4a23-bce9-1972f5189beb" + }, + { + "description": "The Geoportal of the Swiss Federation.", + "fullname": "Swiss Confederation", + "id": 772975927, + "key": "", + "license": "http:\/\/data.geo.admin.ch\/ch.swisstopo-vd.ortschaftenverzeichnis_plz\/", + "license_text": "The information contained on the websites of the Federal Authorities is made available to the public.", + "license_type": "CC0", + "name": "chgov", + "prefix": "chgov", + "url": "http:\/\/data.geo.admin.ch" + }, + { + "description": "", + "fullname": "City of London Companies House", + "id": 1158784151, + "key": "number", + "license": "", + "license_text": "", + "license_type": "", + "name": "companieshouse", + "prefix": "companieshouse", + "url": "https:\/\/data.london.gov.uk\/dataset\/directory-of-london-businesses" + }, + { + "description": "Towards a Public Data Infrastructure for a Large, Multilingual, Semantic Knowledge Graph.", + "fullname": "DBpedia", + "id": 840464281, + "key": "id", + "license": "http:\/\/en.wikipedia.org\/wiki\/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License", + "license_text": "You are free to Share, to copy, distribute and transmit the work, and to Remix, to adapt the work for any purpose, even commercially.", + "license_type": "CC BY-SA 3.0 Unported License", + "name": "dbpedia", + "prefix": "dbp", + "url": "http:\/\/dbpedia.org\/" + }, + { + "description": "Open Data portal for the City of Denver, CO.", + "fullname": "Denver Department of Community Planning and Development", + "id": 1108748977, + "key": "", + "license": "https:\/\/www.denvergov.org\/opendata\/termsofuse", + "license_text": "You are free to: Share, copy and redistribute the material in any medium or format. Adapt, remix, transform, and build upon the material for any purpose, even commercially. The licensor cannot revoke these freedoms as long as you follow the license terms.", + "license_type": "CC BY 3.0", + "name": "denvercpd", + "prefix": "denvercpd", + "url": "https:\/\/www.denvergov.org\/opendata\/dataset\/city-and-county-of-denver-statistical-neighborhoods" + }, + { + "description": "Elections BC is an independent and non-partisan Office of the Legislature, British Colombia.", + "fullname": "Elections BC", + "id": 1108962955, + "key": "id", + "license": "http:\/\/142.34.128.33\/docs\/EBC-Open-Data-Licence.pdf", + "license_text": "You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose", + "license_type": "Elections BC Open Data Licence", + "name": "ebc", + "prefix": "ebc", + "url": "http:\/\/elections.bc.ca\/" + }, + { + "description": "Property prefix. This website describes the current effort to develop a reasonably comprehensive date\/time definition for the bibliographic community, as well as other interested communities, and submitting it for standardization or some other mode of formalization, for example a W3C note or an amendment to ISO 8601.", + "fullname": "Extended Date\/Time Format", + "id": 404734173, + "key": "", + "license": "https:\/\/www.loc.gov\/legal\/", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", + "license_type": "CC0 1.0 Universal", + "name": "edtf", + "prefix": "edtf", + "url": "http:\/\/loc.gov\/standards\/datetime\/" + }, + { + "description": "Homepage for the Federal Aviation Administration.", + "fullname": "Federal Aviation Administration", + "id": 840464293, + "key": "code", + "license": "https:\/\/www.usa.gov\/government-works", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", + "license_type": "CC0 1.0 Universal", + "name": "faa", + "prefix": "faa", + "url": "http:\/\/www.faa.gov\/" + }, + { + "description": "Freebase was a large collaborative knowledge base consisting of data composed mainly by its community members. It was an online collection of structured data harvested from many sources, including individual, user-submitted wiki contributions. See also: http:\/\/creativecommons.org\/licenses\/by\/2.5\/.", + "fullname": "Freebase", + "id": 840464287, + "key": "id", + "license": "https:\/\/developers.google.com\/freebase\/", + "license_text": "Freebase constitutes a snapshot of the data stored in Freebase and the Schema that structures it, and are provided under the same CC-BY license. The Freebase\/Wikidata mappings are provided under the CC0 license.", + "license_type": "CC BY", + "name": "freebase", + "prefix": "fb", + "url": "https:\/\/developers.google.com\/freebase\/" + }, + { + "description": "Location data for Mobile Advertising, Developers, and Enterprise solutions.", + "fullname": "Factual", + "id": 404734193, + "key": "id", + "license": "http:\/\/factual.com\/tos", + "license_text": "All of the information and data made available via the Sites ('Site Data') is provided solely to enable you to learn about Factual and the Services. You are not licensed to store, copy, or use any Site Data for any other purpose.", + "license_type": "Restricted", + "name": "factual", + "prefix": "fct", + "url": "https:\/\/github.com\/Factual\/places" + }, + { + "description": "", + "fullname": "NLS National Land Survey of Finland", + "id": 857125801, + "key": "id", + "license": "http:\/\/www.maanmittauslaitos.fi\/en\/professionals\/digital-products\/datasets-free-charge\/open-data-licence.zip", + "license_text": "", + "license_type": "", + "name": "figov", + "prefix": "figov", + "url": "http:\/\/www.maanmittauslaitos.fi\/en\/digituotteet\/municipal-division-finland" + }, + { + "description": "The American National Standards Institute (ANSI) operates the National Standards System Network (NSSN). This powerful reference tool provides 24-hour access to over 65,000 references to standards and specifications from the U.S. government, U.S. private sector organizations and international standards organizations.", + "fullname": "Federal Information Processing Standards", + "id": 840464229, + "key": "code", + "license": "https:\/\/www.usa.gov\/government-works", + "license_text": "United States government creative works, including writing, images, and computer code, are usually prepared by officers or employees of the United States government as part of their official duties. A government work is generally not subject to copyright in the United States and there is generally no copyright restriction on reproduction, derivative works, distribution, performance, or display of a government work.", + "license_type": "CC0", + "name": "fips", + "prefix": "fips", + "url": "http:\/\/www.nist.gov\/itl\/fips.cfm" + }, + { + "description": "Open platform for French public data.", + "fullname": "Open Data France", + "id": 1108725001, + "key": "id", + "license": "https:\/\/www.data.gouv.fr\/en\/terms\/", + "license_text": "The Open License is part of an international context and is compatible with the standards of open data licenses developed abroad, in particular those of the Government of the United Kingdom (Open Government License) and other international standards (ODC-BY, CC-BY 2.0).", + "license_type": "CC BY 2.0", + "name": "frgov", + "prefix": "frgov", + "url": "https:\/\/www.data.gouv.fr\/en\/datasets\/fond-de-carte-des-codes-postaux\/" + }, + { + "description": "Property prefix.", + "fullname": "geom", + "id": 1108830733, + "key": "id", + "license": "CC0", + "name": "geom", + "prefix": "geom", + "url": "" + }, + { + "description": "The GeoNames geographical database covers all countries and contains over eleven million placenames that are available for download free of charge.", + "fullname": "GeoNames", + "id": 404734175, + "key": "id", + "license": "http:\/\/www.geonames.org\/about.html", + "license_text": "The GeoNames geographical database is available for download free of charge under a creative commons attribution license.", + "license_type": "CC BY", + "name": "geonames", + "prefix": "gn", + "remarks": "https:\/\/github.com\/whosonfirst\/whosonfirst-sources\/blob\/master\/sources\/geonames_remarks.md", + "url": "http:\/\/www.geonames.org\/" + }, + { + "description": "GeoPlanet provides an open, permanent, and intelligent infrastructure for geo-referencing data on the Internet. (Cached, accessed: 2017-05-11, via: https:\/\/web.archive.org\/web\/20111028163611\/http:\/\/developer.yahoo.com\/geo\/geoplanet\/data\/).", + "fullname": "Yahoo! GeoPlanet", + "id": 404734177, + "key": "id", + "license": "http:\/\/developer.yahoo.com\/geo\/geoplanet\/data\/", + "license_text": "This page provides open access to the underlying data under a Creative Commons Attribution license so that you can incorporate WOEIDs and the GeoPlanet hierarchy into your own applications.", + "license_type": "CC BY", + "name": "geoplanet", + "prefix": "gp", + "remarks": "https:\/\/github.com\/whosonfirst\/whosonfirst-sources\/blob\/master\/sources\/geoplanet_remarks.md", + "url": "http:\/\/developer.yahoo.com\/geo\/geoplanet\/" + }, + { + "description": "Administrative subdivisions of countries; a comprehensive world reference, 1900 to 1998. Gwillim Law: 'As far as I'm concerned, HASC codes are in the public domain - to encourage people or organizations to use them for data communication.'", + "fullname": "Statoids HASC", + "id": 1108827445, + "key": "id", + "license": "http:\/\/www.statoids.com\/ihasc.html", + "license_text": "CC0 per email with Gwillim Law of Statoids on August 11, 2015.", + "license_type": "CC0", + "name": "hasc", + "prefix": "hasc", + "url": "http:\/\/www.statoids.com\/" + }, + { + "description": "HRI is a web service for fast and easy access to open data sources between the cities of Helsinki, Espoo, Vantaa and Kauniainen.", + "fullname": "Helsinki City Real Estate Department", + "id": 1108726815, + "key": "", + "license": "http:\/\/www.hri.fi\/dataset\/paakaupunkiseudun-aluejakokartat", + "license_text": "You are free to: Share, copy and redistribute the material in any medium or format and Adapt, remix, transform, and build upon the material for any purpose, even commercially.", + "license_type": "CC BY 4.0", + "name": "hkigis", + "prefix": "hkigis", + "url": "http:\/\/www.hel2.fi\/tietokeskus\/data\/kartta_aineistot\/PKS_Kartta_Rajat_KML2011.zip" + }, + { + "description": "HRI is a web service for fast and easy access to open data sources between the cities of Helsinki, Espoo, Vantaa and Kauniainen.", + "fullname": "Helsinki Region Infoshare", + "id": 874342855, + "key": "id", + "license": "http:\/\/www.hri.fi\/en\/dataset\/helsingin-kaupunginosat", + "license_text": "You are free to: Share, copy and redistribute the material in any medium or format and Adapt, remix, transform, and build upon the material for any purpose, even commercially.", + "license_type": "CC BY 4.0", + "name": "hsgov", + "prefix": "hsgov", + "url": "http:\/\/ptp.hel.fi\/avoindata\/aineistot\/Helsingin_kaupunginosat.zip" + }, + { + "description": "The International Air Transport Association (IATA) is the trade association for the world's airlines, representing some 265 airlines or 83% of total air traffic.", + "fullname": "International Air Transport Association", + "id": 840464241, + "key": "code", + "license": "http:\/\/www.iata.org\/Pages\/terms.aspx", + "license_text": "All rights are reserved.", + "license_type": "Restricted", + "name": "iata", + "prefix": "iata", + "url": "http:\/\/www.iata.org\/" + }, + { + "description": "The International Civil Aviation Organization (ICAO) is a UN specialized agency, established by States in 1944 to manage the administration and governance of the Convention on International Civil Aviation (Chicago Convention).", + "fullname": "International Civil Aviation Organization", + "id": 840464249, + "key": "code", + "license": "http:\/\/www.icao.int\/Pages\/Disclaimer.aspx", + "license_text": "ICAO grants permission to Users to visit the Site and to download, preprint and copy the information, documents and materials (collectively, 'Materials') from the Site for the User's personal, non-commercial use, without any right to resell or redistribute them or to compile or create derivative works therefrom, subject to the terms and conditions outlined below, and also subject to more specific restrictions that may apply to specific Material within this Site. ", + "license_type": "Restricted", + "name": "icao", + "prefix": "icao", + "url": "http:\/\/www.icao.int\/" + }, + { + "description": "ISO is an independent, non-governmental international organization with a membership of 163 national standards bodies.", + "fullname": "International Organization for Standardization", + "id": 1108931861, + "key": "id", + "license": "https:\/\/www.iso.org\/privacy-and-copyright.html", + "license_text": "All content on ISO Online is copyright protected. The copyright is owned by ISO. Any use of the content, including copying of it in whole or in part, for example to another Internet site, is prohibited and would require written permission from ISO.", + "license_type": "Restricted", + "name": "iso", + "prefix": "iso", + "url": "http:\/\/www.iso.org\/" + }, + { + "description": "Official website for the City of Kuopio, Finland.", + "fullname": "City of Kuopio", + "id": 1108729077, + "key": "", + "license": "https:\/\/www.avoindata.fi\/data\/fi\/dataset\/kuopion-kaupunginosat", + "license_text": "You are free to: Share, copy and redistribute the material in any medium or format and Adapt, remix, transform, and build upon the material for any purpose, even commercially.", + "license_type": "CC BY 4.0", + "name": "kuogov", + "prefix": "kuogov", + "url": "https:\/\/www.avoindata.fi\/data\/fi\/dataset\/kuopion-kaupunginosat\/resource\/6ca89290-3743-4832-9ed6-03d8cf9b2d5f" + }, + { + "description": "Official Certified Neighborhood Council boundaries in the City of Los Angeles created and maintained by the Bureau of Engineering \/ GIS Mapping Division.", + "fullname": "City of Los Angeles Neighborhood Councils (Certified)", + "id": 1024497679, + "key": "", + "license": "https:\/\/data.lacity.org\/A-Well-Run-City\/Neighborhood-Councils-Certified-\/fu65-dz2f\/about", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", + "license_type": "CC0", + "name": "lacity", + "prefix": "lacity", + "url": "https:\/\/data.lacity.org\/A-Well-Run-City\/Neighborhood-Councils-Certified-\/fu65-dz2f" + }, + { + "description": "", + "fullname": "City of Los Angeles Office of Finance", + "id": 1158784149, + "key": "id", + "license": "", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", + "license_type": "CC0", + "name": "lacity_oof", + "prefix": "lacity_oof", + "url": "https:\/\/data.lacity.org\/A-Prosperous-City\/Listing-of-Active-Businesses\/6rrh-rzua" + }, + { + "description": "The Los Angeles Times.", + "fullname": "Los Angeles Times", + "id": 1108962957, + "key": "id", + "license": "http:\/\/www.tronc.com\/central-terms-of-service\/", + "license_text": "If you operate a Web site and wish to link to the Site, you may do so provided you agree to cease such link upon request from us. No other use is permitted without prior written permission of tronc.", + "license_type": "Restricted", + "name": "latimes", + "prefix": "latimes", + "url": "http:\/\/www.latimes.com\/" + }, + { + "description": "", + "fullname": "label", + "id": 1108955855, + "key": "id", + "license": "CC0", + "name": "lbl", + "prefix": "lbl", + "url": "" + }, + { + "description": "Property prefix.", + "fullname": "lieu", + "id": 1141961795, + "key": "guid", + "license": "", + "name": "lieu", + "prefix": "lieu", + "url": "https:\/\/github.com\/openvenues\/lieu" + }, + { + "description": "The Library of Congress is the largest library in the world, with millions of books, recordings, photographs, newspapers, maps and manuscripts in its collections. The Library is the main research arm of the U.S. Congress and the home of the U.S. Copyright Office.", + "fullname": "Library of Congress", + "id": 840464301, + "key": "id", + "license": "https:\/\/www.usa.gov\/government-works", + "license_text": "Most U.S. government creative works such as writing or images are copyright-free.", + "license_type": "CC0", + "name": "loc", + "prefix": "loc", + "url": "http:\/\/www.loc.gov" + }, + { + "description": "Mesoshapes are a product of Mapzen for Who's On First.", + "fullname": "Mesoshapes", + "id": 1108756907, + "key": "", + "license": "https:\/\/github.com\/whosonfirst-data\/whosonfirst-data\/blob\/master\/LICENSE.md", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", + "license_type": "CC0", + "name": "meso", + "prefix": "meso", + "remarks": "https:\/\/github.com\/whosonfirst\/whosonfirst-sources\/blob\/master\/sources\/meso_remarks.md", + "url": "https:\/\/github.com\/whosonfirst-data\/whosonfirst-data\/blob\/master\/LICENSE.md" + }, + { + "description": "Mapshaper is software for editing Shapefile, GeoJSON, TopoJSON and several other data formats, written in JavaScript.", + "fullname": "Mapshaper", + "id": 404734195, + "key": "", + "license": "http:\/\/mozilla.org\/MPL\/2.0\/", + "license_text": "This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http:\/\/mozilla.org\/MPL\/2.0\/.", + "license_type": "MPL, v2.0", + "name": "mapshaper", + "prefix": "ms", + "url": "https:\/\/github.com\/mbloch\/mapshaper" + }, + { + "description": "A Tenderloin of many neighbourhoods.", + "fullname": "Mini Tenders", + "id": 404734209, + "key": "id", + "license": "http:\/\/www.thebolditalic.com\/articles\/1101-mini-tenders", + "license_text": "Data is assumed to be in the Public Domain.", + "license_type": "Public domain (assumed)", + "name": "minitenders", + "prefix": "mt", + "url": "http:\/\/www.thebolditalic.com\/articles\/1101-mini-tenders" + }, + { + "description": " Mapzen is an open, sustainable, and accessible mapping platform. Our tools let you display, search, and navigate your world.", + "fullname": "Mapzen", + "id": 404734197, + "key": "", + "license": "https:\/\/mapzen.com\/terms\/", + "license_text": "Subject to these Terms, Mapzen hereby grants to you a non-exclusive, non-transferable, non-sublicensable license during the Term to: (i) copy and use the Tools solely to develop products and services to be made available by you ('Your Products'), and to distribute elements of the Tools as incorporated into Your Products; (ii) use and access the Services as provided by Mapzen subject to the Rate Limits; and (iii) if you've ordered Mapzen Data Products, use the Mapzen Data Products for your internal use and only as part of Your Products which are provided directly to end users, and not for resale or for redistribution or use in conjunction with, or as part of, the products or services of others. Except for the foregoing license, Mapzen and its suppliers own all right, title and interest in and to the Services, Tools and Mapzen Data Products, and no other licenses are granted to you, whether express or implied.", + "license_type": "CC0", + "name": "mapzen", + "prefix": "mz", + "url": "https:\/\/www.mapzen.com\/" + }, + { + "description": "Country, region and city boundary data from OpenStreetMap, served monthly until October 2016.", + "fullname": "Mapzen Borders", + "id": 840464303, + "key": "id", + "license": "https:\/\/mapzen.com\/terms\/", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", + "license_type": "CC0", + "name": "mapzenborders", + "prefix": "mzb", + "url": "https:\/\/mapzen.com\/data\/borders\/" + }, + { + "description": "Property prefix.", + "fullname": "name", + "id": 1108828507, + "key": "id", + "license": "N\/A", + "license_text": "", + "license_type": "CC0", + "name": "name", + "prefix": "name", + "url": "" + }, + { + "description": "Natural Earth is a public domain map dataset available at 1:10m, 1:50m, and 1:110 million scales, which features tightly integrated vector and raster data.", + "fullname": "Natural Earth", + "id": 404734179, + "key": "", + "license": "http:\/\/www.naturalearthdata.com\/about\/terms-of-use\/", + "license_text": "No permission is needed to use Natural Earth. Crediting the authors is unnecessary.", + "license_type": "Public Domain (assumed)", + "name": "naturalearth", + "prefix": "ne", + "remarks": "https:\/\/github.com\/whosonfirst\/whosonfirst-sources\/blob\/master\/sources\/naturalearth_remarks.md", + "url": "http:\/\/www.naturalearthdata.com\/" + }, + { + "description": "Home of Null Island.", + "fullname": "Null Island", + "id": 404734211, + "key": "", + "license": "N\/A", + "license_text": "", + "license_type": "", + "name": "nullisland", + "prefix": "ni", + "url": "http:\/\/www.nullisland.com\/" + }, + { + "description": "Open Data portal for the City of New Orleans, LA.", + "fullname": "City of New Orleans, Office of Information Technology and Innovation, Enterprise Information Team", + "id": 1108732585, + "key": "", + "license": "https:\/\/data.nola.gov\/Geographic-Base-Layers\/Neighborhoods\/92zg-wzkq", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", + "license_type": "CC0", + "name": "nolagis", + "prefix": "nolagis", + "url": "https:\/\/data.nola.gov\/Geographic-Base-Layers\/Neighborhoods\/92zg-wzkq" + }, + { + "description": "Open Data portal for New York City, NY.", + "fullname": "NYC OpenData", + "id": 656342179, + "key": "id", + "license": "http:\/\/legistar.council.nyc.gov\/ViewReport.ashx?M=R&N=Text&GID=61&ID=1090992&GUID=B1263195-66B9-48AD-A381-57584D623443&Title=Legislation+Text", + "license_text": "Such public data sets shall be made available without any registration requirement, license requirement or restrictions on their use provided that the department may require a third party providing to the public any public data set, or application utilizing such data set, to explicitly identify the source and version of the public data set, and a description of any modifications made to such public data set.", + "license_type": "CC0 (assumed)", + "name": "nycgov", + "prefix": "nycgov", + "url": "https:\/\/data.cityofnewyork.us\/" + }, + { + "description": "Open Data portal for New York City, NY.", + "fullname": "New York City Department of Consumer Affairs", + "id": 1158783299, + "key": "license", + "license": "http:\/\/legistar.council.nyc.gov\/ViewReport.ashx?M=R&N=Text&GID=61&ID=1090992&GUID=B1263195-66B9-48AD-A381-57584D623443&Title=Legislation+Text", + "license_text": "Such public data sets shall be made available without any registration requirement, license requirement or restrictions on their use provided that the department may require a third party providing to the public any public data set, or application utilizing such data set, to explicitly identify the source and version of the public data set, and a description of any modifications made to such public data set.", + "license_type": "CC0 (assumed)", + "name": "nycgov_dca", + "prefix": "nycgov_dca", + "url": "https:\/\/data.cityofnewyork.us\/Business\/Legally-Operating-Businesses\/w7w3-xahh\/data" + }, + { + "description": "Open Data portal for New York City, NY.", + "fullname": "New York City Department of Health and Mental Hygiene", + "id": 1158783297, + "key": "camis", + "license": "http:\/\/legistar.council.nyc.gov\/ViewReport.ashx?M=R&N=Text&GID=61&ID=1090992&GUID=B1263195-66B9-48AD-A381-57584D623443&Title=Legislation+Text", + "license_text": "Such public data sets shall be made available without any registration requirement, license requirement or restrictions on their use provided that the department may require a third party providing to the public any public data set, or application utilizing such data set, to explicitly identify the source and version of the public data set, and a description of any modifications made to such public data set.", + "license_type": "CC0 (assumed)", + "name": "nycgov_dohmh", + "prefix": "nycgov_dohmh", + "url": "https:\/\/data.cityofnewyork.us\/Health\/DOHMH-New-York-City-Restaurant-Inspection-Results\/xx67-kt59" + }, + { + "description": "Open Data portal for New York City, NY.", + "fullname": "NYC OpenData - Subway Stations", + "id": 1108960969, + "key": "objectid", + "license": "http:\/\/legistar.council.nyc.gov\/ViewReport.ashx?M=R&N=Text&GID=61&ID=1090992&GUID=B1263195-66B9-48AD-A381-57584D623443&Title=Legislation+Text", + "license_text": "Such public data sets shall be made available without any registration requirement, license requirement or restrictions on their use provided that the department may require a third party providing to the public any public data set, or application utilizing such data set, to explicitly identify the source and version of the public data set, and a description of any modifications made to such public data set.", + "license_type": "CC0 (assumed)", + "name": "nycgov_subway", + "prefix": "nycgov_subway", + "url": "https:\/\/data.cityofnewyork.us\/Transportation\/Subway-Stations\/arq3-7z49" + }, + { + "description": "The New York Times.", + "fullname": "The New York Times", + "id": 840464273, + "key": "id", + "license": "https:\/\/www.nytimes.com\/content\/help\/rights\/terms\/terms-of-service.html", + "license_text": "You may not sublicense, assign or transfer any licenses granted by NYTimes.com, and any attempt at such sublicense, assignment or transfer shall be null and void.", + "license_type": "Restricted", + "name": "nytimes", + "prefix": "nyt", + "url": "http:\/\/www.nytimes.com\/" + }, + { + "description": "OurAirports is a free site where visitors can explore the world's airports. [...] This is an open-data web site, after all, and we don't believe that 'open' means 'we can benefit from it, but we'll hide it from everyone else.", + "fullname": "OurAirports", + "id": 404734181, + "key": "id", + "license": "http:\/\/ourairports.com\/", + "license_text": "OurAirports is a public site, and by 'public', we mean PUBLIC.", + "license_type": "Public domain", + "name": "ourairports", + "prefix": "oa", + "remarks": "https:\/\/github.com\/whosonfirst\/whosonfirst-sources\/blob\/master\/sources\/ourairports_remarks.md", + "url": "http:\/\/ourairports.com\/data\/" + }, + { + "description": "Open Data portal for the City of Oakland, CA.", + "fullname": "Oakland Community and Economic Development Department", + "id": 1108794097, + "key": "", + "license": "https:\/\/data.oaklandnet.com\/Property\/Oakland-Neighborhoods\/7zky-kcq9\/about", + "license_text": "", + "license_type": "Public Domain", + "name": "oakced", + "prefix": "oakced", + "url": "https:\/\/data.oaklandnet.com\/Property\/Oakland-Neighborhoods\/7zky-kcq9" + }, + { + "description": "A non-ministerial government agency that acts as the national mapping agency for Great Britain.", + "fullname": "Ordnance Survey", + "id": 874390485, + "key": "", + "license": "https:\/\/www.ordnancesurvey.co.uk\/business-and-government\/licensing\/using-creating-data-with-os-products\/os-opendata.html", + "license_text": "You are free to: copy, publish, distribute and transmit the Information; adapt the Information; exploit the Information commercially and non-commercially for example, by combining it with other Information, or by including it in your own product or application. You must (where you do any of the above): acknowledge the source of the Information in your product or application by including or linking to any attribution statement specified by the Information Provider(s) and, where possible, provide a link to this licence.", + "license_type": "OGL, v3.0", + "name": "ordnancesurvey", + "prefix": "os", + "remarks": "https:\/\/github.com\/whosonfirst\/whosonfirst-sources\/blob\/master\/sources\/os_remarks.md", + "url": "https:\/\/www.ordnancesurvey.co.uk" + }, + { + "description": "Official website for the City of Oulu, Finland.", + "fullname": "City of Oulu", + "id": 1108728833, + "key": "", + "license": "http:\/\/www.ouka.fi\/oulu\/oulu-tietoa\/kayttoehdot", + "license_text": "The license allows you to share, copy and distribute the material remains in any medium and in the form of, and Modify, combine and edit the material and create the basis for new materials.", + "license_type": "CC BY 4.0", + "name": "oulugov", + "prefix": "oulugov", + "url": "http:\/\/www.ouka.fi\/oulu\/oulu-tietoa\/avoin-data-aineisto" + }, + { + "description": "OUTgoing: The Hidden History of New York's Gay Nightlife by Jeff Ferzoco.", + "fullname": "OUTgoing", + "id": 1108952683, + "key": "", + "license": "N\/A", + "license_text": "Data is assumed to be in the Public Domain.", + "license_type": "Public Domain (assumed)", + "name": "outgoing", + "prefix": "out", + "url": "http:\/\/outgoingnyc.com\/" + }, + { + "description": "An open dataset of administrative areas in New York City.", + "fullname": "Pediacities", + "id": 907131617, + "key": "", + "license": "http:\/\/catalog.opendata.city\/dataset\/pediacities-nyc-neighborhoods\/resource\/91778048-3c58-449c-a3f9-365ed203e914", + "license_text": "Subject to the terms and conditions of this License, the Licensor grants to You a worldwide, royalty-free, non-exclusive, terminable (but only under Section 9) license to Use the Database for the duration of any applicable copyright and Database Rights.", + "license_type": "ODC-By, v1.0", + "name": "pedia", + "prefix": "pedia", + "url": "http:\/\/catalog.opendata.city\/dataset\/pediacities-nyc-neighborhoods" + }, + { + "description": "Confirmed Public Domain by Kevin Martin of the Portland BPS on 2016-10-07 ", + "fullname": "City of Portland Bureau of Planning and Sustainability", + "id": 1108713463, + "key": "", + "license": "https:\/\/www.arcgis.com\/home\/item.html?id=c11815647b3949faa20b16cf50ab214d", + "license_text": "'Intention is free and open use, licensed for the public domain. For now, you can assume the data is completely open.'", + "license_type": "Public Domain", + "name": "porbps", + "prefix": "porbps", + "url": "http:\/\/gis.pdx.opendata.arcgis.com\/datasets\/c11815647b3949faa20b16cf50ab214d_125" + }, + { + "description": "A gazetteer of non-overlapping, authoritative polygons around a curated list of places. Quattroshapes includes open data from government and other sources, many of which require attribution. See [remarks](https:\/\/github.com\/whosonfirst\/whosonfirst-sources\/blob\/master\/sources\/quattroshapes_remarks.md) for detail.", + "fullname": "Quattroshapes", + "id": 404734183, + "key": "id", + "license": "https:\/\/github.com\/foursquare\/quattroshapes\/blob\/master\/LICENSE.md", + "license_text": "Please include attribution in your app, site, or printed work.", + "license_type": "CC BY 2.0", + "name": "quattroshapes", + "prefix": "qs", + "remarks": "https:\/\/github.com\/whosonfirst\/whosonfirst-sources\/blob\/master\/sources\/quattroshapes_remarks.md", + "url": "http:\/\/www.quattroshapes.com\/" + }, + { + "description": "The Quattroshapes point gazetteer. A big list of point locations that supplements the polygons gazetteer.", + "fullname": "Quattroshapes Point Gazetteer", + "id": 1108970625, + "key": "", + "license": "https:\/\/github.com\/foursquare\/quattroshapes\/blob\/master\/LICENSE.md", + "license_text": "Please include attribution in your app, site, or printed work.", + "license_type": "CC BY 2.0", + "name": "quattroshapes_pg", + "prefix": "qs_pg", + "url": "http:\/\/www.quattroshapes.com\/" + }, + { + "description": "The San Diego Geographic Information Source (SanGIS) is a Joint Powers Authority (JPA) of the City of San Diego and the County of San Diego responsible for maintaining a regional geographic information system (GIS) landbase and data warehouse.", + "fullname": "SanGIS\/SANDAG GIS Data Warehouse", + "id": 1108800651, + "key": "", + "license": "http:\/\/www.sangis.org\/Legal_Notice.htm", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", + "license_type": "CC0", + "name": "sdgis", + "prefix": "sdgis", + "url": "http:\/\/rdw.sandag.org\/Account\/GetFSFile.aspx?dir=Law&Name=SDPD_BEATS.zip" + }, + { + "description": "Official data portal for the City of Seattle, WA.", + "fullname": "Seattle City GIS Program", + "id": 874455653, + "key": "", + "license": "https:\/\/data.seattle.gov\/data-policy", + "license_text": "The Open Data Program makes the data generated by the City of Seattle openly available to the public.", + "license_type": "Public Domain", + "name": "seagv", + "prefix": "seagv", + "url": "https:\/\/data.seattle.gov\/dataset\/data-seattle-gov-GIS-shapefile-datasets\/f7tb-rnup" + }, + { + "description": "Official website for the San Francisco Arts Commission.", + "fullname": "San Francisco Arts Commission", + "id": 772974303, + "key": "accession_id", + "license": "http:\/\/www.sfartscommission.org\/terms-use", + "license_text": "As a convenience to potential users, the City and County of San Francisco ('City') makes a variety of datasets ('Data') available for download through this website. Your use of the Data is subject to these terms of use, which constitute a legal agreement between You and the City and County of San Francisco ('City'). This legal agreement is referred to as the 'Terms of Use.'", + "license_type": "CC BY (assumed)", + "name": "sfac", + "prefix": "sfac", + "url": "http:\/\/www.sfartscommission.org\/" + }, + { + "description": "Open Data portal for the City of San Francisco, CA.", + "fullname": "City of San Francisco", + "id": 772974267, + "key": "", + "license": "https:\/\/data.sfgov.org\/terms-of-use", + "license_text": "The Open Data Commons, Public Domain Dedication & Licence is a document intended to allow you to freely share, modify, and use this work for any purpose and without any restrictions. This licence is intended for use on databases or their contents ('data'), either together or individually.", + "license_type": "PDDL 1.0", + "name": "sfgov", + "prefix": "sfgov", + "url": "https:\/\/data.sfgov.org\/" + }, + { + "description": "Open Data portal for the City of San Francisco, CA.", + "fullname": "City of San Francisco Treasurer & Tax Collector's Office (Registered Business Locations)", + "id": 1158783301, + "key": "id", + "license": "https:\/\/data.sfgov.org\/terms-of-use", + "license_text": "The Open Data Commons, Public Domain Dedication & Licence is a document intended to allow you to freely share, modify, and use this work for any purpose and without any restrictions. This licence is intended for use on databases or their contents ('data'), either together or individually.", + "license_type": "PDDL 1.0", + "name": "sfgov_rbl", + "prefix": "sfgov_rbl", + "url": "https:\/\/data.sfgov.org\/" + }, + { + "description": "SimpleGeo was a location aware services company that operated between 2009 and 2011. It is no longer an active company.", + "fullname": "SimpleGeo", + "id": 404734199, + "key": "id", + "license": "https:\/\/creativecommons.org\/publicdomain\/zero\/1.0\/", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", + "license_type": "CC0", + "name": "simplegeo", + "prefix": "sg", + "url": "https:\/\/www.simplegeo.com" + }, + { + "description": "The City of San Jose, CA's Planning Department website.", + "fullname": "San Jose Planning Department", + "id": 1108784751, + "key": "", + "license": "http:\/\/www.sanjoseca.gov\/DocumentCenter\/View\/55954", + "license_text": "Data made open and freely available to the public to be republished, manipulated, or used in any other way without restriction.", + "license_type": "CC0", + "name": "sjp", + "prefix": "sjp", + "url": "https:\/\/www.sanjoseca.gov\/DocumentCenter\/View\/11287" + }, + { + "description": "Open San Mateo County contains data published by the County of San Mateo.", + "fullname": "Open San Mateo County", + "id": 874397695, + "key": "", + "license": "https:\/\/creativecommons.org\/publicdomain\/zero\/1.0\/legalcode", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", + "license_type": "CC0", + "name": "smcgov", + "prefix": "smcgov", + "url": "https:\/\/data.smcgov.org\/" + }, + { + "description": "Bezirke (districts) and Ortsteile (localities) provided under an open data license.", + "fullname": "Senatsverwaltung fur Stadtentwicklung und Umwelt Berlin", + "id": 1108808939, + "key": "", + "license": "http:\/\/www.stadtentwicklung.berlin.de\/geoinformation\/download\/nutzIII.pdf", + "license_text": "Geodata and geodata services, including associated metadata, shall be used for: All currently known as well as for all future known commercial and not. Commercial use, as far as possible by special. Legal provisions, or contractual or legal rights. Third does not oppose it.", + "license_type": "CC0 (assumed)", + "name": "ssuberlin", + "prefix": "ssuberlin", + "url": "http:\/\/daten.berlin.de\/datensaetze?field_category_tid%5B%5D=231" + }, + { + "description": "Statistics Canada produces statistics that help Canadians better understand their country,its population, resources, economy, society and culture.", + "fullname": "Statistics Canada", + "id": 554906275, + "key": "", + "license": "http:\/\/www.statcan.gc.ca\/eng\/reference\/licence-eng", + "license_text": "Subject to this agreement, Statistics Canada grants you a worldwide, royalty-free, non-exclusive licence to: use, reproduce, publish, freely distribute, or sell the Information; use, reproduce, publish, freely distribute, or sell Value-added Products; and, sublicence any or all such rights, under terms consistent with this agreement.", + "license_type": "CC-BY (assumed)", + "name": "statcan", + "prefix": "statcan", + "url": "http:\/\/statcan.gc.ca\/" + }, + { + "description": "The Open Information portal for the Saint Paul, MN government.", + "fullname": "Open Information Saint Paul", + "id": 1108800107, + "key": "", + "license": "https:\/\/information.stpaul.gov\/City-Administration\/Establishing-an-Open-Information-Program-Resolutio\/v7qy-vtzb", + "license_text": "The City shall develop and implement practices allowing it to prioritize the proactive release of high quality, machine-readable, disclosable city data, making it freely available via an open license without restrictions on use, reuse, or redistribution, ensuring it is fully accessible to the broadest range of users possible.", + "license_type": "CC0 (assumed)", + "name": "stpaulgov", + "prefix": "stpaulgov", + "url": "https:\/\/information.stpaul.gov\/City-Administration\/District-Council-Shapefile-Map\/dq4n-yj8b" + }, + { + "description": "The Surveying and Mapping Authority of the Republic of Slovenia's Open Data portal.", + "fullname": "Surveying and Mapping Authority of the Republic of Slovenia", + "id": 1108955989, + "key": "", + "license": "https:\/\/creativecommons.org\/licenses\/by\/2.5\/si\/legalcode", + "license_text": "Licensor in accordance with the terms and conditions of this License grants the user free, nonexclusive, territorial and unlimited (for the duration of the rights stipulated by the Law on copyright) license to exercise the rights at work.", + "license_type": "CC BY 2.5 SI", + "name": "svn-sma", + "prefix": "svn-sma", + "url": "http:\/\/egp.gu.gov.si\/egp\/" + }, + { + "description": "The TGN is an evolving vocabulary, growing and changing thanks to contributions from Getty projects and other institutions.", + "fullname": "Getty Thesaurus of Geographic Names", + "id": 840464261, + "key": "id", + "license": "http:\/\/opendatacommons.org\/licenses\/by\/1-0\/", + "license_text": "The Open Data Commons Attribution License is a license agreement intended to allow users to freely share, modify, and use this Database subject only to the attribution requirements set out in Section 4.", + "license_type": "ODC-By v1.0", + "name": "tgn", + "prefix": "tgn", + "url": "https:\/\/www.getty.edu\/research\/tools\/vocabularies\/tgn\/index.html" + }, + { + "description": "The list is an online concert guide for Northern California and the west coast.", + "fullname": "The List - Bay Area Concert Guide", + "id": 1108973687, + "key": "", + "license": "http:\/\/www.calweb.net\/~skoepke\/", + "license_text": "Public domain per email conversation on May 30th, 2017.", + "license_type": "Public Domain", + "name": "thelist", + "prefix": "thelist", + "url": "http:\/\/www.calweb.net\/~skoepke\/" + }, + { + "description": "Open Data portal for the City of Turku, Finland.", + "fullname": "Turku City Government", + "id": 1108728529, + "key": "", + "license": "http:\/\/www.lounaistieto.fi\/blog\/2015\/08\/18\/turun-palvelualuejakotilastoalueet\/", + "license_text": "You are free to: Share - copy and redistribute the material in any medium or format and Adapt - remix, transform, and build upon the material for any purpose, even commercially.", + "license_type": "CC BY 4.0", + "name": "tkugov", + "prefix": "tkugov", + "url": "http:\/\/opendata.lounaistieto.fi\/aineistoja\/Turku_pienalueet.zip" + }, + { + "description": "Open Data portal for the City of Tampere, Finland.", + "fullname": "Tampere City Survey GIS", + "id": 1108728281, + "key": "", + "license": "http:\/\/www.tampere.fi\/tampereen-kaupunki\/tietoa-tampereesta\/avoin-data\/avoin-data-lisenssi.html", + "license_text": "This is a worldwide, royalty-free, irrevocable, parallel license allowing the above-mentioned material to be freely available to 1. Copy and distribute. 2. Modify and utilize commercially and non-commercially to combine with other products. 3. Used as part of an application or service.", + "license_type": "CC0 (assumed)", + "name": "tmpgov", + "prefix": "tmpgov", + "url": "http:\/\/opendata.navici.com\/tampere\/opendata\/ows?service=WFS&version=2.0.0&request=GetFeature&typeName=opendata:KH_TILASTO&outputFormat=json" + }, + { + "description": "Open Data portal for Toronto, ON.", + "fullname": "Toronto Social Development, Finance & Administration Department", + "id": 1108833305, + "key": "", + "license": "http:\/\/www1.toronto.ca\/wps\/portal\/contentonly?vgnextoid=4a37e03bb8d1e310VgnVCM10000071d60f89RCRD", + "license_text": "You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", + "license_type": "Open Government Licence, Ontario, v1.0", + "name": "torsdfa", + "prefix": "torsdfa", + "url": "http:\/\/www1.toronto.ca\/wps\/portal\/contentonly?vgnextoid=04b489fe9c18b210VgnVCM1000003dd60f89RCRD&vgnextchannel=75d6e03bb8d1e310VgnVCM10000071d60f89RCRD" + }, + { + "description": "Transitland brings together many sources of transit data to build a directory of operators and feeds that can be edited by transit enthusiasts and developers.", + "fullname": "Transitland", + "id": 1108955939, + "key": "onestop_id", + "license": "https:\/\/transit.land\/an-open-project\/contributor-agreement.html", + "license_text": "Mapzen hereby grants to You and You hereby accept a limited, non-exclusive, royalty free, non-transferable, non-sublicensable, freely revocable, worldwide license solely to use the Licensed Material to develop Products.", + "license_type": "CC0", + "name": "transitland", + "prefix": "transitland", + "url": "https:\/\/transit.land\/" + }, + { + "description": "Unknown.", + "fullname": "unknown", + "id": 1108830757, + "key": "id", + "license": "N\/A", + "license_text": "", + "license_type": "", + "name": "unknown", + "prefix": "unknown", + "url": "" + }, + { + "description": "UN\/LOCODE is based on a code structure set up by ECLAC and a list of locations originating in ESCAP, developed in UNCTAD in co-operation with transport organisations like IATA and the ICS and with active contributions from national governments and commercial bodies. Note: Who's On First concatenates the UN\/LOCODE two-character country code and three-character feature code with a deliminator and names the result the 'id'.", + "fullname": "UN\/LOCODE (United Nations Code for Trade and Transport Locations)", + "id": 420573473, + "key": "id", + "license": "http:\/\/www.unece.org\/cefact\/locode\/locode_since1981.html", + "license_text": "UN\/LOCODE is freely available to all interested users.", + "license_type": "CC0", + "name": "unlocode", + "prefix": "unlc", + "url": "http:\/\/www.unece.org\/cefact\/locode\/welcome.html" + }, + { + "alt": [ + { + "function": "display", + "extras": [ + "scope", + "detail" + ] + } + ], + "data_sources": [ + { + "default": "https:\/\/www.census.gov\/cgi-bin\/geo\/shapefiles\/index.php", + "alt-uscensus-display-terrestrial-zoom-10": "http:\/\/www2.census.gov\/geo\/tiger\/GENZ2015\/shp\/cb_2015_us_state_500k.zip" + } + ], + "description": "The leading source of quality data about the nation's people and economy from the United States Census Bureau.", + "fullname": "United States Census Bureau", + "id": 1108739789, + "key": "", + "license": "https:\/\/www.census.gov\/data\/developers\/about\/terms-of-service.html", + "license_text": "All U.S. Census Bureau materials, regardless of the media, are entirely in the public domain. There are no user fees, site licenses, or any special agreements etc for the public or private use, and or reuse of any census title. As tax funded product, it's all in the public record.", + "license_type": "CC0", + "name": "uscensus", + "prefix": "uscensus", + "url": "https:\/\/www.census.gov\/" + }, + { + "description": "ZIP Code Tabulation Areas (ZCTAs) are generalized areal representations of United States Postal Service (USPS) ZIP Code service areas.", + "fullname": "US ZIP Code Tabulation Area", + "id": 554867137, + "key": "id", + "license": "https:\/\/www.census.gov\/data\/developers\/about\/terms-of-service.html", + "license_text": "All U.S. Census Bureau materials, regardless of the media, are entirely in the public domain. There are no user fees, site licenses, or any special agreements etc for the public or private use, and or reuse of any census title. As tax funded product, it's all in the public record.", + "license_type": "CC0", + "name": "uszcta", + "prefix": "uszcta", + "url": "http:\/\/www.census.gov\/geo\/reference\/zctas.html" + }, + { + "description": "Open Data portal for the City of Vancouver.", + "fullname": "Vancouver Planning and Development Services", + "id": 1108906615, + "key": "", + "license": "http:\/\/vancouver.ca\/your-government\/open-data-catalogue.aspx#tab19099", + "license_text": "you are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", + "license_type": "Open Government Licence, British Columbia, v2.0", + "name": "vanpds", + "prefix": "vanpds", + "url": "http:\/\/data.vancouver.ca\/datacatalogue\/localAreaBoundary.htm" + }, + { + "description": "A map of neighborhood boundaries in the District of Columbia.", + "fullname": "Washington Post", + "id": 1108724061, + "key": "", + "license": "http:\/\/opendatadc.org\/dataset\/neighborhood-boundaries-217-neighborhoods-washpost-justgrimes", + "license_text": "The Creative Commons Attribution license allows re-distribution and re-use of a licensed work on the condition that the creator is appropriately credited.", + "license_type": "CC-BY", + "name": "wapo", + "prefix": "wapo", + "url": "http:\/\/opendatadc.org\/dataset\/neighborhood-boundaries-217-neighborhoods-washpost-justgrimes" + }, + { + "description": "Concordances against Wikidata; public domain structured data.", + "fullname": "Wikidata", + "id": 420577535, + "key": "id", + "license": "https:\/\/creativecommons.org\/publicdomain\/zero\/1.0\/", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", + "license_type": "CC0", + "name": "wikidata", + "prefix": "wd", + "url": "https:\/\/www.wikidata.org\/" + }, + { + "fullname": "Wikipedia", + "id": 404734189, + "key": "page", + "license": "https:\/\/en.wikipedia.org\/wiki\/Wikipedia:Copyrights", + "license_text": "Most of Wikipedia's text and many of its images are co-licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License (CC BY-SA) and the GNU Free Documentation License (GFDL) (unversioned, with no invariant sections, front-cover texts, or back-cover texts).", + "license_type": "CC BY-SA 3.0", + "name": "wikipedia", + "prefix": "wk", + "url": "http:\/\/www.wikipedia.org\/" + }, + { + "description": "Cached, accessed: 2017-05-11, via: https:\/\/web.archive.org\/web\/20111028163611\/http:\/\/developer.yahoo.com\/geo\/geoplanet\/data\/.", + "fullname": "Yahoo! GeoPlanet (formerly Where On Earth)", + "id": 404734187, + "key": "id", + "license": "http:\/\/developer.yahoo.com\/geo\/geoplanet\/data\/", + "license_text": "This page provides open access to the underlying data under a Creative Commons Attribution license so that you can incorporate WOEIDs and the GeoPlanet hierarchy into your own applications.", + "license_type": "CC BY", + "name": "whereonearth", + "prefix": "woe", + "url": "http:\/\/developer.yahoo.com\/geo\/geoplanet\/" + }, + { + "description": "Clickable database of Where On Earth (woe) ids.", + "fullname": "WOE DB", + "id": 404734207, + "key": "id", + "license": "N\/A", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", + "license_type": "CC0", + "name": "woedb", + "prefix": "woedb", + "url": "http:\/\/woe.spum.org\/" + }, + { + "description": "Who's On First is a gazetteer of places. Not quite all the places in the world but a whole lot of them and, we hope, the kinds of places that we mostly share in common.", + "fullname": "Who's On First", + "id": 404734215, + "key": "id", + "license": "https:\/\/github.com\/whosonfirst-data\/whosonfirst-data\/blob\/master\/LICENSE.md", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. Note that some included work is available under CC BY.", + "license_type": "CC0", + "name": "whosonfirst", + "prefix": "wof", + "url": "http:\/\/whosonfirst.mapzen.com\/" + }, + { + "description": "Missing - as in a placeholder for WOF records without a geometry.", + "fullname": "Missing", + "id": 404734213, + "key": "", + "license": "N\/A", + "license_text": "", + "license_type": "", + "name": "missing", + "prefix": "xx", + "url": "" + }, + { + "description": "Weighted means from Quattroshapes. Yerbashapes are a product of Mapzen for Who's On First.", + "fullname": "Yerbashapes", + "id": 404734201, + "key": "", + "license": "N\/A", + "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", + "license_type": "CC0", + "name": "yerbashapes", + "prefix": "ys", + "url": "" + }, + { + "description": "An overlay of boundaries for Chicago's 228 neighborhoods.", + "fullname": "Zolk Chicago Neighborhoods Map", + "id": 907219099, + "key": "", + "license": "http:\/\/chicagomap.zolk.com\/about.html", + "license_text": "The resulting KML source data is licensed under a Creative Commons Attribution License. This means that you're free to use the data from this map as you wish, but credit to either Kevin Zolkiewicz or this web site is appreciated.", + "license_type": "CC BY 3.0 US", + "name": "zolk", + "prefix": "zolk", + "url": "http:\/\/chicagomap.zolk.com\/" + }, + { + "description": "Zetashapes is an experiment in crowdsourced US neighborhood polygons.", + "fullname": "Zetashapes", + "id": 404734191, + "key": "id", + "license": "http:\/\/www.zetashapes.com\/license", + "license_text": "The polygons generated by this site do not have any added restrictions beyond the base data from tiger and flickr. The basic source data is from US TIGER\/Line Census Data which is public domain (Q10). This site also makes use of data scraped from the flickr api -- you should probably mention on your site if you reuse this data that there is flickr data associated with it.", + "license_type": "Public domain", + "name": "zetashapes", + "prefix": "zs", + "remarks": "https:\/\/github.com\/whosonfirst\/whosonfirst-sources\/blob\/master\/sources\/zetashapes_remarks.md", + "url": "http:\/\/www.zetashapes.com" } ], "stat": "ok" } ``` -_This example response has been truncated for the sake of brevity._ - -#### whosonfirst.sources.getPrefixes + +#### mapzen.places.sources.getPrefixes Return the list of prefixes for all Who's On First sources. @@ -1345,7 +2886,7 @@ This API method does not define any custom error codes. For the list of error co ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.sources.getPrefixes&api_key=your-mapzen-api-key' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.sources.getPrefixes&api_key=your-mapzen-api-key' { "prefixes": [ @@ -1376,13 +2917,16 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.sources.getP "can-mtlsmvt", "can-nwds", "can-ons", + "can-qcodp", "can-rodca", "can-saskodp", "can-surgis", + "can-vicodc", "can-wpgppd", "canvec-hydro", "cbsnl", "chgov", + "companieshouse", "dbp", "denvercpd", "ebc", @@ -1404,8 +2948,10 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.sources.getP "iso", "kuogov", "lacity", + "lacity_oof", "latimes", "lbl", + "lieu", "loc", "meso", "ms", @@ -1417,6 +2963,8 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.sources.getP "ni", "nolagis", "nycgov", + "nycgov_dca", + "nycgov_dohmh", "nycgov_subway", "nyt", "oa", @@ -1432,6 +2980,7 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.sources.getP "seagv", "sfac", "sfgov", + "sfgov_rbl", "sg", "sjp", "smcgov", @@ -1466,13 +3015,13 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.sources.getP ``` -### whosonfirst.tags +### mapzen.places.tags -* [whosonfirst.tags.getSources](#whosonfirst.tags.getSources) -* [whosonfirst.tags.getTags](#whosonfirst.tags.getTags) +* [mapzen.places.tags.getSources](#mapzen.places.tags.getSources) +* [mapzen.places.tags.getTags](#mapzen.places.tags.getTags) - -#### whosonfirst.tags.getSources + +#### mapzen.places.tags.getSources Return the list of sources for all the tags in Who's On First. @@ -1494,7 +3043,7 @@ This API method does not define any custom error codes. For the list of error co ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.tags.getSources&api_key=your-mapzen-api-key' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.tags.getSources&api_key=your-mapzen-api-key' { "sources": [ @@ -1505,8 +3054,8 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.tags.getSour } ``` - -#### whosonfirst.tags.getTags + +#### mapzen.places.tags.getTags Return the list of unique tags n Who's On First. @@ -1537,7 +3086,7 @@ In addition to [default error codes](errors.md) common to all methods this API m ##### Example ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.tags.getTags&api_key=your-mapzen-api-key&source=wof&per_page=1' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.tags.getTags&api_key=your-mapzen-api-key&source=wof&per_page=1' { "tags": [ @@ -1546,7 +3095,7 @@ curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.tags.getTags "tag": "contractor" } ], - "next_query": "method=whosonfirst.tags.getTags&source=wof&per_page=1&page=2", + "next_query": "method=mapzen.places.tags.getTags&source=wof&per_page=1&page=2", "total": 38151, "page": 1, "per_page": 1, diff --git a/docs/pagination.md b/docs/pagination.md index 272d496..3b3e82f 100644 --- a/docs/pagination.md +++ b/docs/pagination.md @@ -5,7 +5,7 @@ Pagination shouldn't be complicated. But it is. Because databases, after all the Databases have always been about trade-offs. No two databases are the same and so no two sets of trade-offs are the same either. The really short version is that some databases can't tell you exactly how many results there are for a given query. Some databases can tell you how many results there are but can't or won't return results past a certain limit. Other databases can do both but only if you use something called a cursor for pagination rather than the traditional offset and limit model (as in "return the next 5 of 50 results starting from postion 20"). -Since there isn't an all-purpose database, the Who's On First API accounts for multiple different pagination models. We've identified four overlapping models ([plain](#pagination-plain), [cursor](#pagination-cursor), [mixed](#pagination-mixed) and [next-query](#pagination-next-query)) each of which are described in detail below. +Since there isn't an all-purpose database, the Mapzen Places (dev) accounts for multiple different pagination models. We've identified four overlapping models ([plain](#pagination-plain), [cursor](#pagination-cursor), [mixed](#pagination-mixed) and [next-query](#pagination-next-query)) each of which are described in detail below. If you don't really care and just want to get started [you should skip ahead to the documentation for next-query pagination](#pagination-next-query). @@ -19,7 +19,7 @@ For example, let's say you wanted to use the API to fetch all the places with a ``` { "places": [ ... ], - "next_query": "method=whosonfirst.places.search&alt=Paris&per_page=5&page=2", + "next_query": "method=mapzen.places.search&alt=Paris&per_page=5&page=2", "total": 7, "page": 1, "per_page": 5, @@ -41,7 +41,7 @@ For example, let's say you wanted to use the API to fetch all of the venues near ``` { "places": [ ... ], - "next_query": "method=whosonfirst.places.getNearby&latitude=40.784165&longitude=-73.958110&placetype=venue&per_page=10&cursor={CURSOR}", + "next_query": "method=mapzen.places.getNearby&latitude=40.784165&longitude=-73.958110&placetype=venue&per_page=10&cursor={CURSOR}", "per_page": 10, "cursor": {CURSOR}, "stat": "ok" @@ -62,7 +62,7 @@ For example, let's say you wanted to use the API to fetch all the microhoo ``` { "places": [ ... ], - "next_query": "method=whosonfirst.places.search&placetype=microhood&page=2&per_page=5", + "next_query": "method=mapzen.places.search&placetype=microhood&page=2&per_page=5", "total": 186, "page": 1, "per_page": 5, @@ -77,7 +77,7 @@ But if you then asked the API to fetch all of the neighbourhoods, a ``` { "places": [ ... ], - "next_query": "method=whosonfirst.places.search&placetype=neighbourhood&per_page=5&cursor={CURSOR}", + "next_query": "method=mapzen.places.search&placetype=neighbourhood&per_page=5&cursor={CURSOR}", "total": 81065, "page": null, "pages": 16213, @@ -101,7 +101,7 @@ For example, let's say you wanted to use the API to fetch all the localities (th ``` { "places": [ ... ], - "next_query": "method=whosonfirst.places.search&placetype=locality&per_page=5&cursor={CURSOR}", + "next_query": "method=mapzen.places.search&placetype=locality&per_page=5&cursor={CURSOR}", "total": 208214, "page": null, "pages": 41643, @@ -129,7 +129,7 @@ Pagination properties are also returned as HTTP response headers. This is useful For example: ``` -$> curl -s -v -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.search&api_key=API_KEY&q=poutine&extras=geom:bbox&page=1&format=csv&per_page=1' +$> curl -s -v -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.search&api_key=API_KEY&q=poutine&extras=geom:bbox&page=1&format=csv&per_page=1' < HTTP/1.1 200 OK < Access-Control-Allow-Origin: * @@ -137,7 +137,7 @@ $> curl -s -v -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.pla < Date: Tue, 28 Feb 2017 21:13:37 GMT < Status: 200 OK < X-api-pagination-cursor: -< X-api-pagination-next-query: method=whosonfirst.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2&format=csv +< X-api-pagination-next-query: method=mapzen.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2&format=csv < X-api-pagination-page: 1 < X-api-pagination-pages: 13 < X-api-pagination-per-page: 1 diff --git a/elasticsearch/schema/mappings.whosonfirst.json b/elasticsearch/schema/mappings.whosonfirst.json new file mode 100644 index 0000000..18f037a --- /dev/null +++ b/elasticsearch/schema/mappings.whosonfirst.json @@ -0,0 +1,435 @@ +{ + "settings": { + "analysis": { + "char_filter": { + "zwj_char_filter": { + "type": "mapping", + "mappings": [ + "\\u200D=>" + ] + } + }, + "filter": { + "english_emoji": { + "type": "synonym", + "synonyms_path": "synonyms/cldr-emoji-annotation-synonyms-en.txt" + }, + "punctuation_filter": { + "type": "pattern_replace", + "pattern": "\\p{Punct}|\\uFE0E|\\uFE0F|\\uD83C\\uDFFB|\\uD83C\\uDFFC|\\uD83C\\uDFFD|\\uD83C\\uDFFE|\\uD83C\\uDFFF", + "replace": "" + }, + "remove_empty_filter": { + "type": "length", + "min": 1 + }, + "snowball_eng" : { + "type" : "snowball", + "language" : "English" + } + }, + "analyzer": { + "english_with_emoji": { + "char_filter": "zwj_char_filter", + "tokenizer": "whitespace", + "filter": [ + "lowercase", + "punctuation_filter", + "remove_empty_filter", + "snowball_eng", + "english_emoji" + ] + }, + "machinetag-path-analyzer": { + "type": "custom", + "tokenizer": "machinetag-path-tokenizer" + } + }, + "tokenizer": { + "machinetag-path-tokenizer": { + "type": "path_hierarchy", + "delimiter": "/" + } + } + } + }, + "mappings" : { + "_default_": { + "dynamic_templates": [ + { "counts": { + "match": "count*", + "match_mapping_type": "long", + "mapping": { + "type": "long" + } + }}, + { "edtf": { + "match": "edtf:*", + "match_mapping_type": "string", + "mapping": { + "type": "string" + } + }}, + { "fsgov": { + "match": "fsgov:*", + "match_mapping_type": "string", + "mapping": { + "type": "string" + } + }}, + { "names_x_preferred": { + "match": "name:*_x_preferred", + "match_mapping_type": "string", + "mapping": { + "type": "string", + "copy_to": "names_preferred" + } + }}, + { "names_x_variant": { + "match": "name:*_x_variant", + "match_mapping_type": "string", + "mapping": { + "type": "string", + "copy_to": [ "names_alt", "names_variant" ] + } + }}, + { "names_x_colloquial": { + "match": "name:*_x_colloquial", + "match_mapping_type": "string", + "mapping": { + "type": "string", + "copy_to": [ "names_alt", "names_colloquial" ] + } + }}, + { "names_x_unknown": { + "match": "name:*_x_unknown", + "match_mapping_type": "string", + "mapping": { + "type": "string", + "copy_to": "names_alt" + } + }}, + { "names_x_all": { + "match": "name:*_x_*", + "match_mapping_type": "string", + "mapping": { + "type": "string", + "copy_to": "names_all" + } + }}, + { "latitude": { + "match": "*:latitude", + "match_mapping_type": "double", + "mapping": { + "type": "double" + } + }}, + { "longitude": { + "match": "*:longitude", + "match_mapping_type": "double", + "mapping": { + "type": "double" + } + }}, + { "misc": { + "match": "misc:*", + "match_mapping_type": "string", + "mapping": { + "type": "string" + } + }}, + { "quattroshapes": { + "match": "qs:*", + "match_mapping_type": "string", + "mapping": { + "type": "string" + } + }}, + { "zetashapes": { + "match": "zs:*", + "match_mapping_type": "string", + "mapping": { + "type": "string" + } + }} + ], + "properties" : { + "categories_all": { + "type" : "string", + "analyzer": "machinetag-path-analyzer", + "search_analyzer": "keyword" + }, + "names_all" : { + "type" : "string", + "analyzer": "english_with_emoji", + "search_analyzer": "english_with_emoji" + }, + "names_alt" : { + "type" : "string", + "analyzer": "english_with_emoji", + "search_analyzer": "english_with_emoji" + }, + "names_colloquial" : { + "type" : "string", + "analyzer": "english_with_emoji", + "search_analyzer": "english_with_emoji" + }, + "names_preferred" : { + "type" : "string", + "analyzer": "english_with_emoji", + "search_analyzer": "english_with_emoji" + }, + "names_variant" : { + "type" : "string", + "analyzer": "english_with_emoji", + "search_analyzer": "english_with_emoji" + }, + "name_not_analyzed" : { + "type" : "string", + "index" : "not_analyzed" + }, + "machinetags_all": { + "type" : "string", + "analyzer": "machinetag-path-analyzer", + "search_analyzer": "keyword" + }, + "tags_all": { + "type" : "string", + "analyzer": "english_with_emoji", + "search_analyzer": "english_with_emoji" + }, + "geom:area" : { + "type" : "double" + }, + "geom:bbox" : { + "type" : "string" + }, + "geom:type" : { + "type" : "string" + }, + "geonames:id" : { + "type" : "string" + }, + "gn:elevation" : { + "type" : "long" + }, + "gn:id" : { + "type" : "long" + }, + "gn:population" : { + "type" : "long" + }, + "iso:country" : { + "type" : "string", + "analyzer": "english_with_emoji", + "search_analyzer": "english_with_emoji" + }, + "mz:categories": { + "type" : "string", + "analyzer": "machinetag-path-analyzer", + "search_analyzer": "keyword", + "copy_to": [ "categories_all", "machinetags_all" ] + }, + "mz:is_funky" : { + "type" : "integer" + }, + "mz:is_landuse_aoi" : { + "type" : "integer" + }, + "mz:max_zoom" : { + "type" : "integer" + }, + "mz:min_zoom" : { + "type" : "integer" + }, + "sg:categories": { + "type" : "string", + "analyzer": "machinetag-path-analyzer", + "search_analyzer": "keyword", + "copy_to": [ "categories_all", "machinetags_all" ] + }, + "sg:classifiers": { + "properties": { + "category": { + "type" : "string", + "index" : "not_analyzed" + }, + "subcategory": { + "type" : "string", + "index" : "not_analyzed" + }, + "test": { + "type" : "string", + "index" : "not_analyzed" + } + } + }, + "sg:tags": { + "type" : "string", + "index" : "not_analyzed", + "copy_to": "tags_all" + }, + "src:geom" : { + "type" : "string" + }, + "src:lbl:centroid" : { + "type" : "string" + }, + "wof:belongsto" : { + "type" : "long" + }, + "wof:breaches" : { + "type" : "long" + }, + "wof:categories": { + "type" : "string", + "analyzer": "machinetag-path-analyzer", + "search_analyzer": "keyword", + "copy_to": [ "categories_all", "machinetags_all" ] + }, + "wof:concordances" : { + "properties" : { + "dbp:id" : { + "type" : "string", + "index" : "not_analyzed" + }, + "fb:id" : { + "type" : "string", + "index" : "not_analyzed" + }, + "fct:id" : { + "type" : "string", + "index" : "not_analyzed" + }, + "gn:id" : { + "type" : "long" + }, + "gp:id" : { + "type" : "long" + }, + "loc:id" : { + "type" : "string", + "index" : "not_analyzed" + }, + "nyt:id" : { + "type" : "string", + "index" : "not_analyzed" + }, + "qs:id" : { + "type" : "long" + }, + "tgn:id" : { + "type" : "long" + }, + "wd:id" : { + "type" : "string", + "index" : "not_analyzed" + }, + "wk:page" : { + "type" : "string", + "index" : "not_analyzed" + } + } + }, + "wof:concordances_count" : { + "type" : "long" + }, + "wof:country" : { + "type" : "string", + "analyzer": "english_with_emoji", + "search_analyzer": "english_with_emoji" + }, + "wof:geomhash" : { + "type" : "string" + }, + "wof:hierarchy" : { + "properties" : { + "borough_id": { + "type" : "long" + }, + "continent_id" : { + "type" : "long" + }, + "country_id" : { + "type" : "long" + }, + "county_id" : { + "type" : "long" + }, + "dependency_id" : { + "type" : "long" + }, + "disputed_id" : { + "type" : "long" + }, + "empire_id" : { + "type" : "long" + }, + "localadmin_id" : { + "type" : "long" + }, + "locality_id" : { + "type" : "long" + }, + "macrocounty_id" : { + "type" : "long" + }, + "macrohood_id" : { + "type" : "long" + }, + "macroregion_id" : { + "type" : "long" + }, + "microhood_id" : { + "type" : "long" + }, + "neighbourhood_id" : { + "type" : "long" + }, + "region_id" : { + "type" : "long" + } + } + }, + "wof:id" : { + "type" : "long" + }, + "wof:lang" : { + "type" : "string" + }, + "wof:lastmodified" : { + "type" : "long" + }, + "wof:megacity" : { + "type" : "long" + }, + "wof:name" : { + "type" : "string", + "analyzer": "english_with_emoji", + "search_analyzer": "english_with_emoji", + "copy_to" : [ "names_all", "name_not_analyzed" ] + }, + "wof:parent_id" : { + "type" : "long" + }, + "wof:placetype" : { + "type" : "string" + }, + "wof:placetype_id" : { + "type" : "long" + }, + "wof:scale" : { + "type" : "long" + }, + "wof:supersedes" : { + "type" : "long" + }, + "wof:tags" : { + "type" : "string", + "index" : "not_analyzed", + "copy_to": "tags_all" + } + } + } + } +} diff --git a/elasticsearch/synonyms/cldr-emoji-annotation-synonyms-en.txt b/elasticsearch/synonyms/cldr-emoji-annotation-synonyms-en.txt new file mode 100644 index 0000000..c8b6eec --- /dev/null +++ b/elasticsearch/synonyms/cldr-emoji-annotation-synonyms-en.txt @@ -0,0 +1,1229 @@ +😀 => 😀, face, grin +😁 => 😁, eye, face, grin, smile +😂 => 😂, face, joy, laugh, tear +😃 => 😃, face, mouth, open, smile +😄 => 😄, eye, face, mouth, open, smile +😅 => 😅, cold, face, open, smile, sweat +😆 => 😆, face, laugh, mouth, open, satisfied, smile +😉 => 😉, face, wink +😊 => 😊, blush, eye, face, smile +😋 => 😋, delicious, face, savouring, smile, um, yum +😎 => 😎, bright, cool, eye, eyewear, face, glasses, smile, sun, sunglasses, weather +😍 => 😍, eye, face, heart, love, smile +😘 => 😘, face, heart, kiss +😗 => 😗, face, kiss +😙 => 😙, eye, face, kiss, smile +😚 => 😚, closed, eye, face, kiss +☺ => ☺, face, outlined, relaxed, smile +🙂 => 🙂, face, smile +🤗 => 🤗, face, hug, hugging +😇 => 😇, angel, face, fairy tale, fantasy, halo, innocent, smile +🤔 => 🤔, face, thinking +😐 => 😐, deadpan, face, neutral +😑 => 😑, expressionless, face, inexpressive, unexpressive +😶 => 😶, face, mouth, quiet, silent +🙄 => 🙄, eyes, face, rolling +😏 => 😏, face, smirk +😣 => 😣, face, persevere +😥 => 😥, disappointed, face, relieved, whew +😮 => 😮, face, mouth, open, sympathy +🤐 => 🤐, face, mouth, zipper +😯 => 😯, face, hushed, stunned, surprised +😪 => 😪, face, sleep +😫 => 😫, face, tired +😴 => 😴, face, sleep, zzz +😌 => 😌, face, relieved +🤓 => 🤓, face, geek, nerd +😛 => 😛, face, tongue +😜 => 😜, eye, face, joke, tongue, wink +😝 => 😝, eye, face, horrible, taste, tongue +☹ => ☹, face, frown +🙁 => 🙁, face, frown +😒 => 😒, face, unamused, unhappy +😓 => 😓, cold, face, sweat +😔 => 😔, dejected, face, pensive +😕 => 😕, confused, face +😖 => 😖, confounded, face +🙃 => 🙃, face, upside-down +😷 => 😷, cold, doctor, face, mask, medicine, sick +🤒 => 🤒, face, ill, sick, thermometer +🤕 => 🤕, bandage, face, hurt, injury +🤑 => 🤑, face, money, mouth +😲 => 😲, astonished, face, shocked, totally +😞 => 😞, disappointed, face +😟 => 😟, face, worried +😤 => 😤, face, triumph, won +😢 => 😢, cry, face, sad, tear +😭 => 😭, cry, face, sad, sob, tear +😦 => 😦, face, frown, mouth, open +😧 => 😧, anguished, face +😨 => 😨, face, fear, fearful, scared +😩 => 😩, face, tired, weary +😬 => 😬, face, grimace +😰 => 😰, blue, cold, face, mouth, open, rushed, sweat +😱 => 😱, face, fear, fearful, munch, scared, scream +😳 => 😳, dazed, face, flushed +😵 => 😵, dizzy, face +😡 => 😡, angry, face, mad, pouting, rage, red +😠 => 😠, angry, face, mad +😈 => 😈, face, fairy tale, fantasy, horns, smile +👿 => 👿, demon, devil, face, fairy tale, fantasy +👹 => 👹, creature, face, fairy tale, fantasy, japanese, monster +👺 => 👺, creature, face, fairy tale, fantasy, japanese, monster +💀 => 💀, body, death, face, fairy tale, monster +☠ => ☠, body, crossbones, death, face, monster, skull +👻 => 👻, creature, face, fairy tale, fantasy, monster +👽 => 👽, creature, extraterrestrial, face, fairy tale, fantasy, monster, space, ufo +👾 => 👾, alien, creature, extraterrestrial, face, fairy tale, fantasy, monster, space, ufo +🤖 => 🤖, face, monster, robot +💩 => 💩, comic, dung, face, monster, poo, poop +😺 => 😺, cat, face, mouth, open, smile +😸 => 😸, cat, eye, face, grin, smile +😹 => 😹, cat, face, joy, tear +😻 => 😻, cat, eye, face, heart, love, smile +😼 => 😼, cat, face, ironic, smile, wry +😽 => 😽, cat, eye, face, kiss +🙀 => 🙀, cat, face, oh, surprised, weary +😿 => 😿, cat, cry, face, sad, tear +😾 => 😾, cat, face, pouting +🙈 => 🙈, evil, face, forbidden, gesture, monkey, no, not, prohibited, see +🙉 => 🙉, evil, face, forbidden, gesture, hear, monkey, no, not, prohibited +🙊 => 🙊, evil, face, forbidden, gesture, monkey, no, not, prohibited, speak +👧 => 👧, maiden, virgin, virgo, zodiac +👴 => 👴, man, old +👵 => 👵, old, woman +👱 => 👱, blond +👮 => 👮, cop, officer, police +👲 => 👲, gua pi mao, hat, man +👳 => 👳, man, turban +👷 => 👷, construction, hat, worker +⛑ => ⛑, aid, cross, face, hat, helmet +👸 => 👸, fairy tale, fantasy +💂 => 💂, guard +🕵 => 🕵, sleuth, spy +🎅 => 🎅, celebration, christmas, fairy tale, fantasy, father, santa +👼 => 👼, angel, baby, face, fairy tale, fantasy +💆 => 💆, massage, salon +💇 => 💇, barber, beauty, parlor +👰 => 👰, bride, veil, wedding +🙍 => 🙍, frown, gesture +🙎 => 🙎, gesture, pouting +🙅 => 🙅, forbidden, gesture, hand, no, not, prohibited +🙆 => 🙆, gesture, hand, ok +💁 => 💁, hand, help, information, sassy +🙋 => 🙋, gesture, hand, happy, raised +🙇 => 🙇, apology, bow, gesture, sorry +🙌 => 🙌, body, celebration, gesture, hand, hooray, raised +🙏 => 🙏, ask, body, bow, folded, gesture, hand, please, pray, thanks +🗣 => 🗣, face, head, silhouette, speak, speaking +👤 => 👤, bust, silhouette +👥 => 👥, bust, silhouette +🚶 => 🚶, hike, walk, walking +🏃 => 🏃, marathon, running +👯 => 👯, bunny, dancer, ear, girl, woman +🕴 => 🕴, business, man, suit +💏 => 💏, couple, romance +💑 => 💑, couple, heart, love, romance +👪 => 👪, child, father, mother +👫 => 👫, couple, hand, hold, man, woman +👬 => 👬, couple, gemini, hand, hold, man, twins, zodiac +👭 => 👭, couple, hand, hold, woman +🏻 => 🏻, emoji modifier, fitzpatrick, skin, tone +🏼 => 🏼, emoji modifier, fitzpatrick, skin, tone +🏽 => 🏽, emoji modifier, fitzpatrick, skin, tone +🏾 => 🏾, emoji modifier, fitzpatrick, skin, tone +🏿 => 🏿, emoji modifier, fitzpatrick, skin, tone +💪 => 💪, biceps, body, comic, flex, muscle +👈 => 👈, backhand, body, finger, hand, index, point, left +👉 => 👉, backhand, body, finger, hand, index, point, right +☝ => ☝, body, finger, hand, index, point, up +👆 => 👆, backhand, body, finger, hand, index, point, up +🖕 => 🖕, body, finger, hand +👇 => 👇, backhand, body, down, finger, hand, index, point +✌ => ✌, body, hand, v, victory +🖖 => 🖖, body, finger, hand, spock, vulcan +🤘 => 🤘, body, finger, hand, horns, rock-on +🖐 => 🖐, body, finger, hand, splayed +✋ => ✋, body, hand +👌 => 👌, body, hand, ok +👍 => 👍, +1, body, hand, thumb, up +👎 => 👎, -1, body, down, hand, thumb +✊ => ✊, body, clenched, fist, hand, punch +👊 => 👊, body, clenched, fist, hand, punch +👋 => 👋, body, hand, wave, waving +👏 => 👏, body, clap, hand +👐 => 👐, body, hand, open +✍ => ✍, body, hand, write +💅 => 💅, body, care, cosmetics, manicure, nail, polish +👂 => 👂, body +👃 => 👃, body +👣 => 👣, body, clothing, footprint, print +👀 => 👀, body, eye, face +👁 => 👁, body +👅 => 👅, body +👄 => 👄, body, lips +💋 => 💋, heart, kiss, lips, mark, romance +💘 => 💘, arrow, cupid, heart, romance +❤ => ❤, heart +💓 => 💓, beating, heart, heartbeat, pulsating +💔 => 💔, break, broken, heart +💕 => 💕, heart, love +💖 => 💖, excited, heart, sparkle +💗 => 💗, excited, growing, heart, heartpulse, nervous +💙 => 💙, blue, heart +💚 => 💚, green, heart +💛 => 💛, heart, yellow +💜 => 💜, heart, purple +💝 => 💝, heart, ribbon, valentine +💞 => 💞, heart, revolving +💟 => 💟, heart +❣ => ❣, exclamation, heart, mark, punctuation +💌 => 💌, heart, letter, love, mail, romance +💤 => 💤, comic, sleep +💢 => 💢, angry, comic, mad +💣 => 💣, comic +💥 => 💥, boom, comic +💦 => 💦, comic, splashing, sweat +💨 => 💨, comic, dash, running +💫 => 💫, comic, star +💬 => 💬, balloon, bubble, comic, dialog, speech +🗨 => 🗨, dialog, speech +🗯 => 🗯, angry, balloon, bubble, mad +💭 => 💭, balloon, bubble, comic, thought +👓 => 👓, clothing, eye, eyeglasses, eyewear +🕶 => 🕶, dark, eye, eyewear, glasses +👔 => 👔, clothing +👕 => 👕, clothing, shirt, tshirt +👖 => 👖, clothing, pants, trousers +👗 => 👗, clothing +👘 => 👘, clothing +👙 => 👙, clothing, swim +👚 => 👚, clothing, woman +👛 => 👛, clothing, coin +👜 => 👜, bag, clothing +👝 => 👝, bag, clothing +🛍 => 🛍, bag, hotel, shopping +🎒 => 🎒, bag, satchel, school +👞 => 👞, clothing, man, shoe +👟 => 👟, athletic, clothing, shoe, sneaker +👠 => 👠, clothing, heel, shoe, woman +👡 => 👡, clothing, sandal, shoe, woman +👢 => 👢, boot, clothing, shoe, woman +👑 => 👑, clothing, king, queen +👒 => 👒, clothing, hat, woman +🎩 => 🎩, clothing, hat, top, tophat +🎓 => 🎓, cap, celebration, clothing, graduation, hat +📿 => 📿, beads, clothing, necklace, prayer, religion +💄 => 💄, cosmetics, makeup +💍 => 💍, diamond, romance +💎 => 💎, diamond, gem, jewel, romance +🐵 => 🐵, face, monkey +🐶 => 🐶, dog, face, pet +🐕 => 🐕, pet +🐩 => 🐩, dog +🐺 => 🐺, face, wolf +🐱 => 🐱, cat, face, pet +🐈 => 🐈, pet +🦁 => 🦁, face, leo, lion, zodiac +🐯 => 🐯, face, tiger +🐴 => 🐴, face, horse +🐎 => 🐎, racehorse, racing +🦄 => 🦄, face, unicorn +🐮 => 🐮, cow, face +🐂 => 🐂, bull, taurus, zodiac +🐃 => 🐃, buffalo, water +🐷 => 🐷, face, pig +🐖 => 🐖, sow +🐗 => 🐗, pig +🐽 => 🐽, face, nose, pig +🐏 => 🐏, aries, sheep, zodiac +🐑 => 🐑, ewe +🐐 => 🐐, capricorn, zodiac +🐪 => 🐪, dromedary, hump +🐫 => 🐫, bactrian, camel, hump +🐭 => 🐭, face, mouse +🐹 => 🐹, face, hamster, pet +🐰 => 🐰, bunny, face, pet, rabbit +🐇 => 🐇, bunny, pet +🐻 => 🐻, bear, face +🐨 => 🐨, bear +🐼 => 🐼, face, panda +🐾 => 🐾, feet, paw, print +🐣 => 🐣, baby, chick, hatching +🐤 => 🐤, baby, chick +🐥 => 🐥, baby, chick +🕊 => 🕊, bird, fly, peace +🐸 => 🐸, face, frog +🐍 => 🐍, bearer, ophiuchus, serpent, zodiac +🐲 => 🐲, dragon, face, fairy tale +🐉 => 🐉, fairy tale +🐳 => 🐳, face, spouting, whale +🐬 => 🐬, flipper +🐟 => 🐟, pisces, zodiac +🐠 => 🐠, fish, tropical +🐡 => 🐡, fish +🐚 => 🐚, shell, spiral +🦀 => 🦀, cancer, zodiac +🐛 => 🐛, insect +🐜 => 🐜, insect +🐝 => 🐝, bee, insect +🐞 => 🐞, beetle, insect, ladybird, ladybug +🕷 => 🕷, insect +🕸 => 🕸, spider, web +🦂 => 🦂, scorpio, scorpius, zodiac +💐 => 💐, flower, plant, romance +🌸 => 🌸, blossom, cherry, flower, plant +💮 => 💮, flower +🏵 => 🏵, plant +🌹 => 🌹, flower, plant +🌺 => 🌺, flower, plant +🌻 => 🌻, flower, plant, sun +🌼 => 🌼, flower, plant +🌷 => 🌷, flower, plant +🌱 => 🌱, plant, young +🌲 => 🌲, plant, tree +🌳 => 🌳, deciduous, plant, shedding, tree +🌴 => 🌴, palm, plant, tree +🌵 => 🌵, plant +🌾 => 🌾, ear, plant, rice +🌿 => 🌿, leaf, plant +☘ => ☘, plant +🍀 => 🍀, 4, clover, four, leaf, plant +🍁 => 🍁, falling, leaf, maple, plant +🍂 => 🍂, falling, leaf, plant +🍃 => 🍃, blow, flutter, leaf, plant, wind +🍇 => 🍇, fruit, grape, plant +🍈 => 🍈, fruit, plant +🍉 => 🍉, fruit, plant +🍊 => 🍊, fruit, orange, plant +🍋 => 🍋, citrus, fruit, plant +🍌 => 🍌, fruit, plant +🍍 => 🍍, fruit, plant +🍎 => 🍎, apple, fruit, plant, red +🍏 => 🍏, apple, fruit, green, plant +🍐 => 🍐, fruit, plant +🍑 => 🍑, fruit, plant +🍒 => 🍒, cherry, fruit, plant +🍓 => 🍓, berry, fruit, plant +🍅 => 🍅, plant, vegetable +🍆 => 🍆, plant, vegetable +🌽 => 🌽, corn, ear, maize, maze, plant +🌶 => 🌶, hot, pepper, plant +🍄 => 🍄, plant +🌰 => 🌰, plant +🍞 => 🍞, loaf +🧀 => 🧀, cheese +🍖 => 🍖, bone, meat +🍗 => 🍗, bone, chicken, leg, poultry +🍔 => 🍔, burger +🍟 => 🍟, french, fries +🍕 => 🍕, cheese, slice +🌭 => 🌭, frankfurter, hotdog, sausage +🌮 => 🌮, mexican +🌯 => 🌯, mexican +🍲 => 🍲, pot, stew +🍱 => 🍱, bento, box +🍘 => 🍘, cracker, rice +🍙 => 🍙, ball, japanese, rice +🍚 => 🍚, cooked, rice +🍛 => 🍛, curry, rice +🍜 => 🍜, bowl, noodle, ramen, steaming +🍝 => 🍝, pasta +🍠 => 🍠, potato, roasted, sweet +🍢 => 🍢, kebab, seafood, skewer, stick +🍤 => 🍤, fried, prawn, shrimp, tempura +🍥 => 🍥, cake, fish, pastry, swirl +🍡 => 🍡, dessert, japanese, skewer, stick, sweet +🍦 => 🍦, cream, dessert, ice, icecream, soft, sweet +🍧 => 🍧, dessert, ice, shaved, sweet +🍨 => 🍨, cream, dessert, ice, sweet +🍩 => 🍩, dessert, donut, sweet +🍪 => 🍪, dessert, sweet +🎂 => 🎂, birthday, cake, celebration, dessert, pastry, sweet +🍰 => 🍰, cake, dessert, pastry, slice, sweet +🍫 => 🍫, bar, chocolate, dessert, sweet +🍬 => 🍬, dessert, sweet +🍭 => 🍭, candy, dessert, sweet +🍮 => 🍮, dessert, pudding, sweet +🍯 => 🍯, honey, honeypot, pot, sweet +🍼 => 🍼, baby, bottle, drink, milk +☕ => ☕, beverage, coffee, drink, hot, steaming, tea +🍵 => 🍵, beverage, cup, drink, tea, teacup +🍶 => 🍶, bar, beverage, bottle, cup, drink +🍾 => 🍾, bar, bottle, cork, drink, popping +🍷 => 🍷, bar, beverage, drink, glass, wine +🍸 => 🍸, bar, cocktail, drink, glass +🍹 => 🍹, bar, drink, tropical +🍺 => 🍺, bar, beer, drink, mug +🍻 => 🍻, bar, beer, clink, drink, mug +🍽 => 🍽, cooking, fork, knife, plate +🍴 => 🍴, cooking, fork, knife +🍳 => 🍳, egg, frying, pan +🏺 => 🏺, aquarius, cooking, drink, jug, tool, weapon, zodiac +🌍 => 🌍, africa, earth, europe, globe, world +🌎 => 🌎, americas, earth, globe, world +🌏 => 🌏, asia, australia, earth, globe, world +🌐 => 🌐, earth, globe, meridians, world +🗺 => 🗺, map, world +🏔 => 🏔, cold, mountain, snow +🌋 => 🌋, eruption, mountain, weather +🗻 => 🗻, fuji, mountain +🏖 => 🏖, beach, umbrella +🏝 => 🏝, desert, island +🏞 => 🏞, park +🏛 => 🏛, building, classical +🏗 => 🏗, building, construction +🏘 => 🏘, building, house +🏙 => 🏙, building, city +🏚 => 🏚, building, derelict, house +🏠 => 🏠, building, home, house +🏡 => 🏡, building, garden, home, house +⛪ => ⛪, building, christian, cross, religion +🕋 => 🕋, islam, muslim, religion +🕌 => 🕌, islam, muslim, religion +🕍 => 🕍, jew, jewish, religion, temple +⛩ => ⛩, religion, shinto, shrine +🏢 => 🏢, building +🏣 => 🏣, building, japanese, post +🏤 => 🏤, building, european, post +🏥 => 🏥, building, doctor, medicine +🏦 => 🏦, building +🏨 => 🏨, building +🏩 => 🏩, building, hotel, love +🏪 => 🏪, building, convenience, store +🏫 => 🏫, building +🏬 => 🏬, building, department, store +🏭 => 🏭, building +🏯 => 🏯, building, castle, japanese +🏰 => 🏰, building, european +💒 => 💒, chapel, romance +🗼 => 🗼, tokyo, tower +🗽 => 🗽, liberty, statue +🗾 => 🗾, japan, map +⛺ => ⛺, camping +🌁 => 🌁, fog, weather +🌃 => 🌃, night, star, weather +🌄 => 🌄, morning, mountain, sun, sunrise, weather +🌅 => 🌅, morning, sun, weather +🌆 => 🌆, building, city, dusk, evening, landscape, sun, sunset, weather +🌇 => 🌇, building, dusk, sun, weather +🌉 => 🌉, bridge, night, weather +♨ => ♨, hot, hotsprings, springs, steaming +🌌 => 🌌, space, weather +🎠 => 🎠, carousel, horse +🎡 => 🎡, amusement park, ferris, wheel +🎢 => 🎢, amusement park, coaster, roller +💈 => 💈, barber, haircut, pole +🎪 => 🎪, circus, tent +🎭 => 🎭, art, mask, performing, theater, theatre +🖼 => 🖼, art, frame, museum, painting, picture +🎨 => 🎨, art, museum, painting, palette +🎰 => 🎰, game, slot +🚂 => 🚂, engine, railway, steam, train, vehicle +🚃 => 🚃, car, electric, railway, train, tram, trolleybus, vehicle +🚄 => 🚄, railway, shinkansen, speed, train, vehicle +🚅 => 🚅, bullet, railway, shinkansen, speed, train, vehicle +🚆 => 🚆, railway, vehicle +🚇 => 🚇, subway, vehicle +🚈 => 🚈, railway, vehicle +🚉 => 🚉, railway, train, vehicle +🚊 => 🚊, trolleybus, vehicle +🚝 => 🚝, vehicle +🚞 => 🚞, car, mountain, railway, vehicle +🚋 => 🚋, car, tram, trolleybus, vehicle +🚌 => 🚌, vehicle +🚍 => 🚍, bus, oncoming, vehicle +🚎 => 🚎, bus, tram, trolley, vehicle +🚏 => 🚏, bus, busstop, stop +🚐 => 🚐, bus, vehicle +🚑 => 🚑, vehicle +🚒 => 🚒, engine, fire, truck, vehicle +🚓 => 🚓, car, patrol, police, vehicle +🚔 => 🚔, car, oncoming, police, vehicle +🚕 => 🚕, vehicle +🚖 => 🚖, oncoming, taxi, vehicle +🚗 => 🚗, car, vehicle +🚘 => 🚘, automobile, car, oncoming, vehicle +🚙 => 🚙, recreational, rv, vehicle +🚚 => 🚚, delivery, truck, vehicle +🚛 => 🚛, lorry, semi, truck, vehicle +🚜 => 🚜, vehicle +🚲 => 🚲, bike, vehicle +⛽ => ⛽, fuel, fuelpump, gas, pump, station +🛣 => 🛣, highway, road +🛤 => 🛤, railway, train +🚨 => 🚨, beacon, car, light, police, revolving, vehicle +🚥 => 🚥, light, signal, traffic +🚦 => 🚦, light, signal, traffic +🚧 => 🚧, barrier +⚓ => ⚓, ship, tool +⛵ => ⛵, boat, resort, sea, vehicle, yacht +🚣 => 🚣, boat, vehicle +🚤 => 🚤, boat, vehicle +🛳 => 🛳, passenger, ship, vehicle +⛴ => ⛴, boat +🛥 => 🛥, boat, motorboat, vehicle +🚢 => 🚢, vehicle +✈ => ✈, vehicle +🛩 => 🛩, airplane, vehicle +🛫 => 🛫, airplane, check-in, departure, departures, vehicle +🛬 => 🛬, airplane, arrivals, arriving, landing, vehicle +💺 => 💺, chair +🚁 => 🚁, vehicle +🚟 => 🚟, railway, suspension, vehicle +🚠 => 🚠, cable, gondola, mountain, vehicle +🚡 => 🚡, aerial, cable, car, ropeway, tramway, vehicle +🚀 => 🚀, space, vehicle +🛰 => 🛰, space, vehicle +🛎 => 🛎, bell, bellhop, hotel +🛌 => 🛌, hotel, sleep +🛏 => 🛏, hotel, sleep +🛋 => 🛋, couch, hotel, lamp +🚿 => 🚿, water +🛀 => 🛀, bathtub, bath +🛁 => 🛁, bath +⌛ => ⌛, sand, timer +⏳ => ⏳, hourglass, sand, timer +⌚ => ⌚, clock +⏰ => ⏰, alarm, clock +⏱ => ⏱, clock +⏲ => ⏲, clock, timer +🕰 => 🕰, clock +🕛 => 🕛, 00, 12, 12:00, clock, o’clock, twelve +🕧 => 🕧, 12, 12:30, 30, clock, thirty, twelve +🕐 => 🕐, 00, 1, 1:00, clock, o’clock, one +🕜 => 🕜, 1, 1:30, 30, clock, one, thirty +🕑 => 🕑, 00, 2, 2:00, clock, o’clock, two +🕝 => 🕝, 2, 2:30, 30, clock, thirty, two +🕒 => 🕒, 00, 3, 3:00, clock, o’clock, three +🕞 => 🕞, 3, 3:30, 30, clock, thirty, three +🕓 => 🕓, 00, 4, 4:00, clock, four, o’clock +🕟 => 🕟, 30, 4, 4:30, clock, four, thirty +🕔 => 🕔, 00, 5, 5:00, clock, five, o’clock +🕠 => 🕠, 30, 5, 5:30, clock, five, thirty +🕕 => 🕕, 00, 6, 6:00, clock, o’clock, six +🕡 => 🕡, 30, 6, 6:30, clock, six, thirty +🕖 => 🕖, 00, 7, 7:00, clock, o’clock, seven +🕢 => 🕢, 30, 7, 7:30, clock, seven, thirty +🕗 => 🕗, 00, 8, 8:00, clock, eight, o’clock +🕣 => 🕣, 30, 8, 8:30, clock, eight, thirty +🕘 => 🕘, 00, 9, 9:00, clock, nine, o’clock +🕤 => 🕤, 30, 9, 9:30, clock, nine, thirty +🕙 => 🕙, 00, 10, 10:00, clock, o’clock, ten +🕥 => 🕥, 10, 10:30, 30, clock, ten, thirty +🕚 => 🕚, 00, 11, 11:00, clock, eleven, o’clock +🕦 => 🕦, 11, 11:30, 30, clock, eleven, thirty +🌑 => 🌑, dark, moon, space, weather +🌒 => 🌒, crescent, moon, space, waxing, weather +🌓 => 🌓, moon, quarter, space, weather +🌔 => 🌔, gibbous, moon, space, waxing, weather +🌕 => 🌕, full, moon, space, weather +🌖 => 🌖, gibbous, moon, space, waning, weather +🌗 => 🌗, moon, quarter, space, weather +🌘 => 🌘, crescent, moon, space, waning, weather +🌙 => 🌙, crescent, moon, space, weather +🌚 => 🌚, face, moon, space, weather +🌛 => 🌛, face, moon, quarter, space, weather +🌜 => 🌜, face, moon, quarter, space, weather +🌡 => 🌡, weather +☀ => ☀, bright, rays, space, sunny, weather +🌝 => 🌝, bright, face, full, moon, space, weather +🌞 => 🌞, bright, face, space, sun, weather +⭐ => ⭐, star +🌟 => 🌟, glittery, glow, shining, sparkle, star +🌠 => 🌠, falling, shooting, space, star +☁ => ☁, weather +⛅ => ⛅, cloud, sun, weather +⛈ => ⛈, cloud, rain, thunder, weather +🌤 => 🌤, cloud, sun, weather +🌥 => 🌥, cloud, sun, weather +🌦 => 🌦, cloud, rain, sun, weather +🌧 => 🌧, cloud, rain, weather +🌨 => 🌨, cloud, cold, snow, weather +🌩 => 🌩, cloud, lightning, weather +🌪 => 🌪, cloud, weather, whirlwind +🌫 => 🌫, cloud, weather +🌬 => 🌬, blow, cloud, face, weather, wind +🌀 => 🌀, dizzy, twister, typhoon, weather +🌈 => 🌈, rain, weather +🌂 => 🌂, clothing, rain, umbrella, weather +☂ => ☂, clothing, rain, weather +☔ => ☔, clothing, drop, rain, umbrella, weather +⛱ => ⛱, rain, sun, umbrella, weather +⚡ => ⚡, danger, electric, electricity, lightning, voltage, zap +❄ => ❄, cold, snow, weather +☃ => ☃, cold, snow, weather +⛄ => ⛄, cold, snow, snowman, weather +☄ => ☄, space +🔥 => 🔥, flame, tool +💧 => 💧, cold, comic, drop, sweat, weather +🌊 => 🌊, ocean, water, wave, weather +🎃 => 🎃, celebration, halloween, jack, lantern +🎄 => 🎄, celebration, christmas, tree +🎆 => 🎆, celebration +🎇 => 🎇, celebration, fireworks, sparkle +✨ => ✨, sparkle, star +🎈 => 🎈, celebration +🎉 => 🎉, celebration, party, popper, tada +🎊 => 🎊, ball, celebration, confetti +🎋 => 🎋, banner, celebration, japanese, tree +🎌 => 🎌, celebration, cross, crossed, japanese +🎍 => 🎍, bamboo, celebration, japanese, pine, plant +🎎 => 🎎, celebration, doll, festival, japanese +🎏 => 🎏, carp, celebration, streamer +🎐 => 🎐, bell, celebration, chime, wind +🎑 => 🎑, celebration, ceremony, moon +🎀 => 🎀, celebration +🎁 => 🎁, box, celebration, gift, present, wrapped +🎖 => 🎖, celebration, medal, military +🎗 => 🎗, celebration, reminder, ribbon +🎞 => 🎞, cinema, film, frames, movie +🎟 => 🎟, admission, ticket +🎫 => 🎫, admission +⚽ => ⚽, ball, soccer +⚾ => ⚾, ball +🏀 => 🏀, ball, hoop +🏈 => 🏈, american, ball, football +🏉 => 🏉, ball, football, rugby +🎾 => 🎾, ball, racquet +🎱 => 🎱, 8, 8 ball, ball, billiard, eight, game +🎳 => 🎳, ball, game +⛳ => ⛳, golf, hole +🏌 => 🏌, ball, golf +⛸ => ⛸, ice, skate +🎣 => 🎣, fish, pole +🎽 => 🎽, running, sash, shirt +🎿 => 🎿, ski, snow +⛷ => ⛷, ski, snow +🏂 => 🏂, ski, snow, snowboard +🏄 => 🏄, surfing +🏇 => 🏇, horse, jockey, racehorse, racing +🏊 => 🏊, swim +⛹ => ⛹, ball +🏋 => 🏋, lifter, weight +🚴 => 🚴, bicycle, bike, cyclist +🚵 => 🚵, bicycle, bicyclist, bike, cyclist, mountain +🏎 => 🏎, car, racing +🏍 => 🏍, racing +🏅 => 🏅, medal +🏆 => 🏆, prize +🏏 => 🏏, ball, bat, game +🏐 => 🏐, ball, game +🏑 => 🏑, ball, field, game, hockey, stick +🏒 => 🏒, game, hockey, ice, puck, stick +🏓 => 🏓, ball, bat, game, paddle +🏸 => 🏸, birdie, game, racquet, shuttlecock +🎯 => 🎯, bull, bullseye, dart, eye, game, hit, target +🎮 => 🎮, controller, game +🕹 => 🕹, game, video game +🎲 => 🎲, dice, die, game +♠ => ♠, card, game, spade, suit +♥ => ♥, card, game, heart, hearts, suit +♦ => ♦, card, diamond, diamonds, game, suit +♣ => ♣, card, club, clubs, game, suit +🃏 => 🃏, card, game, playing +🀄 => 🀄, game, mahjong, red +🎴 => 🎴, card, flower, game, japanese, playing +🔇 => 🔇, mute, quiet, silent, speaker, volume +🔈 => 🔈, volume +🔉 => 🔉, low, speaker, volume, wave +🔊 => 🔊, 3, high, loud, speaker, three, volume +📢 => 📢, loud, public address +📣 => 📣, cheering +📯 => 📯, horn, post, postal +🔕 => 🔕, bell, forbidden, mute, no, not, prohibited, quiet, silent +🎼 => 🎼, music, score +🎵 => 🎵, music, note +🎶 => 🎶, music, note, notes +🎙 => 🎙, mic, microphone, music, studio +🎚 => 🎚, level, music, slider +🎛 => 🎛, control, knobs, music +🎤 => 🎤, karaoke, mic +🎧 => 🎧, earbud +🎷 => 🎷, instrument, music, sax +🎸 => 🎸, instrument, music +🎹 => 🎹, instrument, keyboard, music, piano +🎺 => 🎺, instrument, music +🎻 => 🎻, instrument, music +📻 => 📻, video +📱 => 📱, cell, mobile, phone, telephone +📲 => 📲, arrow, call, cell, mobile, phone, receive, telephone +☎ => ☎, phone +📞 => 📞, phone, receiver, telephone +📠 => 📠, fax +🔌 => 🔌, electric, electricity, plug +💻 => 💻, computer, pc, personal +🖥 => 🖥, computer, desktop +🖨 => 🖨, computer +⌨ => ⌨, computer +🖱 => 🖱, 3, button, computer, mouse, three +🖲 => 🖲, computer +💽 => 💽, computer, disk, optical +💾 => 💾, computer, disk, floppy +💿 => 💿, dvd, blu-ray, cd, computer, disk, optical +📀 => 📀, blu-ray, cd, computer, disk, optical +🎥 => 🎥, camera, cinema, movie +🎬 => 🎬, clapper, movie +📽 => 📽, cinema, film, movie, projector, video +📺 => 📺, tv, video +📷 => 📷, camera, video +📸 => 📸, camera, flash, video +📹 => 📹, camera, video +📼 => 📼, tape, vhs, video +🔍 => 🔍, glass, magnifying, search, tool +🔎 => 🔎, glass, magnifying, search, tool +🔬 => 🔬, tool +🔭 => 🔭, tool +📡 => 📡, antenna, dish, satellite +🕯 => 🕯, light +💡 => 💡, bulb, comic, electric, idea, light +🔦 => 🔦, electric, light, tool, torch +🏮 => 🏮, bar, japanese, lantern, light, red +📔 => 📔, book, cover, decorated, notebook +📕 => 📕, book, closed +📖 => 📖, book, open +📗 => 📗, book, green +📘 => 📘, blue, book +📙 => 📙, book, orange +📚 => 📚, book +📒 => 📒, notebook +📃 => 📃, curl, document, page +📜 => 📜, paper +📄 => 📄, document, page +📰 => 📰, news, paper +🗞 => 🗞, news, newspaper, paper, rolled +📑 => 📑, bookmark, mark, marker, tabs +🔖 => 🔖, mark +💰 => 💰, bag, dollar, money, moneybag +💴 => 💴, bank, banknote, bill, currency, money, note, yen +💵 => 💵, bank, banknote, bill, currency, dollar, money, note +💶 => 💶, bank, banknote, bill, currency, euro, money, note +💷 => 💷, bank, banknote, bill, currency, money, note, pound +💸 => 💸, bank, banknote, bill, dollar, fly, money, note, wings +💳 => 💳, bank, card, credit, money +💹 => 💹, bank, chart, currency, graph, growth, market, money, rise, trend, upward, yen +✉ => ✉, e-mail, email +📧 => 📧, email, letter, mail +📨 => 📨, e-mail, email, envelope, incoming, letter, mail, receive +📩 => 📩, arrow, down, e-mail, email, envelope, letter, mail, outgoing, sent +📤 => 📤, box, letter, mail, outbox, sent, tray +📥 => 📥, box, inbox, letter, mail, receive, tray +📦 => 📦, box, parcel +📫 => 📫, closed, mail, mailbox, postbox +📪 => 📪, closed, lowered, mail, mailbox, postbox +📬 => 📬, mail, mailbox, open, postbox +📭 => 📭, lowered, mail, mailbox, open, postbox +📮 => 📮, mail, mailbox +🗳 => 🗳, ballot, box +✒ => ✒, nib, pen +🖋 => 🖋, fountain, pen +🖊 => 🖊, ballpoint +🖌 => 🖌, painting +📝 => 📝, pencil +📁 => 📁, file, folder +📂 => 📂, file, folder, open +🗂 => 🗂, card, dividers, index +📅 => 📅, date +📆 => 📆, calendar +🗒 => 🗒, note, pad, spiral +🗓 => 🗓, calendar, pad, spiral +📇 => 📇, card, index, rolodex +📈 => 📈, chart, graph, growth, trend, upward +📉 => 📉, chart, down, graph, trend +📊 => 📊, bar, chart, graph +📍 => 📍, pin, pushpin +🖇 => 🖇, link, paperclip +📏 => 📏, ruler, straight edge +📐 => 📐, ruler, set, triangle +✂ => ✂, tool +🗃 => 🗃, box, card, file +🗄 => 🗄, cabinet, file +🔒 => 🔒, closed +🔓 => 🔓, lock, open, unlock +🔏 => 🔏, ink, lock, nib, pen, privacy +🔐 => 🔐, closed, key, lock, secure +🔑 => 🔑, lock, password +🗝 => 🗝, clue, key, lock, old +🔨 => 🔨, tool +⛏ => ⛏, mining, tool +⚒ => ⚒, hammer, pick, tool +🛠 => 🛠, hammer, tool, wrench +🔧 => 🔧, tool +🔩 => 🔩, bolt, nut, tool +⚙ => ⚙, tool +🗜 => 🗜, tool, vice +⚗ => ⚗, chemistry, tool +⚖ => ⚖, balance, justice, libra, scales, tool, weight, zodiac +⛓ => ⛓, chain +💉 => 💉, doctor, medicine, needle, shot, sick, tool +💊 => 💊, doctor, medicine, sick +🗡 => 🗡, knife, weapon +🔪 => 🔪, cooking, hocho, knife, tool, weapon +⚔ => ⚔, crossed, swords, weapon +🔫 => 🔫, gun, revolver, tool, weapon +🛡 => 🛡, weapon +🏹 => 🏹, archer, arrow, bow, sagittarius, tool, weapon, zodiac +🏁 => 🏁, checkered, chequered, racing +🏳 => 🏳, waving +🏴 => 🏴, waving +🚩 => 🚩, post +⚰ => ⚰, death +⚱ => ⚱, death, funeral, urn +🗿 => 🗿, face, moyai, statue +🛢 => 🛢, drum, oil +🔮 => 🔮, ball, crystal, fairy tale, fantasy, fortune, tool +🏧 => 🏧, atm, automated, bank, teller +🚮 => 🚮, litter, litterbox +🚰 => 🚰, drink, potable, water +♿ => ♿, access +🚹 => 🚹, lavatory, man, restroom, wc +🚺 => 🚺, lavatory, restroom, wc, woman +🚻 => 🚻, wc +🚼 => 🚼, baby, changing +🚾 => 🚾, closet, lavatory, restroom, water, wc +🛂 => 🛂, control, passport +🛄 => 🛄, baggage, claim +🛅 => 🛅, baggage, locker, luggage +🚸 => 🚸, child, crossing, pedestrian, traffic +⛔ => ⛔, entry, forbidden, no, not, prohibited, traffic +🚫 => 🚫, entry, forbidden, no, not +🚳 => 🚳, bicycle, bike, forbidden, no, not, prohibited, vehicle +🚭 => 🚭, forbidden, no, not, prohibited, smoking +🚯 => 🚯, forbidden, litter, no, not, prohibited +🚱 => 🚱, drink, forbidden, no, not, potable, prohibited, water +🚷 => 🚷, forbidden, no, not, pedestrian, prohibited +⬆ => ⬆, arrow, cardinal, direction, north +↗ => ↗, arrow, direction, intercardinal, northeast +➡ => ➡, arrow, cardinal, direction, east +↘ => ↘, arrow, direction, intercardinal, southeast +⬇ => ⬇, arrow, cardinal, direction, down, south +↙ => ↙, arrow, direction, intercardinal, southwest +⬅ => ⬅, arrow, cardinal, direction, west +↖ => ↖, arrow, direction, intercardinal, northwest +↕ => ↕, arrow +↔ => ↔, arrow +↩ => ↩, arrow +↪ => ↪, arrow +⤴ => ⤴, arrow +⤵ => ⤵, arrow, down +🔃 => 🔃, arrow, clockwise, reload +🔄 => 🔄, anticlockwise, arrow, counterclockwise, withershins +🔙 => 🔙, arrow, back +🔚 => 🔚, arrow, end +🔛 => 🔛, arrow, mark, on +🔜 => 🔜, arrow, soon +🔝 => 🔝, arrow, top, up +🛐 => 🛐, religion, worship +⚛ => ⚛, atheist, atom +🕉 => 🕉, hindu, religion +✡ => ✡, david, jew, jewish, religion, star +☸ => ☸, buddhist, dharma, religion, wheel +☯ => ☯, religion, tao, taoist, yang, yin +✝ => ✝, christian, cross, religion +☦ => ☦, christian, cross, religion +☪ => ☪, islam, muslim, religion +☮ => ☮, peace +🕎 => 🕎, candelabrum, candlestick, religion +🔯 => 🔯, fortune, star +♻ => ♻, recycle +📛 => 📛, badge, name +🔰 => 🔰, beginner, chevron, green, japanese, leaf, tool, yellow +🔱 => 🔱, anchor, emblem, ship, tool, trident +⭕ => ⭕, circle, o +✅ => ✅, check, mark +☑ => ☑, ballot, box, check +✔ => ✔, check, mark +✖ => ✖, cancel, multiplication, multiply, x +❌ => ❌, cancel, mark, multiplication, multiply, x +❎ => ❎, mark, square +➕ => ➕, maths, plus +➖ => ➖, maths, minus +➗ => ➗, division, maths +➰ => ➰, curl, loop +➿ => ➿, curl, double, loop +〽 => 〽, mark, part +✳ => ✳, asterisk +✴ => ✴, star +💱 => 💱, bank, currency, exchange, money +💲 => 💲, currency, dollar, money +‼ => ‼, bangbang, exclamation, mark, punctuation +⁉ => ⁉, exclamation, interrobang, mark, punctuation, question +❓ => ❓, mark, punctuation, question +❔ => ❔, mark, outlined, punctuation, question +❕ => ❕, exclamation, mark, outlined, punctuation +❗ => ❗, exclamation, mark, punctuation +〰 => 〰, dash, punctuation, wavy +™ => ™, mark, tm, trademark +♈ => ♈, ram, zodiac +♉ => ♉, bull, ox, zodiac +♊ => ♊, twins, zodiac +♋ => ♋, crab, zodiac +♌ => ♌, lion, zodiac +♍ => ♍, maiden, virgin, zodiac +♎ => ♎, balance, justice, scales, zodiac +♏ => ♏, scorpio, scorpion, zodiac +♐ => ♐, archer, zodiac +♑ => ♑, goat, zodiac +♒ => ♒, bearer, water, zodiac +♓ => ♓, fish, zodiac +⛎ => ⛎, bearer, serpent, snake +🔀 => 🔀, arrow, crossed +🔁 => 🔁, arrow, clockwise, repeat +🔂 => 🔂, arrow, clockwise, once +▶ => ▶, arrow, play, right, triangle +⏩ => ⏩, arrow, double, fast, forward +⏭ => ⏭, arrow, next scene, next track, triangle +⏯ => ⏯, arrow, pause, play, right, triangle +◀ => ◀, arrow, left, reverse, triangle +⏪ => ⏪, arrow, double, rewind +⏮ => ⏮, arrow, previous scene, previous track, triangle +🔼 => 🔼, arrow, button, red +⏫ => ⏫, arrow, double +🔽 => 🔽, arrow, button, down, red +⏬ => ⏬, arrow, double, down +⏸ => ⏸, bar, double, pause, vertical +⏹ => ⏹, square, stop +⏺ => ⏺, circle, record +⏏ => ⏏, eject +🎦 => 🎦, camera, film, movie +🔅 => 🔅, brightness, dim, low +🔆 => 🔆, bright, brightness +📶 => 📶, antenna, bar, cell, mobile, phone, signal, telephone +📵 => 📵, cell, forbidden, mobile, no, not, phone, prohibited, telephone +📳 => 📳, cell, mobile, mode, phone, telephone, vibration +📴 => 📴, cell, mobile, off, phone, telephone +#⃣ => #⃣, hash, keycap, pound +*⃣ => *⃣, asterisk, keycap, star +0⃣ => 0⃣, keycap, zero +1⃣ => 1⃣, 1, keycap, one +2⃣ => 2⃣, 2, keycap, two +3⃣ => 3⃣, 3, keycap, three +4⃣ => 4⃣, 4, four, keycap +5⃣ => 5⃣, 5, five, keycap +6⃣ => 6⃣, 6, keycap, six +7⃣ => 7⃣, 7, keycap, seven +8⃣ => 8⃣, 8, eight, keycap +9⃣ => 9⃣, 9, keycap, nine +🔟 => 🔟, 10, keycap, ten +💯 => 💯, 100, full, hundred, score +🔞 => 🔞, 18, age restriction, eighteen, forbidden, no, not, prohibited, underage +🔠 => 🔠, input, latin, letters, uppercase +🔡 => 🔡, abcd, input, latin, letters, lowercase +🔢 => 🔢, 1234, input, numbers +🔣 => 🔣, input +🔤 => 🔤, abc, alphabet, input, latin, letters +🅰 => 🅰, a, blood +🆎 => 🆎, ab, blood +🅱 => 🅱, b, blood +🆑 => 🆑, cl +🆒 => 🆒, cool +🆓 => 🆓, free +ℹ => ℹ, i, information +🆔 => 🆔, id, identity +Ⓜ => Ⓜ, circle, m +🆕 => 🆕, new +🆖 => 🆖, ng +🅾 => 🅾, blood, o +🆗 => 🆗, ok +🅿 => 🅿, parking +🆘 => 🆘, help, sos +🆙 => 🆙, mark, up +🆚 => 🆚, versus, vs +🈁 => 🈁, japanese +🈂 => 🈂, japanese +🈷 => 🈷, japanese +🈶 => 🈶, japanese +🈯 => 🈯, japanese +🉐 => 🉐, japanese +🈹 => 🈹, japanese +🈚 => 🈚, japanese +🈲 => 🈲, japanese +🉑 => 🉑, chinese +🈸 => 🈸, chinese +🈴 => 🈴, chinese +🈳 => 🈳, chinese +㊗ => ㊗, chinese, congratulation, congratulations, ideograph +㊙ => ㊙, chinese, ideograph, secret +🈺 => 🈺, chinese +🈵 => 🈵, chinese +▪ => ▪, geometric, square +▫ => ▫, geometric, square +◻ => ◻, geometric, square +◼ => ◼, geometric, square +◽ => ◽, geometric, square +◾ => ◾, geometric, square +⬛ => ⬛, geometric, square +⬜ => ⬜, geometric, square +🔶 => 🔶, diamond, geometric, orange +🔷 => 🔷, blue, diamond, geometric +🔸 => 🔸, diamond, geometric, orange +🔹 => 🔹, blue, diamond, geometric +🔺 => 🔺, geometric, red +🔻 => 🔻, down, geometric, red +💠 => 💠, comic, diamond, geometric, inside +🔘 => 🔘, button, geometric, radio +🔲 => 🔲, button, geometric, square +🔳 => 🔳, button, geometric, outlined, square +⚪ => ⚪, circle, geometric +⚫ => ⚫, circle, geometric +🔴 => 🔴, circle, geometric, red +🔵 => 🔵, blue, circle, geometric +🇦🇨 => 🇦🇨, ascension island +🇦🇩 => 🇦🇩, andorra +🇦🇪 => 🇦🇪, united arab emirates +🇦🇫 => 🇦🇫, afghanistan +🇦🇬 => 🇦🇬, antigua & barbuda +🇦🇮 => 🇦🇮, anguilla +🇦🇱 => 🇦🇱, albania +🇦🇲 => 🇦🇲, armenia +🇦🇴 => 🇦🇴, angola +🇦🇶 => 🇦🇶, antarctica +🇦🇷 => 🇦🇷, argentina +🇦🇸 => 🇦🇸, american samoa +🇦🇹 => 🇦🇹, austria +🇦🇺 => 🇦🇺, australia +🇦🇼 => 🇦🇼, aruba +🇦🇽 => 🇦🇽, åland islands +🇦🇿 => 🇦🇿, azerbaijan +🇧🇦 => 🇧🇦, bosnia & herzegovina +🇧🇧 => 🇧🇧, barbados +🇧🇩 => 🇧🇩, bangladesh +🇧🇪 => 🇧🇪, belgium +🇧🇫 => 🇧🇫, burkina faso +🇧🇬 => 🇧🇬, bulgaria +🇧🇭 => 🇧🇭, bahrain +🇧🇮 => 🇧🇮, burundi +🇧🇯 => 🇧🇯, benin +🇧🇱 => 🇧🇱, st. barthélemy +🇧🇲 => 🇧🇲, bermuda +🇧🇳 => 🇧🇳, brunei +🇧🇴 => 🇧🇴, bolivia +🇧🇶 => 🇧🇶, caribbean netherlands +🇧🇷 => 🇧🇷, brazil +🇧🇸 => 🇧🇸, bahamas +🇧🇹 => 🇧🇹, bhutan +🇧🇻 => 🇧🇻, bouvet island +🇧🇼 => 🇧🇼, botswana +🇧🇾 => 🇧🇾, belarus +🇧🇿 => 🇧🇿, belize +🇨🇦 => 🇨🇦, canada +🇨🇨 => 🇨🇨, cocos (keeling) islands +🇨🇩 => 🇨🇩, congo - kinshasa +🇨🇫 => 🇨🇫, central african republic +🇨🇬 => 🇨🇬, congo - brazzaville +🇨🇭 => 🇨🇭, switzerland +🇨🇮 => 🇨🇮, côte d’ivoire +🇨🇰 => 🇨🇰, cook islands +🇨🇱 => 🇨🇱, chile +🇨🇲 => 🇨🇲, cameroon +🇨🇳 => 🇨🇳, china +🇨🇴 => 🇨🇴, colombia +🇨🇵 => 🇨🇵, clipperton island +🇨🇷 => 🇨🇷, costa rica +🇨🇺 => 🇨🇺, cuba +🇨🇻 => 🇨🇻, cape verde +🇨🇼 => 🇨🇼, curaçao +🇨🇽 => 🇨🇽, christmas island +🇨🇾 => 🇨🇾, cyprus +🇨🇿 => 🇨🇿, czech republic +🇩🇪 => 🇩🇪, germany +🇩🇬 => 🇩🇬, diego garcia +🇩🇯 => 🇩🇯, djibouti +🇩🇰 => 🇩🇰, denmark +🇩🇲 => 🇩🇲, dominica +🇩🇴 => 🇩🇴, dominican republic +🇩🇿 => 🇩🇿, algeria +🇪🇦 => 🇪🇦, ceuta & melilla +🇪🇨 => 🇪🇨, ecuador +🇪🇪 => 🇪🇪, estonia +🇪🇬 => 🇪🇬, egypt +🇪🇭 => 🇪🇭, western sahara +🇪🇷 => 🇪🇷, eritrea +🇪🇸 => 🇪🇸, spain +🇪🇹 => 🇪🇹, ethiopia +🇪🇺 => 🇪🇺, european union +🇫🇮 => 🇫🇮, finland +🇫🇯 => 🇫🇯, fiji +🇫🇰 => 🇫🇰, falkland islands +🇫🇲 => 🇫🇲, micronesia +🇫🇴 => 🇫🇴, faroe islands +🇫🇷 => 🇫🇷, france +🇬🇦 => 🇬🇦, gabon +🇬🇧 => 🇬🇧, united kingdom +🇬🇩 => 🇬🇩, grenada +🇬🇪 => 🇬🇪, georgia +🇬🇫 => 🇬🇫, french guiana +🇬🇬 => 🇬🇬, guernsey +🇬🇭 => 🇬🇭, ghana +🇬🇮 => 🇬🇮, gibraltar +🇬🇱 => 🇬🇱, greenland +🇬🇲 => 🇬🇲, gambia +🇬🇳 => 🇬🇳, guinea +🇬🇵 => 🇬🇵, guadeloupe +🇬🇶 => 🇬🇶, equatorial guinea +🇬🇷 => 🇬🇷, greece +🇬🇸 => 🇬🇸, south georgia & south sandwich islands +🇬🇹 => 🇬🇹, guatemala +🇬🇺 => 🇬🇺, guam +🇬🇼 => 🇬🇼, guinea-bissau +🇬🇾 => 🇬🇾, guyana +🇭🇰 => 🇭🇰, hong kong sar china +🇭🇲 => 🇭🇲, heard & mcdonald islands +🇭🇳 => 🇭🇳, honduras +🇭🇷 => 🇭🇷, croatia +🇭🇹 => 🇭🇹, haiti +🇭🇺 => 🇭🇺, hungary +🇮🇨 => 🇮🇨, canary islands +🇮🇩 => 🇮🇩, indonesia +🇮🇪 => 🇮🇪, ireland +🇮🇱 => 🇮🇱, israel +🇮🇲 => 🇮🇲, isle of man +🇮🇳 => 🇮🇳, india +🇮🇴 => 🇮🇴, british indian ocean territory +🇮🇶 => 🇮🇶, iraq +🇮🇷 => 🇮🇷, iran +🇮🇸 => 🇮🇸, iceland +🇮🇹 => 🇮🇹, italy +🇯🇪 => 🇯🇪, jersey +🇯🇲 => 🇯🇲, jamaica +🇯🇴 => 🇯🇴, jordan +🇯🇵 => 🇯🇵, japan +🇰🇪 => 🇰🇪, kenya +🇰🇬 => 🇰🇬, kyrgyzstan +🇰🇭 => 🇰🇭, cambodia +🇰🇮 => 🇰🇮, kiribati +🇰🇲 => 🇰🇲, comoros +🇰🇳 => 🇰🇳, st. kitts & nevis +🇰🇵 => 🇰🇵, north korea +🇰🇷 => 🇰🇷, south korea +🇰🇼 => 🇰🇼, kuwait +🇰🇾 => 🇰🇾, cayman islands +🇰🇿 => 🇰🇿, kazakhstan +🇱🇦 => 🇱🇦, laos +🇱🇧 => 🇱🇧, lebanon +🇱🇨 => 🇱🇨, st. lucia +🇱🇮 => 🇱🇮, liechtenstein +🇱🇰 => 🇱🇰, sri lanka +🇱🇷 => 🇱🇷, liberia +🇱🇸 => 🇱🇸, lesotho +🇱🇹 => 🇱🇹, lithuania +🇱🇺 => 🇱🇺, luxembourg +🇱🇻 => 🇱🇻, latvia +🇱🇾 => 🇱🇾, libya +🇲🇦 => 🇲🇦, morocco +🇲🇨 => 🇲🇨, monaco +🇲🇩 => 🇲🇩, moldova +🇲🇪 => 🇲🇪, montenegro +🇲🇫 => 🇲🇫, st. martin +🇲🇬 => 🇲🇬, madagascar +🇲🇭 => 🇲🇭, marshall islands +🇲🇰 => 🇲🇰, macedonia +🇲🇱 => 🇲🇱, mali +🇲🇲 => 🇲🇲, myanmar (burma) +🇲🇳 => 🇲🇳, mongolia +🇲🇴 => 🇲🇴, macau sar china +🇲🇵 => 🇲🇵, northern mariana islands +🇲🇶 => 🇲🇶, martinique +🇲🇷 => 🇲🇷, mauritania +🇲🇸 => 🇲🇸, montserrat +🇲🇹 => 🇲🇹, malta +🇲🇺 => 🇲🇺, mauritius +🇲🇻 => 🇲🇻, maldives +🇲🇼 => 🇲🇼, malawi +🇲🇽 => 🇲🇽, mexico +🇲🇾 => 🇲🇾, malaysia +🇲🇿 => 🇲🇿, mozambique +🇳🇦 => 🇳🇦, namibia +🇳🇨 => 🇳🇨, new caledonia +🇳🇪 => 🇳🇪, niger +🇳🇫 => 🇳🇫, norfolk island +🇳🇬 => 🇳🇬, nigeria +🇳🇮 => 🇳🇮, nicaragua +🇳🇱 => 🇳🇱, netherlands +🇳🇴 => 🇳🇴, norway +🇳🇵 => 🇳🇵, nepal +🇳🇷 => 🇳🇷, nauru +🇳🇺 => 🇳🇺, niue +🇳🇿 => 🇳🇿, new zealand +🇴🇲 => 🇴🇲, oman +🇵🇦 => 🇵🇦, panama +🇵🇪 => 🇵🇪, peru +🇵🇫 => 🇵🇫, french polynesia +🇵🇬 => 🇵🇬, papua new guinea +🇵🇭 => 🇵🇭, philippines +🇵🇰 => 🇵🇰, pakistan +🇵🇱 => 🇵🇱, poland +🇵🇲 => 🇵🇲, st. pierre & miquelon +🇵🇳 => 🇵🇳, pitcairn islands +🇵🇷 => 🇵🇷, puerto rico +🇵🇸 => 🇵🇸, palestinian territories +🇵🇹 => 🇵🇹, portugal +🇵🇼 => 🇵🇼, palau +🇵🇾 => 🇵🇾, paraguay +🇶🇦 => 🇶🇦, qatar +🇶🇴 => 🇶🇴, outlying oceania +🇷🇪 => 🇷🇪, réunion +🇷🇴 => 🇷🇴, romania +🇷🇸 => 🇷🇸, serbia +🇷🇺 => 🇷🇺, russia +🇷🇼 => 🇷🇼, rwanda +🇸🇦 => 🇸🇦, saudi arabia +🇸🇧 => 🇸🇧, solomon islands +🇸🇨 => 🇸🇨, seychelles +🇸🇩 => 🇸🇩, sudan +🇸🇪 => 🇸🇪, sweden +🇸🇬 => 🇸🇬, singapore +🇸🇭 => 🇸🇭, st. helena +🇸🇮 => 🇸🇮, slovenia +🇸🇯 => 🇸🇯, svalbard & jan mayen +🇸🇰 => 🇸🇰, slovakia +🇸🇱 => 🇸🇱, sierra leone +🇸🇲 => 🇸🇲, san marino +🇸🇳 => 🇸🇳, senegal +🇸🇴 => 🇸🇴, somalia +🇸🇷 => 🇸🇷, suriname +🇸🇸 => 🇸🇸, south sudan +🇸🇹 => 🇸🇹, são tomé & príncipe +🇸🇻 => 🇸🇻, el salvador +🇸🇽 => 🇸🇽, sint maarten +🇸🇾 => 🇸🇾, syria +🇸🇿 => 🇸🇿, swaziland +🇹🇦 => 🇹🇦, tristan da cunha +🇹🇨 => 🇹🇨, turks & caicos islands +🇹🇩 => 🇹🇩, chad +🇹🇫 => 🇹🇫, french southern territories +🇹🇬 => 🇹🇬, togo +🇹🇭 => 🇹🇭, thailand +🇹🇯 => 🇹🇯, tajikistan +🇹🇰 => 🇹🇰, tokelau +🇹🇱 => 🇹🇱, timor-leste +🇹🇲 => 🇹🇲, turkmenistan +🇹🇳 => 🇹🇳, tunisia +🇹🇴 => 🇹🇴, tonga +🇹🇷 => 🇹🇷, turkey +🇹🇹 => 🇹🇹, trinidad & tobago +🇹🇻 => 🇹🇻, tuvalu +🇹🇼 => 🇹🇼, taiwan +🇹🇿 => 🇹🇿, tanzania +🇺🇦 => 🇺🇦, ukraine +🇺🇬 => 🇺🇬, uganda +🇺🇲 => 🇺🇲, u.s. outlying islands +🇺🇸 => 🇺🇸, united states, us, US +🇺🇾 => 🇺🇾, uruguay +🇺🇿 => 🇺🇿, uzbekistan +🇻🇦 => 🇻🇦, vatican city +🇻🇨 => 🇻🇨, st. vincent & grenadines +🇻🇪 => 🇻🇪, venezuela +🇻🇬 => 🇻🇬, british virgin islands +🇻🇮 => 🇻🇮, u.s. virgin islands +🇻🇳 => 🇻🇳, vietnam +🇻🇺 => 🇻🇺, vanuatu +🇼🇫 => 🇼🇫, wallis & futuna +🇼🇸 => 🇼🇸, samoa +🇽🇰 => 🇽🇰, kosovo +🇾🇪 => 🇾🇪, yemen +🇾🇹 => 🇾🇹, mayotte +🇿🇦 => 🇿🇦, south africa +🇿🇲 => 🇿🇲, zambia +🇿🇼 => 🇿🇼, zimbabwe +🇿🇿 => 🇿🇿, unknown region diff --git a/ubuntu/setup-elasticsearch-index.sh b/ubuntu/setup-elasticsearch-index.sh new file mode 100755 index 0000000..402af41 --- /dev/null +++ b/ubuntu/setup-elasticsearch-index.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +WHOAMI=`python -c 'import os, sys; print os.path.realpath(sys.argv[1])' $0` + +PARENT=`dirname $WHOAMI` +PROJECT=`dirname $PARENT` + +DATA=$1 +INDEX=$2 + +if [ "${DATA}" = "" ] ; then + DATA="/usr/local/data/whosonfirst-data/data" +fi + +if [ ! -d ${DATA} ] ; then + echo "Can not find ${DATA}" + exit 1 +fi + +if [ "${INDEX}" = "" ] +then + INDEX="whosonfirst" +fi + +/usr/local/bin/wof-es-index -s ${DATA} --index ${INDEX} -b + +exit 0 diff --git a/ubuntu/setup-elasticsearch-schema.sh b/ubuntu/setup-elasticsearch-schema.sh new file mode 100755 index 0000000..9a15d5a --- /dev/null +++ b/ubuntu/setup-elasticsearch-schema.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +WHOAMI=`python -c 'import os, sys; print os.path.realpath(sys.argv[1])' $0` + +PARENT=`dirname $WHOAMI` +PROJECT=`dirname $PARENT` +SCHEMA="${PROJECT}/elasticsearch/schema" + +cat ${SCHEMA}/mappings.whosonfirst.json | curl -XPUT http://localhost:9200/whosonfirst_current -d @- +curl -XPOST http://localhost:9200/_aliases -d '{ "actions": [ { "add": { "alias": "whosonfirst", "index": "whosonfirst_current" }} ] }' + +exit 0 diff --git a/ubuntu/setup-elasticsearch.sh b/ubuntu/setup-elasticsearch.sh index 9c228e6..8c4b6f7 100755 --- a/ubuntu/setup-elasticsearch.sh +++ b/ubuntu/setup-elasticsearch.sh @@ -17,37 +17,76 @@ WHOAMI=`python -c 'import os, sys; print os.path.realpath(sys.argv[1])' $0` PARENT=`dirname $WHOAMI` PROJECT=`dirname $PARENT` +PROJECT_NAME=`basename ${PROJECT}` -CONF_DIR="${PROJECT}/config" -CONF="${CONF_DIR}/${PROJECT_NAME}-elasticsearch.yml" +ELASTICSEARCH_CONFIG_PATH="${PROJECT}/config/${PROJECT_NAME}-elasticsearch.conf" -if [ ! -f ${CONF}.example ] +# see also: https://github.com/whosonfirst/whosonfirst-www-spelunker/issues/18 + +# https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-service.html + +sudo add-apt-repository ppa:webupd8team/java -y + +sudo apt-get update +sudo apt-get install oracle-java8-installer -y + +curl -o /tmp/elasticsearch-2.4.0.deb https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/deb/elasticsearch/2.4.0/elasticsearch-2.4.0.deb +curl -o /tmp/elasticsearch-2.4.0.deb.sha1 https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/deb/elasticsearch/2.4.0/elasticsearch-2.4.0.deb.sha1 + +remote_sha1=`cat /tmp/elasticsearch-2.4.0.deb.sha1` +local_sha1=`sha1sum /tmp/elasticsearch-2.4.0.deb | cut -c1-40` + +if [ "$remote_sha1" != "$local_sha1" ] then - echo "missing example ${CONF}" + echo "Uh oh, elasticsearch SHA1 checksum is invalid." exit 1 fi -if [ -f ${CONF} ] +sudo dpkg -i /tmp/elasticsearch-2.4.0.deb +sudo update-rc.d elasticsearch defaults 95 10 + +rm /tmp/elasticsearch-2.4.0.deb +rm /tmp/elasticsearch-2.4.0.deb.sha1 + +if [ ! -f ${ELASTICSEARCH_CONFIG_PATH} ] then - cp ${CONF} ${CONF}.bak -fi + cp ${ELASTICSEARCH_CONFIG_PATH}.example ${ELASTICSEARCH_CONFIG_PATH} -cp ${CONF}.example ${CONF} + sudo mv /etc/default/elasticsearch /etc/default/.elasticsearch.dist + sudo ln -s ${ELASTICSEARCH_CONFIG_PATH} /etc/default/elasticsearch +fi -sudo add-apt-repository ppa:webupd8team/java -y -sudo apt-get update -sudo apt-get install oracle-java8-installer -y +if [ ! -d /etc/elasticsearch/synonyms ] +then + sudo mkdir /etc/elasticsearch/synonyms +fi -cd /tmp -wget https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/deb/elasticsearch/2.4.6/elasticsearch-2.4.6.deb -sudo dpkg -i elasticsearch-2.4.6.deb -rm /tmp/elasticsearch-2.4.6.deb -cd - +# Why do I need to copy this... symlinks result in all kinds of (Java) file +# permission errors because... computers? (20161103/thisisaaronland) -if [ -f /etc/elasticsearch/elasticsearch.yml ] - sudo rm /etc/elasticsearch/elasticsearch.yml +if [ ! -f /etc/elasticsearch/synonyms/cldr-emoji-annotation-synonyms-en.txt ] +then + sudo cp ${PROJECT}/elasticsearch/synonyms/cldr-emoji-annotation-synonyms-en.txt /etc/elasticsearch/synonyms/cldr-emoji-annotation-synonyms-en.txt fi -sudo ln -s ${CONF} /etc/elasticsearch/elasticsearch.yml -sudo systemctl enable elasticsearch.service -sudo systemctl start elasticsearch +# sudo update-rc.d elasticsearch defaults 95 10 + +if [ ! -f /var/run/elasticsearch/elasticsearch.pid ] +then + sudo /etc/init.d/elasticsearch start + sleep 10 +else + + PID=`cat /var/run/elasticsearch/elasticsearch.pid` + COUNT=`ps -p ${PID} | grep java | wc -l` + + if [ ${COUNT} = 0 ] + then + + echo "Elasticsearch isn't running BECAUSE COMPUTERS so trying to restart" + sudo /etc/init.d/elasticsearch start + sleep 10 + else + sudo /etc/init.d/elasticsearch restart + fi +fi diff --git a/www/.htaccess b/www/.htaccess index 82f68a3..1642648 100644 --- a/www/.htaccess +++ b/www/.htaccess @@ -47,6 +47,9 @@ ErrorDocument 403 /403.php # Get mod_rewrite fired up RewriteEngine on +RewriteCond %{HTTP_HOST} ^(.*)elb\.amazonaws\.com$ +RewriteRule .* - [F] + # Login stuff # RewriteRule ^signup/?$ signup.php [L] @@ -72,11 +75,24 @@ RewriteRule ^contact/?$ contact.php [L,QSA] RewriteRule ^id/?$ id.php [L] # mostly so we can get cfg.abs_root_url RewriteRule ^id/([0-9]+)/?$ id.php?id=$1&%{QUERY_STRING} [L] +RewriteRule ^id/([0-9]+)/nearby/?$ id.php?id=$1&nearby=1&%{QUERY_STRING} [L] RewriteRule ^id/([0-9]+)/info(.json)?$ info.php?id=$1&%{QUERY_STRING} [L] +RewriteRule ^brands/search/?$ brands_search.php?%{QUERY_STRING} [L] +RewriteRule ^brands(/page([0-9]+))?/?$ brands.php?page=$2%{QUERY_STRING} [L] +RewriteRule ^brands/([0-9]+)(/page([0-9]+))?/?$ brand.php?id=$1&page=$3%{QUERY_STRING} [L] + +RewriteRule ^nearby/?$ nearby.php?%{QUERY_STRING} [L] +RewriteRule ^nearby/([0-9]+)/?$ nearby.php?id=$1&%{QUERY_STRING} [L] + +RewriteRule ^placetypes/([a-z]+)/?$ placetype.php?placetype=$1&%{QUERY_STRING} [L] + +RewriteRule ^tags/([a-z]+)/in-([0-9]+)/?$ tag.php?tag=$1&wofid=$2&%{QUERY_STRING} [L] RewriteRule ^tags/([a-z]+)/?$ tag.php?tag=$1&%{QUERY_STRING} [L] +RewriteRule ^search/?$ search.php?%{QUERY_STRING} [L] + # See all this stuff that's been commented out? It's a lot of hoop-jumping # to separate API calls (api.example.com/rest) from all the other user-level # administrative pages (example.com/api/methods) and to make sure things that diff --git a/www/brand.php b/www/brand.php new file mode 100644 index 0000000..7a438ad --- /dev/null +++ b/www/brand.php @@ -0,0 +1,80 @@ + array("wof:brand_id" => $id )) + ); + + $rsp = whosonfirst_places_get_by_brand($brand, $filters, $more); + + if (! $rsp["ok"]){ + error_500(); + } + + $places = $rsp["rows"]; + $pagination = $rsp["pagination"]; + + $GLOBALS['smarty']->assign_by_ref("brand", $brand); + $GLOBALS['smarty']->assign_by_ref("superseded_by", $superseded_by); + $GLOBALS['smarty']->assign_by_ref("supersedes", $supersedes); + + $GLOBALS['smarty']->assign_by_ref("places", $places); + $GLOBALS['smarty']->assign_by_ref("pagination", $pagination); + + $pagination_url = $GLOBALS['cfg']['abs_root_url'] . "brands/$id/"; + $GLOBALS['smarty']->assign("pagination_url", $pagination_url); + + $GLOBALS['smarty']->display("page_brand.txt"); + exit(); +?> \ No newline at end of file diff --git a/www/brands.php b/www/brands.php new file mode 100644 index 0000000..b898386 --- /dev/null +++ b/www/brands.php @@ -0,0 +1,77 @@ +assign_by_ref("brands", $rows); + $GLOBALS["smarty"]->assign_by_ref("pagination", $pagination); + + $GLOBALS["smarty"]->display("page_brands.txt"); + exit(); + +?> \ No newline at end of file diff --git a/www/brands_search.php b/www/brands_search.php new file mode 100644 index 0000000..99c1199 --- /dev/null +++ b/www/brands_search.php @@ -0,0 +1,44 @@ +assign_by_ref("query", $q); + + $GLOBALS["smarty"]->assign_by_ref("brands", $rows); + $GLOBALS["smarty"]->assign_by_ref("pagination", $pagination); + + $pagination_url = "{$GLOBALS["cfg"]["abs_root_url"]}brands/search/?q=" . urlencode($q); + $pagination_page_as_queryarg = 1; + + $GLOBALS["smarty"]->assign("pagination_url", $pagination_url); + $GLOBALS["smarty"]->assign("pagination_page_as_queryarg", $pagination_page_as_queryarg); + } + + $GLOBALS["smarty"]->display("page_brands_search.txt"); + exit(); +?> + diff --git a/www/common/styleguide/images/background/contour_darkpurple2_lg.png b/www/common/styleguide/images/background/contour_darkpurple2_lg.png new file mode 100644 index 0000000..0d10859 Binary files /dev/null and b/www/common/styleguide/images/background/contour_darkpurple2_lg.png differ diff --git a/www/css/L.Control.Locate.css b/www/css/L.Control.Locate.css new file mode 100644 index 0000000..1fa5e7b --- /dev/null +++ b/www/css/L.Control.Locate.css @@ -0,0 +1,12 @@ +/* Compatible with Leaflet 0.7 */ +.leaflet-control-locate a { + font-size: 1.4em; + color: #444; + cursor: pointer; +} +.leaflet-control-locate.active a { + color: #2074B6; +} +.leaflet-control-locate.active.following a { + color: #FC8428; +} diff --git a/www/css/L.Control.Locate.min.css b/www/css/L.Control.Locate.min.css new file mode 100644 index 0000000..b83f4f7 --- /dev/null +++ b/www/css/L.Control.Locate.min.css @@ -0,0 +1,2 @@ +.leaflet-control-locate a{font-size:1.4em;color:#444;cursor:pointer}.leaflet-control-locate.active a{color:#2074B6}.leaflet-control-locate.active.following a{color:#FC8428} +/*# sourceMappingURL=L.Control.Locate.min.css.map */ diff --git a/www/css/leaflet.markercluster.css b/www/css/leaflet.markercluster.css new file mode 100644 index 0000000..c60d71b --- /dev/null +++ b/www/css/leaflet.markercluster.css @@ -0,0 +1,14 @@ +.leaflet-cluster-anim .leaflet-marker-icon, .leaflet-cluster-anim .leaflet-marker-shadow { + -webkit-transition: -webkit-transform 0.3s ease-out, opacity 0.3s ease-in; + -moz-transition: -moz-transform 0.3s ease-out, opacity 0.3s ease-in; + -o-transition: -o-transform 0.3s ease-out, opacity 0.3s ease-in; + transition: transform 0.3s ease-out, opacity 0.3s ease-in; +} + +.leaflet-cluster-spider-leg { + /* stroke-dashoffset (duration and function) should match with leaflet-marker-icon transform in order to track it exactly */ + -webkit-transition: -webkit-stroke-dashoffset 0.3s ease-out, -webkit-stroke-opacity 0.3s ease-in; + -moz-transition: -moz-stroke-dashoffset 0.3s ease-out, -moz-stroke-opacity 0.3s ease-in; + -o-transition: -o-stroke-dashoffset 0.3s ease-out, -o-stroke-opacity 0.3s ease-in; + transition: stroke-dashoffset 0.3s ease-out, stroke-opacity 0.3s ease-in; +} diff --git a/www/css/leaflet.markercluster.default.css b/www/css/leaflet.markercluster.default.css new file mode 100644 index 0000000..bbc8c9f --- /dev/null +++ b/www/css/leaflet.markercluster.default.css @@ -0,0 +1,60 @@ +.marker-cluster-small { + background-color: rgba(181, 226, 140, 0.6); + } +.marker-cluster-small div { + background-color: rgba(110, 204, 57, 0.6); + } + +.marker-cluster-medium { + background-color: rgba(241, 211, 87, 0.6); + } +.marker-cluster-medium div { + background-color: rgba(240, 194, 12, 0.6); + } + +.marker-cluster-large { + background-color: rgba(253, 156, 115, 0.6); + } +.marker-cluster-large div { + background-color: rgba(241, 128, 23, 0.6); + } + + /* IE 6-8 fallback colors */ +.leaflet-oldie .marker-cluster-small { + background-color: rgb(181, 226, 140); + } +.leaflet-oldie .marker-cluster-small div { + background-color: rgb(110, 204, 57); + } + +.leaflet-oldie .marker-cluster-medium { + background-color: rgb(241, 211, 87); + } +.leaflet-oldie .marker-cluster-medium div { + background-color: rgb(240, 194, 12); + } + +.leaflet-oldie .marker-cluster-large { + background-color: rgb(253, 156, 115); + } +.leaflet-oldie .marker-cluster-large div { + background-color: rgb(241, 128, 23); +} + +.marker-cluster { + background-clip: padding-box; + border-radius: 20px; + } +.marker-cluster div { + width: 30px; + height: 30px; + margin-left: 5px; + margin-top: 5px; + + text-align: center; + border-radius: 15px; + font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif; + } +.marker-cluster span { + line-height: 30px; + } \ No newline at end of file diff --git a/www/css/leaflet.markercluster.mapzen.css b/www/css/leaflet.markercluster.mapzen.css new file mode 100644 index 0000000..328cb5c --- /dev/null +++ b/www/css/leaflet.markercluster.mapzen.css @@ -0,0 +1,42 @@ +.marker-cluster { + background-clip: padding-box; + border-radius: 20px; +} +.marker-cluster div { + color: #fff; + width: 30px; + height: 30px; + margin-left: 5px; + margin-top: 5px; + text-align: center; + border-radius: 15px; + font: bold 12px "open sans", "Helvetica Neue", Arial, Helvetica, sans-serif; +} + +.marker-cluster span { + line-height: 30px; +} + +.marker-cluster-small { + background-color: rgba(253, 219, 218, 0.6); +} + +.marker-cluster-small div { + color: #2c1e3f; + background-color: rgba(255, 122, 123, 0.6); +} + +.marker-cluster-medium { + background-color: rgba(190, 162, 221, 0.6); +} + +.marker-cluster-medium div { + background-color: rgba(151, 95, 220, 0.6); +} + +.marker-cluster-large { + background-color: rgba(99, 83, 120, 0.6); +} +.marker-cluster-large div { + background-color: rgba(44, 30, 63, 0.6); +} diff --git a/www/css/mapzen.places.api.css b/www/css/mapzen.places.api.css new file mode 100644 index 0000000..7f4b720 --- /dev/null +++ b/www/css/mapzen.places.api.css @@ -0,0 +1,8 @@ +.map-marker { + background: #f9a293; +} + +.pagination > .active > a, .pagination > .active > span, .pagination > .active > a:hover, .pagination > .active > span:hover, .pagination > .active > a:focus, .pagination > .active > span:focus { + background-color: #635378; + border-color: #635378; +} diff --git a/www/css/mapzen.styleguide.css b/www/css/mapzen.styleguide.css index c88c2ac..1b850db 100644 --- a/www/css/mapzen.styleguide.css +++ b/www/css/mapzen.styleguide.css @@ -1,41 +1,8 @@ @charset "UTF-8"; +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ @import url(https://fonts.googleapis.com/css?family=Source+Code+Pro:400,600|Open+Sans:300italic,400italic,700italic,400,300,600,700|Playfair+Display:400,700,900,400italic|Montserrat); @import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css); @import url(https://fonts.googleapis.com/css?family=Poppins:300,400,600,700); -.mz-red { - background-color: #d4645c; } - -.mz-blue { - background-color: #6ea0a4; } - -.mz-yellow { - background-color: #e6ead2; } - -.mz-black { - background-color: #191919; } - -.mz-darkgray { - background-color: #444; } - -.mz-mediumgray { - background-color: #666666; } - -.mz-lightgray { - background-color: #f8f8f8; } - -.mz-darkred { - background-color: #993434; } - -.mz-darkblue { - background-color: #385d5c; } - -.mz-darkyellow { - background-color: #d3c756; } - -.mz-brown { - background-color: #563630; } - -/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ html { font-family: sans-serif; -ms-text-size-adjust: 100%; @@ -263,13 +230,10 @@ th { border-top-color: #000 !important; } .label { border: 1px solid #000; } - .table, .content table, - .static-content table { + .table { border-collapse: collapse !important; } - .table td, .content table td, - .static-content table td, - .table th, .content table th, - .static-content table th { + .table td, + .table th { background-color: #fff !important; } .table-bordered th, .table-bordered td { @@ -375,8 +339,8 @@ hr { h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { - font-family: inherit; - font-weight: 500; + font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; + font-weight: 700; line-height: 1.1; color: inherit; } h1 small, @@ -1257,51 +1221,33 @@ caption { th { text-align: left; } -.table, .content table, -.static-content table { +.table { width: 100%; max-width: 100%; margin-bottom: 20px; } - .table > thead > tr > th, .content table > thead > tr > th, - .static-content table > thead > tr > th, - .table > thead > tr > td, .content table > thead > tr > td, - .static-content table > thead > tr > td, - .table > tbody > tr > th, .content table > tbody > tr > th, - .static-content table > tbody > tr > th, - .table > tbody > tr > td, .content table > tbody > tr > td, - .static-content table > tbody > tr > td, - .table > tfoot > tr > th, .content table > tfoot > tr > th, - .static-content table > tfoot > tr > th, - .table > tfoot > tr > td, .content table > tfoot > tr > td, - .static-content table > tfoot > tr > td { + .table > thead > tr > th, + .table > thead > tr > td, + .table > tbody > tr > th, + .table > tbody > tr > td, + .table > tfoot > tr > th, + .table > tfoot > tr > td { padding: 8px; line-height: 1.42857; vertical-align: top; border-top: 1px solid #ddd; } - .table > thead > tr > th, .content table > thead > tr > th, - .static-content table > thead > tr > th { + .table > thead > tr > th { vertical-align: bottom; border-bottom: 2px solid #ddd; } - .table > caption + thead > tr:first-child > th, .content table > caption + thead > tr:first-child > th, - .static-content table > caption + thead > tr:first-child > th, - .table > caption + thead > tr:first-child > td, .content table > caption + thead > tr:first-child > td, - .static-content table > caption + thead > tr:first-child > td, - .table > colgroup + thead > tr:first-child > th, .content table > colgroup + thead > tr:first-child > th, - .static-content table > colgroup + thead > tr:first-child > th, - .table > colgroup + thead > tr:first-child > td, .content table > colgroup + thead > tr:first-child > td, - .static-content table > colgroup + thead > tr:first-child > td, - .table > thead:first-child > tr:first-child > th, .content table > thead:first-child > tr:first-child > th, - .static-content table > thead:first-child > tr:first-child > th, - .table > thead:first-child > tr:first-child > td, .content table > thead:first-child > tr:first-child > td, - .static-content table > thead:first-child > tr:first-child > td { + .table > caption + thead > tr:first-child > th, + .table > caption + thead > tr:first-child > td, + .table > colgroup + thead > tr:first-child > th, + .table > colgroup + thead > tr:first-child > td, + .table > thead:first-child > tr:first-child > th, + .table > thead:first-child > tr:first-child > td { border-top: 0; } - .table > tbody + tbody, .content table > tbody + tbody, - .static-content table > tbody + tbody { + .table > tbody + tbody { border-top: 2px solid #ddd; } - .table .table, .content table .table, - .static-content table .table, .table .content table, .content .table table, .content table table, .table - .static-content table, - .static-content .table table, .static-content table table { + .table .table { background-color: #fff; } .table-condensed > thead > tr > th, @@ -1342,30 +1288,18 @@ table th[class*="col-"] { float: none; display: table-cell; } -.table > thead > tr > td.active, .content table > thead > tr > td.active, -.static-content table > thead > tr > td.active, -.table > thead > tr > th.active, .content table > thead > tr > th.active, -.static-content table > thead > tr > th.active, -.table > thead > tr.active > td, .content table > thead > tr.active > td, -.static-content table > thead > tr.active > td, -.table > thead > tr.active > th, .content table > thead > tr.active > th, -.static-content table > thead > tr.active > th, -.table > tbody > tr > td.active, .content table > tbody > tr > td.active, -.static-content table > tbody > tr > td.active, -.table > tbody > tr > th.active, .content table > tbody > tr > th.active, -.static-content table > tbody > tr > th.active, -.table > tbody > tr.active > td, .content table > tbody > tr.active > td, -.static-content table > tbody > tr.active > td, -.table > tbody > tr.active > th, .content table > tbody > tr.active > th, -.static-content table > tbody > tr.active > th, -.table > tfoot > tr > td.active, .content table > tfoot > tr > td.active, -.static-content table > tfoot > tr > td.active, -.table > tfoot > tr > th.active, .content table > tfoot > tr > th.active, -.static-content table > tfoot > tr > th.active, -.table > tfoot > tr.active > td, .content table > tfoot > tr.active > td, -.static-content table > tfoot > tr.active > td, -.table > tfoot > tr.active > th, .content table > tfoot > tr.active > th, -.static-content table > tfoot > tr.active > th { +.table > thead > tr > td.active, +.table > thead > tr > th.active, +.table > thead > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr > td.active, +.table > tbody > tr > th.active, +.table > tbody > tr.active > td, +.table > tbody > tr.active > th, +.table > tfoot > tr > td.active, +.table > tfoot > tr > th.active, +.table > tfoot > tr.active > td, +.table > tfoot > tr.active > th { background-color: transparent; } .table-hover > tbody > tr > td.active:hover, @@ -1375,30 +1309,18 @@ table th[class*="col-"] { .table-hover > tbody > tr.active:hover > th { background-color: transparent; } -.table > thead > tr > td.success, .content table > thead > tr > td.success, -.static-content table > thead > tr > td.success, -.table > thead > tr > th.success, .content table > thead > tr > th.success, -.static-content table > thead > tr > th.success, -.table > thead > tr.success > td, .content table > thead > tr.success > td, -.static-content table > thead > tr.success > td, -.table > thead > tr.success > th, .content table > thead > tr.success > th, -.static-content table > thead > tr.success > th, -.table > tbody > tr > td.success, .content table > tbody > tr > td.success, -.static-content table > tbody > tr > td.success, -.table > tbody > tr > th.success, .content table > tbody > tr > th.success, -.static-content table > tbody > tr > th.success, -.table > tbody > tr.success > td, .content table > tbody > tr.success > td, -.static-content table > tbody > tr.success > td, -.table > tbody > tr.success > th, .content table > tbody > tr.success > th, -.static-content table > tbody > tr.success > th, -.table > tfoot > tr > td.success, .content table > tfoot > tr > td.success, -.static-content table > tfoot > tr > td.success, -.table > tfoot > tr > th.success, .content table > tfoot > tr > th.success, -.static-content table > tfoot > tr > th.success, -.table > tfoot > tr.success > td, .content table > tfoot > tr.success > td, -.static-content table > tfoot > tr.success > td, -.table > tfoot > tr.success > th, .content table > tfoot > tr.success > th, -.static-content table > tfoot > tr.success > th { +.table > thead > tr > td.success, +.table > thead > tr > th.success, +.table > thead > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr > td.success, +.table > tbody > tr > th.success, +.table > tbody > tr.success > td, +.table > tbody > tr.success > th, +.table > tfoot > tr > td.success, +.table > tfoot > tr > th.success, +.table > tfoot > tr.success > td, +.table > tfoot > tr.success > th { background-color: #dff0d8; } .table-hover > tbody > tr > td.success:hover, @@ -1408,30 +1330,18 @@ table th[class*="col-"] { .table-hover > tbody > tr.success:hover > th { background-color: #d0e9c6; } -.table > thead > tr > td.info, .content table > thead > tr > td.info, -.static-content table > thead > tr > td.info, -.table > thead > tr > th.info, .content table > thead > tr > th.info, -.static-content table > thead > tr > th.info, -.table > thead > tr.info > td, .content table > thead > tr.info > td, -.static-content table > thead > tr.info > td, -.table > thead > tr.info > th, .content table > thead > tr.info > th, -.static-content table > thead > tr.info > th, -.table > tbody > tr > td.info, .content table > tbody > tr > td.info, -.static-content table > tbody > tr > td.info, -.table > tbody > tr > th.info, .content table > tbody > tr > th.info, -.static-content table > tbody > tr > th.info, -.table > tbody > tr.info > td, .content table > tbody > tr.info > td, -.static-content table > tbody > tr.info > td, -.table > tbody > tr.info > th, .content table > tbody > tr.info > th, -.static-content table > tbody > tr.info > th, -.table > tfoot > tr > td.info, .content table > tfoot > tr > td.info, -.static-content table > tfoot > tr > td.info, -.table > tfoot > tr > th.info, .content table > tfoot > tr > th.info, -.static-content table > tfoot > tr > th.info, -.table > tfoot > tr.info > td, .content table > tfoot > tr.info > td, -.static-content table > tfoot > tr.info > td, -.table > tfoot > tr.info > th, .content table > tfoot > tr.info > th, -.static-content table > tfoot > tr.info > th { +.table > thead > tr > td.info, +.table > thead > tr > th.info, +.table > thead > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr > td.info, +.table > tbody > tr > th.info, +.table > tbody > tr.info > td, +.table > tbody > tr.info > th, +.table > tfoot > tr > td.info, +.table > tfoot > tr > th.info, +.table > tfoot > tr.info > td, +.table > tfoot > tr.info > th { background-color: #d9edf7; } .table-hover > tbody > tr > td.info:hover, @@ -1441,30 +1351,18 @@ table th[class*="col-"] { .table-hover > tbody > tr.info:hover > th { background-color: #c4e3f3; } -.table > thead > tr > td.warning, .content table > thead > tr > td.warning, -.static-content table > thead > tr > td.warning, -.table > thead > tr > th.warning, .content table > thead > tr > th.warning, -.static-content table > thead > tr > th.warning, -.table > thead > tr.warning > td, .content table > thead > tr.warning > td, -.static-content table > thead > tr.warning > td, -.table > thead > tr.warning > th, .content table > thead > tr.warning > th, -.static-content table > thead > tr.warning > th, -.table > tbody > tr > td.warning, .content table > tbody > tr > td.warning, -.static-content table > tbody > tr > td.warning, -.table > tbody > tr > th.warning, .content table > tbody > tr > th.warning, -.static-content table > tbody > tr > th.warning, -.table > tbody > tr.warning > td, .content table > tbody > tr.warning > td, -.static-content table > tbody > tr.warning > td, -.table > tbody > tr.warning > th, .content table > tbody > tr.warning > th, -.static-content table > tbody > tr.warning > th, -.table > tfoot > tr > td.warning, .content table > tfoot > tr > td.warning, -.static-content table > tfoot > tr > td.warning, -.table > tfoot > tr > th.warning, .content table > tfoot > tr > th.warning, -.static-content table > tfoot > tr > th.warning, -.table > tfoot > tr.warning > td, .content table > tfoot > tr.warning > td, -.static-content table > tfoot > tr.warning > td, -.table > tfoot > tr.warning > th, .content table > tfoot > tr.warning > th, -.static-content table > tfoot > tr.warning > th { +.table > thead > tr > td.warning, +.table > thead > tr > th.warning, +.table > thead > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr > td.warning, +.table > tbody > tr > th.warning, +.table > tbody > tr.warning > td, +.table > tbody > tr.warning > th, +.table > tfoot > tr > td.warning, +.table > tfoot > tr > th.warning, +.table > tfoot > tr.warning > td, +.table > tfoot > tr.warning > th { background-color: #fcf8e3; } .table-hover > tbody > tr > td.warning:hover, @@ -1474,30 +1372,18 @@ table th[class*="col-"] { .table-hover > tbody > tr.warning:hover > th { background-color: #faf2cc; } -.table > thead > tr > td.danger, .content table > thead > tr > td.danger, -.static-content table > thead > tr > td.danger, -.table > thead > tr > th.danger, .content table > thead > tr > th.danger, -.static-content table > thead > tr > th.danger, -.table > thead > tr.danger > td, .content table > thead > tr.danger > td, -.static-content table > thead > tr.danger > td, -.table > thead > tr.danger > th, .content table > thead > tr.danger > th, -.static-content table > thead > tr.danger > th, -.table > tbody > tr > td.danger, .content table > tbody > tr > td.danger, -.static-content table > tbody > tr > td.danger, -.table > tbody > tr > th.danger, .content table > tbody > tr > th.danger, -.static-content table > tbody > tr > th.danger, -.table > tbody > tr.danger > td, .content table > tbody > tr.danger > td, -.static-content table > tbody > tr.danger > td, -.table > tbody > tr.danger > th, .content table > tbody > tr.danger > th, -.static-content table > tbody > tr.danger > th, -.table > tfoot > tr > td.danger, .content table > tfoot > tr > td.danger, -.static-content table > tfoot > tr > td.danger, -.table > tfoot > tr > th.danger, .content table > tfoot > tr > th.danger, -.static-content table > tfoot > tr > th.danger, -.table > tfoot > tr.danger > td, .content table > tfoot > tr.danger > td, -.static-content table > tfoot > tr.danger > td, -.table > tfoot > tr.danger > th, .content table > tfoot > tr.danger > th, -.static-content table > tfoot > tr.danger > th { +.table > thead > tr > td.danger, +.table > thead > tr > th.danger, +.table > thead > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr > td.danger, +.table > tbody > tr > th.danger, +.table > tbody > tr.danger > td, +.table > tbody > tr.danger > th, +.table > tfoot > tr > td.danger, +.table > tfoot > tr > th.danger, +.table > tfoot > tr.danger > td, +.table > tfoot > tr.danger > th { background-color: #f2dede; } .table-hover > tbody > tr > td.danger:hover, @@ -1517,31 +1403,14 @@ table th[class*="col-"] { overflow-y: hidden; -ms-overflow-style: -ms-autohiding-scrollbar; border: 1px solid #ddd; } - .table-responsive > .table, .content .table-responsive > table, - .static-content .table-responsive > table { + .table-responsive > .table { margin-bottom: 0; } - .table-responsive > .table > thead > tr > th, .content .table-responsive > table > thead > tr > th, - .static-content .table-responsive > table > thead > tr > th, - .table-responsive > .table > thead > tr > td, .content - .table-responsive > table > thead > tr > td, - .static-content - .table-responsive > table > thead > tr > td, - .table-responsive > .table > tbody > tr > th, .content - .table-responsive > table > tbody > tr > th, - .static-content - .table-responsive > table > tbody > tr > th, - .table-responsive > .table > tbody > tr > td, .content - .table-responsive > table > tbody > tr > td, - .static-content - .table-responsive > table > tbody > tr > td, - .table-responsive > .table > tfoot > tr > th, .content - .table-responsive > table > tfoot > tr > th, - .static-content - .table-responsive > table > tfoot > tr > th, - .table-responsive > .table > tfoot > tr > td, .content - .table-responsive > table > tfoot > tr > td, - .static-content - .table-responsive > table > tfoot > tr > td { + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > tfoot > tr > td { white-space: nowrap; } .table-responsive > .table-bordered { border: 0; } @@ -2115,29 +1984,37 @@ select[multiple].input-lg { color: #fff; background-color: #333; } -.btn-primary { +.btn-primary, .btn-mapzen { color: #fff; - background-color: #337ab7; - border-color: #2e6da4; } - .btn-primary:hover, .btn-primary:focus, .btn-primary.focus, .btn-primary:active, .btn-primary.active, - .open > .btn-primary.dropdown-toggle { + background-color: #1E0E33; + border-color: #12091f; } + .btn-primary:hover, .btn-mapzen:hover, .btn-primary:focus, .btn-mapzen:focus, .btn-primary.focus, .focus.btn-mapzen, .btn-primary:active, .btn-mapzen:active, .btn-primary.active, .active.btn-mapzen, + .open > .btn-primary.dropdown-toggle, + .open > .dropdown-toggle.btn-mapzen { color: #fff; - background-color: #286090; - border-color: #204d74; } - .btn-primary:active, .btn-primary.active, - .open > .btn-primary.dropdown-toggle { + background-color: #06030b; + border-color: black; } + .btn-primary:active, .btn-mapzen:active, .btn-primary.active, .active.btn-mapzen, + .open > .btn-primary.dropdown-toggle, + .open > .dropdown-toggle.btn-mapzen { background-image: none; } - .btn-primary.disabled, .btn-primary.disabled:hover, .btn-primary.disabled:focus, .btn-primary.disabled.focus, .btn-primary.disabled:active, .btn-primary.disabled.active, .btn-primary[disabled], .btn-primary[disabled]:hover, .btn-primary[disabled]:focus, .btn-primary[disabled].focus, .btn-primary[disabled]:active, .btn-primary[disabled].active, + .btn-primary.disabled, .disabled.btn-mapzen, .btn-primary.disabled:hover, .disabled.btn-mapzen:hover, .btn-primary.disabled:focus, .disabled.btn-mapzen:focus, .btn-primary.disabled.focus, .disabled.focus.btn-mapzen, .btn-primary.disabled:active, .disabled.btn-mapzen:active, .btn-primary.disabled.active, .disabled.active.btn-mapzen, .btn-primary[disabled], [disabled].btn-mapzen, .btn-primary[disabled]:hover, [disabled].btn-mapzen:hover, .btn-primary[disabled]:focus, [disabled].btn-mapzen:focus, .btn-primary[disabled].focus, [disabled].focus.btn-mapzen, .btn-primary[disabled]:active, [disabled].btn-mapzen:active, .btn-primary[disabled].active, [disabled].active.btn-mapzen, fieldset[disabled] .btn-primary, + fieldset[disabled] .btn-mapzen, fieldset[disabled] .btn-primary:hover, + fieldset[disabled] .btn-mapzen:hover, fieldset[disabled] .btn-primary:focus, + fieldset[disabled] .btn-mapzen:focus, fieldset[disabled] .btn-primary.focus, + fieldset[disabled] .focus.btn-mapzen, fieldset[disabled] .btn-primary:active, - fieldset[disabled] .btn-primary.active { - background-color: #337ab7; - border-color: #2e6da4; } - .btn-primary .badge { - color: #337ab7; + fieldset[disabled] .btn-mapzen:active, + fieldset[disabled] .btn-primary.active, + fieldset[disabled] .active.btn-mapzen { + background-color: #1E0E33; + border-color: #12091f; } + .btn-primary .badge, .btn-mapzen .badge { + color: #1E0E33; background-color: #fff; } .btn-success { @@ -3021,19 +2898,19 @@ tbody.collapse.in { background-color: rgba(30, 14, 51, 0.9); border-color: rgba(15, 7, 25, 0.9); } .navbar-default .navbar-brand { - color: #EEE7F8; } + color: white; } .navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus { - color: #d2c0ec; + color: #e6e6e6; background-color: transparent; } .navbar-default .navbar-text { color: #777; } .navbar-default .navbar-nav > li > a { - color: #EEE7F8; } + color: white; } .navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus { - color: white; + color: #EEE7F8; background-color: transparent; } .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus { - color: white; + color: #EEE7F8; background-color: transparent; } .navbar-default .navbar-nav > .disabled > a, .navbar-default .navbar-nav > .disabled > a:hover, .navbar-default .navbar-nav > .disabled > a:focus { color: #ccc; @@ -3043,33 +2920,33 @@ tbody.collapse.in { .navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus { background-color: transparent; } .navbar-default .navbar-toggle .icon-bar { - background-color: white; } + background-color: #EEE7F8; } .navbar-default .navbar-collapse, .navbar-default .navbar-form { border-color: rgba(15, 7, 25, 0.9); } .navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus { background-color: transparent; - color: white; } + color: #EEE7F8; } @media (max-width: 767px) { .navbar-default .navbar-nav .open .dropdown-menu > li > a { - color: #EEE7F8; } + color: white; } .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { - color: white; + color: #EEE7F8; background-color: transparent; } .navbar-default .navbar-nav .open .dropdown-menu > .active > a, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { - color: white; + color: #EEE7F8; background-color: transparent; } .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { color: #ccc; background-color: transparent; } } .navbar-default .navbar-link { - color: #EEE7F8; } + color: white; } .navbar-default .navbar-link:hover { - color: white; } + color: #EEE7F8; } .navbar-default .btn-link { - color: #EEE7F8; } + color: white; } .navbar-default .btn-link:hover, .navbar-default .btn-link:focus { - color: white; } + color: #EEE7F8; } .navbar-default .btn-link[disabled]:hover, .navbar-default .btn-link[disabled]:focus, fieldset[disabled] .navbar-default .btn-link:hover, fieldset[disabled] .navbar-default .btn-link:focus { @@ -3152,6 +3029,83 @@ tbody.collapse.in { .breadcrumb > .active { color: #898989; } +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; } + to { + background-position: 0 0; } } + +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; } + to { + background-position: 0 0; } } + +.progress { + overflow: hidden; + height: 20px; + margin-bottom: 20px; + background-color: #f5f5f5; + border-radius: 0; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); } + +.progress-bar { + float: left; + width: 0%; + height: 100%; + font-size: 12px; + line-height: 20px; + color: #fff; + text-align: center; + background-color: #337ab7; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; } + +.progress-striped .progress-bar, +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 40px 40px; } + +.progress.active .progress-bar, +.progress-bar.active { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; } + +.progress-bar-success { + background-color: #5cb85c; } + .progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } + +.progress-bar-info { + background-color: #5bc0de; } + .progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } + +.progress-bar-warning { + background-color: #f0ad4e; } + .progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } + +.progress-bar-danger { + background-color: #d9534f; } + .progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } + .panel { margin-bottom: 20px; background-color: #fff; @@ -3219,220 +3173,82 @@ tbody.collapse.in { .list-group + .panel-footer { border-top-width: 0; } -.panel > .table, .content .panel > table, -.static-content .panel > table, -.panel > .table-responsive > .table, .content -.panel > .table-responsive > table, -.static-content -.panel > .table-responsive > table, -.panel > .panel-collapse > .table, .content -.panel > .panel-collapse > table, -.static-content -.panel > .panel-collapse > table { +.panel > .table, +.panel > .table-responsive > .table, +.panel > .panel-collapse > .table { margin-bottom: 0; } - .panel > .table caption, .content .panel > table caption, - .static-content .panel > table caption, - .panel > .table-responsive > .table caption, .content - .panel > .table-responsive > table caption, - .static-content - .panel > .table-responsive > table caption, - .panel > .panel-collapse > .table caption, .content - .panel > .panel-collapse > table caption, - .static-content - .panel > .panel-collapse > table caption { + .panel > .table caption, + .panel > .table-responsive > .table caption, + .panel > .panel-collapse > .table caption { padding-left: 15px; padding-right: 15px; } -.panel > .table:first-child, .content .panel > table:first-child, -.static-content .panel > table:first-child, -.panel > .table-responsive:first-child > .table:first-child, .content -.panel > .table-responsive:first-child > table:first-child, -.static-content -.panel > .table-responsive:first-child > table:first-child { +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { border-top-right-radius: -1; border-top-left-radius: -1; } - .panel > .table:first-child > thead:first-child > tr:first-child, .content .panel > table:first-child > thead:first-child > tr:first-child, - .static-content .panel > table:first-child > thead:first-child > tr:first-child, - .panel > .table:first-child > tbody:first-child > tr:first-child, .content - .panel > table:first-child > tbody:first-child > tr:first-child, - .static-content - .panel > table:first-child > tbody:first-child > tr:first-child, - .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, .content - .panel > .table-responsive:first-child > table:first-child > thead:first-child > tr:first-child, - .static-content - .panel > .table-responsive:first-child > table:first-child > thead:first-child > tr:first-child, - .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child, .content - .panel > .table-responsive:first-child > table:first-child > tbody:first-child > tr:first-child, - .static-content - .panel > .table-responsive:first-child > table:first-child > tbody:first-child > tr:first-child { + .panel > .table:first-child > thead:first-child > tr:first-child, + .panel > .table:first-child > tbody:first-child > tr:first-child, + .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, + .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { border-top-left-radius: -1; border-top-right-radius: -1; } - .panel > .table:first-child > thead:first-child > tr:first-child td:first-child, .content .panel > table:first-child > thead:first-child > tr:first-child td:first-child, - .static-content .panel > table:first-child > thead:first-child > tr:first-child td:first-child, - .panel > .table:first-child > thead:first-child > tr:first-child th:first-child, .content - .panel > table:first-child > thead:first-child > tr:first-child th:first-child, - .static-content - .panel > table:first-child > thead:first-child > tr:first-child th:first-child, - .panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, .content - .panel > table:first-child > tbody:first-child > tr:first-child td:first-child, - .static-content - .panel > table:first-child > tbody:first-child > tr:first-child td:first-child, - .panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, .content - .panel > table:first-child > tbody:first-child > tr:first-child th:first-child, - .static-content - .panel > table:first-child > tbody:first-child > tr:first-child th:first-child, - .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, .content - .panel > .table-responsive:first-child > table:first-child > thead:first-child > tr:first-child td:first-child, - .static-content - .panel > .table-responsive:first-child > table:first-child > thead:first-child > tr:first-child td:first-child, - .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, .content - .panel > .table-responsive:first-child > table:first-child > thead:first-child > tr:first-child th:first-child, - .static-content - .panel > .table-responsive:first-child > table:first-child > thead:first-child > tr:first-child th:first-child, - .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, .content - .panel > .table-responsive:first-child > table:first-child > tbody:first-child > tr:first-child td:first-child, - .static-content - .panel > .table-responsive:first-child > table:first-child > tbody:first-child > tr:first-child td:first-child, - .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child, .content - .panel > .table-responsive:first-child > table:first-child > tbody:first-child > tr:first-child th:first-child, - .static-content - .panel > .table-responsive:first-child > table:first-child > tbody:first-child > tr:first-child th:first-child { + .panel > .table:first-child > thead:first-child > tr:first-child td:first-child, + .panel > .table:first-child > thead:first-child > tr:first-child th:first-child, + .panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, + .panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, + .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, + .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, + .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, + .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { border-top-left-radius: -1; } - .panel > .table:first-child > thead:first-child > tr:first-child td:last-child, .content .panel > table:first-child > thead:first-child > tr:first-child td:last-child, - .static-content .panel > table:first-child > thead:first-child > tr:first-child td:last-child, - .panel > .table:first-child > thead:first-child > tr:first-child th:last-child, .content - .panel > table:first-child > thead:first-child > tr:first-child th:last-child, - .static-content - .panel > table:first-child > thead:first-child > tr:first-child th:last-child, - .panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, .content - .panel > table:first-child > tbody:first-child > tr:first-child td:last-child, - .static-content - .panel > table:first-child > tbody:first-child > tr:first-child td:last-child, - .panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, .content - .panel > table:first-child > tbody:first-child > tr:first-child th:last-child, - .static-content - .panel > table:first-child > tbody:first-child > tr:first-child th:last-child, - .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, .content - .panel > .table-responsive:first-child > table:first-child > thead:first-child > tr:first-child td:last-child, - .static-content - .panel > .table-responsive:first-child > table:first-child > thead:first-child > tr:first-child td:last-child, - .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, .content - .panel > .table-responsive:first-child > table:first-child > thead:first-child > tr:first-child th:last-child, - .static-content - .panel > .table-responsive:first-child > table:first-child > thead:first-child > tr:first-child th:last-child, - .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, .content - .panel > .table-responsive:first-child > table:first-child > tbody:first-child > tr:first-child td:last-child, - .static-content - .panel > .table-responsive:first-child > table:first-child > tbody:first-child > tr:first-child td:last-child, - .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child, .content - .panel > .table-responsive:first-child > table:first-child > tbody:first-child > tr:first-child th:last-child, - .static-content - .panel > .table-responsive:first-child > table:first-child > tbody:first-child > tr:first-child th:last-child { + .panel > .table:first-child > thead:first-child > tr:first-child td:last-child, + .panel > .table:first-child > thead:first-child > tr:first-child th:last-child, + .panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, + .panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, + .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, + .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, + .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, + .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { border-top-right-radius: -1; } -.panel > .table:last-child, .content .panel > table:last-child, -.static-content .panel > table:last-child, -.panel > .table-responsive:last-child > .table:last-child, .content -.panel > .table-responsive:last-child > table:last-child, -.static-content -.panel > .table-responsive:last-child > table:last-child { +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { border-bottom-right-radius: -1; border-bottom-left-radius: -1; } - .panel > .table:last-child > tbody:last-child > tr:last-child, .content .panel > table:last-child > tbody:last-child > tr:last-child, - .static-content .panel > table:last-child > tbody:last-child > tr:last-child, - .panel > .table:last-child > tfoot:last-child > tr:last-child, .content - .panel > table:last-child > tfoot:last-child > tr:last-child, - .static-content - .panel > table:last-child > tfoot:last-child > tr:last-child, - .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, .content - .panel > .table-responsive:last-child > table:last-child > tbody:last-child > tr:last-child, - .static-content - .panel > .table-responsive:last-child > table:last-child > tbody:last-child > tr:last-child, - .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child, .content - .panel > .table-responsive:last-child > table:last-child > tfoot:last-child > tr:last-child, - .static-content - .panel > .table-responsive:last-child > table:last-child > tfoot:last-child > tr:last-child { + .panel > .table:last-child > tbody:last-child > tr:last-child, + .panel > .table:last-child > tfoot:last-child > tr:last-child, + .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, + .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { border-bottom-left-radius: -1; border-bottom-right-radius: -1; } - .panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, .content .panel > table:last-child > tbody:last-child > tr:last-child td:first-child, - .static-content .panel > table:last-child > tbody:last-child > tr:last-child td:first-child, - .panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, .content - .panel > table:last-child > tbody:last-child > tr:last-child th:first-child, - .static-content - .panel > table:last-child > tbody:last-child > tr:last-child th:first-child, - .panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, .content - .panel > table:last-child > tfoot:last-child > tr:last-child td:first-child, - .static-content - .panel > table:last-child > tfoot:last-child > tr:last-child td:first-child, - .panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, .content - .panel > table:last-child > tfoot:last-child > tr:last-child th:first-child, - .static-content - .panel > table:last-child > tfoot:last-child > tr:last-child th:first-child, - .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, .content - .panel > .table-responsive:last-child > table:last-child > tbody:last-child > tr:last-child td:first-child, - .static-content - .panel > .table-responsive:last-child > table:last-child > tbody:last-child > tr:last-child td:first-child, - .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, .content - .panel > .table-responsive:last-child > table:last-child > tbody:last-child > tr:last-child th:first-child, - .static-content - .panel > .table-responsive:last-child > table:last-child > tbody:last-child > tr:last-child th:first-child, - .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, .content - .panel > .table-responsive:last-child > table:last-child > tfoot:last-child > tr:last-child td:first-child, - .static-content - .panel > .table-responsive:last-child > table:last-child > tfoot:last-child > tr:last-child td:first-child, - .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child, .content - .panel > .table-responsive:last-child > table:last-child > tfoot:last-child > tr:last-child th:first-child, - .static-content - .panel > .table-responsive:last-child > table:last-child > tfoot:last-child > tr:last-child th:first-child { + .panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, + .panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, + .panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, + .panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, + .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, + .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, + .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, + .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { border-bottom-left-radius: -1; } - .panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, .content .panel > table:last-child > tbody:last-child > tr:last-child td:last-child, - .static-content .panel > table:last-child > tbody:last-child > tr:last-child td:last-child, - .panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, .content - .panel > table:last-child > tbody:last-child > tr:last-child th:last-child, - .static-content - .panel > table:last-child > tbody:last-child > tr:last-child th:last-child, - .panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, .content - .panel > table:last-child > tfoot:last-child > tr:last-child td:last-child, - .static-content - .panel > table:last-child > tfoot:last-child > tr:last-child td:last-child, - .panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, .content - .panel > table:last-child > tfoot:last-child > tr:last-child th:last-child, - .static-content - .panel > table:last-child > tfoot:last-child > tr:last-child th:last-child, - .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, .content - .panel > .table-responsive:last-child > table:last-child > tbody:last-child > tr:last-child td:last-child, - .static-content - .panel > .table-responsive:last-child > table:last-child > tbody:last-child > tr:last-child td:last-child, - .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, .content - .panel > .table-responsive:last-child > table:last-child > tbody:last-child > tr:last-child th:last-child, - .static-content - .panel > .table-responsive:last-child > table:last-child > tbody:last-child > tr:last-child th:last-child, - .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, .content - .panel > .table-responsive:last-child > table:last-child > tfoot:last-child > tr:last-child td:last-child, - .static-content - .panel > .table-responsive:last-child > table:last-child > tfoot:last-child > tr:last-child td:last-child, - .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child, .content - .panel > .table-responsive:last-child > table:last-child > tfoot:last-child > tr:last-child th:last-child, - .static-content - .panel > .table-responsive:last-child > table:last-child > tfoot:last-child > tr:last-child th:last-child { + .panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, + .panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, + .panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, + .panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, + .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, + .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, + .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, + .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { border-bottom-right-radius: -1; } -.panel > .panel-body + .table, .content .panel > .panel-body + table, -.static-content .panel > .panel-body + table, +.panel > .panel-body + .table, .panel > .panel-body + .table-responsive, -.panel > .table + .panel-body, .content -.panel > table + .panel-body, -.static-content -.panel > table + .panel-body, +.panel > .table + .panel-body, .panel > .table-responsive + .panel-body { border-top: 1px solid #ddd; } -.panel > .table > tbody:first-child > tr:first-child th, .content .panel > table > tbody:first-child > tr:first-child th, -.static-content .panel > table > tbody:first-child > tr:first-child th, -.panel > .table > tbody:first-child > tr:first-child td, .content -.panel > table > tbody:first-child > tr:first-child td, -.static-content -.panel > table > tbody:first-child > tr:first-child td { +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { border-top: 0; } .panel > .table-bordered, @@ -3706,6 +3522,216 @@ tbody.collapse.in { .modal-lg { width: 900px; } } +.tooltip { + position: absolute; + z-index: 1070; + display: block; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 12px; + font-weight: normal; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); } + .tooltip.in { + opacity: 0.9; + filter: alpha(opacity=90); } + .tooltip.top { + margin-top: -3px; + padding: 5px 0; } + .tooltip.right { + margin-left: 3px; + padding: 0 5px; } + .tooltip.bottom { + margin-top: 3px; + padding: 5px 0; } + .tooltip.left { + margin-left: -3px; + padding: 0 5px; } + +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + text-decoration: none; + background-color: #000; + border-radius: 0; } + +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; } + +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; } + +.tooltip.top-left .tooltip-arrow { + bottom: 0; + right: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; } + +.tooltip.top-right .tooltip-arrow { + bottom: 0; + left: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; } + +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; } + +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; } + +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; } + +.tooltip.bottom-left .tooltip-arrow { + top: 0; + right: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; } + +.tooltip.bottom-right .tooltip-arrow { + top: 0; + left: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; } + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + font-weight: normal; + line-height: 1.42857; + text-align: left; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + white-space: normal; } + .popover.top { + margin-top: -10px; } + .popover.right { + margin-left: 10px; } + .popover.bottom { + margin-top: 10px; } + .popover.left { + margin-left: -10px; } + +.popover-title { + margin: 0; + padding: 8px 14px; + font-size: 14px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; } + +.popover-content { + padding: 9px 14px; } + +.popover > .arrow, .popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; } + +.popover > .arrow { + border-width: 11px; } + +.popover > .arrow:after { + border-width: 10px; + content: ""; } + +.popover.top > .arrow { + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: #999999; + border-top-color: rgba(0, 0, 0, 0.25); + bottom: -11px; } + .popover.top > .arrow:after { + content: " "; + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #fff; } + +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: #999999; + border-right-color: rgba(0, 0, 0, 0.25); } + .popover.right > .arrow:after { + content: " "; + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #fff; } + +.popover.bottom > .arrow { + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999999; + border-bottom-color: rgba(0, 0, 0, 0.25); + top: -11px; } + .popover.bottom > .arrow:after { + content: " "; + top: 1px; + margin-left: -10px; + border-top-width: 0; + border-bottom-color: #fff; } + +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999999; + border-left-color: rgba(0, 0, 0, 0.25); } + .popover.left > .arrow:after { + content: " "; + right: 1px; + border-right-width: 0; + border-left-color: #fff; + bottom: -10px; } + .carousel { position: relative; } @@ -4108,6 +4134,111 @@ tbody.collapse.in { .hidden-print { display: none !important; } } +.rangeslider, +.rangeslider__fill { + display: block; + -moz-box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.3); + -webkit-box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.3); + box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.3); + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + border-radius: 10px; } + +.rangeslider { + background: #e6e6e6; + position: relative; } + +.rangeslider--horizontal { + height: 20px; + width: 100%; } + +.rangeslider--vertical { + width: 20px; + min-height: 150px; + max-height: 100%; + height: 100%; } + +.rangeslider--disabled { + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40); + opacity: 0.4; } + +.rangeslider__fill { + background: #00ff00; + position: absolute; } + +.rangeslider--horizontal .rangeslider__fill { + top: 0; + height: 100%; } + +.rangeslider--vertical .rangeslider__fill { + bottom: 0; + width: 100%; } + +.rangeslider__handle { + background: white; + border: 1px solid #ccc; + cursor: pointer; + display: inline-block; + width: 40px; + height: 40px; + position: absolute; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMC4xIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4g"); + background-size: 100%; + background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(100%, rgba(0, 0, 0, 0.1))); + background-image: -moz-linear-gradient(rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.1)); + background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.1)); + background-image: linear-gradient(rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.1)); + -moz-box-shadow: 0 0 8px rgba(0, 0, 0, 0.3); + -webkit-box-shadow: 0 0 8px rgba(0, 0, 0, 0.3); + box-shadow: 0 0 8px rgba(0, 0, 0, 0.3); + -moz-border-radius: 50%; + -webkit-border-radius: 50%; + border-radius: 50%; } + +.rangeslider__handle:after { + content: ""; + display: block; + width: 18px; + height: 18px; + margin: auto; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjEzIi8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjZmZmZmZmIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA=="); + background-size: 100%; + background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(0, 0, 0, 0.13)), color-stop(100%, rgba(255, 255, 255, 0))); + background-image: -moz-linear-gradient(rgba(0, 0, 0, 0.13), rgba(255, 255, 255, 0)); + background-image: -webkit-linear-gradient(rgba(0, 0, 0, 0.13), rgba(255, 255, 255, 0)); + background-image: linear-gradient(rgba(0, 0, 0, 0.13), rgba(255, 255, 255, 0)); + -moz-border-radius: 50%; + -webkit-border-radius: 50%; + border-radius: 50%; } + +.rangeslider__handle:active, .rangeslider--active .rangeslider__handle { + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjEiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMC4xMiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA=="); + background-size: 100%; + background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(0, 0, 0, 0.1)), color-stop(100%, rgba(0, 0, 0, 0.12))); + background-image: -moz-linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.12)); + background-image: -webkit-linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.12)); + background-image: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.12)); } + +.rangeslider--horizontal .rangeslider__handle { + top: -10px; + touch-action: pan-y; + -ms-touch-action: pan-y; } + +.rangeslider--vertical .rangeslider__handle { + left: -10px; + touch-action: pan-x; + -ms-touch-action: pan-x; } + +input[type="range"]:focus + .rangeslider .rangeslider__handle { + -moz-box-shadow: 0 0 8px rgba(255, 0, 255, 0.9); + -webkit-box-shadow: 0 0 8px rgba(255, 0, 255, 0.9); + box-shadow: 0 0 8px rgba(255, 0, 255, 0.9); } + .admonition { padding: 15px; margin-bottom: 20px; @@ -4144,6 +4275,13 @@ tbody.collapse.in { text-decoration: underline; } .alert a:hover { color: inherit; } + .alert .btn { + text-decoration: inherit; + white-space: normal; } + .alert .btn-primary, .alert .btn-mapzen, + .alert .btn-primary:hover, + .alert .btn-mapzen:hover { + color: white; } .alert-dismissible { padding-right: 35px; } @@ -4178,6 +4316,11 @@ tbody.collapse.in { border-color: rgba(153, 52, 52, 0.3); color: rgba(153, 52, 52, 0.8); } +.alert-upsell { + background-color: #EEE7F8; + border-color: rgba(173, 156, 194, 0.4); + color: #635378; } + @media (max-width: 767px) { .authors img.avatar { display: none; } } @@ -4188,7 +4331,7 @@ img.avatar { height: 64px; margin-right: 0.5em; padding: 2px; - border: 1.5px solid #1E0E33; + border: 2px solid #1E0E33; border-radius: 50%; box-shadow: inset 0 0 0 3px white; } @@ -4197,7 +4340,7 @@ img.avatar-about { width: 42px; height: 42px; padding: 2px; - border: 1.5px solid #1E0E33; + border: 2px solid #1E0E33; border-radius: 50%; box-shadow: inset 0 0 0 3px white; z-index: 1; } @@ -4209,7 +4352,7 @@ img.avatar-about { /*inside of dashboard*/ .profile-picture, img.dashboard-profile-pic { border-radius: 50%; - border: 1.5px solid #1E0E33; + border: 2px solid #1E0E33; padding: 2px; } img.dashboard-profile-pic { @@ -4217,50 +4360,46 @@ img.dashboard-profile-pic { width: 60px; height: 60px; float: left; - box-shadow: 30px #FFF inset; } + box-shadow: 30px white inset; } /* button styles */ .btn { border-radius: 5px; border: 0; text-transform: uppercase; - font-weight: 600; + font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; + font-weight: 700; padding: 12px 24px; } + .btn.disabled, .btn[disabled] { + background-color: #898989; + opacity: 1; + filter: alpha(opacity=100); } input[type="search"] + .btn { padding: 0; } -.btn-mapzen { - background-color: #1E0E33; - color: #ffffff; } - .btn-mapzen:hover, .btn-mapzen:focus { - background-color: #635378; - color: #f8f8f8; } - -.btn-mapzen-alt { - border-color: #6ea0a4; - background-color: #6ea0a4; - color: #fff; - text-shadow: none; - text-transform: uppercase; - font-weight: 400; } - .btn-mapzen-alt:hover, .btn-mapzen-alt:focus { - border-color: #385d5c; - background-color: #385d5c; - color: #fff; } - -.btn-darkpurple { - background-color: #1E0E33; - color: #ffffff; } - .btn-darkpurple:hover, .btn-darkpurple:focus { - background-color: #635378; - color: #f8f8f8; } +.btn-primary:hover, .btn-mapzen:hover, .btn-primary:focus, .btn-mapzen:focus { + background-color: #2C1E3F; } -.btn-white, footer .btn-transparent, nav .btn-mapzen { +.btn-inverse, .btn-white { background-color: #ffffff; color: #1E0E33; } - .btn-white:hover, footer .btn-transparent:hover, nav .btn-mapzen:hover, .btn-white:focus, footer .btn-transparent:focus, nav .btn-mapzen:focus { - background-color: #EEE7F8; } + .btn-inverse:hover, .btn-white:hover, .btn-inverse:focus, .btn-white:focus { + background-color: #EEE7F8; + color: #1E0E33; } + .btn-inverse.disabled, .disabled.btn-white, .btn-inverse[disabled], [disabled].btn-white { + color: #1E0E33; } + +.btn-secondary, .btn-transparent { + background: white; + border: 1px solid #1E0E33; + color: #1E0E33; } + .btn-secondary:hover, .btn-transparent:hover, .btn-secondary:focus, .btn-transparent:focus { + background-color: #EEE7F8; + color: #1E0E33; } + .btn-secondary.disabled, .disabled.btn-transparent, .btn-secondary[disabled], [disabled].btn-transparent { + border-color: #898989; + color: #1E0E33; } .btn-with-arrow { background-color: transparent; @@ -4270,21 +4409,19 @@ input[type="search"] + .btn { padding-left: 0; padding-right: 32px; font-size: 0.85em; + font-weight: 700; background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMS42IiBoZWlnaHQ9IjguNjQiIHZpZXdCb3g9IjAgMCAyMS42IDguNjQiPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsPSIjRkY3QjdCIiBkPSJNMjAuOCA0LjMybC03IDMuNXYtN3oiLz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZmlsbD0iI0ZGN0I3QiIgZD0iTS44IDIuODJoMTR2M0guOHoiLz48L3N2Zz4="); background-repeat: no-repeat; background-position: right center; } .btn-with-arrow:hover, .btn-with-arrow:focus { color: #FF4947; background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMS42IiBoZWlnaHQ9IjguNjQiIHZpZXdCb3g9IjAgMCAyMS42IDguNjQiPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsPSIjRkY0OTQ3IiBkPSJNMjAuOCA0LjMybC03IDMuNXYtN3oiLz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZmlsbD0iI0ZGNDk0NyIgZD0iTS44IDIuODJoMTR2M0guOHoiLz48L3N2Zz4="); } - -.btn-transparent { - background: transparent; - border: 1px solid #444; - color: #444; } - .btn-transparent:hover, .btn-transparent:focus { - background-color: #e5e5e5; - border-color: #444; - color: #444; } + .btn-with-arrow:active { + box-shadow: none; } + .btn-with-arrow.disabled, .btn-with-arrow[disabled] { + color: #777777; + background-color: transparent; + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMS42IiBoZWlnaHQ9IjguNjQiIHZpZXdCb3g9IjAgMCAyMS42IDguNjQiPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsPSIjNzc3Nzc3IiBkPSJNMjAuOCA0LjMybC03IDMuNXYtN3oiLz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZmlsbD0iIzc3Nzc3NyIgZD0iTS44IDIuODJoMTR2M0guOHoiLz48L3N2Zz4="); } .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { border-bottom-right-radius: 5px; @@ -4314,6 +4451,21 @@ input[type="search"] + .btn { .btn-group { margin-bottom: -10px; } +.btn + .btn { + margin-left: 10px; } + +.btn-flexible { + width: 100%; } + .btn-flexible + .btn-flexible { + margin-top: 12px; + margin-left: 0; } + @media (min-width: 768px) { + .btn-flexible { + width: auto; } + .btn-flexible + .btn-flexible { + margin-top: auto; + margin-left: 10px; } } + .byline { color: #666666; font-size: 14px; } @@ -4423,15 +4575,13 @@ input[type="search"] + .btn { .breadcrumb li::before { font: normal normal normal 14px/1 FontAwesome; } .breadcrumb li > a { - font-weight: 600; } + font-weight: 700; } .breadcrumb > li + li:before { content: "" " "; } -h6.category-title { - font-weight: 600; - font-size: 1.5em; - line-height: 1.5; } +h3.category-title { + text-transform: capitalize; } .category-info-container { width: 100%; @@ -4539,14 +4689,13 @@ img.avatar-byline { height: 42px; margin-right: 0.5em; padding: 2px; - border: 1.5px solid #1E0E33; + border: 2px solid #1E0E33; border-radius: 50%; box-shadow: inset 0 0 0 3px white; } .featured-item { padding-top: 30px; padding-bottom: 10px; - font-weight: 300; font-size: 24px; line-height: 1.4; } @@ -4624,6 +4773,10 @@ img.avatar-byline { line-height: 32px; font-weight: 300; } +.cta-primary { + padding-top: 72px; + padding-bottom: 72px; } + .cta-container { background-color: #f8f8f8; padding: 25px 20px; @@ -4675,9 +4828,20 @@ img.avatar-byline { align-items: center; justify-content: center; padding: 40px 20px; } - .documentation-hero h1 { + .documentation-hero .documentation-header { + /* former _documentation.scss documentation-hero h1*/ padding-top: 20px; - color: #fff; } + color: #fff; + /* former _documentation.scss h1*/ + font-weight: 700; + font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; + /* former _typography.scss */ + font-size: 48px; + line-height: 1.2em; + /* scale back margins on mobile */ } + @media (max-width: 768px) { + .documentation-hero .documentation-header { + font-size: 42px; } } .documentation-hero p { margin-top: 24px; } @@ -4693,6 +4857,9 @@ img.avatar-byline { font-size: 16px; word-wrap: break-word; overflow-wrap: break-word; + /*smaller for documentation than styleguide*/ + /*smaller for documentation than styleguide*/ + /*smaller for documentation than styleguide*/ /* // allows hash links to navigate to proper location h1[id]:before, @@ -4734,9 +4901,12 @@ img.avatar-byline { margin-bottom: 24px; } .documentation-content h1, .documentation-content h2, .documentation-content h3, .documentation-content h4, .documentation-content h5, .documentation-content h6 { position: relative; } - @media (min-width: 767px) { - .documentation-content { - /* no more special header for documentation */ } } + .documentation-content h1 { + font-size: 36px; } + .documentation-content h2 { + font-size: 24px; } + .documentation-content h3 { + font-size: 20px; } .documentation-content section { margin-top: -50px; padding-top: 50px; @@ -4790,32 +4960,52 @@ h5:hover .headerlink, h6:hover .headerlink { display: inline-block; } +/* This is for 404 page */ +.error-page-logo { + width: 180px; } + +#physics-wrapper { + height: 300px; + margin-top: 50px; + margin-bottom: 50px; + border-bottom: 3px solid #666; } + body.no-footer #footer, body.no-footer footer { display: none; } +.footer-no-background { + color: #1E0E33; } + .footer-no-background a { + color: #FF7B7B; } + .footer-background { + color: #AD9CC2; padding-top: 50px; background-color: #1E0E33; - border-top: 10px solid #FF7B7B; } + background: url("/common/styleguide/images/background/contour_darkpurple_xs.png"); + background-size: cover; + border-top: 5px solid #FF7B7B; } .footer-background a, .footer-background a:active, .footer-background a:visited { color: #EEE7F8; } .footer-background a:hover { color: white; } - .footer-background img, .footer-background .slogan { - display: none; } - -footer { - color: #AD9CC2; } + @media (min-width: 480px) { + .footer-background { + background-image: url("/common/styleguide/images/background/contour_darkpurple_sm.png"); } } + @media (min-width: 768px) { + .footer-background { + background-image: url("/common/styleguide/images/background/contour_darkpurple2_lg.png"); + background-attachment: fixed; + background-position: center center; } } .footer-menu { font-size: 13px; line-height: 1.8; } .footer-menu h6 { font-size: inherit; - font-weight: 600; text-transform: uppercase; } .footer-menu h6:not(:first-of-type) { margin-top: 20px; } @@ -4830,11 +5020,6 @@ footer { .footer-menu .fa { margin-right: 0.25em; } -footer > div:first-child { - color: #1E0E33; } - footer > div:first-child a { - color: #FF7B7B; } - .footer-section { padding-left: 30px; } @media (min-width: 480px) { @@ -4844,15 +5029,34 @@ footer > div:first-child { .footer-section { padding-left: 80px; } } +.compass-logo { + width: 36px; + height: 36px; + background-image: url("https://mapzen.com/common/styleguide/images/logos/mapzen-logo-compass-white.png"); + background-repeat: no-repeat; + background-size: 36px; + margin: 6px auto; } + .form-group-header { font-weight: bold; margin-bottom: 15px; } .form-group { + position: relative; margin-bottom: 24px; } +/* we want to place recover password link on top of password field, but with higher tabindex */ +.form-group > .recover-password-link { + position: absolute; + top: 0; + right: 0; } + +/* It is less likely that bold text is wanted for checkbox label */ +input[type="checkbox"] + label { + font-weight: 400; } + label { - font-weight: normal; } + font-weight: 700; } .wide label { margin: 5px 0; } @@ -4867,7 +5071,7 @@ input[type="text"], input[type="email"], input[type="password"] { height: 41px; padding: 8px 5px; border: 1px solid #ccc; - border-radius: 0; + border-radius: 5px; -webkit-appearance: none; } input[type="text"]:-moz-focusring, @@ -4893,7 +5097,7 @@ textarea { padding: 5px; height: 6em; border: 1px solid #ccc; - border-radius: 0; + border-radius: 5px; -webkit-appearance: none; } .has-success .control-label { @@ -4916,13 +5120,13 @@ textarea { input[type="search"] { height: 41px; - background-image: url(data:image/svg+xml,%3Csvg%20version%3D%271.1%27%20id%3D%27Layer_1%27%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Ctitle%3Esearch%3C/title%3E%3Ccircle%20fill%3D%27none%27%20stroke%3D%27%23666666%27%20stroke-width%3D%272.2677%27%20stroke-miterlimit%3D%2710%27%20cx%3D%279.99%27%20cy%3D%276.512%27%20r%3D%275.5%27/%3E%3Cline%20fill%3D%27none%27%20stroke%3D%27%23666666%27%20stroke-width%3D%272.2677%27%20stroke-miterlimit%3D%2710%27%20x1%3D%2713.5%27%20y1%3D%2710.637%27%20x2%3D%2716.789%27%20y2%3D%2714.173%27/%3E%3C/svg%3E%0A); + background-image: url(data:image/svg+xml,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Ctitle%3Esearch%3C/title%3E%3Ccircle%20fill%3D%27none%27%20stroke%3D%27%23666666%27%20stroke-width%3D%272.2677%27%20stroke-miterlimit%3D%2710%27%20cx%3D%279.99%27%20cy%3D%276.512%27%20r%3D%275.5%27/%3E%3Cline%20fill%3D%27none%27%20stroke%3D%27%23666666%27%20stroke-width%3D%272.2677%27%20stroke-miterlimit%3D%2710%27%20x1%3D%2713.5%27%20y1%3D%2710.637%27%20x2%3D%2716.789%27%20y2%3D%2714.173%27/%3E%3C/svg%3E%0A); background-repeat: no-repeat; background-size: 19px 19px; background-position: 3px 14px; padding: 8px 2px 8px 26px; border: 1px solid #ccc; - border-radius: 0; } + border-radius: 5px; } .form-group { /* we have hidden type of search for google/duckduckgo search */ @@ -4930,6 +5134,8 @@ input[type="search"] { .form-group input[type="hidden"]:first-child + input { border-top-left-radius: 5px; border-bottom-left-radius: 5px; } + .form-group input[type="search"] { + border-radius: 0; } .form-group input[type="search"]:first-child:not(:last-child) { border-top-left-radius: 5px; border-bottom-left-radius: 5px; } @@ -4966,7 +5172,7 @@ select { background-size: 25px auto; background-color: white; padding: 8px 38px 8px 10px; - border-radius: 0; } + border-radius: 5px; } select::-ms-expand { display: none; } @@ -4990,7 +5196,8 @@ input[type="radio"] + *:before { content: ' '; display: inline-block; box-sizing: content-box; - border: 1px solid white; } + border: 1px solid white; + border-radius: 5px; } input[type="checkbox"]:focus + *:before, input[type="radio"]:focus + *:before { @@ -4998,65 +5205,85 @@ input[type="radio"]:focus + *:before { box-shadow: 0px 0px 5px 0px #70ace9; } input[type="checkbox"] + *:before { - background-image: url(data:image/svg+xml,%3Csvg%20id%3D%27Layer_1%27%20data-name%3D%27Layer%201%27%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2036%2036%27%3E%3Ctitle%3Echeckbox%3C/title%3E%3Cpath%20d%3D%27M31.75%2C4.25v27.5H4.25V4.25h27.5M36%2C0H0V36H36V0h0Z%27%20transform%3D%27translate%280%200%29%27%20style%3D%27fill%3A%23cdcccc%27/%3E%3C/svg%3E); } + background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2036%2036%27%3E%3Ctitle%3Echeckbox%3C/title%3E%3Cpath%20d%3D%27M31.75%2C4.25v27.5H4.25V4.25h27.5M36%2C0H0V36H36V0h0Z%27%20transform%3D%27translate%280%200%29%27%20style%3D%27fill%3A%23cdcccc%27/%3E%3C/svg%3E); } input[type="checkbox"]:hover + *:before { - background-image: url(data:image/svg+xml,%3Csvg%20data-name%3D%27Layer%201%27%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2036%2036%27%3E%3Ctitle%3Echeckbox-hover%3C/title%3E%3Cpath%20d%3D%27M31.75%204.25v27.5H4.25V4.25h27.5M36%200H0v36h36V0z%27%20fill%3D%27%23989898%27/%3E%3C/svg%3E); } + background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2036%2036%27%3E%3Ctitle%3Echeckbox-hover%3C/title%3E%3Cpath%20d%3D%27M31.75%204.25v27.5H4.25V4.25h27.5M36%200H0v36h36V0z%27%20fill%3D%27%23989898%27/%3E%3C/svg%3E); } input[type="checkbox"]:checked + *:before { - background-image: url(data:image/svg+xml,%3Csvg%20data-name%3D%27Layer%201%27%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2036%2036%27%3E%3Ctitle%3Echeckbox-checked%3C/title%3E%3Cpath%20fill%3D%27%23553831%27%20d%3D%27M0%200h36v36H0z%27/%3E%3Cpath%20fill%3D%27none%27%20stroke%3D%27%23fff%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%20stroke-width%3D%274.252%27%20d%3D%27M26.19%2011.16l-9.17%2013.68-7.21-5.22%27/%3E%3C/svg%3E); } - -input[type="checkbox"]:checked:hover + *:before { - background-image: url(data:image/svg+xml,%3Csvg%20data-name%3D%27Layer%201%27%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2036%2036%27%3E%3Ctitle%3Echeckbox-focused%3C/title%3E%3Cpath%20fill%3D%27%233c231e%27%20d%3D%27M0%200h36v36H0z%27/%3E%3Cpath%20fill%3D%27none%27%20stroke%3D%27%23fff%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%20stroke-width%3D%274.252%27%20d%3D%27M26.19%2011.16l-9.17%2013.68-7.21-5.22%27/%3E%3C/svg%3E); } + background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2036%2036%27%3E%3Ctitle%3Echeckbox-checked%3C/title%3E%3Cpath%20fill%3D%27%232C1E3F%27%20d%3D%27M0%200h36v36H0z%27/%3E%3Cpath%20fill%3D%27none%27%20stroke%3D%27%23fff%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%20stroke-width%3D%274.252%27%20d%3D%27M26.19%2011.16l-9.17%2013.68-7.21-5.22%27/%3E%3C/svg%3E); + background-color: #2C1E3F; } input[type="radio"] + *:before { - background-image: url(data:image/svg+xml,%3Csvg%20id%3D%27Layer_1%27%20data-name%3D%27Layer%201%27%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2035%2035%27%3E%3Ctitle%3EUntitled-5%3C/title%3E%3Cpath%20d%3D%27M18%2C4.75A13.25%2C13.25%2C0%2C1%2C1%2C4.75%2C18%2C13.26%2C13.26%2C0%2C0%2C1%2C18%2C4.75M18%2C0.5A17.5%2C17.5%2C0%2C1%2C0%2C35.5%2C18%2C17.5%2C17.5%2C0%2C0%2C0%2C18%2C.5h0Z%27%20transform%3D%27translate%28-0.5%20-0.5%29%27%20style%3D%27fill%3A%23cdcccc%27/%3E%3C/svg%3E); + background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2035%2035%27%3E%3Ctitle%3EUntitled-5%3C/title%3E%3Cpath%20d%3D%27M18%2C4.75A13.25%2C13.25%2C0%2C1%2C1%2C4.75%2C18%2C13.26%2C13.26%2C0%2C0%2C1%2C18%2C4.75M18%2C0.5A17.5%2C17.5%2C0%2C1%2C0%2C35.5%2C18%2C17.5%2C17.5%2C0%2C0%2C0%2C18%2C.5h0Z%27%20transform%3D%27translate%28-0.5%20-0.5%29%27%20style%3D%27fill%3A%23cdcccc%27/%3E%3C/svg%3E); border-radius: 10px; } input[type="radio"]:hover + *:before { - background-image: url(data:image/svg+xml,%3Csvg%20id%3D%27Layer_1%27%20data-name%3D%27Layer%201%27%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2035%2035%27%3E%3Ctitle%3EUntitled-6%3C/title%3E%3Cpath%20d%3D%27M18%2C4.75A13.25%2C13.25%2C0%2C1%2C1%2C4.75%2C18%2C13.26%2C13.26%2C0%2C0%2C1%2C18%2C4.75M18%2C0.5A17.5%2C17.5%2C0%2C1%2C0%2C35.5%2C18%2C17.5%2C17.5%2C0%2C0%2C0%2C18%2C.5h0Z%27%20transform%3D%27translate%28-0.5%20-0.5%29%27%20style%3D%27fill%3A%23989898%27/%3E%3C/svg%3E); } + background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2035%2035%27%3E%3Ctitle%3EUntitled-6%3C/title%3E%3Cpath%20d%3D%27M18%2C4.75A13.25%2C13.25%2C0%2C1%2C1%2C4.75%2C18%2C13.26%2C13.26%2C0%2C0%2C1%2C18%2C4.75M18%2C0.5A17.5%2C17.5%2C0%2C1%2C0%2C35.5%2C18%2C17.5%2C17.5%2C0%2C0%2C0%2C18%2C.5h0Z%27%20transform%3D%27translate%28-0.5%20-0.5%29%27%20style%3D%27fill%3A%23989898%27/%3E%3C/svg%3E); } input[type="radio"]:checked + *:before { - background-image: url(data:image/svg+xml,%3Csvg%20id%3D%27Layer_1%27%20data-name%3D%27Layer%201%27%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2035%2035%27%3E%3Ctitle%3EUntitled-7%3C/title%3E%3Cpath%20d%3D%27M18%2C4.75A13.25%2C13.25%2C0%2C1%2C1%2C4.75%2C18%2C13.26%2C13.26%2C0%2C0%2C1%2C18%2C4.75M18%2C0.5A17.5%2C17.5%2C0%2C1%2C0%2C35.5%2C18%2C17.5%2C17.5%2C0%2C0%2C0%2C18%2C.5h0Z%27%20transform%3D%27translate%28-0.5%20-0.5%29%27%20style%3D%27fill%3A%23553831%27/%3E%3Ccircle%20cx%3D%2717.5%27%20cy%3D%2717.5%27%20r%3D%279%27%20style%3D%27fill%3A%23553831%27/%3E%3C/svg%3E); } - -input[type="radio"]:checked:hover + *:before { - background-image: url(data:image/svg+xml,%3Csvg%20id%3D%27Layer_1%27%20data-name%3D%27Layer%201%27%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2034.97%2034.97%27%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%233c231e%3B%7D%3C/style%3E%3C/defs%3E%3Ctitle%3EUntitled-8%3C/title%3E%3Cpath%20class%3D%27cls-1%27%20d%3D%27M19%2C5.77A13.23%2C13.23%2C0%2C1%2C1%2C5.77%2C19%2C13.25%2C13.25%2C0%2C0%2C1%2C19%2C5.77m0-4.25A17.48%2C17.48%2C0%2C1%2C0%2C36.49%2C19%2C17.48%2C17.48%2C0%2C0%2C0%2C19%2C1.51h0Z%27%20transform%3D%27translate%28-1.51%20-1.51%29%27/%3E%3Ccircle%20class%3D%27cls-1%27%20cx%3D%2717.49%27%20cy%3D%2717.48%27%20r%3D%279%27/%3E%3C/svg%3E); } + background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2035%2035%27%3E%3Ctitle%3EUntitled-7%3C/title%3E%3Cpath%20d%3D%27M18%2C4.75A13.25%2C13.25%2C0%2C1%2C1%2C4.75%2C18%2C13.26%2C13.26%2C0%2C0%2C1%2C18%2C4.75M18%2C0.5A17.5%2C17.5%2C0%2C1%2C0%2C35.5%2C18%2C17.5%2C17.5%2C0%2C0%2C0%2C18%2C.5h0Z%27%20transform%3D%27translate%28-0.5%20-0.5%29%27%20style%3D%27fill%3A%232C1E3F%27/%3E%3Ccircle%20cx%3D%2717.5%27%20cy%3D%2717.5%27%20r%3D%279%27%20style%3D%27fill%3A%232C1E3F%27/%3E%3C/svg%3E); } input[type="range"] { -webkit-appearance: none; cursor: pointer; - padding: 2px; - background-color: white; - border: 1px solid #ccc; - border-radius: 15px; } + padding: 5px 0; } + +input[type=range]::-webkit-slider-runnable-track { + height: 5px; + background-color: #EEE7F8; + border: none; + border-radius: 25px; } input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; height: 15px; - width: 25px; - border-radius: 10px; - background: #563630; } + width: 15px; + margin-top: -5px; + border-radius: 50%; + border-width: 0; + background: #1E0E33; } input[type="range"]::-moz-range-thumb { height: 15px; - width: 25px; - border-radius: 10px; - background: #563630; } + width: 15px; + border-radius: 50%; + border-width: 0; + background: #1E0E33; } input[type="range"]::-ms-thumb { height: 15px; - width: 25px; - border-radius: 10px; - background: #563630; } + width: 15px; + border-radius: 50%; + border-width: 0; + background: #1E0E33; } input[type=range]::-moz-range-track { - opacity: 0; } + height: 5px; + background-color: #EEE7F8; + border: none; + border-radius: 25px; } + +input[type=range]::-moz-range-progress { + background-color: #985FDD; + height: 5px; + border-radius: 25px; } + +input[type="range"]::-ms-fill-lower { + background-color: #985FDD; + border-radius: 25px; } -input[type="range"]::-ms-fill-lower, input[type="range"]::-ms-fill-upper { - display: none; } + background-color: #EEE7F8; + border-radius: 25px; } + +input[type="range"]::-ms-track { + height: 5px; + background: transparent; + border-color: transparent; + border-width: 6px 0; + color: transparent; } -input[type="range"]::-ms-track, input[type="range"]::-ms-ticks-after, input[type="range"]::-ms-ticks-before { color: transparent; @@ -5125,9 +5352,8 @@ html { height: 100%; } body { - font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; + font-family: "Open Sans", Helvetica, Arial, sans-serif; font-weight: 400; - background: transparent; overflow-x: hidden; width: 100%; height: 100%; } @@ -5142,73 +5368,73 @@ hr { overflow: inherit; } .headroom { - margin-top: 10px; } + margin-top: 12px; } @media (min-width: 768px) { .headroom { - margin-top: 20px; } } + margin-top: 12px; } } .headroom-med { - margin-top: 15px; } + margin-top: 18px; } @media (min-width: 768px) { .headroom-med { - margin-top: 30px; } } + margin-top: 24px; } } .headroom-large { - margin-top: 20px; } + margin-top: 24px; } @media (min-width: 768px) { .headroom-large { - margin-top: 40px; } } + margin-top: 48px; } } .headroom-extra-large { - margin-top: 50px; } + margin-top: 48px; } @media (min-width: 768px) { .headroom-extra-large { - margin-top: 100px; } } + margin-top: 72px; } } .footroom { - margin-bottom: 10px; } + margin-bottom: 12px; } @media (min-width: 768px) { .footroom { - margin-bottom: 20px; } } + margin-bottom: 12px; } } .footroom-med { - margin-bottom: 15px; } + margin-bottom: 18px; } @media (min-width: 768px) { .footroom-med { - margin-bottom: 30px; } } + margin-bottom: 24px; } } .footroom-large { - margin-bottom: 20px; } + margin-bottom: 24px; } @media (min-width: 768px) { .footroom-large { - margin-bottom: 40px; } } + margin-bottom: 48px; } } .footroom-extra-large { - margin-bottom: 50px; } + margin-bottom: 48px; } @media (min-width: 768px) { .footroom-extra-large { - margin-bottom: 100px; } } + margin-bottom: 72px; } } .neg-margin-top { - margin-top: -20px; } + margin-top: -24px; } @media (min-width: 768px) { .neg-margin-top { - margin-top: -30px; } } + margin-top: -24px; } } .hor-margin { - margin-left: 20px; - margin-right: 20px; } + margin-left: 24px; + margin-right: 24px; } @media (min-width: 768px) { .hor-margin { - margin-left: 40px; - margin-right: 40px; } } + margin-left: 48px; + margin-right: 48px; } } .vert-pad { - padding-top: 30px; - padding-bottom: 10px; } + padding-top: 24px; + padding-bottom: 12px; } .horz-pad { - padding: 0px 15px; } + padding: 0px 12px; } .no_margin, .no-margin { @@ -5224,15 +5450,27 @@ hr { @media only screen and (min-width: 992px) { .hor-pad-left { - padding-left: 40px; + padding-left: 48px; padding-right: 0; } } @media only screen and (min-width: 992px) { .hor-pad-right { padding-left: 0; - padding-right: 40px; } } + padding-right: 48px; } } -.blue-text { +@media (min-width: 768px) { + .col-sm-no-padding { + padding: 0px; } } + +@media (min-width: 992px) { + .col-md-no-padding { + padding: 0px; } } + +@media (min-width: 1200px) { + .col-lg-no-padding { + padding: 0px; } } + +.blue-text { color: #6ea0a4; } .red-text { @@ -5245,10 +5483,49 @@ hr { .dark-gray-text { color: #333333; } -.table.icons > tbody > tr > td, .content table.icons > tbody > tr > td, -.static-content table.icons > tbody > tr > td { +.text-deemphasize { + color: #cccccc; } + +.background-light { + background-color: #f8f8f8; } + +.table.icons > tbody > tr > td { vertical-align: middle; } +.icon, .icon-sm, .icon-lg { + width: 16px; + height: 16px; + background-repeat: no-repeat; + background-position: center center; + background-size: contain; + vertical-align: text-top; } + +span.icon, span.icon-sm, span.icon-lg { + display: inline-block; + margin-left: 0.25em; + margin-right: 0.25em; } + span.icon:first-child, span.icon-sm:first-child, span.icon-lg:first-child { + margin-left: 0; } + span.icon:last-child, span.icon-sm:last-child, span.icon-lg:last-child { + margin-right: 0; } + +.icon-sm { + width: 24px; + height: 24px; } + +.icon-lg { + width: 60px; + height: 60px; } + +.icon-award-ribbon-circle { + background-image: url("https://mapzen.com/common/styleguide/images/icons/award-ribbon-circle.svg"); } + +.icon-dollar-sign-circle { + background-image: url("https://mapzen.com/common/styleguide/images/icons/dollar-sign-circle.svg"); } + +.icon-folding-map-circle { + background-image: url("https://mapzen.com/common/styleguide/images/icons/folding-map-circle.svg"); } + .leaflet-control-attribution a { font-weight: normal; } @@ -5262,25 +5539,24 @@ ol.legal-terms { ol.legal-terms > li:before { content: counter(legal-counter) "."; counter-increment: legal-counter; - font-family: "Open Sans", Helvetica, Arial, sans-serif; + font-weight: 700; font-size: 1.2em; - font-weight: 600; - color: #666666; + line-height: 1em; position: absolute; left: -40px; } -article ul li { +.list-checkmarks { list-style: none; - text-indent: -0.8em; } - -article ul li::before { - content: ' • '; - font-size: 15px; - vertical-align: middle; - padding-right: 5px; } - -article ul li.static p { - display: inline; } + padding-left: 0; } + .list-checkmarks li { + margin-bottom: 0.375em; + margin-left: 1.75em; } + .list-checkmarks li:before { + font-family: 'FontAwesome'; + content: '\f058'; + color: #BDA2DD; + padding-right: 0.875em; + margin-left: -1.75em; } .loading-spinner-01 { width: 26px; @@ -5312,30 +5588,28 @@ article ul li.static p { background-repeat: no-repeat; background-image: url("https://cdnjs.cloudflare.com/ajax/libs/leaflet-geocoder-mapzen/1.4.1/images/loading.gif"); } -@media only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2 / 1), only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) { +@media only screen and (-webkit-min-device-pixel-ratio: 1.25), only screen and (min-resolution: 120dpi), only screen and (min-resolution: 1.25dppx) { .loading-spinner-02::before { background-image: url("https://cdnjs.cloudflare.com/ajax/libs/leaflet-geocoder-mapzen/1.4.1/images/loading@2x.gif"); } } +.logos .bright-logo-wrapper { + background-color: #635378; + width: 180px; + margin: 0 auto; + margin-bottom: 20px; } + +.logos .dark-logo-wrapper { + margin-bottom: 20px; } + .logos img.logo-sample { width: 100%; height: auto; max-width: 180px; - margin-bottom: 10px; } - -.logos img.logo-sample-square { - max-width: 120px; } - -@media (max-width: 767px) { - .logos > div:not(:first-child) img.logo-sample { - border-top: 1px solid #e0e0e0; - padding-top: 20px; } } - -@media (min-width: 480px) { - .logos > div:not(:nth-child(-n+2)) img.logo-sample { - border-top: 1px solid #e0e0e0; - padding-top: 20px; } } + padding: 20px; } nav { + font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; + font-weight: 300; width: 100%; height: 50px; -webkit-transform: translate(0, 0); @@ -5350,14 +5624,15 @@ nav { height: 56px; } nav .container { padding: 0px; } } + nav .container-fluid { + max-width: 960px; } nav li { text-transform: uppercase; text-align: center; } - nav .btn-mapzen { - font-weight: 600; + nav .btn-white { padding: 8px 16px; } - nav .btn-mapzen:hover, nav .btn-mapzen:focus { - color: #444; } + nav a { + font-weight: 300; } body:not(.is-scrolling) nav.navbar-fixed-top { top: 0; } @@ -5374,50 +5649,105 @@ body { @media (max-width: 767px) { .navbar-nav { background: rgba(30, 14, 51, 0.9); - margin-top: 0; } + margin-top: 0; + margin-bottom: 0; } + .navbar-nav li { + text-align: left; + border-top: 1px solid #635378; } .navbar-nav li > a { display: inline-block; - background: transparent !important; } } + background: transparent !important; + width: 100%; } + .navbar-nav .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + box-shadow: none; + display: block; } + .navbar-nav .dropdown-menu > li > a, + .navbar-nav .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; } + .navbar-nav .dropdown-menu > li > a { + line-height: 20px; + color: white; } + .navbar-nav .dropdown-menu > li > a:hover, .navbar-nav .dropdown-menu > li > a:focus { + background-image: none; } + .navbar-right { + border-top: 1px solid #635378; } + .navbar-right li { + border-top: none; } + .navbar-right #sign-up { + padding-top: 0; } } .navbar { - border: 0; } + border: 0; + transition: 0.8s; + -webkit-transition: 0.8s; } .navbar-nav > li > a { line-height: 26px; font-size: 14px; } .navbar-fixed-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { - max-height: 360px; } + max-height: 420px; } .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus { padding-bottom: 10px; border-bottom: 5px solid #FF7B7B; } + @media (max-width: 767px) { + .navbar-default .navbar-nav > .active > a, + .navbar-default .navbar-nav > .active > a:hover, + .navbar-default .navbar-nav > .active > a:focus { + border-bottom: 0; + border-left: 5px solid #FF7B7B; } } + +@media (min-width: 768px) { + body.transparent-main-nav nav.navbar { + background: transparent; + padding-top: 12px; + height: 68px; } + body.transparent-main-nav nav.navbar .navbar-nav > .active > a, + body.transparent-main-nav nav.navbar .navbar-nav > .active > a:hover, + body.transparent-main-nav nav.navbar .navbar-nav > .active > a:focus { + border-color: white; } } .navbar-brand { - padding: 8px 15px; } + padding: 9px 10px; } @media (min-width: 768px) { .navbar-brand { - height: 100%; } + height: 100%; + padding: 5px 30px 11px 15px; } .container-fluid .navbar-brand { padding-left: 15px; } } .mapzen-logo { width: 130px; height: 40px; - background-image: url("https://mapzen.com/common/styleguide/images/logos/mapzen-logo-white.png"); + background-image: url("https://mapzen.com/common/styleguide/images/mapzen-logo-stacked.png"); background-repeat: no-repeat; - background-size: 130px; } + background-size: 130px; + background-position: 0 0; } + .mapzen-logo:hover { + background-position: 0 -40px; } @media (max-width: 767px) { .mapzen-logo { - height: 31px; + height: 36px; background-position: 0 0; - background-size: 110px; } } + background-size: 117px; } + .mapzen-logo:hover { + background-position: 0 -36px; } } + @media only screen and (-webkit-min-device-pixel-ratio: 1.25), only screen and (min-resolution: 120dpi), only screen and (min-resolution: 1.25dppx) { + .mapzen-logo { + background-image: url("https://mapzen.com/common/styleguide/images/mapzen-logo-stacked@2x.png"); } } .navbar-nav > li > a#sign-in { min-width: 80px; - max-width: 225px; + max-width: 215px; text-overflow: ellipsis; } @media (min-width: 767px) { @@ -5430,7 +5760,7 @@ body { .navbar-nav > li > a#sign-up > span { line-height: 26px; } -.navbar-nav > li > a > #login-profile { +.navbar-nav > li > a > .login-profile-github { width: 22px; height: 22px; float: left; @@ -5441,99 +5771,55 @@ body { box-sizing: border-box; margin-right: 10px; } +.navbar-nav > li > a > .login-profile-default { + width: 28px; + height: 28px; + float: left; + position: relative; + margin-top: -2px; + border-radius: 50%; + border: 1px solid #EEE7F8; + box-sizing: border-box; + margin-right: 10px; } + .navbar-nav > li > a > .login-txt { float: left; overflow: hidden; - max-width: 160px; + max-width: 135px; white-space: nowrap; text-overflow: ellipsis; } +.navbar-nav > li > a > .login-arrow { + display: none; } + @media (min-width: 768px) { + .navbar-nav > li > a > .login-arrow { + display: inline-block; + margin-left: 6px; + font-weight: 700; } } + .navbar-nav li.active:hover .login-txt { - color: white; } + color: #EEE7F8; } .navbar-nav li.active:focus .login-txt { - color: white; } + color: #EEE7F8; } .navbar-nav li:hover .login-txt { - color: white; } + color: #EEE7F8; } .navbar-nav li a:focus .login-txt { - color: white; } + color: #EEE7F8; } .navbar-nav li.active:hover #login-profile { - border-color: white; } + border-color: #EEE7F8; } .navbar-nav li.active a:focus #login-profile { - border-color: white; } + border-color: #EEE7F8; } .navbar-nav li:hover #login-profile { - border-color: white; } + border-color: #EEE7F8; } .navbar-nav li a:focus #login-profile { - border-color: white; } - -.navbar-nav li.active:hover .compass:before { - border-bottom-color: white; } - -.navbar-nav li.active a:focus .compass:before { - border-bottom-color: white; } - -.navbar-nav li.active:hover .compass:after { - border-top-color: white; } - -.navbar-nav li.active a:focus .compass:after { - border-top-color: white; } - -.navbar-nav li:hover .compass:before { - border-bottom-color: white; } - -.navbar-nav li a:focus .compass:before { - border-bottom-color: white; } - -.navbar-nav li:hover .compass:after { - border-top-color: white; } - -.navbar-nav li a:focus .compass:after { - border-top-color: white; } - -.compass { - width: 22px; - height: 22px; - position: relative; - margin-left: -1px; - /* arm of compass looks off, this is lame solution for the problem */ - margin-top: -1px; - /* same with the line above */ - transform-origin: center center; - transform: rotate(30deg); - transition: all 2s ease; } - .compass:before { - content: ' '; - position: absolute; - left: 7px; - top: 3px; - border-bottom: 8px solid #EEE7F8; - border-left: 4px solid transparent; - border-right: 4px solid transparent; } - .compass:after { - content: ' '; - position: absolute; - left: 7px; - top: 11px; - border-top: 8px solid #EEE7F8; - border-left: 4px solid transparent; - border-right: 4px solid transparent; } - .compass:hover { - transform: rotate(390deg); } - -.compass > .center-dot { - width: 2px; - height: 2px; - background-color: #1E0E33; - z-index: 10; - position: absolute; - top: 10px; - left: 10px; } + border-color: #EEE7F8; } #sign-in + .dropdown-menu > li > a { text-transform: capitalize; } @@ -5545,6 +5831,46 @@ body { #sign-in + .dropdown-menu > li { text-align: left; } } +.navbar-toggle .icon-bar { + width: 22px; + transition: all 0.2s; } + +.navbar-toggle .top-bar { + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + transform: rotate(45deg); + -webkit-transform: 10% 10%; + -moz-transform: 10% 10%; + transform-origin: 10% 10%; } + +.navbar-toggle .middle-bar { + opacity: 0; } + +.navbar-toggle .bottom-bar { + -webkit-transform: rotate(-45deg); + -moz-transform: rotate(-45deg); + transform: rotate(-45deg); + -webkit-transform: 10% 90%; + -moz-transform: 10% 90%; + transform-origin: 10% 90%; } + +.navbar-toggle.collapsed .top-bar, +.navbar-toggle.collapsed .bottom-bar { + -webkit-transform: rotate(0); + -moz-transform: rotate(0); + transform: rotate(0); } + +.navbar-toggle.collapsed .middle-bar { + opacity: 1; } + +.newsletter-cta-container form { + padding-top: 4px; } + +.newsletter-cta-container input[type="email"] { + height: 43px; + /* To match height of submit button */ + margin-bottom: 8px; } + .pagination { display: table; table-layout: fixed; @@ -5613,14 +5939,6 @@ body { width: auto; padding: 0px; } -@media (min-width: 992px) { - .content .table-wrapper, - .static-content .table-wrapper { - margin-left: -10%; - margin-right: 10%; - max-width: 120%; - width: 120%; } } - .content .footnotes ol, .static-content .footnotes ol { font-size: 14px; @@ -5639,6 +5957,13 @@ body { display: inline-block; pointer-events: none; } +@media (min-width: 992px) { + .blog-content .table-wrapper { + margin-left: -10%; + margin-right: 10%; + max-width: 120%; + width: 120%; } } + .demo-wrapper { margin-left: calc(50% - 50vw); width: 100vw; @@ -5678,6 +6003,61 @@ body { background-color: #f8f8f8; padding: 30px 20px; } +.pricing-table { + border: 2px solid #ddd; + padding: 0 0.5em; + line-height: 1.4; + font-size: 0.85em; + color: #666666; } + +.pricing-table-row { + border-bottom: 1px solid #ddd; + margin: 0; } + .pricing-table-row:last-of-type { + border-bottom: 0; } + @media (min-width: 768px) { + .pricing-table-row > div { + padding: 0.5em 0; } } + +@media (max-width: 767px) { + .pricing-table-product { + text-align: center; + background-color: #f8f8f8; + padding: 0.5em; + margin-top: 0.5em; } } + +.pricing-table-product-label { + text-transform: uppercase; } + @media (min-width: 768px) { + .pricing-table-product-label { + margin-top: 0.5em; } } + +.pricing-table-product-link { + font-size: 16px; } + +@media (max-width: 767px) { + .pricing-table-cost { + margin-top: 10px; + margin-bottom: 10px; } + .pricing-table-cost:last-of-type { + border-left: 1px solid #ddd; } } + +.pricing-table-cost-amount { + color: #7F2DE3; + font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; + font-size: 2em; + font-weight: 700; + line-height: 1; + margin-top: 0.25em; } + +.pricing-table-notes { + margin-top: 12px; + padding: 0 0.5em; + color: #666666; } + +.pricing-table-notes-right { + float: right; } + @media print { a.btn[href]:after, a.no-print-link:after { @@ -5707,29 +6087,29 @@ body.project .demo-container { .static-content { font-size: 16px; } } .static-content h1 { - font-weight: 600; + font-weight: 700; font-size: 36px; margin-top: 48px; margin-bottom: 12px; } .static-content h2 { - font-weight: 600; + font-weight: 700; font-size: 24px; margin-top: 48px; margin-bottom: 12px; } .static-content h3 { - font-weight: 600; + font-weight: 700; font-size: 16px; margin-top: 24px; margin-bottom: 12px; } .static-content h4 { margin-top: 24px; margin-bottom: 12px; - font-weight: 600; + font-weight: 700; font-size: 14px; } .static-content h5, .static-content h6 { margin-top: 24px; margin-bottom: 12px; - font-weight: 600; + font-weight: 700; font-size: 11px; } .static-content h1[id]:before, .static-content h2[id]:before, @@ -5820,6 +6200,7 @@ body.project .demo-container { text-overflow: ellipsis; overflow: hidden; cursor: pointer; + font-weight: 700; width: 100%; display: none; } .demo-control.active { @@ -5839,7 +6220,8 @@ body.project .demo-container { .demo-control.hover, .demo-control-previous.hover, .demo-control-next.hover { - color: #141414; } + background: #FCDBDB; + color: #FF7B7B; } .demo-control-previous, .demo-control-next { @@ -5940,15 +6322,17 @@ body.project .demo-container { width: 100%; height: 100%; padding: 0 20px; - outline: 0; } + outline: 0; + font-weight: 700; } @media (min-width: 768px) and (max-width: 1199px) { .section-nav a { padding: 0 15px; } } - .section-nav a:hover, - .section-nav a:focus, .section-nav a:visited, - .section-nav a:active { + .section-nav a:active, + .section-nav a:focus { color: white; } + .section-nav a:hover { + color: #FF7B7B; } .section-nav.is-floating { top: 20px; } body.fixed-main-nav .section-nav.is-floating { @@ -6019,7 +6403,6 @@ body.project .demo-container { .section-nav-title h2 { margin: 0; font-size: 2em; - font-weight: 600; line-height: 50px; } @media (min-width: 768px) and (max-width: 1199px) { .section-nav-title h2 { @@ -6048,10 +6431,11 @@ body.project .demo-container { font-size: 13px; } } .section-nav-items li:not(.active):not(:hover) { text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5); } - .section-nav-items li:hover { - background-color: #FF4947; } body:not(.is-scrolling) .section-nav-items li.active, .section-nav-items li.active:hover, .section-nav-items li.activated { background-color: #FF7B7B; } + .section-nav-items li.active:hover a, + .section-nav-items li.activated a { + color: #ffffff; } .section-nav-items li.section-nav-item-egg { display: none; padding: 0 20px; } @@ -6173,21 +6557,947 @@ body.project .demo-container { .social-button-pinterest svg polygon { fill: #b81621; } -.table, .content table, -.static-content table { +.m-0 { + margin: 0 !important; } + +.mt-0 { + margin-top: 0 !important; } + +.mr-0 { + margin-right: 0 !important; } + +.mb-0 { + margin-bottom: 0 !important; } + +.ml-0 { + margin-left: 0 !important; } + +.mx-0 { + margin-right: 0 !important; + margin-left: 0 !important; } + +.my-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; } + +.m-1 { + margin: 6px !important; } + +.mt-1 { + margin-top: 6px !important; } + +.mr-1 { + margin-right: 6px !important; } + +.mb-1 { + margin-bottom: 6px !important; } + +.ml-1 { + margin-left: 6px !important; } + +.mx-1 { + margin-right: 6px !important; + margin-left: 6px !important; } + +.my-1 { + margin-top: 6px !important; + margin-bottom: 6px !important; } + +.m-2 { + margin: 12px !important; } + +.mt-2 { + margin-top: 12px !important; } + +.mr-2 { + margin-right: 12px !important; } + +.mb-2 { + margin-bottom: 12px !important; } + +.ml-2 { + margin-left: 12px !important; } + +.mx-2 { + margin-right: 12px !important; + margin-left: 12px !important; } + +.my-2 { + margin-top: 12px !important; + margin-bottom: 12px !important; } + +.m-3 { + margin: 24px !important; } + +.mt-3 { + margin-top: 24px !important; } + +.mr-3 { + margin-right: 24px !important; } + +.mb-3 { + margin-bottom: 24px !important; } + +.ml-3 { + margin-left: 24px !important; } + +.mx-3 { + margin-right: 24px !important; + margin-left: 24px !important; } + +.my-3 { + margin-top: 24px !important; + margin-bottom: 24px !important; } + +.m-4 { + margin: 36px !important; } + +.mt-4 { + margin-top: 36px !important; } + +.mr-4 { + margin-right: 36px !important; } + +.mb-4 { + margin-bottom: 36px !important; } + +.ml-4 { + margin-left: 36px !important; } + +.mx-4 { + margin-right: 36px !important; + margin-left: 36px !important; } + +.my-4 { + margin-top: 36px !important; + margin-bottom: 36px !important; } + +.m-5 { + margin: 72px !important; } + +.mt-5 { + margin-top: 72px !important; } + +.mr-5 { + margin-right: 72px !important; } + +.mb-5 { + margin-bottom: 72px !important; } + +.ml-5 { + margin-left: 72px !important; } + +.mx-5 { + margin-right: 72px !important; + margin-left: 72px !important; } + +.my-5 { + margin-top: 72px !important; + margin-bottom: 72px !important; } + +.p-0 { + padding: 0 !important; } + +.pt-0 { + padding-top: 0 !important; } + +.pr-0 { + padding-right: 0 !important; } + +.pb-0 { + padding-bottom: 0 !important; } + +.pl-0 { + padding-left: 0 !important; } + +.px-0 { + padding-right: 0 !important; + padding-left: 0 !important; } + +.py-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; } + +.p-1 { + padding: 6px !important; } + +.pt-1 { + padding-top: 6px !important; } + +.pr-1 { + padding-right: 6px !important; } + +.pb-1 { + padding-bottom: 6px !important; } + +.pl-1 { + padding-left: 6px !important; } + +.px-1 { + padding-right: 6px !important; + padding-left: 6px !important; } + +.py-1 { + padding-top: 6px !important; + padding-bottom: 6px !important; } + +.p-2 { + padding: 12px !important; } + +.pt-2 { + padding-top: 12px !important; } + +.pr-2 { + padding-right: 12px !important; } + +.pb-2 { + padding-bottom: 12px !important; } + +.pl-2 { + padding-left: 12px !important; } + +.px-2 { + padding-right: 12px !important; + padding-left: 12px !important; } + +.py-2 { + padding-top: 12px !important; + padding-bottom: 12px !important; } + +.p-3 { + padding: 24px !important; } + +.pt-3 { + padding-top: 24px !important; } + +.pr-3 { + padding-right: 24px !important; } + +.pb-3 { + padding-bottom: 24px !important; } + +.pl-3 { + padding-left: 24px !important; } + +.px-3 { + padding-right: 24px !important; + padding-left: 24px !important; } + +.py-3 { + padding-top: 24px !important; + padding-bottom: 24px !important; } + +.p-4 { + padding: 36px !important; } + +.pt-4 { + padding-top: 36px !important; } + +.pr-4 { + padding-right: 36px !important; } + +.pb-4 { + padding-bottom: 36px !important; } + +.pl-4 { + padding-left: 36px !important; } + +.px-4 { + padding-right: 36px !important; + padding-left: 36px !important; } + +.py-4 { + padding-top: 36px !important; + padding-bottom: 36px !important; } + +.p-5 { + padding: 72px !important; } + +.pt-5 { + padding-top: 72px !important; } + +.pr-5 { + padding-right: 72px !important; } + +.pb-5 { + padding-bottom: 72px !important; } + +.pl-5 { + padding-left: 72px !important; } + +.px-5 { + padding-right: 72px !important; + padding-left: 72px !important; } + +.py-5 { + padding-top: 72px !important; + padding-bottom: 72px !important; } + +.m-auto { + margin: auto !important; } + +.mt-auto { + margin-top: auto !important; } + +.mr-auto { + margin-right: auto !important; } + +.mb-auto { + margin-bottom: auto !important; } + +.ml-auto { + margin-left: auto !important; } + +.mx-auto { + margin-right: auto !important; + margin-left: auto !important; } + +.my-auto { + margin-top: auto !important; + margin-bottom: auto !important; } + +@media (min-width: 768px) { + .m-sm-0 { + margin: 0 !important; } + .mt-sm-0 { + margin-top: 0 !important; } + .mr-sm-0 { + margin-right: 0 !important; } + .mb-sm-0 { + margin-bottom: 0 !important; } + .ml-sm-0 { + margin-left: 0 !important; } + .mx-sm-0 { + margin-right: 0 !important; + margin-left: 0 !important; } + .my-sm-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; } + .m-sm-1 { + margin: 6px !important; } + .mt-sm-1 { + margin-top: 6px !important; } + .mr-sm-1 { + margin-right: 6px !important; } + .mb-sm-1 { + margin-bottom: 6px !important; } + .ml-sm-1 { + margin-left: 6px !important; } + .mx-sm-1 { + margin-right: 6px !important; + margin-left: 6px !important; } + .my-sm-1 { + margin-top: 6px !important; + margin-bottom: 6px !important; } + .m-sm-2 { + margin: 12px !important; } + .mt-sm-2 { + margin-top: 12px !important; } + .mr-sm-2 { + margin-right: 12px !important; } + .mb-sm-2 { + margin-bottom: 12px !important; } + .ml-sm-2 { + margin-left: 12px !important; } + .mx-sm-2 { + margin-right: 12px !important; + margin-left: 12px !important; } + .my-sm-2 { + margin-top: 12px !important; + margin-bottom: 12px !important; } + .m-sm-3 { + margin: 24px !important; } + .mt-sm-3 { + margin-top: 24px !important; } + .mr-sm-3 { + margin-right: 24px !important; } + .mb-sm-3 { + margin-bottom: 24px !important; } + .ml-sm-3 { + margin-left: 24px !important; } + .mx-sm-3 { + margin-right: 24px !important; + margin-left: 24px !important; } + .my-sm-3 { + margin-top: 24px !important; + margin-bottom: 24px !important; } + .m-sm-4 { + margin: 36px !important; } + .mt-sm-4 { + margin-top: 36px !important; } + .mr-sm-4 { + margin-right: 36px !important; } + .mb-sm-4 { + margin-bottom: 36px !important; } + .ml-sm-4 { + margin-left: 36px !important; } + .mx-sm-4 { + margin-right: 36px !important; + margin-left: 36px !important; } + .my-sm-4 { + margin-top: 36px !important; + margin-bottom: 36px !important; } + .m-sm-5 { + margin: 72px !important; } + .mt-sm-5 { + margin-top: 72px !important; } + .mr-sm-5 { + margin-right: 72px !important; } + .mb-sm-5 { + margin-bottom: 72px !important; } + .ml-sm-5 { + margin-left: 72px !important; } + .mx-sm-5 { + margin-right: 72px !important; + margin-left: 72px !important; } + .my-sm-5 { + margin-top: 72px !important; + margin-bottom: 72px !important; } + .p-sm-0 { + padding: 0 !important; } + .pt-sm-0 { + padding-top: 0 !important; } + .pr-sm-0 { + padding-right: 0 !important; } + .pb-sm-0 { + padding-bottom: 0 !important; } + .pl-sm-0 { + padding-left: 0 !important; } + .px-sm-0 { + padding-right: 0 !important; + padding-left: 0 !important; } + .py-sm-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; } + .p-sm-1 { + padding: 6px !important; } + .pt-sm-1 { + padding-top: 6px !important; } + .pr-sm-1 { + padding-right: 6px !important; } + .pb-sm-1 { + padding-bottom: 6px !important; } + .pl-sm-1 { + padding-left: 6px !important; } + .px-sm-1 { + padding-right: 6px !important; + padding-left: 6px !important; } + .py-sm-1 { + padding-top: 6px !important; + padding-bottom: 6px !important; } + .p-sm-2 { + padding: 12px !important; } + .pt-sm-2 { + padding-top: 12px !important; } + .pr-sm-2 { + padding-right: 12px !important; } + .pb-sm-2 { + padding-bottom: 12px !important; } + .pl-sm-2 { + padding-left: 12px !important; } + .px-sm-2 { + padding-right: 12px !important; + padding-left: 12px !important; } + .py-sm-2 { + padding-top: 12px !important; + padding-bottom: 12px !important; } + .p-sm-3 { + padding: 24px !important; } + .pt-sm-3 { + padding-top: 24px !important; } + .pr-sm-3 { + padding-right: 24px !important; } + .pb-sm-3 { + padding-bottom: 24px !important; } + .pl-sm-3 { + padding-left: 24px !important; } + .px-sm-3 { + padding-right: 24px !important; + padding-left: 24px !important; } + .py-sm-3 { + padding-top: 24px !important; + padding-bottom: 24px !important; } + .p-sm-4 { + padding: 36px !important; } + .pt-sm-4 { + padding-top: 36px !important; } + .pr-sm-4 { + padding-right: 36px !important; } + .pb-sm-4 { + padding-bottom: 36px !important; } + .pl-sm-4 { + padding-left: 36px !important; } + .px-sm-4 { + padding-right: 36px !important; + padding-left: 36px !important; } + .py-sm-4 { + padding-top: 36px !important; + padding-bottom: 36px !important; } + .p-sm-5 { + padding: 72px !important; } + .pt-sm-5 { + padding-top: 72px !important; } + .pr-sm-5 { + padding-right: 72px !important; } + .pb-sm-5 { + padding-bottom: 72px !important; } + .pl-sm-5 { + padding-left: 72px !important; } + .px-sm-5 { + padding-right: 72px !important; + padding-left: 72px !important; } + .py-sm-5 { + padding-top: 72px !important; + padding-bottom: 72px !important; } + .m-sm-auto { + margin: auto !important; } + .mt-sm-auto { + margin-top: auto !important; } + .mr-sm-auto { + margin-right: auto !important; } + .mb-sm-auto { + margin-bottom: auto !important; } + .ml-sm-auto { + margin-left: auto !important; } + .mx-sm-auto { + margin-right: auto !important; + margin-left: auto !important; } + .my-sm-auto { + margin-top: auto !important; + margin-bottom: auto !important; } } + +@media (min-width: 992px) { + .m-md-0 { + margin: 0 !important; } + .mt-md-0 { + margin-top: 0 !important; } + .mr-md-0 { + margin-right: 0 !important; } + .mb-md-0 { + margin-bottom: 0 !important; } + .ml-md-0 { + margin-left: 0 !important; } + .mx-md-0 { + margin-right: 0 !important; + margin-left: 0 !important; } + .my-md-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; } + .m-md-1 { + margin: 6px !important; } + .mt-md-1 { + margin-top: 6px !important; } + .mr-md-1 { + margin-right: 6px !important; } + .mb-md-1 { + margin-bottom: 6px !important; } + .ml-md-1 { + margin-left: 6px !important; } + .mx-md-1 { + margin-right: 6px !important; + margin-left: 6px !important; } + .my-md-1 { + margin-top: 6px !important; + margin-bottom: 6px !important; } + .m-md-2 { + margin: 12px !important; } + .mt-md-2 { + margin-top: 12px !important; } + .mr-md-2 { + margin-right: 12px !important; } + .mb-md-2 { + margin-bottom: 12px !important; } + .ml-md-2 { + margin-left: 12px !important; } + .mx-md-2 { + margin-right: 12px !important; + margin-left: 12px !important; } + .my-md-2 { + margin-top: 12px !important; + margin-bottom: 12px !important; } + .m-md-3 { + margin: 24px !important; } + .mt-md-3 { + margin-top: 24px !important; } + .mr-md-3 { + margin-right: 24px !important; } + .mb-md-3 { + margin-bottom: 24px !important; } + .ml-md-3 { + margin-left: 24px !important; } + .mx-md-3 { + margin-right: 24px !important; + margin-left: 24px !important; } + .my-md-3 { + margin-top: 24px !important; + margin-bottom: 24px !important; } + .m-md-4 { + margin: 36px !important; } + .mt-md-4 { + margin-top: 36px !important; } + .mr-md-4 { + margin-right: 36px !important; } + .mb-md-4 { + margin-bottom: 36px !important; } + .ml-md-4 { + margin-left: 36px !important; } + .mx-md-4 { + margin-right: 36px !important; + margin-left: 36px !important; } + .my-md-4 { + margin-top: 36px !important; + margin-bottom: 36px !important; } + .m-md-5 { + margin: 72px !important; } + .mt-md-5 { + margin-top: 72px !important; } + .mr-md-5 { + margin-right: 72px !important; } + .mb-md-5 { + margin-bottom: 72px !important; } + .ml-md-5 { + margin-left: 72px !important; } + .mx-md-5 { + margin-right: 72px !important; + margin-left: 72px !important; } + .my-md-5 { + margin-top: 72px !important; + margin-bottom: 72px !important; } + .p-md-0 { + padding: 0 !important; } + .pt-md-0 { + padding-top: 0 !important; } + .pr-md-0 { + padding-right: 0 !important; } + .pb-md-0 { + padding-bottom: 0 !important; } + .pl-md-0 { + padding-left: 0 !important; } + .px-md-0 { + padding-right: 0 !important; + padding-left: 0 !important; } + .py-md-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; } + .p-md-1 { + padding: 6px !important; } + .pt-md-1 { + padding-top: 6px !important; } + .pr-md-1 { + padding-right: 6px !important; } + .pb-md-1 { + padding-bottom: 6px !important; } + .pl-md-1 { + padding-left: 6px !important; } + .px-md-1 { + padding-right: 6px !important; + padding-left: 6px !important; } + .py-md-1 { + padding-top: 6px !important; + padding-bottom: 6px !important; } + .p-md-2 { + padding: 12px !important; } + .pt-md-2 { + padding-top: 12px !important; } + .pr-md-2 { + padding-right: 12px !important; } + .pb-md-2 { + padding-bottom: 12px !important; } + .pl-md-2 { + padding-left: 12px !important; } + .px-md-2 { + padding-right: 12px !important; + padding-left: 12px !important; } + .py-md-2 { + padding-top: 12px !important; + padding-bottom: 12px !important; } + .p-md-3 { + padding: 24px !important; } + .pt-md-3 { + padding-top: 24px !important; } + .pr-md-3 { + padding-right: 24px !important; } + .pb-md-3 { + padding-bottom: 24px !important; } + .pl-md-3 { + padding-left: 24px !important; } + .px-md-3 { + padding-right: 24px !important; + padding-left: 24px !important; } + .py-md-3 { + padding-top: 24px !important; + padding-bottom: 24px !important; } + .p-md-4 { + padding: 36px !important; } + .pt-md-4 { + padding-top: 36px !important; } + .pr-md-4 { + padding-right: 36px !important; } + .pb-md-4 { + padding-bottom: 36px !important; } + .pl-md-4 { + padding-left: 36px !important; } + .px-md-4 { + padding-right: 36px !important; + padding-left: 36px !important; } + .py-md-4 { + padding-top: 36px !important; + padding-bottom: 36px !important; } + .p-md-5 { + padding: 72px !important; } + .pt-md-5 { + padding-top: 72px !important; } + .pr-md-5 { + padding-right: 72px !important; } + .pb-md-5 { + padding-bottom: 72px !important; } + .pl-md-5 { + padding-left: 72px !important; } + .px-md-5 { + padding-right: 72px !important; + padding-left: 72px !important; } + .py-md-5 { + padding-top: 72px !important; + padding-bottom: 72px !important; } + .m-md-auto { + margin: auto !important; } + .mt-md-auto { + margin-top: auto !important; } + .mr-md-auto { + margin-right: auto !important; } + .mb-md-auto { + margin-bottom: auto !important; } + .ml-md-auto { + margin-left: auto !important; } + .mx-md-auto { + margin-right: auto !important; + margin-left: auto !important; } + .my-md-auto { + margin-top: auto !important; + margin-bottom: auto !important; } } + +@media (min-width: 1200px) { + .m-lg-0 { + margin: 0 !important; } + .mt-lg-0 { + margin-top: 0 !important; } + .mr-lg-0 { + margin-right: 0 !important; } + .mb-lg-0 { + margin-bottom: 0 !important; } + .ml-lg-0 { + margin-left: 0 !important; } + .mx-lg-0 { + margin-right: 0 !important; + margin-left: 0 !important; } + .my-lg-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; } + .m-lg-1 { + margin: 6px !important; } + .mt-lg-1 { + margin-top: 6px !important; } + .mr-lg-1 { + margin-right: 6px !important; } + .mb-lg-1 { + margin-bottom: 6px !important; } + .ml-lg-1 { + margin-left: 6px !important; } + .mx-lg-1 { + margin-right: 6px !important; + margin-left: 6px !important; } + .my-lg-1 { + margin-top: 6px !important; + margin-bottom: 6px !important; } + .m-lg-2 { + margin: 12px !important; } + .mt-lg-2 { + margin-top: 12px !important; } + .mr-lg-2 { + margin-right: 12px !important; } + .mb-lg-2 { + margin-bottom: 12px !important; } + .ml-lg-2 { + margin-left: 12px !important; } + .mx-lg-2 { + margin-right: 12px !important; + margin-left: 12px !important; } + .my-lg-2 { + margin-top: 12px !important; + margin-bottom: 12px !important; } + .m-lg-3 { + margin: 24px !important; } + .mt-lg-3 { + margin-top: 24px !important; } + .mr-lg-3 { + margin-right: 24px !important; } + .mb-lg-3 { + margin-bottom: 24px !important; } + .ml-lg-3 { + margin-left: 24px !important; } + .mx-lg-3 { + margin-right: 24px !important; + margin-left: 24px !important; } + .my-lg-3 { + margin-top: 24px !important; + margin-bottom: 24px !important; } + .m-lg-4 { + margin: 36px !important; } + .mt-lg-4 { + margin-top: 36px !important; } + .mr-lg-4 { + margin-right: 36px !important; } + .mb-lg-4 { + margin-bottom: 36px !important; } + .ml-lg-4 { + margin-left: 36px !important; } + .mx-lg-4 { + margin-right: 36px !important; + margin-left: 36px !important; } + .my-lg-4 { + margin-top: 36px !important; + margin-bottom: 36px !important; } + .m-lg-5 { + margin: 72px !important; } + .mt-lg-5 { + margin-top: 72px !important; } + .mr-lg-5 { + margin-right: 72px !important; } + .mb-lg-5 { + margin-bottom: 72px !important; } + .ml-lg-5 { + margin-left: 72px !important; } + .mx-lg-5 { + margin-right: 72px !important; + margin-left: 72px !important; } + .my-lg-5 { + margin-top: 72px !important; + margin-bottom: 72px !important; } + .p-lg-0 { + padding: 0 !important; } + .pt-lg-0 { + padding-top: 0 !important; } + .pr-lg-0 { + padding-right: 0 !important; } + .pb-lg-0 { + padding-bottom: 0 !important; } + .pl-lg-0 { + padding-left: 0 !important; } + .px-lg-0 { + padding-right: 0 !important; + padding-left: 0 !important; } + .py-lg-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; } + .p-lg-1 { + padding: 6px !important; } + .pt-lg-1 { + padding-top: 6px !important; } + .pr-lg-1 { + padding-right: 6px !important; } + .pb-lg-1 { + padding-bottom: 6px !important; } + .pl-lg-1 { + padding-left: 6px !important; } + .px-lg-1 { + padding-right: 6px !important; + padding-left: 6px !important; } + .py-lg-1 { + padding-top: 6px !important; + padding-bottom: 6px !important; } + .p-lg-2 { + padding: 12px !important; } + .pt-lg-2 { + padding-top: 12px !important; } + .pr-lg-2 { + padding-right: 12px !important; } + .pb-lg-2 { + padding-bottom: 12px !important; } + .pl-lg-2 { + padding-left: 12px !important; } + .px-lg-2 { + padding-right: 12px !important; + padding-left: 12px !important; } + .py-lg-2 { + padding-top: 12px !important; + padding-bottom: 12px !important; } + .p-lg-3 { + padding: 24px !important; } + .pt-lg-3 { + padding-top: 24px !important; } + .pr-lg-3 { + padding-right: 24px !important; } + .pb-lg-3 { + padding-bottom: 24px !important; } + .pl-lg-3 { + padding-left: 24px !important; } + .px-lg-3 { + padding-right: 24px !important; + padding-left: 24px !important; } + .py-lg-3 { + padding-top: 24px !important; + padding-bottom: 24px !important; } + .p-lg-4 { + padding: 36px !important; } + .pt-lg-4 { + padding-top: 36px !important; } + .pr-lg-4 { + padding-right: 36px !important; } + .pb-lg-4 { + padding-bottom: 36px !important; } + .pl-lg-4 { + padding-left: 36px !important; } + .px-lg-4 { + padding-right: 36px !important; + padding-left: 36px !important; } + .py-lg-4 { + padding-top: 36px !important; + padding-bottom: 36px !important; } + .p-lg-5 { + padding: 72px !important; } + .pt-lg-5 { + padding-top: 72px !important; } + .pr-lg-5 { + padding-right: 72px !important; } + .pb-lg-5 { + padding-bottom: 72px !important; } + .pl-lg-5 { + padding-left: 72px !important; } + .px-lg-5 { + padding-right: 72px !important; + padding-left: 72px !important; } + .py-lg-5 { + padding-top: 72px !important; + padding-bottom: 72px !important; } + .m-lg-auto { + margin: auto !important; } + .mt-lg-auto { + margin-top: auto !important; } + .mr-lg-auto { + margin-right: auto !important; } + .mb-lg-auto { + margin-bottom: auto !important; } + .ml-lg-auto { + margin-left: auto !important; } + .mx-lg-auto { + margin-right: auto !important; + margin-left: auto !important; } + .my-lg-auto { + margin-top: auto !important; + margin-bottom: auto !important; } } + +.table { width: 100%; border: 2px solid #ddd; margin-bottom: 0; } - .table th, .content table th, - .static-content table th { + .table th { padding: 8px; border-right: 1px dotted #ddd; border-bottom: 2px solid #ddd; color: #FF7B7B; font-weight: 700; font-size: 16px; } - .table td, .content table td, - .static-content table td { + .table td { line-height: inherit !important; border-right: 1px dotted #ddd; border-top: 1px solid #ddd; @@ -6217,7 +7527,7 @@ body.project .demo-container { /* First level of nav */ .toc { font-size: 14px; - font-weight: 300; + font-weight: 400; line-height: 1.4; background-color: #f8f8f8; margin-bottom: 30px; @@ -6238,15 +7548,15 @@ body.project .demo-container { padding: 6px 15px; z-index: 1; color: #635378; - font-weight: 300; + font-weight: 400; text-decoration: none; -webkit-transition: box-shadow 100ms ease-in-out; -moz-transition: box-shadow 100ms ease-in-out; transition: box-shadow 100ms ease-in-out; } .toc li.toc-top-level { - font-weight: 600; } + font-weight: 700; } .toc li.toc-top-level > a { - font-weight: 600; } + font-weight: 700; } .toc li.toc-top-level.toc-current > a { background-color: #635378; color: white; } @@ -6301,17 +7611,18 @@ ul.nav > li:first-child:last-child { padding-left: 30px; } body { - font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; - font-weight: 300; + font-family: "Open Sans", Helvetica, Arial, sans-serif; + font-weight: 400; color: #2C1E3F; font-size: 16px; line-height: 1.5; } +p { + margin-bottom: 1em; } + h1, h2, h3 { - font-weight: 600; margin-top: 48px; - margin-bottom: 12px; - line-height: 1.2em; } + margin-bottom: 12px; } @media (max-width: 768px) { h1, h2, h3 { margin-top: 24px; @@ -6333,37 +7644,47 @@ h3 { font-size: 24px; } @media (max-width: 768px) { h3 { - font-size: 18px; } } + font-size: 20px; } } -h4 { - font-weight: 600; - font-size: 16px; +h4, h5, h6 { margin-top: 24px; margin-bottom: 12px; } + @media (max-width: 768px) { + h4, h5, h6 { + margin-bottom: 6px; } } -h5 { - font-weight: 600; - font-size: 14px; - margin-top: 24px; - margin-bottom: 12px; } +h4 { + font-size: 20px; } + @media (max-width: 768px) { + h4 { + font-size: 18px; } } + +h5, h6 { + font-size: 16px; } a { - color: #FF7B7B; } + color: #FF7B7B; + font-weight: 700; } a:hover, a:focus { color: #FF4947; } +h1, h2, h3, h4, h5, h6 { + line-height: 1.2; } + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + font-weight: inherit; } + .caption { font-size: 16px; font-weight: 300; font-style: italic; - color: #666666; } + color: #1E0E33; } code { padding: 4px 8px; margin: 0 2px; font-size: 14px; line-height: 1.6em; - color: #666666; + color: #1E0E33; background-color: #f8f8f8; } pre { @@ -6389,45 +7710,64 @@ pre { background-image: linear-gradient(135deg, transparent 25%, rgba(0, 0, 0, 0.04) 25%, rgba(0, 0, 0, 0.04) 50%, transparent 50%, transparent 75%, rgba(0, 0, 0, 0.04) 75%, rgba(0, 0, 0, 0.04)); } quote { - font-size: 18px; - color: #444; } - @media (min-width: 992px) { + font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; + font-size: 24px; + color: #1E0E33; } + @media (max-width: 768px) { quote { - font-size: 24px; } } + font-size: 18px; } } pullquote { width: 100%; margin-top: 1.5em; margin-bottom: 1.5em; display: block; + font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; font-size: 24px; font-style: italic; text-align: center; - color: #444; } - @media (min-width: 992px) { + color: #1E0E33; } + @media (max-width: 768px) { pullquote { - font-size: 28px; - width: 120%; - margin-left: -10%; - margin-right: -10%; } } + font-size: 18px; } } /* about page styles */ .team .name { font-size: 15px; } -/* This stylefile is written to be temporary. This needs to be gone after dom change of homepage*/ -#content h5, -footer h5 { - /* h2 style */ - font-weight: 600; - font-size: 36px; - margin-top: 48px; - margin-bottom: 12px; } +/* This style overrides rangeslider's style + we are using rangeslider to polyfill input[type="range"]*/ +.rangeslider, +.rangeslider__fill { + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; } -#content .static-content h5, -footer .static-content h5 { - /* h3 style */ - font-weight: 600; - font-size: 24px; - margin-top: 48px; - margin-bottom: 12px; } +.rangeslider { + background: #EEE7F8; } + +.rangeslider--horizontal { + height: 5px; } + +.rangeslider__fill { + background: #985FDD; } + +.rangeslider__handle { + background: #1E0E33; + border: none; + width: 15px; + height: 15px; + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; } + +.rangeslider__handle:after { + display: none; } + +.rangeslider--horizontal .rangeslider__handle { + top: -5px; } + +input[type="range"]:focus + .rangeslider .rangeslider__handle { + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; } diff --git a/www/css/mapzen.styleguide.whosonfirst.css b/www/css/mapzen.styleguide.whosonfirst.css index a8c27f4..16127a2 100644 --- a/www/css/mapzen.styleguide.whosonfirst.css +++ b/www/css/mapzen.styleguide.whosonfirst.css @@ -50,4 +50,8 @@ h3 { .hey-look { font-weight:700; -} \ No newline at end of file +} + +#search-results { + margin-top: 1em; +} diff --git a/www/css/mapzen.website.css b/www/css/mapzen.website.css new file mode 100644 index 0000000..d48fc37 --- /dev/null +++ b/www/css/mapzen.website.css @@ -0,0 +1,8127 @@ +@charset "UTF-8"; +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ +@import url(https://fonts.googleapis.com/css?family=Source+Code+Pro:400,600|Open+Sans:300italic,400italic,700italic,400,300,600,700|Playfair+Display:400,700,900,400italic|Montserrat); +@import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css); +@import url(https://fonts.googleapis.com/css?family=Poppins:300,400,600,700); +html { + font-family: sans-serif; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; } + +body { + margin: 0; } + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; } + +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; } + +audio:not([controls]) { + display: none; + height: 0; } + +[hidden], +template { + display: none; } + +a { + background-color: transparent; } + +a:active, +a:hover { + outline: 0; } + +abbr[title] { + border-bottom: 1px dotted; } + +b, +strong { + font-weight: bold; } + +dfn { + font-style: italic; } + +h1 { + font-size: 2em; + margin: 0.67em 0; } + +mark { + background: #ff0; + color: #000; } + +small { + font-size: 80%; } + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +img { + border: 0; } + +svg:not(:root) { + overflow: hidden; } + +figure { + margin: 1em 40px; } + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; } + +pre { + overflow: auto; } + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; } + +button, +input, +optgroup, +select, +textarea { + color: inherit; + font: inherit; + margin: 0; } + +button { + overflow: visible; } + +button, +select { + text-transform: none; } + +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; } + +button[disabled], +html input[disabled] { + cursor: default; } + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; } + +input { + line-height: normal; } + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + padding: 0; } + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; } + +input[type="search"] { + -webkit-appearance: textfield; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + box-sizing: content-box; } + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; } + +legend { + border: 0; + padding: 0; } + +textarea { + overflow: auto; } + +optgroup { + font-weight: bold; } + +table { + border-collapse: collapse; + border-spacing: 0; } + +td, +th { + padding: 0; } + +/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ +@media print { + *, + *:before, + *:after { + background: transparent !important; + color: #000 !important; + box-shadow: none !important; + text-shadow: none !important; } + a, + a:visited { + text-decoration: underline; } + a[href]:after { + content: " (" attr(href) ")"; } + abbr[title]:after { + content: " (" attr(title) ")"; } + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; } + thead { + display: table-header-group; } + tr, + img { + page-break-inside: avoid; } + img { + max-width: 100% !important; } + p, + h2, + h3 { + orphans: 3; + widows: 3; } + h2, + h3 { + page-break-after: avoid; } + select { + background: #fff !important; } + .navbar { + display: none; } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; } + .label { + border: 1px solid #000; } + .table { + border-collapse: collapse !important; } + .table td, + .table th { + background-color: #fff !important; } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; } } + +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } + +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } + +html { + font-size: 10px; + -webkit-tap-highlight-color: transparent; } + +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.42857; + color: #333333; + background-color: #fff; } + +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; } + +a { + color: #6ea0a4; + text-decoration: none; } + a:hover, a:focus { + color: #385d5c; + text-decoration: none; } + a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +figure { + margin: 0; } + +img { + vertical-align: middle; } + +.img-responsive { + display: block; + max-width: 100%; + height: auto; } + +.img-rounded { + border-radius: 6px; } + +.img-thumbnail { + padding: 4px; + line-height: 1.42857; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 0; + -webkit-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; + display: inline-block; + max-width: 100%; + height: auto; } + +.img-circle { + border-radius: 50%; } + +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eeeeee; } + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; } + +.sr-only-focusable:active, .sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; } + +[role="button"] { + cursor: pointer; } + +h1, h2, h3, h4, h5, h6, +.h1, .h2, .h3, .h4, .h5, .h6 { + font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; + font-weight: 700; + line-height: 1.1; + color: inherit; } + h1 small, + h1 .small, h2 small, + h2 .small, h3 small, + h3 .small, h4 small, + h4 .small, h5 small, + h5 .small, h6 small, + h6 .small, + .h1 small, + .h1 .small, .h2 small, + .h2 .small, .h3 small, + .h3 .small, .h4 small, + .h4 .small, .h5 small, + .h5 .small, .h6 small, + .h6 .small { + font-weight: normal; + line-height: 1; + color: #777777; } + +h1, .h1, +h2, .h2, +h3, .h3 { + margin-top: 20px; + margin-bottom: 10px; } + h1 small, + h1 .small, .h1 small, + .h1 .small, + h2 small, + h2 .small, .h2 small, + .h2 .small, + h3 small, + h3 .small, .h3 small, + .h3 .small { + font-size: 65%; } + +h4, .h4, +h5, .h5, +h6, .h6 { + margin-top: 10px; + margin-bottom: 10px; } + h4 small, + h4 .small, .h4 small, + .h4 .small, + h5 small, + h5 .small, .h5 small, + .h5 .small, + h6 small, + h6 .small, .h6 small, + .h6 .small { + font-size: 75%; } + +h1, .h1 { + font-size: 36px; } + +h2, .h2 { + font-size: 30px; } + +h3, .h3 { + font-size: 24px; } + +h4, .h4 { + font-size: 18px; } + +h5, .h5 { + font-size: 14px; } + +h6, .h6 { + font-size: 12px; } + +p { + margin: 0 0 10px; } + +.lead { + margin-bottom: 20px; + font-size: 16px; + font-weight: 300; + line-height: 1.4; } + @media (min-width: 768px) { + .lead { + font-size: 21px; } } + +small, +.small { + font-size: 85%; } + +mark, +.mark { + background-color: #fcf8e3; + padding: .2em; } + +.text-left { + text-align: left; } + +.text-right { + text-align: right; } + +.text-center { + text-align: center; } + +.text-justify { + text-align: justify; } + +.text-nowrap { + white-space: nowrap; } + +.text-lowercase { + text-transform: lowercase; } + +.text-uppercase, .initialism { + text-transform: uppercase; } + +.text-capitalize { + text-transform: capitalize; } + +.text-muted { + color: #777777; } + +.text-primary { + color: #337ab7; } + +a.text-primary:hover { + color: #286090; } + +.text-success { + color: #3c763d; } + +a.text-success:hover { + color: #2b542c; } + +.text-info { + color: #31708f; } + +a.text-info:hover { + color: #245269; } + +.text-warning { + color: #8a6d3b; } + +a.text-warning:hover { + color: #66512c; } + +.text-danger { + color: #a94442; } + +a.text-danger:hover { + color: #843534; } + +.bg-primary { + color: #fff; } + +.bg-primary { + background-color: #337ab7; } + +a.bg-primary:hover { + background-color: #286090; } + +.bg-success { + background-color: #dff0d8; } + +a.bg-success:hover { + background-color: #c1e2b3; } + +.bg-info { + background-color: #d9edf7; } + +a.bg-info:hover { + background-color: #afd9ee; } + +.bg-warning { + background-color: #fcf8e3; } + +a.bg-warning:hover { + background-color: #f7ecb5; } + +.bg-danger { + background-color: #f2dede; } + +a.bg-danger:hover { + background-color: #e4b9b9; } + +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eeeeee; } + +ul, +ol { + margin-top: 0; + margin-bottom: 10px; } + ul ul, + ul ol, + ol ul, + ol ol { + margin-bottom: 0; } + +.list-unstyled { + padding-left: 0; + list-style: none; } + +.list-inline { + padding-left: 0; + list-style: none; + margin-left: -5px; } + .list-inline > li { + display: inline-block; + padding-left: 5px; + padding-right: 5px; } + +dl { + margin-top: 0; + margin-bottom: 20px; } + +dt, +dd { + line-height: 1.42857; } + +dt { + font-weight: bold; } + +dd { + margin-left: 0; } + +.dl-horizontal dd:before, .dl-horizontal dd:after { + content: " "; + display: table; } + +.dl-horizontal dd:after { + clear: both; } + +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } + .dl-horizontal dd { + margin-left: 180px; } } + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #777777; } + +.initialism { + font-size: 90%; } + +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + font-size: 17.5px; + border-left: 5px solid #eeeeee; } + blockquote p:last-child, + blockquote ul:last-child, + blockquote ol:last-child { + margin-bottom: 0; } + blockquote footer, + blockquote small, + blockquote .small { + display: block; + font-size: 80%; + line-height: 1.42857; + color: #777777; } + blockquote footer:before, + blockquote small:before, + blockquote .small:before { + content: '\2014 \00A0'; } + +.blockquote-reverse, +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; + text-align: right; } + .blockquote-reverse footer:before, + .blockquote-reverse small:before, + .blockquote-reverse .small:before, + blockquote.pull-right footer:before, + blockquote.pull-right small:before, + blockquote.pull-right .small:before { + content: ''; } + .blockquote-reverse footer:after, + .blockquote-reverse small:after, + .blockquote-reverse .small:after, + blockquote.pull-right footer:after, + blockquote.pull-right small:after, + blockquote.pull-right .small:after { + content: '\00A0 \2014'; } + +address { + margin-bottom: 20px; + font-style: normal; + line-height: 1.42857; } + +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; } + +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + border-radius: 0; } + +kbd { + padding: 2px 4px; + font-size: 90%; + color: #fff; + background-color: #333; + border-radius: 3px; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); } + kbd kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + box-shadow: none; } + +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.42857; + word-break: break-all; + word-wrap: break-word; + color: #333333; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 0; } + pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; } + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; } + +.container { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; } + .container:before, .container:after { + content: " "; + display: table; } + .container:after { + clear: both; } + @media (min-width: 768px) { + .container { + width: 750px; } } + @media (min-width: 992px) { + .container { + width: 960px; } } + @media (min-width: 1200px) { + .container { + width: 960px; } } + +.container-fluid { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; } + .container-fluid:before, .container-fluid:after { + content: " "; + display: table; } + .container-fluid:after { + clear: both; } + +.row { + margin-left: -15px; + margin-right: -15px; } + .row:before, .row:after { + content: " "; + display: table; } + .row:after { + clear: both; } + +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; } + +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; } + +.col-xs-1 { + width: 8.33333%; } + +.col-xs-2 { + width: 16.66667%; } + +.col-xs-3 { + width: 25%; } + +.col-xs-4 { + width: 33.33333%; } + +.col-xs-5 { + width: 41.66667%; } + +.col-xs-6 { + width: 50%; } + +.col-xs-7 { + width: 58.33333%; } + +.col-xs-8 { + width: 66.66667%; } + +.col-xs-9 { + width: 75%; } + +.col-xs-10 { + width: 83.33333%; } + +.col-xs-11 { + width: 91.66667%; } + +.col-xs-12 { + width: 100%; } + +.col-xs-pull-0 { + right: auto; } + +.col-xs-pull-1 { + right: 8.33333%; } + +.col-xs-pull-2 { + right: 16.66667%; } + +.col-xs-pull-3 { + right: 25%; } + +.col-xs-pull-4 { + right: 33.33333%; } + +.col-xs-pull-5 { + right: 41.66667%; } + +.col-xs-pull-6 { + right: 50%; } + +.col-xs-pull-7 { + right: 58.33333%; } + +.col-xs-pull-8 { + right: 66.66667%; } + +.col-xs-pull-9 { + right: 75%; } + +.col-xs-pull-10 { + right: 83.33333%; } + +.col-xs-pull-11 { + right: 91.66667%; } + +.col-xs-pull-12 { + right: 100%; } + +.col-xs-push-0 { + left: auto; } + +.col-xs-push-1 { + left: 8.33333%; } + +.col-xs-push-2 { + left: 16.66667%; } + +.col-xs-push-3 { + left: 25%; } + +.col-xs-push-4 { + left: 33.33333%; } + +.col-xs-push-5 { + left: 41.66667%; } + +.col-xs-push-6 { + left: 50%; } + +.col-xs-push-7 { + left: 58.33333%; } + +.col-xs-push-8 { + left: 66.66667%; } + +.col-xs-push-9 { + left: 75%; } + +.col-xs-push-10 { + left: 83.33333%; } + +.col-xs-push-11 { + left: 91.66667%; } + +.col-xs-push-12 { + left: 100%; } + +.col-xs-offset-0 { + margin-left: 0%; } + +.col-xs-offset-1 { + margin-left: 8.33333%; } + +.col-xs-offset-2 { + margin-left: 16.66667%; } + +.col-xs-offset-3 { + margin-left: 25%; } + +.col-xs-offset-4 { + margin-left: 33.33333%; } + +.col-xs-offset-5 { + margin-left: 41.66667%; } + +.col-xs-offset-6 { + margin-left: 50%; } + +.col-xs-offset-7 { + margin-left: 58.33333%; } + +.col-xs-offset-8 { + margin-left: 66.66667%; } + +.col-xs-offset-9 { + margin-left: 75%; } + +.col-xs-offset-10 { + margin-left: 83.33333%; } + +.col-xs-offset-11 { + margin-left: 91.66667%; } + +.col-xs-offset-12 { + margin-left: 100%; } + +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; } + .col-sm-1 { + width: 8.33333%; } + .col-sm-2 { + width: 16.66667%; } + .col-sm-3 { + width: 25%; } + .col-sm-4 { + width: 33.33333%; } + .col-sm-5 { + width: 41.66667%; } + .col-sm-6 { + width: 50%; } + .col-sm-7 { + width: 58.33333%; } + .col-sm-8 { + width: 66.66667%; } + .col-sm-9 { + width: 75%; } + .col-sm-10 { + width: 83.33333%; } + .col-sm-11 { + width: 91.66667%; } + .col-sm-12 { + width: 100%; } + .col-sm-pull-0 { + right: auto; } + .col-sm-pull-1 { + right: 8.33333%; } + .col-sm-pull-2 { + right: 16.66667%; } + .col-sm-pull-3 { + right: 25%; } + .col-sm-pull-4 { + right: 33.33333%; } + .col-sm-pull-5 { + right: 41.66667%; } + .col-sm-pull-6 { + right: 50%; } + .col-sm-pull-7 { + right: 58.33333%; } + .col-sm-pull-8 { + right: 66.66667%; } + .col-sm-pull-9 { + right: 75%; } + .col-sm-pull-10 { + right: 83.33333%; } + .col-sm-pull-11 { + right: 91.66667%; } + .col-sm-pull-12 { + right: 100%; } + .col-sm-push-0 { + left: auto; } + .col-sm-push-1 { + left: 8.33333%; } + .col-sm-push-2 { + left: 16.66667%; } + .col-sm-push-3 { + left: 25%; } + .col-sm-push-4 { + left: 33.33333%; } + .col-sm-push-5 { + left: 41.66667%; } + .col-sm-push-6 { + left: 50%; } + .col-sm-push-7 { + left: 58.33333%; } + .col-sm-push-8 { + left: 66.66667%; } + .col-sm-push-9 { + left: 75%; } + .col-sm-push-10 { + left: 83.33333%; } + .col-sm-push-11 { + left: 91.66667%; } + .col-sm-push-12 { + left: 100%; } + .col-sm-offset-0 { + margin-left: 0%; } + .col-sm-offset-1 { + margin-left: 8.33333%; } + .col-sm-offset-2 { + margin-left: 16.66667%; } + .col-sm-offset-3 { + margin-left: 25%; } + .col-sm-offset-4 { + margin-left: 33.33333%; } + .col-sm-offset-5 { + margin-left: 41.66667%; } + .col-sm-offset-6 { + margin-left: 50%; } + .col-sm-offset-7 { + margin-left: 58.33333%; } + .col-sm-offset-8 { + margin-left: 66.66667%; } + .col-sm-offset-9 { + margin-left: 75%; } + .col-sm-offset-10 { + margin-left: 83.33333%; } + .col-sm-offset-11 { + margin-left: 91.66667%; } + .col-sm-offset-12 { + margin-left: 100%; } } + +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; } + .col-md-1 { + width: 8.33333%; } + .col-md-2 { + width: 16.66667%; } + .col-md-3 { + width: 25%; } + .col-md-4 { + width: 33.33333%; } + .col-md-5 { + width: 41.66667%; } + .col-md-6 { + width: 50%; } + .col-md-7 { + width: 58.33333%; } + .col-md-8 { + width: 66.66667%; } + .col-md-9 { + width: 75%; } + .col-md-10 { + width: 83.33333%; } + .col-md-11 { + width: 91.66667%; } + .col-md-12 { + width: 100%; } + .col-md-pull-0 { + right: auto; } + .col-md-pull-1 { + right: 8.33333%; } + .col-md-pull-2 { + right: 16.66667%; } + .col-md-pull-3 { + right: 25%; } + .col-md-pull-4 { + right: 33.33333%; } + .col-md-pull-5 { + right: 41.66667%; } + .col-md-pull-6 { + right: 50%; } + .col-md-pull-7 { + right: 58.33333%; } + .col-md-pull-8 { + right: 66.66667%; } + .col-md-pull-9 { + right: 75%; } + .col-md-pull-10 { + right: 83.33333%; } + .col-md-pull-11 { + right: 91.66667%; } + .col-md-pull-12 { + right: 100%; } + .col-md-push-0 { + left: auto; } + .col-md-push-1 { + left: 8.33333%; } + .col-md-push-2 { + left: 16.66667%; } + .col-md-push-3 { + left: 25%; } + .col-md-push-4 { + left: 33.33333%; } + .col-md-push-5 { + left: 41.66667%; } + .col-md-push-6 { + left: 50%; } + .col-md-push-7 { + left: 58.33333%; } + .col-md-push-8 { + left: 66.66667%; } + .col-md-push-9 { + left: 75%; } + .col-md-push-10 { + left: 83.33333%; } + .col-md-push-11 { + left: 91.66667%; } + .col-md-push-12 { + left: 100%; } + .col-md-offset-0 { + margin-left: 0%; } + .col-md-offset-1 { + margin-left: 8.33333%; } + .col-md-offset-2 { + margin-left: 16.66667%; } + .col-md-offset-3 { + margin-left: 25%; } + .col-md-offset-4 { + margin-left: 33.33333%; } + .col-md-offset-5 { + margin-left: 41.66667%; } + .col-md-offset-6 { + margin-left: 50%; } + .col-md-offset-7 { + margin-left: 58.33333%; } + .col-md-offset-8 { + margin-left: 66.66667%; } + .col-md-offset-9 { + margin-left: 75%; } + .col-md-offset-10 { + margin-left: 83.33333%; } + .col-md-offset-11 { + margin-left: 91.66667%; } + .col-md-offset-12 { + margin-left: 100%; } } + +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; } + .col-lg-1 { + width: 8.33333%; } + .col-lg-2 { + width: 16.66667%; } + .col-lg-3 { + width: 25%; } + .col-lg-4 { + width: 33.33333%; } + .col-lg-5 { + width: 41.66667%; } + .col-lg-6 { + width: 50%; } + .col-lg-7 { + width: 58.33333%; } + .col-lg-8 { + width: 66.66667%; } + .col-lg-9 { + width: 75%; } + .col-lg-10 { + width: 83.33333%; } + .col-lg-11 { + width: 91.66667%; } + .col-lg-12 { + width: 100%; } + .col-lg-pull-0 { + right: auto; } + .col-lg-pull-1 { + right: 8.33333%; } + .col-lg-pull-2 { + right: 16.66667%; } + .col-lg-pull-3 { + right: 25%; } + .col-lg-pull-4 { + right: 33.33333%; } + .col-lg-pull-5 { + right: 41.66667%; } + .col-lg-pull-6 { + right: 50%; } + .col-lg-pull-7 { + right: 58.33333%; } + .col-lg-pull-8 { + right: 66.66667%; } + .col-lg-pull-9 { + right: 75%; } + .col-lg-pull-10 { + right: 83.33333%; } + .col-lg-pull-11 { + right: 91.66667%; } + .col-lg-pull-12 { + right: 100%; } + .col-lg-push-0 { + left: auto; } + .col-lg-push-1 { + left: 8.33333%; } + .col-lg-push-2 { + left: 16.66667%; } + .col-lg-push-3 { + left: 25%; } + .col-lg-push-4 { + left: 33.33333%; } + .col-lg-push-5 { + left: 41.66667%; } + .col-lg-push-6 { + left: 50%; } + .col-lg-push-7 { + left: 58.33333%; } + .col-lg-push-8 { + left: 66.66667%; } + .col-lg-push-9 { + left: 75%; } + .col-lg-push-10 { + left: 83.33333%; } + .col-lg-push-11 { + left: 91.66667%; } + .col-lg-push-12 { + left: 100%; } + .col-lg-offset-0 { + margin-left: 0%; } + .col-lg-offset-1 { + margin-left: 8.33333%; } + .col-lg-offset-2 { + margin-left: 16.66667%; } + .col-lg-offset-3 { + margin-left: 25%; } + .col-lg-offset-4 { + margin-left: 33.33333%; } + .col-lg-offset-5 { + margin-left: 41.66667%; } + .col-lg-offset-6 { + margin-left: 50%; } + .col-lg-offset-7 { + margin-left: 58.33333%; } + .col-lg-offset-8 { + margin-left: 66.66667%; } + .col-lg-offset-9 { + margin-left: 75%; } + .col-lg-offset-10 { + margin-left: 83.33333%; } + .col-lg-offset-11 { + margin-left: 91.66667%; } + .col-lg-offset-12 { + margin-left: 100%; } } + +table { + background-color: transparent; } + +caption { + padding-top: 8px; + padding-bottom: 8px; + color: #777777; + text-align: left; } + +th { + text-align: left; } + +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; } + .table > thead > tr > th, + .table > thead > tr > td, + .table > tbody > tr > th, + .table > tbody > tr > td, + .table > tfoot > tr > th, + .table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857; + vertical-align: top; + border-top: 1px solid #ddd; } + .table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; } + .table > caption + thead > tr:first-child > th, + .table > caption + thead > tr:first-child > td, + .table > colgroup + thead > tr:first-child > th, + .table > colgroup + thead > tr:first-child > td, + .table > thead:first-child > tr:first-child > th, + .table > thead:first-child > tr:first-child > td { + border-top: 0; } + .table > tbody + tbody { + border-top: 2px solid #ddd; } + .table .table { + background-color: #fff; } + +.table-condensed > thead > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > th, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > th, +.table-condensed > tfoot > tr > td { + padding: 5px; } + +.table-bordered { + border: 1px solid #ddd; } + .table-bordered > thead > tr > th, + .table-bordered > thead > tr > td, + .table-bordered > tbody > tr > th, + .table-bordered > tbody > tr > td, + .table-bordered > tfoot > tr > th, + .table-bordered > tfoot > tr > td { + border: 1px solid #ddd; } + .table-bordered > thead > tr > th, + .table-bordered > thead > tr > td { + border-bottom-width: 2px; } + +.table-striped > tbody > tr:nth-of-type(odd) { + background-color: #f9f9f9; } + +.table-hover > tbody > tr:hover { + background-color: transparent; } + +table col[class*="col-"] { + position: static; + float: none; + display: table-column; } + +table td[class*="col-"], +table th[class*="col-"] { + position: static; + float: none; + display: table-cell; } + +.table > thead > tr > td.active, +.table > thead > tr > th.active, +.table > thead > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr > td.active, +.table > tbody > tr > th.active, +.table > tbody > tr.active > td, +.table > tbody > tr.active > th, +.table > tfoot > tr > td.active, +.table > tfoot > tr > th.active, +.table > tfoot > tr.active > td, +.table > tfoot > tr.active > th { + background-color: transparent; } + +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: transparent; } + +.table > thead > tr > td.success, +.table > thead > tr > th.success, +.table > thead > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr > td.success, +.table > tbody > tr > th.success, +.table > tbody > tr.success > td, +.table > tbody > tr.success > th, +.table > tfoot > tr > td.success, +.table > tfoot > tr > th.success, +.table > tfoot > tr.success > td, +.table > tfoot > tr.success > th { + background-color: #dff0d8; } + +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; } + +.table > thead > tr > td.info, +.table > thead > tr > th.info, +.table > thead > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr > td.info, +.table > tbody > tr > th.info, +.table > tbody > tr.info > td, +.table > tbody > tr.info > th, +.table > tfoot > tr > td.info, +.table > tfoot > tr > th.info, +.table > tfoot > tr.info > td, +.table > tfoot > tr.info > th { + background-color: #d9edf7; } + +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; } + +.table > thead > tr > td.warning, +.table > thead > tr > th.warning, +.table > thead > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr > td.warning, +.table > tbody > tr > th.warning, +.table > tbody > tr.warning > td, +.table > tbody > tr.warning > th, +.table > tfoot > tr > td.warning, +.table > tfoot > tr > th.warning, +.table > tfoot > tr.warning > td, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; } + +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; } + +.table > thead > tr > td.danger, +.table > thead > tr > th.danger, +.table > thead > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr > td.danger, +.table > tbody > tr > th.danger, +.table > tbody > tr.danger > td, +.table > tbody > tr.danger > th, +.table > tfoot > tr > td.danger, +.table > tfoot > tr > th.danger, +.table > tfoot > tr.danger > td, +.table > tfoot > tr.danger > th { + background-color: #f2dede; } + +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; } + +.table-responsive { + overflow-x: auto; + min-height: 0.01%; } + @media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #ddd; } + .table-responsive > .table { + margin-bottom: 0; } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; } + .table-responsive > .table-bordered { + border: 0; } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; } } + +fieldset { + padding: 0; + margin: 0; + border: 0; + min-width: 0; } + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; } + +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; } + +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } + +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; } + +input[type="file"] { + display: block; } + +input[type="range"] { + display: block; + width: 100%; } + +select[multiple], +select[size] { + height: auto; } + +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.42857; + color: #555555; } + +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857; + color: #555555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; } + .form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); } + .form-control::-moz-placeholder { + color: #999; + opacity: 1; } + .form-control:-ms-input-placeholder { + color: #999; } + .form-control::-webkit-input-placeholder { + color: #999; } + .form-control[disabled], .form-control[readonly], + fieldset[disabled] .form-control { + background-color: #eeeeee; + opacity: 1; } + .form-control[disabled], + fieldset[disabled] .form-control { + cursor: not-allowed; } + +textarea.form-control { + height: auto; } + +input[type="search"] { + -webkit-appearance: none; } + +@media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"], + input[type="time"], + input[type="datetime-local"], + input[type="month"] { + line-height: 34px; } + input[type="date"].input-sm, + .input-group-sm input[type="date"], + input[type="time"].input-sm, + .input-group-sm + input[type="time"], + input[type="datetime-local"].input-sm, + .input-group-sm + input[type="datetime-local"], + input[type="month"].input-sm, + .input-group-sm + input[type="month"] { + line-height: 30px; } + input[type="date"].input-lg, + .input-group-lg input[type="date"], + input[type="time"].input-lg, + .input-group-lg + input[type="time"], + input[type="datetime-local"].input-lg, + .input-group-lg + input[type="datetime-local"], + input[type="month"].input-lg, + .input-group-lg + input[type="month"] { + line-height: 46px; } } + +.form-group { + margin-bottom: 15px; } + +.radio, +.checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; } + .radio label, + .checkbox label { + min-height: 20px; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; } + +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-left: -20px; + margin-top: 4px \9; } + +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; } + +.radio-inline, +.checkbox-inline { + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + vertical-align: middle; + font-weight: normal; + cursor: pointer; } + +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; } + +input[type="radio"][disabled], input[type="radio"].disabled, +fieldset[disabled] input[type="radio"], +input[type="checkbox"][disabled], +input[type="checkbox"].disabled, +fieldset[disabled] +input[type="checkbox"] { + cursor: not-allowed; } + +.radio-inline.disabled, +fieldset[disabled] .radio-inline, +.checkbox-inline.disabled, +fieldset[disabled] +.checkbox-inline { + cursor: not-allowed; } + +.radio.disabled label, +fieldset[disabled] .radio label, +.checkbox.disabled label, +fieldset[disabled] +.checkbox label { + cursor: not-allowed; } + +.form-control-static { + padding-top: 7px; + padding-bottom: 7px; + margin-bottom: 0; + min-height: 34px; } + .form-control-static.input-lg, .form-control-static.input-sm { + padding-left: 0; + padding-right: 0; } + +.input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; } + +select.input-sm { + height: 30px; + line-height: 30px; } + +textarea.input-sm, +select[multiple].input-sm { + height: auto; } + +.form-group-sm .form-control { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; } + +.form-group-sm select.form-control { + height: 30px; + line-height: 30px; } + +.form-group-sm textarea.form-control, +.form-group-sm select[multiple].form-control { + height: auto; } + +.form-group-sm .form-control-static { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + min-height: 32px; } + +.input-lg { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33333; + border-radius: 6px; } + +select.input-lg { + height: 46px; + line-height: 46px; } + +textarea.input-lg, +select[multiple].input-lg { + height: auto; } + +.form-group-lg .form-control { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33333; + border-radius: 6px; } + +.form-group-lg select.form-control { + height: 46px; + line-height: 46px; } + +.form-group-lg textarea.form-control, +.form-group-lg select[multiple].form-control { + height: auto; } + +.form-group-lg .form-control-static { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33333; + min-height: 38px; } + +.has-feedback { + position: relative; } + .has-feedback .form-control { + padding-right: 42.5px; } + +.form-control-feedback { + position: absolute; + top: 0; + right: 0; + z-index: 2; + display: block; + width: 34px; + height: 34px; + line-height: 34px; + text-align: center; + pointer-events: none; } + +.input-lg + .form-control-feedback { + width: 46px; + height: 46px; + line-height: 46px; } + +.input-sm + .form-control-feedback { + width: 30px; + height: 30px; + line-height: 30px; } + +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline, +.has-success.radio label, +.has-success.checkbox label, +.has-success.radio-inline label, +.has-success.checkbox-inline label { + color: #3c763d; } + +.has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } + .has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; } + +.has-success .input-group-addon { + color: #3c763d; + border-color: #3c763d; + background-color: #dff0d8; } + +.has-success .form-control-feedback { + color: #3c763d; } + +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline, +.has-warning.radio label, +.has-warning.checkbox label, +.has-warning.radio-inline label, +.has-warning.checkbox-inline label { + color: #8a6d3b; } + +.has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } + .has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; } + +.has-warning .input-group-addon { + color: #8a6d3b; + border-color: #8a6d3b; + background-color: #fcf8e3; } + +.has-warning .form-control-feedback { + color: #8a6d3b; } + +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline, +.has-error.radio label, +.has-error.checkbox label, +.has-error.radio-inline label, +.has-error.checkbox-inline label { + color: #a94442; } + +.has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } + .has-error .form-control:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; } + +.has-error .input-group-addon { + color: #a94442; + border-color: #a94442; + background-color: #f2dede; } + +.has-error .form-control-feedback { + color: #a94442; } + +.has-feedback label ~ .form-control-feedback { + top: 25px; } + +.has-feedback label.sr-only ~ .form-control-feedback { + top: 0; } + +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; } + +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; } + .form-inline .form-control-static { + display: inline-block; } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; } + .form-inline .input-group > .form-control { + width: 100%; } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; } + .form-inline .has-feedback .form-control-feedback { + top: 0; } } + +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + margin-top: 0; + margin-bottom: 0; + padding-top: 7px; } + +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; } + +.form-horizontal .form-group { + margin-left: -15px; + margin-right: -15px; } + .form-horizontal .form-group:before, .form-horizontal .form-group:after { + content: " "; + display: table; } + .form-horizontal .form-group:after { + clear: both; } + +@media (min-width: 768px) { + .form-horizontal .control-label { + text-align: right; + margin-bottom: 0; + padding-top: 7px; } } + +.form-horizontal .has-feedback .form-control-feedback { + right: 15px; } + +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 14.33333px; } } + +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; } } + +.btn { + display: inline-block; + margin-bottom: 0; + font-weight: normal; + text-align: center; + vertical-align: middle; + touch-action: manipulation; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + white-space: nowrap; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857; + border-radius: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + .btn:focus, .btn.focus, .btn:active:focus, .btn:active.focus, .btn.active:focus, .btn.active.focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + .btn:hover, .btn:focus, .btn.focus { + color: #333; + text-decoration: none; } + .btn:active, .btn.active { + outline: 0; + background-image: none; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); } + .btn.disabled, .btn[disabled], + fieldset[disabled] .btn { + cursor: not-allowed; + pointer-events: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; } + +.btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; } + .btn-default:hover, .btn-default:focus, .btn-default.focus, .btn-default:active, .btn-default.active, + .open > .btn-default.dropdown-toggle { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; } + .btn-default:active, .btn-default.active, + .open > .btn-default.dropdown-toggle { + background-image: none; } + .btn-default.disabled, .btn-default.disabled:hover, .btn-default.disabled:focus, .btn-default.disabled.focus, .btn-default.disabled:active, .btn-default.disabled.active, .btn-default[disabled], .btn-default[disabled]:hover, .btn-default[disabled]:focus, .btn-default[disabled].focus, .btn-default[disabled]:active, .btn-default[disabled].active, + fieldset[disabled] .btn-default, + fieldset[disabled] .btn-default:hover, + fieldset[disabled] .btn-default:focus, + fieldset[disabled] .btn-default.focus, + fieldset[disabled] .btn-default:active, + fieldset[disabled] .btn-default.active { + background-color: #fff; + border-color: #ccc; } + .btn-default .badge { + color: #fff; + background-color: #333; } + +.btn-primary, .btn-mapzen { + color: #fff; + background-color: #1E0E33; + border-color: #12091f; } + .btn-primary:hover, .btn-mapzen:hover, .btn-primary:focus, .btn-mapzen:focus, .btn-primary.focus, .focus.btn-mapzen, .btn-primary:active, .btn-mapzen:active, .btn-primary.active, .active.btn-mapzen, + .open > .btn-primary.dropdown-toggle, + .open > .dropdown-toggle.btn-mapzen { + color: #fff; + background-color: #06030b; + border-color: black; } + .btn-primary:active, .btn-mapzen:active, .btn-primary.active, .active.btn-mapzen, + .open > .btn-primary.dropdown-toggle, + .open > .dropdown-toggle.btn-mapzen { + background-image: none; } + .btn-primary.disabled, .disabled.btn-mapzen, .btn-primary.disabled:hover, .disabled.btn-mapzen:hover, .btn-primary.disabled:focus, .disabled.btn-mapzen:focus, .btn-primary.disabled.focus, .disabled.focus.btn-mapzen, .btn-primary.disabled:active, .disabled.btn-mapzen:active, .btn-primary.disabled.active, .disabled.active.btn-mapzen, .btn-primary[disabled], [disabled].btn-mapzen, .btn-primary[disabled]:hover, [disabled].btn-mapzen:hover, .btn-primary[disabled]:focus, [disabled].btn-mapzen:focus, .btn-primary[disabled].focus, [disabled].focus.btn-mapzen, .btn-primary[disabled]:active, [disabled].btn-mapzen:active, .btn-primary[disabled].active, [disabled].active.btn-mapzen, + fieldset[disabled] .btn-primary, + fieldset[disabled] .btn-mapzen, + fieldset[disabled] .btn-primary:hover, + fieldset[disabled] .btn-mapzen:hover, + fieldset[disabled] .btn-primary:focus, + fieldset[disabled] .btn-mapzen:focus, + fieldset[disabled] .btn-primary.focus, + fieldset[disabled] .focus.btn-mapzen, + fieldset[disabled] .btn-primary:active, + fieldset[disabled] .btn-mapzen:active, + fieldset[disabled] .btn-primary.active, + fieldset[disabled] .active.btn-mapzen { + background-color: #1E0E33; + border-color: #12091f; } + .btn-primary .badge, .btn-mapzen .badge { + color: #1E0E33; + background-color: #fff; } + +.btn-success { + color: #fff; + background-color: #5cb85c; + border-color: #4cae4c; } + .btn-success:hover, .btn-success:focus, .btn-success.focus, .btn-success:active, .btn-success.active, + .open > .btn-success.dropdown-toggle { + color: #fff; + background-color: #449d44; + border-color: #398439; } + .btn-success:active, .btn-success.active, + .open > .btn-success.dropdown-toggle { + background-image: none; } + .btn-success.disabled, .btn-success.disabled:hover, .btn-success.disabled:focus, .btn-success.disabled.focus, .btn-success.disabled:active, .btn-success.disabled.active, .btn-success[disabled], .btn-success[disabled]:hover, .btn-success[disabled]:focus, .btn-success[disabled].focus, .btn-success[disabled]:active, .btn-success[disabled].active, + fieldset[disabled] .btn-success, + fieldset[disabled] .btn-success:hover, + fieldset[disabled] .btn-success:focus, + fieldset[disabled] .btn-success.focus, + fieldset[disabled] .btn-success:active, + fieldset[disabled] .btn-success.active { + background-color: #5cb85c; + border-color: #4cae4c; } + .btn-success .badge { + color: #5cb85c; + background-color: #fff; } + +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; } + .btn-info:hover, .btn-info:focus, .btn-info.focus, .btn-info:active, .btn-info.active, + .open > .btn-info.dropdown-toggle { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; } + .btn-info:active, .btn-info.active, + .open > .btn-info.dropdown-toggle { + background-image: none; } + .btn-info.disabled, .btn-info.disabled:hover, .btn-info.disabled:focus, .btn-info.disabled.focus, .btn-info.disabled:active, .btn-info.disabled.active, .btn-info[disabled], .btn-info[disabled]:hover, .btn-info[disabled]:focus, .btn-info[disabled].focus, .btn-info[disabled]:active, .btn-info[disabled].active, + fieldset[disabled] .btn-info, + fieldset[disabled] .btn-info:hover, + fieldset[disabled] .btn-info:focus, + fieldset[disabled] .btn-info.focus, + fieldset[disabled] .btn-info:active, + fieldset[disabled] .btn-info.active { + background-color: #5bc0de; + border-color: #46b8da; } + .btn-info .badge { + color: #5bc0de; + background-color: #fff; } + +.btn-warning { + color: #fff; + background-color: #f0ad4e; + border-color: #eea236; } + .btn-warning:hover, .btn-warning:focus, .btn-warning.focus, .btn-warning:active, .btn-warning.active, + .open > .btn-warning.dropdown-toggle { + color: #fff; + background-color: #ec971f; + border-color: #d58512; } + .btn-warning:active, .btn-warning.active, + .open > .btn-warning.dropdown-toggle { + background-image: none; } + .btn-warning.disabled, .btn-warning.disabled:hover, .btn-warning.disabled:focus, .btn-warning.disabled.focus, .btn-warning.disabled:active, .btn-warning.disabled.active, .btn-warning[disabled], .btn-warning[disabled]:hover, .btn-warning[disabled]:focus, .btn-warning[disabled].focus, .btn-warning[disabled]:active, .btn-warning[disabled].active, + fieldset[disabled] .btn-warning, + fieldset[disabled] .btn-warning:hover, + fieldset[disabled] .btn-warning:focus, + fieldset[disabled] .btn-warning.focus, + fieldset[disabled] .btn-warning:active, + fieldset[disabled] .btn-warning.active { + background-color: #f0ad4e; + border-color: #eea236; } + .btn-warning .badge { + color: #f0ad4e; + background-color: #fff; } + +.btn-danger { + color: #fff; + background-color: #d9534f; + border-color: #d43f3a; } + .btn-danger:hover, .btn-danger:focus, .btn-danger.focus, .btn-danger:active, .btn-danger.active, + .open > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; } + .btn-danger:active, .btn-danger.active, + .open > .btn-danger.dropdown-toggle { + background-image: none; } + .btn-danger.disabled, .btn-danger.disabled:hover, .btn-danger.disabled:focus, .btn-danger.disabled.focus, .btn-danger.disabled:active, .btn-danger.disabled.active, .btn-danger[disabled], .btn-danger[disabled]:hover, .btn-danger[disabled]:focus, .btn-danger[disabled].focus, .btn-danger[disabled]:active, .btn-danger[disabled].active, + fieldset[disabled] .btn-danger, + fieldset[disabled] .btn-danger:hover, + fieldset[disabled] .btn-danger:focus, + fieldset[disabled] .btn-danger.focus, + fieldset[disabled] .btn-danger:active, + fieldset[disabled] .btn-danger.active { + background-color: #d9534f; + border-color: #d43f3a; } + .btn-danger .badge { + color: #d9534f; + background-color: #fff; } + +.btn-link { + color: #6ea0a4; + font-weight: normal; + border-radius: 0; } + .btn-link, .btn-link:active, .btn-link.active, .btn-link[disabled], + fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; } + .btn-link, .btn-link:hover, .btn-link:focus, .btn-link:active { + border-color: transparent; } + .btn-link:hover, .btn-link:focus { + color: #385d5c; + text-decoration: none; + background-color: transparent; } + .btn-link[disabled]:hover, .btn-link[disabled]:focus, + fieldset[disabled] .btn-link:hover, + fieldset[disabled] .btn-link:focus { + color: #777777; + text-decoration: none; } + +.btn-lg, .btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.33333; + border-radius: 6px; } + +.btn-sm, .btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; } + +.btn-xs, .btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; } + +.btn-block { + display: block; + width: 100%; } + +.btn-block + .btn-block { + margin-top: 5px; } + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; } + +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; } + .fade.in { + opacity: 1; } + +.collapse { + display: none; } + .collapse.in { + display: block; } + +tr.collapse.in { + display: table-row; } + +tbody.collapse.in { + display: table-row-group; } + +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition-property: height, visibility; + transition-property: height, visibility; + -webkit-transition-duration: 0.35s; + transition-duration: 0.35s; + -webkit-transition-timing-function: ease; + transition-timing-function: ease; } + +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px dashed; + border-right: 4px solid transparent; + border-left: 4px solid transparent; } + +.dropup, +.dropdown { + position: relative; } + +.dropdown-toggle:focus { + outline: 0; } + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + font-size: 14px; + text-align: left; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + background-clip: padding-box; } + .dropdown-menu.pull-right { + right: 0; + left: auto; } + .dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; } + .dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857; + color: #333333; + white-space: nowrap; } + +.dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus { + text-decoration: none; + color: #262626; + background-color: #f5f5f5; } + +.dropdown-menu > .active > a, .dropdown-menu > .active > a:hover, .dropdown-menu > .active > a:focus { + color: #fff; + text-decoration: none; + outline: 0; + background-color: #337ab7; } + +.dropdown-menu > .disabled > a, .dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus { + color: #777777; } + +.dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + cursor: not-allowed; } + +.open > .dropdown-menu { + display: block; } + +.open > a { + outline: 0; } + +.dropdown-menu-right { + left: auto; + right: 0; } + +.dropdown-menu-left { + left: 0; + right: auto; } + +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.42857; + color: #777777; + white-space: nowrap; } + +.dropdown-backdrop { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + z-index: 990; } + +.pull-right > .dropdown-menu { + right: 0; + left: auto; } + +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid; + content: ""; } + +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 2px; } + +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; } + .navbar-right .dropdown-menu-left { + left: 0; + right: auto; } } + +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; } + .btn-group > .btn, + .btn-group-vertical > .btn { + position: relative; + float: left; } + .btn-group > .btn:hover, .btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active, + .btn-group-vertical > .btn:hover, + .btn-group-vertical > .btn:focus, + .btn-group-vertical > .btn:active, + .btn-group-vertical > .btn.active { + z-index: 2; } + +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; } + +.btn-toolbar { + margin-left: -5px; } + .btn-toolbar:before, .btn-toolbar:after { + content: " "; + display: table; } + .btn-toolbar:after { + clear: both; } + .btn-toolbar .btn-group, + .btn-toolbar .input-group { + float: left; } + .btn-toolbar > .btn, + .btn-toolbar > .btn-group, + .btn-toolbar > .input-group { + margin-left: 5px; } + +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; } + +.btn-group > .btn:first-child { + margin-left: 0; } + .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; } + +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; } + +.btn-group > .btn-group { + float: left; } + +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; } + +.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-top-right-radius: 0; } + +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-bottom-left-radius: 0; + border-top-left-radius: 0; } + +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; } + +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; } + +.btn-group > .btn-lg + .dropdown-toggle, .btn-group-lg.btn-group > .btn + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; } + +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); } + .btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; } + +.btn .caret { + margin-left: 0; } + +.btn-lg .caret, .btn-group-lg > .btn .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; } + +.dropup .btn-lg .caret, .dropup .btn-group-lg > .btn .caret { + border-width: 0 5px 5px; } + +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; } + +.btn-group-vertical > .btn-group:before, .btn-group-vertical > .btn-group:after { + content: " "; + display: table; } + +.btn-group-vertical > .btn-group:after { + clear: both; } + +.btn-group-vertical > .btn-group > .btn { + float: none; } + +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; } + +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; } + +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; } + +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-bottom-left-radius: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; } + +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; } + +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; } + +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; } + +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; } + .btn-group-justified > .btn, + .btn-group-justified > .btn-group { + float: none; + display: table-cell; + width: 1%; } + .btn-group-justified > .btn-group .btn { + width: 100%; } + .btn-group-justified > .btn-group .dropdown-menu { + left: auto; } + +[data-toggle="buttons"] > .btn input[type="radio"], +[data-toggle="buttons"] > .btn input[type="checkbox"], +[data-toggle="buttons"] > .btn-group > .btn input[type="radio"], +[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; } + +.nav { + margin-bottom: 0; + padding-left: 0; + list-style: none; } + .nav:before, .nav:after { + content: " "; + display: table; } + .nav:after { + clear: both; } + .nav > li { + position: relative; + display: block; } + .nav > li > a { + position: relative; + display: block; + padding: 10px 12px; } + .nav > li > a:hover, .nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; } + .nav > li.disabled > a { + color: #777777; } + .nav > li.disabled > a:hover, .nav > li.disabled > a:focus { + color: #777777; + text-decoration: none; + background-color: transparent; + cursor: not-allowed; } + .nav .open > a, .nav .open > a:hover, .nav .open > a:focus { + background-color: #eeeeee; + border-color: #6ea0a4; } + .nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; } + .nav > li > a > img { + max-width: none; } + +.nav-tabs { + border-bottom: 1px solid #ddd; } + .nav-tabs > li { + float: left; + margin-bottom: -1px; } + .nav-tabs > li > a { + margin-right: 2px; + line-height: 1.42857; + border: 1px solid transparent; + border-radius: 0 0 0 0; } + .nav-tabs > li > a:hover { + border-color: #eeeeee #eeeeee #ddd; } + .nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus { + color: #555555; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; + cursor: default; } + +.nav-pills > li { + float: left; } + .nav-pills > li > a { + border-radius: 0; } + .nav-pills > li + li { + margin-left: 2px; } + .nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus { + color: #fff; + background-color: #337ab7; } + +.nav-stacked > li { + float: none; } + .nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; } + +.nav-justified, .nav-tabs.nav-justified { + width: 100%; } + .nav-justified > li, .nav-tabs.nav-justified > li { + float: none; } + .nav-justified > li > a, .nav-tabs.nav-justified > li > a { + text-align: center; + margin-bottom: 5px; } + .nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; } + @media (min-width: 768px) { + .nav-justified > li, .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; } + .nav-justified > li > a, .nav-tabs.nav-justified > li > a { + margin-bottom: 0; } } + +.nav-tabs-justified, .nav-tabs.nav-justified { + border-bottom: 0; } + .nav-tabs-justified > li > a, .nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 0; } + .nav-tabs-justified > .active > a, .nav-tabs.nav-justified > .active > a, + .nav-tabs-justified > .active > a:hover, .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus, .nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #ddd; } + @media (min-width: 768px) { + .nav-tabs-justified > li > a, .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 0 0 0 0; } + .nav-tabs-justified > .active > a, .nav-tabs.nav-justified > .active > a, + .nav-tabs-justified > .active > a:hover, .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus, .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #fff; } } + +.tab-content > .tab-pane { + display: none; } + +.tab-content > .active { + display: block; } + +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-right-radius: 0; + border-top-left-radius: 0; } + +.navbar { + position: relative; + min-height: 50px; + margin-bottom: 0; + border: 1px solid transparent; } + .navbar:before, .navbar:after { + content: " "; + display: table; } + .navbar:after { + clear: both; } + @media (min-width: 768px) { + .navbar { + border-radius: 0; } } + +.navbar-header:before, .navbar-header:after { + content: " "; + display: table; } + +.navbar-header:after { + clear: both; } + +@media (min-width: 768px) { + .navbar-header { + float: left; } } + +.navbar-collapse { + overflow-x: visible; + padding-right: 15px; + padding-left: 15px; + border-top: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-overflow-scrolling: touch; } + .navbar-collapse:before, .navbar-collapse:after { + content: " "; + display: table; } + .navbar-collapse:after { + clear: both; } + .navbar-collapse.in { + overflow-y: auto; } + @media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + box-shadow: none; } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; } + .navbar-collapse.in { + overflow-y: visible; } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-left: 0; + padding-right: 0; } } + +.navbar-fixed-top .navbar-collapse, +.navbar-fixed-bottom .navbar-collapse { + max-height: 340px; } + @media (max-device-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; } } + +.container > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-header, +.container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; } + @media (min-width: 768px) { + .container > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-header, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; } } + +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; } + @media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; } } + +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; } + @media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; } } + +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; } + +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; } + +.navbar-brand { + float: left; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; + height: 50px; } + .navbar-brand:hover, .navbar-brand:focus { + text-decoration: none; } + .navbar-brand > img { + display: block; } + @media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; } } + +.navbar-toggle { + position: relative; + float: right; + margin-right: 15px; + padding: 9px 10px; + margin-top: 8px; + margin-bottom: 8px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 0; } + .navbar-toggle:focus { + outline: 0; } + .navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; } + .navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; } + @media (min-width: 768px) { + .navbar-toggle { + display: none; } } + +.navbar-nav { + margin: 7.5px -15px; } + .navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; } + @media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + box-shadow: none; } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; } + .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; } } + @media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; } + .navbar-nav > li { + float: left; } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; } } + +.navbar-form { + margin-left: -15px; + margin-right: -15px; + padding: 10px 15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + margin-top: 8px; + margin-bottom: 8px; } + @media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; } + .navbar-form .form-control-static { + display: inline-block; } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; } + .navbar-form .input-group > .form-control { + width: 100%; } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; } + .navbar-form .has-feedback .form-control-feedback { + top: 0; } } + @media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; } + .navbar-form .form-group:last-child { + margin-bottom: 0; } } + @media (min-width: 768px) { + .navbar-form { + width: auto; + border: 0; + margin-left: 0; + margin-right: 0; + padding-top: 0; + padding-bottom: 0; + -webkit-box-shadow: none; + box-shadow: none; } } + +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; } + +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + margin-bottom: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; } + +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; } + .navbar-btn.btn-sm, .btn-group-sm > .navbar-btn.btn { + margin-top: 10px; + margin-bottom: 10px; } + .navbar-btn.btn-xs, .btn-group-xs > .navbar-btn.btn { + margin-top: 14px; + margin-bottom: 14px; } + +.navbar-text { + margin-top: 15px; + margin-bottom: 15px; } + @media (min-width: 768px) { + .navbar-text { + float: left; + margin-left: 15px; + margin-right: 15px; } } + +@media (min-width: 768px) { + .navbar-left { + float: left !important; } + .navbar-right { + float: right !important; + margin-right: -15px; } + .navbar-right ~ .navbar-right { + margin-right: 0; } } + +.navbar-default { + background-color: rgba(30, 14, 51, 0.9); + border-color: rgba(15, 7, 25, 0.9); } + .navbar-default .navbar-brand { + color: white; } + .navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus { + color: #e6e6e6; + background-color: transparent; } + .navbar-default .navbar-text { + color: #777; } + .navbar-default .navbar-nav > li > a { + color: white; } + .navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus { + color: #EEE7F8; + background-color: transparent; } + .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus { + color: #EEE7F8; + background-color: transparent; } + .navbar-default .navbar-nav > .disabled > a, .navbar-default .navbar-nav > .disabled > a:hover, .navbar-default .navbar-nav > .disabled > a:focus { + color: #ccc; + background-color: transparent; } + .navbar-default .navbar-toggle { + border-color: transparent; } + .navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus { + background-color: transparent; } + .navbar-default .navbar-toggle .icon-bar { + background-color: #EEE7F8; } + .navbar-default .navbar-collapse, + .navbar-default .navbar-form { + border-color: rgba(15, 7, 25, 0.9); } + .navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus { + background-color: transparent; + color: #EEE7F8; } + @media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: white; } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #EEE7F8; + background-color: transparent; } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #EEE7F8; + background-color: transparent; } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #ccc; + background-color: transparent; } } + .navbar-default .navbar-link { + color: white; } + .navbar-default .navbar-link:hover { + color: #EEE7F8; } + .navbar-default .btn-link { + color: white; } + .navbar-default .btn-link:hover, .navbar-default .btn-link:focus { + color: #EEE7F8; } + .navbar-default .btn-link[disabled]:hover, .navbar-default .btn-link[disabled]:focus, + fieldset[disabled] .navbar-default .btn-link:hover, + fieldset[disabled] .navbar-default .btn-link:focus { + color: #ccc; } + +.navbar-inverse { + background-color: #222; + border-color: #090909; } + .navbar-inverse .navbar-brand { + color: #9d9d9d; } + .navbar-inverse .navbar-brand:hover, .navbar-inverse .navbar-brand:focus { + color: #fff; + background-color: transparent; } + .navbar-inverse .navbar-text { + color: #9d9d9d; } + .navbar-inverse .navbar-nav > li > a { + color: #9d9d9d; } + .navbar-inverse .navbar-nav > li > a:hover, .navbar-inverse .navbar-nav > li > a:focus { + color: #fff; + background-color: transparent; } + .navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .active > a:hover, .navbar-inverse .navbar-nav > .active > a:focus { + color: #fff; + background-color: #090909; } + .navbar-inverse .navbar-nav > .disabled > a, .navbar-inverse .navbar-nav > .disabled > a:hover, .navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444; + background-color: transparent; } + .navbar-inverse .navbar-toggle { + border-color: #333; } + .navbar-inverse .navbar-toggle:hover, .navbar-inverse .navbar-toggle:focus { + background-color: #333; } + .navbar-inverse .navbar-toggle .icon-bar { + background-color: #fff; } + .navbar-inverse .navbar-collapse, + .navbar-inverse .navbar-form { + border-color: #101010; } + .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus { + background-color: #090909; + color: #fff; } + @media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #090909; } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #090909; } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #9d9d9d; } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #fff; + background-color: transparent; } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-color: #090909; } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444; + background-color: transparent; } } + .navbar-inverse .navbar-link { + color: #9d9d9d; } + .navbar-inverse .navbar-link:hover { + color: #fff; } + .navbar-inverse .btn-link { + color: #9d9d9d; } + .navbar-inverse .btn-link:hover, .navbar-inverse .btn-link:focus { + color: #fff; } + .navbar-inverse .btn-link[disabled]:hover, .navbar-inverse .btn-link[disabled]:focus, + fieldset[disabled] .navbar-inverse .btn-link:hover, + fieldset[disabled] .navbar-inverse .btn-link:focus { + color: #444; } + +.breadcrumb { + padding: 1em 0; + margin-bottom: 20px; + list-style: none; + background-color: transparent; + border-radius: 0; } + .breadcrumb > li { + display: inline-block; } + .breadcrumb > li + li:before { + content: " "; + padding: 0 5px; + color: #ccc; } + .breadcrumb > .active { + color: #898989; } + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; } + to { + background-position: 0 0; } } + +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; } + to { + background-position: 0 0; } } + +.progress { + overflow: hidden; + height: 20px; + margin-bottom: 20px; + background-color: #f5f5f5; + border-radius: 0; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); } + +.progress-bar { + float: left; + width: 0%; + height: 100%; + font-size: 12px; + line-height: 20px; + color: #fff; + text-align: center; + background-color: #337ab7; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; } + +.progress-striped .progress-bar, +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 40px 40px; } + +.progress.active .progress-bar, +.progress-bar.active { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; } + +.progress-bar-success { + background-color: #5cb85c; } + .progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } + +.progress-bar-info { + background-color: #5bc0de; } + .progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } + +.progress-bar-warning { + background-color: #f0ad4e; } + .progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } + +.progress-bar-danger { + background-color: #d9534f; } + .progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } + +.panel { + margin-bottom: 20px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 0; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); } + +.panel-body { + padding: 15px; } + .panel-body:before, .panel-body:after { + content: " "; + display: table; } + .panel-body:after { + clear: both; } + +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-right-radius: -1; + border-top-left-radius: -1; } + .panel-heading > .dropdown .dropdown-toggle { + color: inherit; } + +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; } + .panel-title > a, + .panel-title > small, + .panel-title > .small, + .panel-title > small > a, + .panel-title > .small > a { + color: inherit; } + +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + border-bottom-right-radius: -1; + border-bottom-left-radius: -1; } + +.panel > .list-group, +.panel > .panel-collapse > .list-group { + margin-bottom: 0; } + .panel > .list-group .list-group-item, + .panel > .panel-collapse > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; } + .panel > .list-group:first-child .list-group-item:first-child, + .panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { + border-top: 0; + border-top-right-radius: -1; + border-top-left-radius: -1; } + .panel > .list-group:last-child .list-group-item:last-child, + .panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { + border-bottom: 0; + border-bottom-right-radius: -1; + border-bottom-left-radius: -1; } + +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; } + +.list-group + .panel-footer { + border-top-width: 0; } + +.panel > .table, +.panel > .table-responsive > .table, +.panel > .panel-collapse > .table { + margin-bottom: 0; } + .panel > .table caption, + .panel > .table-responsive > .table caption, + .panel > .panel-collapse > .table caption { + padding-left: 15px; + padding-right: 15px; } + +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { + border-top-right-radius: -1; + border-top-left-radius: -1; } + .panel > .table:first-child > thead:first-child > tr:first-child, + .panel > .table:first-child > tbody:first-child > tr:first-child, + .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, + .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { + border-top-left-radius: -1; + border-top-right-radius: -1; } + .panel > .table:first-child > thead:first-child > tr:first-child td:first-child, + .panel > .table:first-child > thead:first-child > tr:first-child th:first-child, + .panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, + .panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, + .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, + .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, + .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, + .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: -1; } + .panel > .table:first-child > thead:first-child > tr:first-child td:last-child, + .panel > .table:first-child > thead:first-child > tr:first-child th:last-child, + .panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, + .panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, + .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, + .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, + .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, + .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: -1; } + +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: -1; + border-bottom-left-radius: -1; } + .panel > .table:last-child > tbody:last-child > tr:last-child, + .panel > .table:last-child > tfoot:last-child > tr:last-child, + .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, + .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { + border-bottom-left-radius: -1; + border-bottom-right-radius: -1; } + .panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, + .panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, + .panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, + .panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, + .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, + .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, + .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, + .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: -1; } + .panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, + .panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, + .panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, + .panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, + .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, + .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, + .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, + .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: -1; } + +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive, +.panel > .table + .panel-body, +.panel > .table-responsive + .panel-body { + border-top: 1px solid #ddd; } + +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; } + +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; } + .panel > .table-bordered > thead > tr > th:first-child, + .panel > .table-bordered > thead > tr > td:first-child, + .panel > .table-bordered > tbody > tr > th:first-child, + .panel > .table-bordered > tbody > tr > td:first-child, + .panel > .table-bordered > tfoot > tr > th:first-child, + .panel > .table-bordered > tfoot > tr > td:first-child, + .panel > .table-responsive > .table-bordered > thead > tr > th:first-child, + .panel > .table-responsive > .table-bordered > thead > tr > td:first-child, + .panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, + .panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, + .panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; } + .panel > .table-bordered > thead > tr > th:last-child, + .panel > .table-bordered > thead > tr > td:last-child, + .panel > .table-bordered > tbody > tr > th:last-child, + .panel > .table-bordered > tbody > tr > td:last-child, + .panel > .table-bordered > tfoot > tr > th:last-child, + .panel > .table-bordered > tfoot > tr > td:last-child, + .panel > .table-responsive > .table-bordered > thead > tr > th:last-child, + .panel > .table-responsive > .table-bordered > thead > tr > td:last-child, + .panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, + .panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, + .panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; } + .panel > .table-bordered > thead > tr:first-child > td, + .panel > .table-bordered > thead > tr:first-child > th, + .panel > .table-bordered > tbody > tr:first-child > td, + .panel > .table-bordered > tbody > tr:first-child > th, + .panel > .table-responsive > .table-bordered > thead > tr:first-child > td, + .panel > .table-responsive > .table-bordered > thead > tr:first-child > th, + .panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, + .panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; } + .panel > .table-bordered > tbody > tr:last-child > td, + .panel > .table-bordered > tbody > tr:last-child > th, + .panel > .table-bordered > tfoot > tr:last-child > td, + .panel > .table-bordered > tfoot > tr:last-child > th, + .panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, + .panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, + .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, + .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; } + +.panel > .table-responsive { + border: 0; + margin-bottom: 0; } + +.panel-group { + margin-bottom: 20px; } + .panel-group .panel { + margin-bottom: 0; + border-radius: 0; } + .panel-group .panel + .panel { + margin-top: 5px; } + .panel-group .panel-heading { + border-bottom: 0; } + .panel-group .panel-heading + .panel-collapse > .panel-body, + .panel-group .panel-heading + .panel-collapse > .list-group { + border-top: 1px solid #ddd; } + .panel-group .panel-footer { + border-top: 0; } + .panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #ddd; } + +.panel-default { + border-color: #ddd; } + .panel-default > .panel-heading { + color: #333333; + background-color: #f5f5f5; + border-color: #ddd; } + .panel-default > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ddd; } + .panel-default > .panel-heading .badge { + color: #f5f5f5; + background-color: #333333; } + .panel-default > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ddd; } + +.panel-primary { + border-color: #337ab7; } + .panel-primary > .panel-heading { + color: #fff; + background-color: #337ab7; + border-color: #337ab7; } + .panel-primary > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #337ab7; } + .panel-primary > .panel-heading .badge { + color: #337ab7; + background-color: #fff; } + .panel-primary > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #337ab7; } + +.panel-success { + border-color: #d6e9c6; } + .panel-success > .panel-heading { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; } + .panel-success > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #d6e9c6; } + .panel-success > .panel-heading .badge { + color: #dff0d8; + background-color: #3c763d; } + .panel-success > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #d6e9c6; } + +.panel-info { + border-color: #bce8f1; } + .panel-info > .panel-heading { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; } + .panel-info > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #bce8f1; } + .panel-info > .panel-heading .badge { + color: #d9edf7; + background-color: #31708f; } + .panel-info > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #bce8f1; } + +.panel-warning { + border-color: #faebcc; } + .panel-warning > .panel-heading { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; } + .panel-warning > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #faebcc; } + .panel-warning > .panel-heading .badge { + color: #fcf8e3; + background-color: #8a6d3b; } + .panel-warning > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #faebcc; } + +.panel-danger { + border-color: #ebccd1; } + .panel-danger > .panel-heading { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; } + .panel-danger > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ebccd1; } + .panel-danger > .panel-heading .badge { + color: #f2dede; + background-color: #a94442; } + .panel-danger > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ebccd1; } + +.modal-open { + overflow: hidden; } + +.modal { + display: none; + overflow: hidden; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + -webkit-overflow-scrolling: touch; + outline: 0; } + .modal.fade .modal-dialog { + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + -o-transform: translate(0, -25%); + transform: translate(0, -25%); + -webkit-transition: -webkit-transform 0.3s ease-out; + -moz-transition: -moz-transform 0.3s ease-out; + -o-transition: -o-transform 0.3s ease-out; + transition: transform 0.3s ease-out; } + .modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); } + +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; } + +.modal-dialog { + position: relative; + width: auto; + margin: 10px; } + +.modal-content { + position: relative; + background-color: #fff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + background-clip: padding-box; + outline: 0; } + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; } + .modal-backdrop.fade { + opacity: 0; + filter: alpha(opacity=0); } + .modal-backdrop.in { + opacity: 0.5; + filter: alpha(opacity=50); } + +.modal-header { + padding: 15px; + border-bottom: 1px solid #e5e5e5; + min-height: 16.42857px; } + +.modal-header .close { + margin-top: -2px; } + +.modal-title { + margin: 0; + line-height: 1.42857; } + +.modal-body { + position: relative; + padding: 15px; } + +.modal-footer { + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; } + .modal-footer:before, .modal-footer:after { + content: " "; + display: table; } + .modal-footer:after { + clear: both; } + .modal-footer .btn + .btn { + margin-left: 5px; + margin-bottom: 0; } + .modal-footer .btn-group .btn + .btn { + margin-left: -1px; } + .modal-footer .btn-block + .btn-block { + margin-left: 0; } + +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; } + +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); } + .modal-sm { + width: 300px; } } + +@media (min-width: 992px) { + .modal-lg { + width: 900px; } } + +.tooltip { + position: absolute; + z-index: 1070; + display: block; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 12px; + font-weight: normal; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); } + .tooltip.in { + opacity: 0.9; + filter: alpha(opacity=90); } + .tooltip.top { + margin-top: -3px; + padding: 5px 0; } + .tooltip.right { + margin-left: 3px; + padding: 0 5px; } + .tooltip.bottom { + margin-top: 3px; + padding: 5px 0; } + .tooltip.left { + margin-left: -3px; + padding: 0 5px; } + +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + text-decoration: none; + background-color: #000; + border-radius: 0; } + +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; } + +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; } + +.tooltip.top-left .tooltip-arrow { + bottom: 0; + right: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; } + +.tooltip.top-right .tooltip-arrow { + bottom: 0; + left: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; } + +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; } + +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; } + +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; } + +.tooltip.bottom-left .tooltip-arrow { + top: 0; + right: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; } + +.tooltip.bottom-right .tooltip-arrow { + top: 0; + left: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; } + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + font-weight: normal; + line-height: 1.42857; + text-align: left; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + white-space: normal; } + .popover.top { + margin-top: -10px; } + .popover.right { + margin-left: 10px; } + .popover.bottom { + margin-top: 10px; } + .popover.left { + margin-left: -10px; } + +.popover-title { + margin: 0; + padding: 8px 14px; + font-size: 14px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; } + +.popover-content { + padding: 9px 14px; } + +.popover > .arrow, .popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; } + +.popover > .arrow { + border-width: 11px; } + +.popover > .arrow:after { + border-width: 10px; + content: ""; } + +.popover.top > .arrow { + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: #999999; + border-top-color: rgba(0, 0, 0, 0.25); + bottom: -11px; } + .popover.top > .arrow:after { + content: " "; + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #fff; } + +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: #999999; + border-right-color: rgba(0, 0, 0, 0.25); } + .popover.right > .arrow:after { + content: " "; + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #fff; } + +.popover.bottom > .arrow { + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999999; + border-bottom-color: rgba(0, 0, 0, 0.25); + top: -11px; } + .popover.bottom > .arrow:after { + content: " "; + top: 1px; + margin-left: -10px; + border-top-width: 0; + border-bottom-color: #fff; } + +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999999; + border-left-color: rgba(0, 0, 0, 0.25); } + .popover.left > .arrow:after { + content: " "; + right: 1px; + border-right-width: 0; + border-left-color: #fff; + bottom: -10px; } + +.carousel { + position: relative; } + +.carousel-inner { + position: relative; + overflow: hidden; + width: 100%; } + .carousel-inner > .item { + display: none; + position: relative; + -webkit-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; } + .carousel-inner > .item > img, + .carousel-inner > .item > a > img { + display: block; + max-width: 100%; + height: auto; + line-height: 1; } + @media all and (transform-3d), (-webkit-transform-3d) { + .carousel-inner > .item { + -webkit-transition: -webkit-transform 0.6s ease-in-out; + -moz-transition: -moz-transform 0.6s ease-in-out; + -o-transition: -o-transform 0.6s ease-in-out; + transition: transform 0.6s ease-in-out; + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000; + -moz-perspective: 1000; + perspective: 1000; } + .carousel-inner > .item.next, .carousel-inner > .item.active.right { + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + left: 0; } + .carousel-inner > .item.prev, .carousel-inner > .item.active.left { + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + left: 0; } + .carousel-inner > .item.next.left, .carousel-inner > .item.prev.right, .carousel-inner > .item.active { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + left: 0; } } + .carousel-inner > .active, + .carousel-inner > .next, + .carousel-inner > .prev { + display: block; } + .carousel-inner > .active { + left: 0; } + .carousel-inner > .next, + .carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; } + .carousel-inner > .next { + left: 100%; } + .carousel-inner > .prev { + left: -100%; } + .carousel-inner > .next.left, + .carousel-inner > .prev.right { + left: 0; } + .carousel-inner > .active.left { + left: -100%; } + .carousel-inner > .active.right { + left: 100%; } + +.carousel-control { + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: 15%; + opacity: 0.5; + filter: alpha(opacity=50); + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); } + .carousel-control.left { + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); } + .carousel-control.right { + left: auto; + right: 0; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); } + .carousel-control:hover, .carousel-control:focus { + outline: 0; + color: #fff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); } + .carousel-control .icon-prev, + .carousel-control .icon-next, + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; } + .carousel-control .icon-prev, + .carousel-control .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; } + .carousel-control .icon-next, + .carousel-control .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; } + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 20px; + height: 20px; + margin-top: -10px; + line-height: 1; + font-family: serif; } + .carousel-control .icon-prev:before { + content: '\2039'; } + .carousel-control .icon-next:before { + content: '\203a'; } + +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + margin-left: -30%; + padding-left: 0; + list-style: none; + text-align: center; } + .carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + border: 1px solid #fff; + border-radius: 10px; + cursor: pointer; + background-color: #000 \9; + background-color: transparent; } + .carousel-indicators .active { + margin: 0; + width: 12px; + height: 12px; + background-color: #fff; } + +.carousel-caption { + position: absolute; + left: 15%; + right: 15%; + bottom: 20px; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); } + .carousel-caption .btn { + text-shadow: none; } + +@media screen and (min-width: 768px) { + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + font-size: 30px; } + .carousel-control .glyphicon-chevron-left, + .carousel-control .icon-prev { + margin-left: -15px; } + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-next { + margin-right: -15px; } + .carousel-caption { + left: 20%; + right: 20%; + padding-bottom: 30px; } + .carousel-indicators { + bottom: 20px; } } + +.clearfix:before, .clearfix:after { + content: " "; + display: table; } + +.clearfix:after { + clear: both; } + +.center-block { + display: block; + margin-left: auto; + margin-right: auto; } + +.pull-right { + float: right !important; } + +.pull-left { + float: left !important; } + +.hide { + display: none !important; } + +.show { + display: block !important; } + +.invisible { + visibility: hidden; } + +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; } + +.hidden { + display: none !important; } + +.affix { + position: fixed; } + +@-ms-viewport { + width: device-width; } + +.visible-xs { + display: none !important; } + +.visible-sm { + display: none !important; } + +.visible-md { + display: none !important; } + +.visible-lg { + display: none !important; } + +.visible-xs-block, +.visible-xs-inline, +.visible-xs-inline-block, +.visible-sm-block, +.visible-sm-inline, +.visible-sm-inline-block, +.visible-md-block, +.visible-md-inline, +.visible-md-inline-block, +.visible-lg-block, +.visible-lg-inline, +.visible-lg-inline-block { + display: none !important; } + +@media (max-width: 767px) { + .visible-xs { + display: block !important; } + table.visible-xs { + display: table; } + tr.visible-xs { + display: table-row !important; } + th.visible-xs, + td.visible-xs { + display: table-cell !important; } } + +@media (max-width: 767px) { + .visible-xs-block { + display: block !important; } } + +@media (max-width: 767px) { + .visible-xs-inline { + display: inline !important; } } + +@media (max-width: 767px) { + .visible-xs-inline-block { + display: inline-block !important; } } + +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; } + table.visible-sm { + display: table; } + tr.visible-sm { + display: table-row !important; } + th.visible-sm, + td.visible-sm { + display: table-cell !important; } } + +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-block { + display: block !important; } } + +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline { + display: inline !important; } } + +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline-block { + display: inline-block !important; } } + +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; } + table.visible-md { + display: table; } + tr.visible-md { + display: table-row !important; } + th.visible-md, + td.visible-md { + display: table-cell !important; } } + +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-block { + display: block !important; } } + +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline { + display: inline !important; } } + +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline-block { + display: inline-block !important; } } + +@media (min-width: 1200px) { + .visible-lg { + display: block !important; } + table.visible-lg { + display: table; } + tr.visible-lg { + display: table-row !important; } + th.visible-lg, + td.visible-lg { + display: table-cell !important; } } + +@media (min-width: 1200px) { + .visible-lg-block { + display: block !important; } } + +@media (min-width: 1200px) { + .visible-lg-inline { + display: inline !important; } } + +@media (min-width: 1200px) { + .visible-lg-inline-block { + display: inline-block !important; } } + +@media (max-width: 767px) { + .hidden-xs { + display: none !important; } } + +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; } } + +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; } } + +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; } } + +.visible-print { + display: none !important; } + +@media print { + .visible-print { + display: block !important; } + table.visible-print { + display: table; } + tr.visible-print { + display: table-row !important; } + th.visible-print, + td.visible-print { + display: table-cell !important; } } + +.visible-print-block { + display: none !important; } + @media print { + .visible-print-block { + display: block !important; } } + +.visible-print-inline { + display: none !important; } + @media print { + .visible-print-inline { + display: inline !important; } } + +.visible-print-inline-block { + display: none !important; } + @media print { + .visible-print-inline-block { + display: inline-block !important; } } + +@media print { + .hidden-print { + display: none !important; } } + +.rangeslider, +.rangeslider__fill { + display: block; + -moz-box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.3); + -webkit-box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.3); + box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.3); + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + border-radius: 10px; } + +.rangeslider { + background: #e6e6e6; + position: relative; } + +.rangeslider--horizontal { + height: 20px; + width: 100%; } + +.rangeslider--vertical { + width: 20px; + min-height: 150px; + max-height: 100%; + height: 100%; } + +.rangeslider--disabled { + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40); + opacity: 0.4; } + +.rangeslider__fill { + background: #00ff00; + position: absolute; } + +.rangeslider--horizontal .rangeslider__fill { + top: 0; + height: 100%; } + +.rangeslider--vertical .rangeslider__fill { + bottom: 0; + width: 100%; } + +.rangeslider__handle { + background: white; + border: 1px solid #ccc; + cursor: pointer; + display: inline-block; + width: 40px; + height: 40px; + position: absolute; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMC4xIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4g"); + background-size: 100%; + background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(100%, rgba(0, 0, 0, 0.1))); + background-image: -moz-linear-gradient(rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.1)); + background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.1)); + background-image: linear-gradient(rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.1)); + -moz-box-shadow: 0 0 8px rgba(0, 0, 0, 0.3); + -webkit-box-shadow: 0 0 8px rgba(0, 0, 0, 0.3); + box-shadow: 0 0 8px rgba(0, 0, 0, 0.3); + -moz-border-radius: 50%; + -webkit-border-radius: 50%; + border-radius: 50%; } + +.rangeslider__handle:after { + content: ""; + display: block; + width: 18px; + height: 18px; + margin: auto; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjEzIi8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjZmZmZmZmIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA=="); + background-size: 100%; + background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(0, 0, 0, 0.13)), color-stop(100%, rgba(255, 255, 255, 0))); + background-image: -moz-linear-gradient(rgba(0, 0, 0, 0.13), rgba(255, 255, 255, 0)); + background-image: -webkit-linear-gradient(rgba(0, 0, 0, 0.13), rgba(255, 255, 255, 0)); + background-image: linear-gradient(rgba(0, 0, 0, 0.13), rgba(255, 255, 255, 0)); + -moz-border-radius: 50%; + -webkit-border-radius: 50%; + border-radius: 50%; } + +.rangeslider__handle:active, .rangeslider--active .rangeslider__handle { + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjEiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMC4xMiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA=="); + background-size: 100%; + background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(0, 0, 0, 0.1)), color-stop(100%, rgba(0, 0, 0, 0.12))); + background-image: -moz-linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.12)); + background-image: -webkit-linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.12)); + background-image: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.12)); } + +.rangeslider--horizontal .rangeslider__handle { + top: -10px; + touch-action: pan-y; + -ms-touch-action: pan-y; } + +.rangeslider--vertical .rangeslider__handle { + left: -10px; + touch-action: pan-x; + -ms-touch-action: pan-x; } + +input[type="range"]:focus + .rangeslider .rangeslider__handle { + -moz-box-shadow: 0 0 8px rgba(255, 0, 255, 0.9); + -webkit-box-shadow: 0 0 8px rgba(255, 0, 255, 0.9); + box-shadow: 0 0 8px rgba(255, 0, 255, 0.9); } + +.admonition { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; + text-align: left; } + +.admonition.note { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; } + +.admonition.warning { + color: #c09853; + background-color: #fcf8e3; + border-color: #fbeed5; } + +.admonition.danger { + color: #b94a48; + background-color: #f2dede; + border-color: #eed3d7; } + +.admonition-title { + font-weight: bold; + text-align: left; } + +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; } + .alert a { + color: inherit; + cursor: pointer; + text-decoration: underline; } + .alert a:hover { + color: inherit; } + .alert .btn { + text-decoration: inherit; + white-space: normal; } + .alert .btn-primary, .alert .btn-mapzen, + .alert .btn-primary:hover, + .alert .btn-mapzen:hover { + color: white; } + +.alert-dismissible { + padding-right: 35px; } + .alert-dismissible .close { + float: right; + position: relative; + top: 3px; + right: -21px; + color: inherit; + text-decoration: none; + opacity: .5; } + .alert-dismissible .close:hover { + opacity: 1; } + +.alert-success { + background-color: rgba(53, 110, 43, 0.1); + border-color: rgba(53, 110, 43, 0.3); + color: rgba(53, 110, 43, 0.8); } + +.alert-info { + background-color: rgba(56, 93, 92, 0.1); + border-color: rgba(56, 93, 92, 0.3); + color: rgba(56, 93, 92, 0.8); } + +.alert-warning { + background-color: rgba(211, 199, 86, 0.2); + border-color: rgba(211, 199, 86, 0.6); + color: #91893b; } + +.alert-danger { + background-color: rgba(153, 52, 52, 0.1); + border-color: rgba(153, 52, 52, 0.3); + color: rgba(153, 52, 52, 0.8); } + +.alert-upsell { + background-color: #EEE7F8; + border-color: rgba(173, 156, 194, 0.4); + color: #635378; } + +@media (max-width: 767px) { + .authors img.avatar { + display: none; } } + +img.avatar { + position: relative; + width: 64px; + height: 64px; + margin-right: 0.5em; + padding: 2px; + border: 2px solid #1E0E33; + border-radius: 50%; + box-shadow: inset 0 0 0 3px white; } + +img.avatar-about { + position: relative; + width: 42px; + height: 42px; + padding: 2px; + border: 2px solid #1E0E33; + border-radius: 50%; + box-shadow: inset 0 0 0 3px white; + z-index: 1; } + @media (min-width: 768px) { + img.avatar-about { + width: 60px; + height: 60px; } } + +/*inside of dashboard*/ +.profile-picture, img.dashboard-profile-pic { + border-radius: 50%; + border: 2px solid #1E0E33; + padding: 2px; } + +img.dashboard-profile-pic { + margin-top: -10px; + width: 60px; + height: 60px; + float: left; + box-shadow: 30px white inset; } + +/* button styles */ +.btn { + border-radius: 5px; + border: 0; + text-transform: uppercase; + font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; + font-weight: 700; + padding: 12px 24px; } + .btn.disabled, .btn[disabled] { + background-color: #898989; + opacity: 1; + filter: alpha(opacity=100); } + +input[type="search"] + .btn { + padding: 0; } + +.btn-primary:hover, .btn-mapzen:hover, .btn-primary:focus, .btn-mapzen:focus { + background-color: #2C1E3F; } + +.btn-inverse, .btn-white { + background-color: #ffffff; + color: #1E0E33; } + .btn-inverse:hover, .btn-white:hover, .btn-inverse:focus, .btn-white:focus { + background-color: #EEE7F8; + color: #1E0E33; } + .btn-inverse.disabled, .disabled.btn-white, .btn-inverse[disabled], [disabled].btn-white { + color: #1E0E33; } + +.btn-secondary, .btn-transparent { + background: white; + border: 1px solid #1E0E33; + color: #1E0E33; } + .btn-secondary:hover, .btn-transparent:hover, .btn-secondary:focus, .btn-transparent:focus { + background-color: #EEE7F8; + color: #1E0E33; } + .btn-secondary.disabled, .disabled.btn-transparent, .btn-secondary[disabled], [disabled].btn-transparent { + border-color: #898989; + color: #1E0E33; } + +.btn-with-arrow { + background-color: transparent; + color: #FF7B7B; + padding: 12px; + /* Make only padding right bigger, so we can put arrow image */ + padding-left: 0; + padding-right: 32px; + font-size: 0.85em; + font-weight: 700; + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMS42IiBoZWlnaHQ9IjguNjQiIHZpZXdCb3g9IjAgMCAyMS42IDguNjQiPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsPSIjRkY3QjdCIiBkPSJNMjAuOCA0LjMybC03IDMuNXYtN3oiLz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZmlsbD0iI0ZGN0I3QiIgZD0iTS44IDIuODJoMTR2M0guOHoiLz48L3N2Zz4="); + background-repeat: no-repeat; + background-position: right center; } + .btn-with-arrow:hover, .btn-with-arrow:focus { + color: #FF4947; + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMS42IiBoZWlnaHQ9IjguNjQiIHZpZXdCb3g9IjAgMCAyMS42IDguNjQiPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsPSIjRkY0OTQ3IiBkPSJNMjAuOCA0LjMybC03IDMuNXYtN3oiLz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZmlsbD0iI0ZGNDk0NyIgZD0iTS44IDIuODJoMTR2M0guOHoiLz48L3N2Zz4="); } + .btn-with-arrow:active { + box-shadow: none; } + .btn-with-arrow.disabled, .btn-with-arrow[disabled] { + color: #777777; + background-color: transparent; + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMS42IiBoZWlnaHQ9IjguNjQiIHZpZXdCb3g9IjAgMCAyMS42IDguNjQiPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsPSIjNzc3Nzc3IiBkPSJNMjAuOCA0LjMybC03IDMuNXYtN3oiLz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZmlsbD0iIzc3Nzc3NyIgZD0iTS44IDIuODJoMTR2M0guOHoiLz48L3N2Zz4="); } + +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 5px; + border-top-right-radius: 5px; } + +.btn-group > .btn:last-child:not(:first-child), .btn-group > .dropdown-toggle:not(:first-child) { + border-bottom-left-radius: 5px; + border-top-left-radius: 5px; } + +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 5px; } + +.tag-list { + text-align: center; + padding: 0; } + .tag-list a li { + display: inline-block; + color: #666666; + background-color: #f8f8f8; + padding: .35em .8em; + margin: .4em .4em; } + +.btn-group .btn { + margin-right: 10px; + margin-bottom: 10px; } + +.btn-group { + margin-bottom: -10px; } + +.btn + .btn { + margin-left: 10px; } + +.btn-flexible { + width: 100%; } + .btn-flexible + .btn-flexible { + margin-top: 12px; + margin-left: 0; } + @media (min-width: 768px) { + .btn-flexible { + width: auto; } + .btn-flexible + .btn-flexible { + margin-top: auto; + margin-left: 10px; } } + +.byline { + color: #666666; + font-size: 14px; } + +.byline-authors { + list-style: none; + padding-left: 0; + margin: 0; + text-align: left; + display: inline; + vertical-align: left; } + @media (max-width: 540px) { + .byline-authors { + display: inline-block; } } + +.byline-author { + display: inline-block; + white-space: nowrap; + margin-bottom: 0.4em; } + .byline-author > a { + font-weight: 700; + color: #666666; + text-decoration: none; } + @media (min-width: 541px) { + .byline-author:not(:last-of-type) { + margin-right: 1.5em; } } + @media (max-width: 540px) { + .byline-author { + display: block; + margin-right: 0; } } + +.byline-date { + white-space: nowrap; } + .byline-date::before { + content: '\00b7'; + margin: 0 1em; } + @media (max-width: 540px) { + .byline-date { + display: block; + margin: 0.5em; } + .byline-date::before, .byline-date::after { + content: '\00b7'; + margin: 0 1em; } } + .byline-date.is-newlined { + display: block; + margin: 1em; } + .byline-date.is-newlined::before, .byline-date.is-newlined::after { + content: '\00b7'; + margin: 0 1em; } + .byline-date.no-top-margin { + display: block; + margin-bottom: 1em; } + .byline-date.no-top-margin::before, .byline-date.no-top-margin::after { + content: '\00b7'; + margin: 0 1em; } + +.author-blurbs { + list-style: none; + padding-left: 0; + margin-top: 2em; + margin-bottom: 0; + font-size: 14px; } + +.author-blurb { + display: table; + white-space: normal; + text-align: left; } + +.author-blurb-full-width { + width: 100%; + margin: 0%; } + +.author-blurb-half-width { + float: left; + width: 50%; + padding: 0; + padding-right: 20px; + height: 140px; } + .author-blurb-half-width:nth-child(n+3) { + margin-top: 20px; } + @media (max-width: 767px) { + .author-blurb-half-width { + width: 100%; + padding-right: 0; + height: auto; } + .author-blurb-half-width:nth-child(n+2) { + margin-top: 30px; } } + +.author-blurb p { + margin-bottom: 0; } + +.author-blurb-portrait { + display: table-cell; + vertical-align: top; + width: 64px; + padding-right: 8px; } + +.blurb-full-width .author-blurb-portrait { + padding-left: 16px; } + +.author-blurb-text { + display: table-cell; + vertical-align: top; } + +.breadcrumb { + margin-bottom: 0; } + .breadcrumb li::before { + font: normal normal normal 14px/1 FontAwesome; } + .breadcrumb li > a { + font-weight: 700; } + +.breadcrumb > li + li:before { + content: "" " "; } + +h3.category-title { + text-transform: capitalize; } + +.category-info-container { + width: 100%; + display: table; + border-top: 1px dotted #ccc; + padding: 25px 0px; + font-size: 16px; + color: #666; } + @media (max-width: 767px) { + .category-info-container { + padding: 20px 0px; } } + .category-info-container.first { + border-top: 2px solid #ccc; } + .category-info-container .category-info { + display: table-cell; } + @media (max-width: 767px) { + .category-info-container .category-info { + display: table-row; } } + .category-info-container .category-info .sub-info { + font-size: 14px; } + .category-info-container .category-info .sub-info:before { + content: '·'; } + @media (max-width: 767px) { + .category-info-container .category-info .sub-info { + display: block; + line-height: 1.8; } + .category-info-container .category-info .sub-info:before { + content: none; } } + @media (max-width: 767px) { + .category-info-container .category-info .excerpt { + margin-bottom: 20px; } } + .category-info-container .read-more { + display: table-cell; + vertical-align: middle; + width: 150px; + text-align: center; + text-transform: capitalize; } + @media (max-width: 767px) { + .category-info-container .read-more { + display: table-row; + padding: 10px 0; } } + +/* responsiveness */ +/* small mobile devices */ +@media (max-width: 767px) { + ul.team { + list-style: none; + background-color: #f8f8f8; + padding: 15px; + width: 100%; + margin-bottom: 24px; } + .content img { + max-width: 100%; + width: auto; + height: auto; + padding: 20px 0; + max-height: 400px; + display: block; + margin: auto; } + .background-image-lg { + height: 250px; + background-position: top left; + background-size: cover; } } + +/* tablets */ +@media (min-width: 768px) { + ul.team { + list-style: none; + background-color: #f8f8f8; + padding: 15px; + width: 100%; } + .background-image-lg { + height: 350px; + background-position: top left; + background-size: cover; } } + +/* blog post styles */ +.project-row { + margin-left: 4%; + margin-right: 4%; } + +.meta { + list-style: none; + padding-left: 0; + margin: 0; + text-align: left; + display: inline; + vertical-align: center; } + .meta li:not(:first-of-type) { + padding-left: 10px; } + .meta:not(:first-of-type) { + margin-left: 1em; } + +.inline li { + display: inline-block; } + +.team-soc a { + display: inline-block; + padding: 0 15px; + font-size: 1.4em; } + +img.avatar-byline { + position: relative; + width: 42px; + height: 42px; + margin-right: 0.5em; + padding: 2px; + border: 2px solid #1E0E33; + border-radius: 50%; + box-shadow: inset 0 0 0 3px white; } + +.featured-item { + padding-top: 30px; + padding-bottom: 10px; + font-size: 24px; + line-height: 1.4; } + +/* posts bg image */ +.background-image { + background-size: cover; + background-position: center center; + background-repeat: no-repeat; + height: 350px; } + +.blogpost-image { + background-size: cover; + background-position: center center; + background-repeat: no-repeat; + height: auto; + max-height: 350px; + overflow: hidden; } + .blogpost-image img { + visibility: hidden; + max-height: none !important; + height: auto !important; + width: 100% !important; + margin: 0 !important; + padding: 0 !important; } + +.content.excerpt img { + width: 100%; + height: 200px; } + +.content.excerpt_feed img { + width: 100%; + max-height: 600px; + margin: 10px 0; } + +.blog-index-excerpt .blogpost-image { + background-size: cover; + background-position: center center; + background-repeat: no-repeat; + height: auto; + max-height: 350px; + overflow: hidden; } + .blog-index-excerpt .blogpost-image img { + visibility: hidden; + max-height: none !important; + height: auto !important; + width: 100% !important; + margin: 0 !important; + padding: 0 !important; } + +.blog-index-excerpt .content.excerpt img { + width: 100%; + height: 200px; } + +.blog-index-excerpt .content.excerpt-feed img { + width: 100%; + max-height: 600px; + margin: 10px 0; } + +/* posts bg image */ +.background-image { + background-size: cover; + background-position: center center; + background-repeat: no-repeat; + height: 350px; } + +/* community section styles */ +.blog-excerpt { + background-color: #f8f8f8; + padding: 0 20px; + font-size: 16px; + line-height: 24px; } + +.blog-title-sm a { + font-size: 26px; + line-height: 32px; + font-weight: 300; } + +.cta-primary { + padding-top: 72px; + padding-bottom: 72px; } + +.cta-container { + background-color: #f8f8f8; + padding: 25px 20px; + position: relative; + text-align: center; + width: 100%; } + @media (min-width: 992px) { + .cta-container { + display: table; } } + +.cta-text { + padding: 10px 16px; + font-weight: 700; } + .cta-text p { + margin: 0; } + @media (min-width: 992px) { + .cta-text { + display: table-cell; + vertical-align: middle; + text-align: left; } } + +.cta-paragraph { + font-weight: 300; } + +.cta-btn { + text-align: right; } + @media (min-width: 992px) { + .cta-btn { + display: table-cell; + vertical-align: middle; + padding: 0 10px; } } + .cta-btn .btn { + width: 100%; + margin-top: 20px; } + @media (min-width: 992px) { + .cta-btn .btn { + margin-top: 0; + width: auto; } } + +.docs-title { + font-size: 20px; } + +.documentation-hero { + background-color: #F7BEB4; + text-align: center; + color: white; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 40px 20px; } + .documentation-hero .documentation-header { + /* former _documentation.scss documentation-hero h1*/ + padding-top: 20px; + color: #fff; + /* former _documentation.scss h1*/ + font-weight: 700; + font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; + /* former _typography.scss */ + font-size: 48px; + line-height: 1.2em; + /* scale back margins on mobile */ } + @media (max-width: 768px) { + .documentation-hero .documentation-header { + font-size: 42px; } } + .documentation-hero p { + margin-top: 24px; } + +.documentation-nav { + position: relative; + z-index: 20; } + +.documentation-container { + padding-top: 2em; } + +.documentation-content { + line-height: 1.8; + font-size: 16px; + word-wrap: break-word; + overflow-wrap: break-word; + /*smaller for documentation than styleguide*/ + /*smaller for documentation than styleguide*/ + /*smaller for documentation than styleguide*/ + /* + // allows hash links to navigate to proper location + h1[id]:before, + h2[id]:before, + h3[id]:before, + h4[id]:before, + h5[id]:before, + h6[id]:before { + content: ''; + display: block; + margin-top: -70px; + height: 70px; + pointer-events: none; + } + */ } + .documentation-content section > p, + .documentation-content section > ol, + .documentation-content section > ul { + margin-bottom: 24px; } + .documentation-content > :last-child { + margin-bottom: 0 !important; } + .documentation-content img { + max-width: 100%; + display: inline; + padding: 4px; + line-height: 1.428571429; + background-color: #fff; } + .documentation-content img.emoji { + padding: 0; + background-color: transparent; + line-height: inherit; + max-width: initial; } + .documentation-content li > p { + margin-bottom: 0; } + .documentation-content li > p + p { + margin-top: 24px; } + .documentation-content li > p > img { + margin-top: 0; + margin-bottom: 24px; } + .documentation-content h1, .documentation-content h2, .documentation-content h3, .documentation-content h4, .documentation-content h5, .documentation-content h6 { + position: relative; } + .documentation-content h1 { + font-size: 36px; } + .documentation-content h2 { + font-size: 24px; } + .documentation-content h3 { + font-size: 20px; } + .documentation-content section { + margin-top: -50px; + padding-top: 50px; + overflow: hidden; } + .documentation-content h1, .documentation-content h2, .documentation-content h3, .documentation-content h4, .documentation-content h5, .documentation-content h6 { + margin-top: 25px; } + .documentation-content > section:first-child { + margin-top: -70px; + padding-top: 70px; } + .documentation-content > section:first-child > h1:first-child, + .documentation-content > section:first-child > h2:first-child, + .documentation-content > section:first-child > h3:first-child, + .documentation-content > section:first-child > h4:first-child, + .documentation-content > section:first-child > h5:first-child, + .documentation-content > section:first-child > h6:first-child { + margin-top: 0; } + .documentation-content .caption { + margin-top: -0.8em; + font-size: 0.9em; + font-weight: 300; + font-style: italic; + color: #666; } + +.documentation-edit { + text-align: right; + line-height: 2em; } + .documentation-edit i.fa { + vertical-align: middle; + color: #666; } + +a.headerlink { + position: absolute; + display: none; + font-size: 0.80em; + padding-left: .5em; + width: 1.5em; + min-height: 1em; + line-height: inherit; + bottom: 0.15em; + padding-left: .5em; + background-image: url(data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%20100%20100%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20stroke-linejoin%3D%22round%22%20stroke-miterlimit%3D%221.414%22%3E%3Cpath%20d%3D%22M53.496%2056.598c0-.012-.002-.025%200-.036l-.003.035h.003zm15.488%208.076c-.244.143-.493.277-.74.412%200%20.002%200%20.005-.003.007.24-.13.49-.268.745-.42zm-21.932%201.71l-.003.003c.512.225%201.137.437%201.72.614l.01-.01c-.584-.18-1.16-.38-1.73-.605zM48.77%2067c.59.18%201.135.32%201.477.407-.494-.122-.983-.264-1.47-.414L48.77%2067zm1.842.495l.005-.004c-.09-.02-.18-.035-.268-.06l.26.066zm17.248-2.2c-.586.308-1.184.585-1.786.84%200%20.004-.003.008-.004.01.06-.025.782-.323%201.79-.85zm.38-.203c.002%200%20.003-.005.003-.007-.096.054-.19.11-.29.16.096-.047.192-.098.287-.153z%22%20fill%3D%22%23505050%22%20fill-rule%3D%22nonzero%22%2F%3E%3Cpath%20d%3D%22M49.585%2014.996L38.88%2025.7c-.923.923-1.76%201.902-2.51%202.925-.164.223-.31.454-.467.68%205.17-1.4%2010.66-1.318%2015.79.252l6.777-6.777c5.177-5.177%2013.572-5.176%2018.75.002%205.176%205.176%205.177%2013.572%200%2018.75l-6.73%206.728-1.383%201.384-1.347%201.347-.005.006-2.242%202.242c-2.337%202.337-5.33%203.615-8.385%203.843v.005h-.003c-.642.056-1.194.06-1.665.04-1.035-.045-1.636-.206-1.636-.206v-.005h-.004c-2.585-.456-5.06-1.68-7.056-3.677-1.942-1.942-3.155-4.335-3.642-6.842-.013-.072-.02-.144-.034-.214-2.27.187-4.487%201.14-6.22%202.873l-3.564%203.564c1.22%203.094%203.075%206%205.578%208.5%202.502%202.5%205.402%204.36%208.497%205.58.567.226%201.143.427%201.725.61.486.15.974.292%201.47.414.037.01.067.016.1.024.09.022.177.037.267.06%205.13%201.18%2010.556.73%2015.458-1.355.604-.257%201.202-.533%201.787-.84.032-.016.063-.032.094-.05.1-.05.195-.107.29-.16.25-.135.498-.27.74-.413l.01-.006c1.778-1.05%203.454-2.34%204.98-3.866L85%2050.415c9.78-9.78%209.78-25.638%200-35.418-9.78-9.78-25.636-9.782-35.417%200z%22%20fill%3D%22%23505050%22%20fill-rule%3D%22nonzero%22%2F%3E%3Cpath%20d%3D%22M50.415%2085.004L61.118%2074.3c.925-.925%201.762-1.904%202.512-2.927.163-.223.313-.454.467-.68-5.17%201.4-10.66%201.32-15.79-.252l-.875.878-5.902%205.902c-5.177%205.177-13.57%205.176-18.75-.002-5.177-5.178-5.177-13.57%200-18.75l11.707-11.705c2.336-2.336%205.328-3.614%208.384-3.84v-.005h.005c.642-.057%201.193-.06%201.664-.04%201.034.043%201.635.205%201.635.205v.004h.005c2.583.456%205.06%201.68%207.054%203.675%201.942%201.942%203.155%204.337%203.64%206.843.015.072.024.143.035.214%202.27-.188%204.487-1.14%206.22-2.873l3.564-3.565c-1.222-3.095-3.077-5.998-5.58-8.5-2.503-2.504-5.402-4.36-8.497-5.583-.57-.225-1.145-.427-1.727-.608-.486-.152-.975-.295-1.47-.415l-.1-.025c-.088-.022-.177-.038-.266-.06-5.13-1.18-10.557-.73-15.458%201.355-.603.257-1.2.534-1.786.84-.032.015-.063.032-.095.05-.097.05-.192.107-.288.16-.248.135-.497.27-.74.414l-.01.006c-1.777%201.05-3.452%202.338-4.98%203.865l-10.7%2010.704c-9.782%209.78-9.782%2025.636%200%2035.417%209.78%209.783%2025.637%209.783%2035.418.003zM68.993%2064.67c-.002%200-.006%200-.01.004l.01-.005zm-1.133.626c.03-.016.063-.032.094-.05-.03.018-.062.034-.095.05z%22%20fill%3D%22%23505050%22%20fill-rule%3D%22nonzero%22%2F%3E%3Cpath%20d%3D%22M53.497%2056.6s.6.162%201.636.208v-.022c-.548-.027-1.094-.093-1.637-.188v.003zm-3.15%2010.83l-.1-.023.1.024z%22%20fill%3D%22%23505050%22%20fill-rule%3D%22nonzero%22%2F%3E%3Cpath%20d%3D%22M55.134%2056.786c-.002.006%200%20.014%200%20.022.47.02%201.02.016%201.664-.04v-.005c-.554.04-1.11.05-1.664.023zm1.667-.023v-.02c0%20.007%200%20.014-.002.02h.005z%22%20fill%3D%22%23505050%22%20fill-rule%3D%22nonzero%22%2F%3E%3Cpath%20d%3D%22M56.8%2056.762l-.003.003.002.003v-.003l-.002-.003z%22%20fill%3D%22%23505050%22%2F%3E%3C%2Fsvg%3E); + background-repeat: no-repeat; + background-position: center right; + background-size: contain; } + +h1:hover:not(:first-child) .headerlink, +h2:hover .headerlink, +h3:hover .headerlink, +h4:hover .headerlink, +h5:hover .headerlink, +h6:hover .headerlink { + display: inline-block; } + +/* This is for 404 page */ +.error-page-logo { + width: 180px; } + +#physics-wrapper { + height: 300px; + margin-top: 50px; + margin-bottom: 50px; + border-bottom: 3px solid #666; } + +body.no-footer #footer, +body.no-footer footer { + display: none; } + +.footer-no-background { + color: #1E0E33; } + .footer-no-background a { + color: #FF7B7B; } + +.footer-background { + color: #AD9CC2; + padding-top: 50px; + background-color: #1E0E33; + background: url("/common/styleguide/images/background/contour_darkpurple_xs.png"); + background-size: cover; + border-top: 5px solid #FF7B7B; } + .footer-background a, + .footer-background a:active, + .footer-background a:visited { + color: #EEE7F8; } + .footer-background a:hover { + color: white; } + @media (min-width: 480px) { + .footer-background { + background-image: url("/common/styleguide/images/background/contour_darkpurple_sm.png"); } } + @media (min-width: 768px) { + .footer-background { + background-image: url("/common/styleguide/images/background/contour_darkpurple2_lg.png"); + background-attachment: fixed; + background-position: center center; } } + +.footer-menu { + font-size: 13px; + line-height: 1.8; } + .footer-menu h6 { + font-size: inherit; + text-transform: uppercase; } + .footer-menu h6:not(:first-of-type) { + margin-top: 20px; } + .footer-menu h6 a, + .footer-menu h6 a:hover, + .footer-menu h6 a:active, + .footer-menu h6 a:visited { + color: #AD9CC2; } + .footer-menu ul { + list-style-type: none; + padding-left: 0; } + .footer-menu .fa { + margin-right: 0.25em; } + +.footer-section { + padding-left: 30px; } + @media (min-width: 480px) { + .footer-section { + padding-left: 40px; } } + @media (min-width: 992px) { + .footer-section { + padding-left: 80px; } } + +.compass-logo { + width: 36px; + height: 36px; + background-image: url("https://mapzen.com/common/styleguide/images/logos/mapzen-logo-compass-white.png"); + background-repeat: no-repeat; + background-size: 36px; + margin: 6px auto; } + +.form-group-header { + font-weight: bold; + margin-bottom: 15px; } + +.form-group { + position: relative; + margin-bottom: 24px; } + +/* we want to place recover password link on top of password field, but with higher tabindex */ +.form-group > .recover-password-link { + position: absolute; + top: 0; + right: 0; } + +/* It is less likely that bold text is wanted for checkbox label */ +input[type="checkbox"] + label { + font-weight: 400; } + +label { + font-weight: 700; } + +.wide label { + margin: 5px 0; } + +.tall label { + display: block; } + +.tall input[type="text"], .tall input[type="email"] { + width: 100%; } + +input[type="text"], input[type="email"], input[type="password"] { + height: 41px; + padding: 8px 5px; + border: 1px solid #ccc; + border-radius: 5px; + -webkit-appearance: none; } + +input[type="text"]:-moz-focusring, +input[type="email"]:-moz-focusring, +textarea:-moz-focusring, +input[type="search"]:-moz-focusring { + outline: 1px dotted #212121; } + +::-webkit-input-placeholder { + font-size: 14px; + line-height: 24px; } + +::-moz-placeholder { + font-size: 14px; + line-height: 24px; } + +:-ms-input-placeholder { + font-size: 14px; + line-height: 24px; } + +textarea { + width: 100%; + padding: 5px; + height: 6em; + border: 1px solid #ccc; + border-radius: 5px; + -webkit-appearance: none; } + +.has-success .control-label { + color: rgba(53, 110, 43, 0.8); } + +.has-success .form-control { + border-color: rgba(53, 110, 43, 0.8); } + +.has-warning .control-label { + color: #91893b; } + +.has-warning .form-control { + border-color: #91893b; } + +.has-error .control-label { + color: rgba(153, 52, 52, 0.8); } + +.has-error .form-control { + border-color: rgba(153, 52, 52, 0.8); } + +input[type="search"] { + height: 41px; + background-image: url(data:image/svg+xml,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Ctitle%3Esearch%3C/title%3E%3Ccircle%20fill%3D%27none%27%20stroke%3D%27%23666666%27%20stroke-width%3D%272.2677%27%20stroke-miterlimit%3D%2710%27%20cx%3D%279.99%27%20cy%3D%276.512%27%20r%3D%275.5%27/%3E%3Cline%20fill%3D%27none%27%20stroke%3D%27%23666666%27%20stroke-width%3D%272.2677%27%20stroke-miterlimit%3D%2710%27%20x1%3D%2713.5%27%20y1%3D%2710.637%27%20x2%3D%2716.789%27%20y2%3D%2714.173%27/%3E%3C/svg%3E%0A); + background-repeat: no-repeat; + background-size: 19px 19px; + background-position: 3px 14px; + padding: 8px 2px 8px 26px; + border: 1px solid #ccc; + border-radius: 5px; } + +.form-group { + /* we have hidden type of search for google/duckduckgo search */ + /* first child selector won't work with this */ } + .form-group input[type="hidden"]:first-child + input { + border-top-left-radius: 5px; + border-bottom-left-radius: 5px; } + .form-group input[type="search"] { + border-radius: 0; } + .form-group input[type="search"]:first-child:not(:last-child) { + border-top-left-radius: 5px; + border-bottom-left-radius: 5px; } + .form-group input[type="search"]:last-child:not(:first-child) { + border-top-right-radius: 5px; + border-bottom-right-radius: 5px; } + +.inline-submit .btn { + height: 41px; + margin-left: -1px; + border-color: #ccc; + border-radius: 0; } + +.inline-submit input[type="hidden"]:first-child + .btn { + border-top-left-radius: 5px; + border-bottom-left-radius: 5px; } + +.inline-submit .btn:first-child:not(:last-child) { + border-top-left-radius: 5px; + border-bottom-left-radius: 5px; } + +.inline-submit .btn:last-child:not(:first-child) { + border-top-right-radius: 5px; + border-bottom-right-radius: 5px; } + +select { + appearance: none; + -webkit-appearance: none; + -moz-appearance: none; + border: 1px solid #ccc; + background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20width%3D%2740%27%20height%3D%2715%27%20viewBox%3D%270%200%2040%2015%27%3E%3Cpath%20fill%3D%27none%27%20stroke%3D%27%23333%27%20stroke-width%3D%272.835%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%20stroke-miterlimit%3D%2710%27%20d%3D%27M17.501%204.381l-7.5%206.238-7.5-6.238%27/%3E%3C/svg%3E); + background-repeat: no-repeat; + background-position: right center; + background-size: 25px auto; + background-color: white; + padding: 8px 38px 8px 10px; + border-radius: 5px; } + +select::-ms-expand { + display: none; } + +input[type="checkbox"], +input[type="radio"] { + opacity: .01; + position: absolute; + cursor: pointer; + width: 20px; + height: 20px; } + +input[type="checkbox"] + *:before, +input[type="radio"] + *:before { + -webkit-appearance: none; + -moz-appearance: none; + width: 18px; + height: 18px; + cursor: pointer; + margin: 0 8px -3px 0; + content: ' '; + display: inline-block; + box-sizing: content-box; + border: 1px solid white; + border-radius: 5px; } + +input[type="checkbox"]:focus + *:before, +input[type="radio"]:focus + *:before { + border: 1px solid #70ace9; + box-shadow: 0px 0px 5px 0px #70ace9; } + +input[type="checkbox"] + *:before { + background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2036%2036%27%3E%3Ctitle%3Echeckbox%3C/title%3E%3Cpath%20d%3D%27M31.75%2C4.25v27.5H4.25V4.25h27.5M36%2C0H0V36H36V0h0Z%27%20transform%3D%27translate%280%200%29%27%20style%3D%27fill%3A%23cdcccc%27/%3E%3C/svg%3E); } + +input[type="checkbox"]:hover + *:before { + background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2036%2036%27%3E%3Ctitle%3Echeckbox-hover%3C/title%3E%3Cpath%20d%3D%27M31.75%204.25v27.5H4.25V4.25h27.5M36%200H0v36h36V0z%27%20fill%3D%27%23989898%27/%3E%3C/svg%3E); } + +input[type="checkbox"]:checked + *:before { + background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2036%2036%27%3E%3Ctitle%3Echeckbox-checked%3C/title%3E%3Cpath%20fill%3D%27%232C1E3F%27%20d%3D%27M0%200h36v36H0z%27/%3E%3Cpath%20fill%3D%27none%27%20stroke%3D%27%23fff%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%20stroke-width%3D%274.252%27%20d%3D%27M26.19%2011.16l-9.17%2013.68-7.21-5.22%27/%3E%3C/svg%3E); + background-color: #2C1E3F; } + +input[type="radio"] + *:before { + background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2035%2035%27%3E%3Ctitle%3EUntitled-5%3C/title%3E%3Cpath%20d%3D%27M18%2C4.75A13.25%2C13.25%2C0%2C1%2C1%2C4.75%2C18%2C13.26%2C13.26%2C0%2C0%2C1%2C18%2C4.75M18%2C0.5A17.5%2C17.5%2C0%2C1%2C0%2C35.5%2C18%2C17.5%2C17.5%2C0%2C0%2C0%2C18%2C.5h0Z%27%20transform%3D%27translate%28-0.5%20-0.5%29%27%20style%3D%27fill%3A%23cdcccc%27/%3E%3C/svg%3E); + border-radius: 10px; } + +input[type="radio"]:hover + *:before { + background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2035%2035%27%3E%3Ctitle%3EUntitled-6%3C/title%3E%3Cpath%20d%3D%27M18%2C4.75A13.25%2C13.25%2C0%2C1%2C1%2C4.75%2C18%2C13.26%2C13.26%2C0%2C0%2C1%2C18%2C4.75M18%2C0.5A17.5%2C17.5%2C0%2C1%2C0%2C35.5%2C18%2C17.5%2C17.5%2C0%2C0%2C0%2C18%2C.5h0Z%27%20transform%3D%27translate%28-0.5%20-0.5%29%27%20style%3D%27fill%3A%23989898%27/%3E%3C/svg%3E); } + +input[type="radio"]:checked + *:before { + background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20viewBox%3D%270%200%2035%2035%27%3E%3Ctitle%3EUntitled-7%3C/title%3E%3Cpath%20d%3D%27M18%2C4.75A13.25%2C13.25%2C0%2C1%2C1%2C4.75%2C18%2C13.26%2C13.26%2C0%2C0%2C1%2C18%2C4.75M18%2C0.5A17.5%2C17.5%2C0%2C1%2C0%2C35.5%2C18%2C17.5%2C17.5%2C0%2C0%2C0%2C18%2C.5h0Z%27%20transform%3D%27translate%28-0.5%20-0.5%29%27%20style%3D%27fill%3A%232C1E3F%27/%3E%3Ccircle%20cx%3D%2717.5%27%20cy%3D%2717.5%27%20r%3D%279%27%20style%3D%27fill%3A%232C1E3F%27/%3E%3C/svg%3E); } + +input[type="range"] { + -webkit-appearance: none; + cursor: pointer; + padding: 5px 0; } + +input[type=range]::-webkit-slider-runnable-track { + height: 5px; + background-color: #EEE7F8; + border: none; + border-radius: 25px; } + +input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + height: 15px; + width: 15px; + margin-top: -5px; + border-radius: 50%; + border-width: 0; + background: #1E0E33; } + +input[type="range"]::-moz-range-thumb { + height: 15px; + width: 15px; + border-radius: 50%; + border-width: 0; + background: #1E0E33; } + +input[type="range"]::-ms-thumb { + height: 15px; + width: 15px; + border-radius: 50%; + border-width: 0; + background: #1E0E33; } + +input[type=range]::-moz-range-track { + height: 5px; + background-color: #EEE7F8; + border: none; + border-radius: 25px; } + +input[type=range]::-moz-range-progress { + background-color: #985FDD; + height: 5px; + border-radius: 25px; } + +input[type="range"]::-ms-fill-lower { + background-color: #985FDD; + border-radius: 25px; } + +input[type="range"]::-ms-fill-upper { + background-color: #EEE7F8; + border-radius: 25px; } + +input[type="range"]::-ms-track { + height: 5px; + background: transparent; + border-color: transparent; + border-width: 6px 0; + color: transparent; } + +input[type="range"]::-ms-ticks-after, +input[type="range"]::-ms-ticks-before { + color: transparent; + border-color: transparent; } + +.gallery { + display: none; + position: relative; + background-color: #f8f8f8; + max-height: 250px; + overflow: hidden; } + @media (min-width: 768px) { + .gallery { + max-height: 500px; } } + .gallery.full { + display: block; + margin-top: -50px; } + @media (min-width: 768px) { + .gallery.full { + margin-top: -60px; } } + .gallery.half { + display: block; + margin-top: -100px; } + @media (min-width: 768px) { + .gallery.half { + margin-top: -260px; } } + +.gallery::before { + content: ''; + position: absolute; + bottom: -1px; + width: 100%; + height: 250px; + background-image: url("data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgMjQwMCA1MDAiPjxzdHlsZT4uc3Qwe2ZpbGw6I2ZmZn0uc3Qxe2ZpbGw6bm9uZTtzdHJva2U6IzFlMGUzMztzdHJva2Utd2lkdGg6MS4zMztzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6MS40MTR9PC9zdHlsZT48cGF0aCBjbGFzcz0ic3QwIiBkPSJNMjQwMCAyMzhMMTIwMCA0OTAgMCAyMzh2MjYyaDI0MDBWMjM4eiIvPjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0yNDAwIDI0NEwxMjAwIDQ5NiAwIDI0NCIvPjwvc3ZnPg=="); + background-position: center bottom; + background-repeat: no-repeat; + /* + How to create the data-URI SVG mask for the carousel and the footer + + 1. SVGs were recreated from vector files. I used Affinity Designer, + but any program that can create SVGs will be okay. The source files + for these should be located in the Mapzen Google Drive. + 2. The exported SVGs from Affinity Designer are minified using + SVGOMG (https://jakearchibald.github.io/svgomg/), using its + default settings. + 3. The minified SVGs are then data-URI encoded on this site: + http://dopiaza.org/tools/datauri/index.php + Un-check "Use base64 encoding" (so that it will work with IE, possibly Firefox) + Select "Explicitly specify mime type" and set it to 'image/svg+xml' + Paste the new data-URI into the background-image property above. + */ } + @media (min-width: 768px) { + .gallery::before { + height: 500px; } } + @media (min-width: 2400px) { + .gallery::before { + background-size: 101%; } } + +.gallery-image { + width: 100%; + height: auto; + margin-top: -10%; } + +html { + width: 100%; + height: 100%; } + +body { + font-family: "Open Sans", Helvetica, Arial, sans-serif; + font-weight: 400; + overflow-x: hidden; + width: 100%; + height: 100%; } + +iframe { + border: 0px; } + +hr { + border-top: 1px solid lightgray; } + +.no-overflow { + overflow: inherit; } + +.headroom { + margin-top: 12px; } + @media (min-width: 768px) { + .headroom { + margin-top: 12px; } } + +.headroom-med { + margin-top: 18px; } + @media (min-width: 768px) { + .headroom-med { + margin-top: 24px; } } + +.headroom-large { + margin-top: 24px; } + @media (min-width: 768px) { + .headroom-large { + margin-top: 48px; } } + +.headroom-extra-large { + margin-top: 48px; } + @media (min-width: 768px) { + .headroom-extra-large { + margin-top: 72px; } } + +.footroom { + margin-bottom: 12px; } + @media (min-width: 768px) { + .footroom { + margin-bottom: 12px; } } + +.footroom-med { + margin-bottom: 18px; } + @media (min-width: 768px) { + .footroom-med { + margin-bottom: 24px; } } + +.footroom-large { + margin-bottom: 24px; } + @media (min-width: 768px) { + .footroom-large { + margin-bottom: 48px; } } + +.footroom-extra-large { + margin-bottom: 48px; } + @media (min-width: 768px) { + .footroom-extra-large { + margin-bottom: 72px; } } + +.neg-margin-top { + margin-top: -24px; } + @media (min-width: 768px) { + .neg-margin-top { + margin-top: -24px; } } + +.hor-margin { + margin-left: 24px; + margin-right: 24px; } + @media (min-width: 768px) { + .hor-margin { + margin-left: 48px; + margin-right: 48px; } } + +.vert-pad { + padding-top: 24px; + padding-bottom: 12px; } + +.horz-pad { + padding: 0px 12px; } + +.no_margin, +.no-margin { + margin: 0px; } + +.no_padding, +.no-padding { + padding: 0px; } + +@media only screen and (max-width: 991px) { + .sm-no-padding { + padding: 0px; } } + +@media only screen and (min-width: 992px) { + .hor-pad-left { + padding-left: 48px; + padding-right: 0; } } + +@media only screen and (min-width: 992px) { + .hor-pad-right { + padding-left: 0; + padding-right: 48px; } } + +@media (min-width: 768px) { + .col-sm-no-padding { + padding: 0px; } } + +@media (min-width: 992px) { + .col-md-no-padding { + padding: 0px; } } + +@media (min-width: 1200px) { + .col-lg-no-padding { + padding: 0px; } } + +.blue-text { + color: #6ea0a4; } + +.red-text { + /* This class should be deprecated after mapzen website v1.0 */ + color: #FF4947; } + +.gray-text { + color: #666; } + +.dark-gray-text { + color: #333333; } + +.text-deemphasize { + color: #cccccc; } + +.background-light { + background-color: #f8f8f8; } + +.table.icons > tbody > tr > td { + vertical-align: middle; } + +.icon, .icon-sm, .icon-lg { + width: 16px; + height: 16px; + background-repeat: no-repeat; + background-position: center center; + background-size: contain; + vertical-align: text-top; } + +span.icon, span.icon-sm, span.icon-lg { + display: inline-block; + margin-left: 0.25em; + margin-right: 0.25em; } + span.icon:first-child, span.icon-sm:first-child, span.icon-lg:first-child { + margin-left: 0; } + span.icon:last-child, span.icon-sm:last-child, span.icon-lg:last-child { + margin-right: 0; } + +.icon-sm { + width: 24px; + height: 24px; } + +.icon-lg { + width: 60px; + height: 60px; } + +.icon-award-ribbon-circle { + background-image: url("https://mapzen.com/common/styleguide/images/icons/award-ribbon-circle.svg"); } + +.icon-dollar-sign-circle { + background-image: url("https://mapzen.com/common/styleguide/images/icons/dollar-sign-circle.svg"); } + +.icon-folding-map-circle { + background-image: url("https://mapzen.com/common/styleguide/images/icons/folding-map-circle.svg"); } + +.leaflet-control-attribution a { + font-weight: normal; } + +ol.legal-terms { + counter-reset: legal-counter; } + ol.legal-terms h3 { + line-height: inherit; } + ol.legal-terms > li { + list-style-type: none; + position: relative; } + ol.legal-terms > li:before { + content: counter(legal-counter) "."; + counter-increment: legal-counter; + font-weight: 700; + font-size: 1.2em; + line-height: 1em; + position: absolute; + left: -40px; } + +.list-checkmarks { + list-style: none; + padding-left: 0; } + .list-checkmarks li { + margin-bottom: 0.375em; + margin-left: 1.75em; } + .list-checkmarks li:before { + font-family: 'FontAwesome'; + content: '\f058'; + color: #BDA2DD; + padding-right: 0.875em; + margin-left: -1.75em; } + +.loading-spinner-01 { + width: 26px; + height: 26px; } + +.loading-spinner-01::before { + content: ''; + display: block; + position: relative; + width: 100%; + height: 100%; + background-size: 70%; + background-position: center center; + background-repeat: no-repeat; + background-image: url(data:image/gif;base64,R0lGODlhQABAAMQRAMLDxPf3+Ojo6eDh4aSlp42PkNHS0/Dw8LO0tcnKy5SWmJyen9nZ2qutrru8vYWHif///////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFCgARACwAAAAAQABAAAAF/yAkjmRpnmiqrmzrvnAsz3Rt33iu7/xpLI8C4tDjIR5IZEFQzA2SUEXzdUgADAFSAwplTlcG6HJE4CYHX9XBLBVtzQ90GgWAM0RhtmlLmJfNAGRmdyVJc3WDIwEOBUgLciVAC3NrXAVZczR5Sl6ZNAcAAAmYniwMoZClMkdJCKoym0mdTQEJCTOIUIFfiLcxuUm7U6zCL09cs0UBCAikMKxIxa/GocnT19jZ2tvcBgQNqdwoDlCErwPWJwFcbapv0ifHUNNJfSyN9dPELZtj0+hUbDkTR7CgwYMIE9oAhUUhiQH4FgwsQk5BOhZvkBhIIyBJOxh/NKaR9/FFv4k9gE082DiDAQEEF3sIIOKwpk2CAhQ8IICSBQAC8JqofODqV7BMUOyBzDcHmq8SFdPlCtqjFgGWJfqhSEDgqTZgNxl4vAnB5RCyaNOqXfsqBAAh+QQFCgARACwFAAYANAA1AAAF/yAkjmRpnmiqrqUgoEFCNAZrq4PyPMpLHrrdYxG4GUeHgvBRKI4Iyx3geAREHwnSlUc1WqPT0fbRvSWutZEyuigNBmVTYLFskxzoEWBdCLMCCAQEDCWABQoITiQIS354UQg2dEKERwIGDAdIYz4pA1EEcSRnW34on0uhoiJfV6YnB5CrIgZjWSu1O0SzEAFrSwWaLAdvvCMMvztpxl0HgQQInczT1NXWogINDwTS1yxBXN4nAQ0Ky1HiJ6iqEL8F6SaxD5G0a8vwSHAkAQOK+P8AAwocSLAgQQAzuhHMFQ4gOQL6ILQiE5AUO4YKBKJyQAJhA4XwBEQ0SLKkyZMAGUoASOCvIEN6zATouGUDihBqjHYYedTQ2KN3NwJA6UEN0EeU1kSqENDSW052JWzeuyZgiUJUPa/J26Gwqi58j2CWwFMApLUAwqqFAAAh+QQFCgARACwFAAcANQA0AAAF/yAkjmRpisDzKMLpvnAsGqpaBHKun0StDiYGIIHbwRINoqnnA44Ci1qhZTw5agQTTVpE+VbV0/cEKKyoI2YzXBob1TUnW3RVOaqIb2FeMgAMYVA+gHyFTwkAAAeGjDACiYSNfHk1C10kAg0EAJIuWz5ZSzUJnaJfD5cioKVtpw9yaaOsJHA1qRCZBHezI59YvDuUKpbAO49/xcnKy2wBBghJt8wjAlFSVH6L0xDWPjd1U9MDrg8JPpzMKa7qKujL5utbCtK8AuSAB7DMDacL2yYB+GGht+2AgQRo/ilcyLBhiQCI9DVUo63YAQUFGLw4p0xdqBMK4igb98CdiVwmLTkmdMiyJTOJDS8+CBfmEUw27FLqMPOgYiF4Jdnw9MknQA9iADVpPMGgwdJllPa4jOoSQkACT6t2CgEAIfkEBQoAEQAsBQAHADUAMwAABf8gJI5kORrJYYpAUThrLM8j8TyFWhr3bdBAoKD3AJgARGNwuToQE6bEk0ktOW6LgClgexC01TDkMJgJBLHAAMw8AAA68erqaxduBbb8RHyggwNEZXskDX1KQIE9f4QidD1QS3QwjSOKeHGVcgwLDw2MmqGio6SlpksBBgAMp1QCdzdfIlw4rK0lCociUjcKtySXPQQsPQW/ln1eIgewlMcQsD0II2qgxzw9Wc8zbg0Jetvh4uPk5UABCHcKkSMC4LcBnUkj8rbHvH0ql8PPXX1l+7b5E+TogQJrrfARySQuXh9n5dDhQWSuIrUBBgZZNBDtYEVsRHIsccOuUq5k04JLnCy5Z0gyZUF6NNAUjIivIAhwaGz00lObd3seEYw48MEPmghJCGAowgACAg6YykHywF4JBjestjJUJAZViq0EECAgFcIrjxbTngoBACH5BAUKABEALAUABgA0ADUAAAX/ICSOZGmOzqMMZ+u+sGg8dBHfeAvQdO6XDMXCcBrwFCfBQgH4nQIF3uHEICCmpiiN6CQJeA+Wz8hrdkmLWsCpDZ9JgQQA+xM0CIy3fs/v+/8lBwB5gE8IDwuEgVpmhSSHNXQjZA8EjiUEYGJePAiXJA1gAlRWa58iAloOp2OSrK+wsbKztLVPCQQOWAIAXLRpkVBbtJQ0CF80jbE7YJahBa6vyDyrEKa1kIjXtiIDvdvc4eLj5HsHCAQNm9ypYL4kAAXVp6FgNiY8645gPKOYDwXAFWrDQ2CAAQILpWgmLkAmGgui1RIwQB+rOASsSJQVAFgNf3oouqCIsAQzMEj0Tcx4kMCEQzDKHvID2YWZJzgey4yQqUnPgTs0ISTgp0ZEPX4J+fDsCaEYjXmFluYbYaANVIVEabiquNHPgayWuK3ksSBprAMO0iUwiyMEACH5BAUKABEALAUABgA0ADUAAAX/ICSOZEkOhzkeg6C+cCwGy/MYKmM/jOz7gx1B1RD+ji/BrqFC7BDIaMlRWLhMB8VDcZV6v+DwsRUNEB4OsYlmgx4Tu64aYtg95LG6LTUXweNIDgQ4fTMFNguFYgEGPYqPkJGSk5SVhQwAeJZmDwWEEAc2CpYlf50jSqekIwB2JAwNmpVBiKsyAwAAAba8vb6/wMHCjwEJCXwimMirAYedfKmJvKYPACK00ratO9YiALG9qTYDwxADDQ2O5evsXgFObcu9zXadu324APIv8PVuag52FJBVwlm9B3NC2WEi4+COObSMyDBop0DCegxj9LPz70CCXAQhyApoY6APNnYWTdwTQPETK2cO7o0wkGvfiwAAtChAcI9ePXKs6qWRpOPgUBFa6k3aVm/ICIchxUS0cxRCjYqUktpZVpQbJQFaPZlgUENBt0qYDMhsBykEACH5BAUKABEALAUABgA1ADQAAAX/ICSOZGmeaKqubKA8DSvPavLcA63vxv0cKIFgpxIsFsOTAcBAIW4IIgpwA0h9D6nyZpAWbgXtSag1KBRdsXrNbrvf8DhJAADKS4IvIYAKfBV3JQQ+CUE+gSSDVSkABE2IIj0PBXaQMgIDlZabnJ2ecgMADQBJnyUOWA8OpiQ2qQ+PnQwJQC+vC56okwKvh51YVL1Zvz4AC70xnZIKBwy9OZ4H0BAGX2BprCMBDEx82d/gbAwNBAjT309Y2KwDvZpx1Q97JsGphYHWD/ckDb1WgcBMuEoVS84xHCb8pMKFKEACAOfm2JLnLdyAAaXC9UFAgMA/cAp9RNkxrkFBLQN9S2Rk0c5HRCKKAuIZUJFEvQcftaRTRyLAwQfrRNzMKaWljwI1dfl4F5ISm3gPFKyMibBEAAMGaqoJcPEE1QcvPznzwTAcg44ItBIJAQAh+QQFCgARACwAAAAAQABAAAAFTmAkjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEgsGo/IpHLJbDqf0Kh0Sq1ar9isdsvter/gsHhMLpvP6LR6zW673/C4fE6v2+/4vD4SAgA7); } + +.loading-spinner-02 { + width: 26px; + height: 26px; } + +.loading-spinner-02::before { + content: ''; + display: block; + position: relative; + width: 100%; + height: 100%; + background-size: 16px; + background-position: center center; + background-repeat: no-repeat; + background-image: url("https://cdnjs.cloudflare.com/ajax/libs/leaflet-geocoder-mapzen/1.4.1/images/loading.gif"); } + +@media only screen and (-webkit-min-device-pixel-ratio: 1.25), only screen and (min-resolution: 120dpi), only screen and (min-resolution: 1.25dppx) { + .loading-spinner-02::before { + background-image: url("https://cdnjs.cloudflare.com/ajax/libs/leaflet-geocoder-mapzen/1.4.1/images/loading@2x.gif"); } } + +.logos .bright-logo-wrapper { + background-color: #635378; + width: 180px; + margin: 0 auto; + margin-bottom: 20px; } + +.logos .dark-logo-wrapper { + margin-bottom: 20px; } + +.logos img.logo-sample { + width: 100%; + height: auto; + max-width: 180px; + padding: 20px; } + +nav { + font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; + font-weight: 300; + width: 100%; + height: 50px; + -webkit-transform: translate(0, 0); + -moz-transform: translate(0, 0); + transform: translate(0, 0); + -webkit-transition: top 250ms; + -moz-transition: top 250ms; + transition: top 250ms; + z-index: 3500 !important; } + @media (min-width: 768px) { + nav { + height: 56px; } + nav .container { + padding: 0px; } } + nav .container-fluid { + max-width: 960px; } + nav li { + text-transform: uppercase; + text-align: center; } + nav .btn-white { + padding: 8px 16px; } + nav a { + font-weight: 300; } + +body:not(.is-scrolling) nav.navbar-fixed-top { + top: 0; } + +body.hide-fixed-main-nav nav.navbar-fixed-top { + top: -60px; } + +body { + margin-top: 50px; } + @media (min-width: 768px) { + body { + margin-top: 56px; } } + +@media (max-width: 767px) { + .navbar-nav { + background: rgba(30, 14, 51, 0.9); + margin-top: 0; + margin-bottom: 0; } + .navbar-nav li { + text-align: left; + border-top: 1px solid #635378; } + .navbar-nav li > a { + display: inline-block; + background: transparent !important; + width: 100%; } + .navbar-nav .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + box-shadow: none; + display: block; } + .navbar-nav .dropdown-menu > li > a, + .navbar-nav .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; } + .navbar-nav .dropdown-menu > li > a { + line-height: 20px; + color: white; } + .navbar-nav .dropdown-menu > li > a:hover, .navbar-nav .dropdown-menu > li > a:focus { + background-image: none; } + .navbar-right { + border-top: 1px solid #635378; } + .navbar-right li { + border-top: none; } + .navbar-right #sign-up { + padding-top: 0; } } + +.navbar { + border: 0; + transition: 0.8s; + -webkit-transition: 0.8s; } + +.navbar-nav > li > a { + line-height: 26px; + font-size: 14px; } + +.navbar-fixed-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { + max-height: 420px; } + +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + padding-bottom: 10px; + border-bottom: 5px solid #FF7B7B; } + @media (max-width: 767px) { + .navbar-default .navbar-nav > .active > a, + .navbar-default .navbar-nav > .active > a:hover, + .navbar-default .navbar-nav > .active > a:focus { + border-bottom: 0; + border-left: 5px solid #FF7B7B; } } + +@media (min-width: 768px) { + body.transparent-main-nav nav.navbar { + background: transparent; + padding-top: 12px; + height: 68px; } + body.transparent-main-nav nav.navbar .navbar-nav > .active > a, + body.transparent-main-nav nav.navbar .navbar-nav > .active > a:hover, + body.transparent-main-nav nav.navbar .navbar-nav > .active > a:focus { + border-color: white; } } + +.navbar-brand { + padding: 9px 10px; } + @media (min-width: 768px) { + .navbar-brand { + height: 100%; + padding: 5px 30px 11px 15px; } + .container-fluid .navbar-brand { + padding-left: 15px; } } + +.mapzen-logo { + width: 130px; + height: 40px; + background-image: url("https://mapzen.com/common/styleguide/images/mapzen-logo-stacked.png"); + background-repeat: no-repeat; + background-size: 130px; + background-position: 0 0; } + .mapzen-logo:hover { + background-position: 0 -40px; } + @media (max-width: 767px) { + .mapzen-logo { + height: 36px; + background-position: 0 0; + background-size: 117px; } + .mapzen-logo:hover { + background-position: 0 -36px; } } + @media only screen and (-webkit-min-device-pixel-ratio: 1.25), only screen and (min-resolution: 120dpi), only screen and (min-resolution: 1.25dppx) { + .mapzen-logo { + background-image: url("https://mapzen.com/common/styleguide/images/mapzen-logo-stacked@2x.png"); } } + +.navbar-nav > li > a#sign-in { + min-width: 80px; + max-width: 215px; + text-overflow: ellipsis; } + +@media (min-width: 767px) { + .navbar-nav > li > a#sign-in { + float: left; } } + +.navbar-nav > li > a#sign-up { + min-width: 118px; } + +.navbar-nav > li > a#sign-up > span { + line-height: 26px; } + +.navbar-nav > li > a > .login-profile-github { + width: 22px; + height: 22px; + float: left; + position: relative; + margin-top: 2px; + border-radius: 50%; + border: 1px solid #EEE7F8; + box-sizing: border-box; + margin-right: 10px; } + +.navbar-nav > li > a > .login-profile-default { + width: 28px; + height: 28px; + float: left; + position: relative; + margin-top: -2px; + border-radius: 50%; + border: 1px solid #EEE7F8; + box-sizing: border-box; + margin-right: 10px; } + +.navbar-nav > li > a > .login-txt { + float: left; + overflow: hidden; + max-width: 135px; + white-space: nowrap; + text-overflow: ellipsis; } + +.navbar-nav > li > a > .login-arrow { + display: none; } + @media (min-width: 768px) { + .navbar-nav > li > a > .login-arrow { + display: inline-block; + margin-left: 6px; + font-weight: 700; } } + +.navbar-nav li.active:hover .login-txt { + color: #EEE7F8; } + +.navbar-nav li.active:focus .login-txt { + color: #EEE7F8; } + +.navbar-nav li:hover .login-txt { + color: #EEE7F8; } + +.navbar-nav li a:focus .login-txt { + color: #EEE7F8; } + +.navbar-nav li.active:hover #login-profile { + border-color: #EEE7F8; } + +.navbar-nav li.active a:focus #login-profile { + border-color: #EEE7F8; } + +.navbar-nav li:hover #login-profile { + border-color: #EEE7F8; } + +.navbar-nav li a:focus #login-profile { + border-color: #EEE7F8; } + +#sign-in + .dropdown-menu > li > a { + text-transform: capitalize; } + +.dropdown-menu > li > a { + font-weight: 300; } + +@media (min-width: 767px) { + #sign-in + .dropdown-menu > li { + text-align: left; } } + +.navbar-toggle .icon-bar { + width: 22px; + transition: all 0.2s; } + +.navbar-toggle .top-bar { + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + transform: rotate(45deg); + -webkit-transform: 10% 10%; + -moz-transform: 10% 10%; + transform-origin: 10% 10%; } + +.navbar-toggle .middle-bar { + opacity: 0; } + +.navbar-toggle .bottom-bar { + -webkit-transform: rotate(-45deg); + -moz-transform: rotate(-45deg); + transform: rotate(-45deg); + -webkit-transform: 10% 90%; + -moz-transform: 10% 90%; + transform-origin: 10% 90%; } + +.navbar-toggle.collapsed .top-bar, +.navbar-toggle.collapsed .bottom-bar { + -webkit-transform: rotate(0); + -moz-transform: rotate(0); + transform: rotate(0); } + +.navbar-toggle.collapsed .middle-bar { + opacity: 1; } + +.newsletter-cta-container form { + padding-top: 4px; } + +.newsletter-cta-container input[type="email"] { + height: 43px; + /* To match height of submit button */ + margin-bottom: 8px; } + +.pagination { + display: table; + table-layout: fixed; + width: 100%; + font-size: 16px; + margin-bottom: 0; } + .pagination a.pagination-link { + position: relative; + display: table-cell; + margin: 0; + padding: 20px; + vertical-align: middle; + width: 50%; } + .pagination a.pagination-link:hover { + background-color: #f8f8f8; } + .pagination .fa { + position: absolute; + top: 50%; + margin-top: -20px; + width: 25px; + height: 40px; + font-size: 30px; + line-height: 40px; } + .pagination .pagination-link-text { + display: block; } + .pagination .pagination-previous .pagination-link-text { + padding-left: 20px; } + .pagination .pagination-previous .fa { + left: 5px; } + .pagination .pagination-previous + .pagination-next { + border-left: 1px solid #e0e0e0; } + .pagination .pagination-next { + text-align: right; } + .pagination .pagination-next .pagination-link-text { + padding-right: 20px; } + .pagination .pagination-next .fa { + right: 5px; } + +.pagination-alt { + border-top: 1px solid #e0e0e0; + border-bottom: 1px solid #e0e0e0; + border-radius: 0; } + .pagination-alt .pagination-previous + .pagination-next { + border-left: 0; } + +.content { + line-height: 30px; } + +.content > * + *, +.static-content > * + * { + margin-top: 24px; + margin-bottom: 24px; } + +.content p, +.static-content p { + word-wrap: break-word; } + +.content img[alt^='screenshot'], +.content img[alt^='Screenshot'], +.static-content img[alt^='screenshot'], +.static-content img[alt^='Screenshot'] { + border: 3px solid #e9e9e9; } + +.content img.emoji, +.static-content img.emoji { + width: auto; + padding: 0px; } + +.content .footnotes ol, +.static-content .footnotes ol { + font-size: 14px; + padding-left: 20px; } + +.content .footnotes li a[rev], +.static-content .footnotes li a[rev] { + font-size: 10px; + margin-left: 0.25em; } + +.content sup[id^="fnref"]::before, +.static-content sup[id^="fnref"]::before { + padding-top: 80px; + margin-top: -80px; + content: ''; + display: inline-block; + pointer-events: none; } + +@media (min-width: 992px) { + .blog-content .table-wrapper { + margin-left: -10%; + margin-right: 10%; + max-width: 120%; + width: 120%; } } + +.demo-wrapper { + margin-left: calc(50% - 50vw); + width: 100vw; + height: 500px; + overflow-x: hidden; + overflow-y: hidden; } + .demo-wrapper iframe { + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: hidden; + overflow: hidden; } + +.multimedia-wrapper { + width: 100%; + margin-top: 1.5em; + margin-bottom: 1.5em; } + @media (min-width: 992px) { + .multimedia-wrapper { + width: 120%; + margin-left: -10%; + margin-right: -10%; } } + .multimedia-wrapper video, + .multimedia-wrapper iframe { + margin: 0 auto; + display: block; + margin-bottom: 20px; + margin-top: 20px; + width: 100%; } + .multimedia-wrapper iframe { + border: 0; } + +.upside-down { + transform: rotate(180deg); } + +.post-meta { + background-color: #f8f8f8; + padding: 30px 20px; } + +.pricing-table { + border: 2px solid #ddd; + padding: 0 0.5em; + line-height: 1.4; + font-size: 0.85em; + color: #666666; } + +.pricing-table-row { + border-bottom: 1px solid #ddd; + margin: 0; } + .pricing-table-row:last-of-type { + border-bottom: 0; } + @media (min-width: 768px) { + .pricing-table-row > div { + padding: 0.5em 0; } } + +@media (max-width: 767px) { + .pricing-table-product { + text-align: center; + background-color: #f8f8f8; + padding: 0.5em; + margin-top: 0.5em; } } + +.pricing-table-product-label { + text-transform: uppercase; } + @media (min-width: 768px) { + .pricing-table-product-label { + margin-top: 0.5em; } } + +.pricing-table-product-link { + font-size: 16px; } + +@media (max-width: 767px) { + .pricing-table-cost { + margin-top: 10px; + margin-bottom: 10px; } + .pricing-table-cost:last-of-type { + border-left: 1px solid #ddd; } } + +.pricing-table-cost-amount { + color: #7F2DE3; + font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; + font-size: 2em; + font-weight: 700; + line-height: 1; + margin-top: 0.25em; } + +.pricing-table-notes { + margin-top: 12px; + padding: 0 0.5em; + color: #666666; } + +.pricing-table-notes-right { + float: right; } + +@media print { + a.btn[href]:after, + a.no-print-link:after { + content: none; } } + +body.project .demo-container { + position: relative; + height: 600px; + overflow: hidden; + z-index: 1990; } + body.project .demo-container > .demo-map { + width: 100%; + height: 100%; + z-index: 100; } + +.static-content { + font-size: 16px; + line-height: 1.6; } + .static-content img.red-compass { + width: auto; + height: auto; } + @media (min-width: 992px) { + .static-content img.red-compass { + width: auto; + height: auto; } } + @media (min-width: 992px) { + .static-content { + font-size: 16px; } } + .static-content h1 { + font-weight: 700; + font-size: 36px; + margin-top: 48px; + margin-bottom: 12px; } + .static-content h2 { + font-weight: 700; + font-size: 24px; + margin-top: 48px; + margin-bottom: 12px; } + .static-content h3 { + font-weight: 700; + font-size: 16px; + margin-top: 24px; + margin-bottom: 12px; } + .static-content h4 { + margin-top: 24px; + margin-bottom: 12px; + font-weight: 700; + font-size: 14px; } + .static-content h5, .static-content h6 { + margin-top: 24px; + margin-bottom: 12px; + font-weight: 700; + font-size: 11px; } + .static-content h1[id]:before, + .static-content h2[id]:before, + .static-content h3[id]:before, + .static-content h4[id]:before, + .static-content h5[id]:before, + .static-content h6[id]:before { + content: ''; + display: block; + margin-top: -146px; + height: 146px; + pointer-events: none; } + body.hide-fixed-main-nav .static-content h1[id]:before, body.hide-fixed-main-nav + .static-content h2[id]:before, body.hide-fixed-main-nav + .static-content h3[id]:before, body.hide-fixed-main-nav + .static-content h4[id]:before, body.hide-fixed-main-nav + .static-content h5[id]:before, body.hide-fixed-main-nav + .static-content h6[id]:before { + margin-top: -90px; + height: 90px; } + .static-content img:not([width]):not([height]) { + width: 100%; } + @media (min-width: 992px) { + .static-content img:not([width]):not([height]) { + width: 120%; + margin-left: -10%; + margin-right: -10%; } } + .static-content h1 + p > img, + .static-content h2 + p > img, + .static-content h3 + p > img, + .static-content h4 + p > img, + .static-content h5 + p > img, + .static-content h6 + p > img { + margin-top: 0; } + .static-content ul { + list-style-type: disc; } + .static-content ul.no-bullet { + list-style-type: none; } + .static-content .image-bullet { + width: 100%; + margin-top: -2%; + margin-left: 0; } + +.project-demo { + width: 100%; + height: calc(100% - 60px); } + +.demo-frame { + width: 100%; + height: 100%; } + +.demo-blocker { + position: absolute; + width: 100%; + height: calc(100% - 60px); + display: block; + left: 0px; + top: 0px; + z-index: 1998; } + .demo-blocker.disable-blocker { + display: none; } + +.demo-controls { + position: relative; + width: 100%; + height: 60px; + background-color: rgba(255, 255, 255, 0.9); + border-bottom: 1px solid #e0e0e0; + color: #FF7B7B; } + +.demo-control-list { + width: calc(100% - 120px); + margin: 0 auto; + padding: 0; + list-style-type: none; } + @media (min-width: 768px) { + .demo-control-list { + width: 100%; + margin: 0; + display: table; + table-layout: fixed; } } + +.demo-control { + padding: 0 10px; + text-align: center; + line-height: 60px; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + cursor: pointer; + font-weight: 700; + width: 100%; + display: none; } + .demo-control.active { + display: block; } + @media (min-width: 768px) { + .demo-control { + display: table-cell; + width: auto; + border-left: 1px solid #e0e0e0; } + .demo-control:first-child { + border-left: 0; } + .demo-control.active { + display: table-cell; + background: #FF7B7B; + color: #fff; } } + +.demo-control.hover, +.demo-control-previous.hover, +.demo-control-next.hover { + background: #FCDBDB; + color: #FF7B7B; } + +.demo-control-previous, +.demo-control-next { + position: absolute; + top: 0; + width: 60px; + font-size: 2em; + line-height: 60px; + text-align: center; + cursor: pointer; + -webkit-user-select: none; + user-select: none; } + @media (min-width: 768px) { + .demo-control-previous, + .demo-control-next { + display: none; } } + +.demo-control-previous { + left: 0; } + +.demo-control-next { + right: 0; } + +.search-label { + color: #606060; + margin-bottom: 0.5em; } + +.search-container form { + margin-top: 8px; } + +.search-results-container { + display: none; + position: absolute; + background-color: white; + padding: 0; + box-sizing: border-box; + right: 15px; + left: 15px; + border: 1px solid #e1e1e1; + border-top: 0; + margin-top: 0; + box-shadow: 0 2px 8px 1px rgba(0, 0, 0, 0.1); + overflow-x: hidden; + overflow-y: auto; } + .search-results-container::-webkit-scrollbar { + height: 6px; + width: 6px; } + .search-results-container::-webkit-scrollbar-thumb { + background-color: rgba(110, 160, 164, 0.75); } + .search-results-container h3 { + font-size: 1.4em; + margin-top: 0; + margin-bottom: 0.5em; } + .search-results-container p:first-child:last-child { + padding: 0.85em 10px; + margin: 0; + font-weight: bold; } + .search-results-container article { + padding: 10px; + cursor: pointer; } + .search-results-container article:not(:last-child) { + border-bottom: 1px solid #e1e1e1; } + .search-results-container article:hover { + background-color: rgba(192, 192, 192, 0.1); } + .search-results-container article:hover a { + color: #385d5c; } + .search-results-container article.selected { + background-color: rgba(128, 128, 128, 0.1); } + .search-results-container strong { + color: #385d5c; + background-color: papayawhip; } + +@media (max-width: 768px) { + .form-control { + line-height: 40px; + padding: 0 15px; + height: auto; } } + +.section-nav { + position: fixed; + top: 76px; + width: 100%; + height: 50px; + font-size: 1rem; + overflow: hidden; + z-index: 2000; + pointer-events: none; + -webkit-transform: translate(0, 0); + -moz-transform: translate(0, 0); + transform: translate(0, 0); + -webkit-transition: top 0.25s; + -moz-transition: top 0.25s; + transition: top 0.25s; + -webkit-font-smoothing: subpixel-antialiased; } + .section-nav a { + display: block; + color: white; + width: 100%; + height: 100%; + padding: 0 20px; + outline: 0; + font-weight: 700; } + @media (min-width: 768px) and (max-width: 1199px) { + .section-nav a { + padding: 0 15px; } } + .section-nav a:visited, + .section-nav a:active, + .section-nav a:focus { + color: white; } + .section-nav a:hover { + color: #FF7B7B; } + .section-nav.is-floating { + top: 20px; } + body.fixed-main-nav .section-nav.is-floating { + top: 76px; } + .section-nav.is-collapsed .section-nav-container { + width: 300px; } + .section-nav.is-collapsed .section-nav-items { + width: 150px; } + .section-nav.is-collapsed .section-nav-items { + background-color: #FF7B7B; } + .section-nav.is-collapsed ul { + position: absolute; + top: 0; + -webkit-transition: top 0.25s; + -moz-transition: top 0.25s; + transition: top 0.25s; } + .section-nav.is-collapsed li { + display: block; } + .section-nav.is-collapsed li.section-nav-item-egg { + display: block; } + .section-nav.is-collapsed a { + padding-right: 40px; } + .section-nav.is-collapsed .section-nav-dropdown { + display: block; } + @media (max-width: 767px) { + .section-nav { + top: 50px !important; } + body.hide-fixed-main-nav .section-nav { + top: 0 !important; } + .section-nav .container { + padding: 0; } + .section-nav .section-nav-container { + width: 100% !important; } + .section-nav .section-nav-items { + display: none; } + .section-nav a { + padding-right: 20px !important; } } + +@media (min-width: 768px) { + .section-nav > .container { + max-width: calc(100% - 70px); } } + +.section-nav-container { + display: inline-block; + position: relative; + width: 100%; + height: 50px; + background-color: rgba(15, 15, 15, 0.75); + overflow: hidden; + z-index: 2000; + pointer-events: auto; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; } + .section-nav.enable-animation .section-nav-container { + -webkit-transition: width 0.25s; + -moz-transition: width 0.25s; + transition: width 0.25s; } + +.section-nav-title { + display: inline-block; + position: relative; + height: 50px; + color: white; + text-shadow: 0 1px 1px black; + vertical-align: top; + opacity: 1; } + .section-nav-title h2 { + margin: 0; + font-size: 2em; + line-height: 50px; } + @media (min-width: 768px) and (max-width: 1199px) { + .section-nav-title h2 { + font-size: 1.8em; } } + +.section-nav-items { + display: inline-block; + height: 50px; + position: absolute; + right: 0; + overflow: hidden; } + .section-nav-items ul { + display: inline-block; + padding: 0; + margin: 0; + font-size: 0; + white-space: nowrap; + float: right; } + .section-nav-items li { + display: inline-block; + line-height: 50px; + font-size: 14px; + color: white; } + @media (min-width: 768px) and (max-width: 1199px) { + .section-nav-items li { + font-size: 13px; } } + .section-nav-items li:not(.active):not(:hover) { + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5); } + body:not(.is-scrolling) .section-nav-items li.active, .section-nav-items li.active:hover, .section-nav-items li.activated { + background-color: #FF7B7B; } + .section-nav-items li.active:hover a, + .section-nav-items li.activated a { + color: #ffffff; } + .section-nav-items li.section-nav-item-egg { + display: none; + padding: 0 20px; } + +.section-nav-dropdown { + display: none; + position: absolute; + right: 9px; + bottom: 9px; + color: white; + font-size: 8px; + opacity: 0.85; + pointer-events: none; } + +.section-nav-hitbox { + position: fixed; + top: 0; + width: 100%; + height: 100px; + z-index: 1999; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + pointer-events: none; } + .section-nav.enable-hitbox + .section-nav-hitbox { + pointer-events: auto; } + body.fixed-main-nav .section-nav-hitbox { + height: 156px; } + @media (max-width: 767px) { + .section-nav-hitbox { + display: none; } } + +.post-meta .byline + .social-buttons { + margin-top: 20px; } + +.social-buttons > ul { + margin: 0; + padding: 0; + list-style-type: none; } + .social-buttons > ul > li { + display: inline-block; + width: 44px; + height: 44px; } + @media (max-width: 767px) { + .social-buttons > ul > li { + width: calc(25% - 1em); } } + .social-buttons > ul > li:not(:last-of-type) { + margin-right: 1em; } + +.social-buttons a { + display: block; + width: 100%; + height: 100%; + text-align: center; + border-radius: 0; + border-width: 1px; + border-style: solid; + -webkit-transition: background-color 100ms linear; + -moz-transition: background-color 100ms linear; + transition: background-color 100ms linear; } + .social-buttons a:hover svg path, + .social-buttons a:hover svg polygon { + fill: white; } + +.social-buttons svg { + position: relative; + width: 22px; + top: 7px; } + +.social-buttons svg path, +.social-buttons svg polygon { + -webkit-transition: fill 100ms linear; + -moz-transition: fill 100ms linear; + transition: fill 100ms linear; } + +.social-button-email a { + border-color: #0a88ff; } + +.social-button-email a:hover { + background-color: #0a88ff; } + +.social-button-email svg { + width: 20px; } + +.social-button-email svg path, +.social-button-email svg polygon { + fill: #0a88ff; } + +.social-button-facebook a { + border-color: #306199; } + +.social-button-facebook a:hover { + background-color: #306199; } + +.social-button-facebook svg { + width: 20px; } + +.social-button-facebook svg path, +.social-button-facebook svg polygon { + fill: #306199; } + +.social-button-twitter a { + border-color: #26c4f1; } + +.social-button-twitter a:hover { + background-color: #26c4f1; } + +.social-button-twitter svg path, +.social-button-twitter svg polygon { + fill: #26c4f1; } + +.social-button-pinterest a { + border-color: #b81621; } + +.social-button-pinterest a:hover { + background-color: #b81621; } + +.social-button-pinterest svg path, +.social-button-pinterest svg polygon { + fill: #b81621; } + +.m-0 { + margin: 0 !important; } + +.mt-0 { + margin-top: 0 !important; } + +.mr-0 { + margin-right: 0 !important; } + +.mb-0 { + margin-bottom: 0 !important; } + +.ml-0 { + margin-left: 0 !important; } + +.mx-0 { + margin-right: 0 !important; + margin-left: 0 !important; } + +.my-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; } + +.m-1 { + margin: 6px !important; } + +.mt-1 { + margin-top: 6px !important; } + +.mr-1 { + margin-right: 6px !important; } + +.mb-1 { + margin-bottom: 6px !important; } + +.ml-1 { + margin-left: 6px !important; } + +.mx-1 { + margin-right: 6px !important; + margin-left: 6px !important; } + +.my-1 { + margin-top: 6px !important; + margin-bottom: 6px !important; } + +.m-2 { + margin: 12px !important; } + +.mt-2 { + margin-top: 12px !important; } + +.mr-2 { + margin-right: 12px !important; } + +.mb-2 { + margin-bottom: 12px !important; } + +.ml-2 { + margin-left: 12px !important; } + +.mx-2 { + margin-right: 12px !important; + margin-left: 12px !important; } + +.my-2 { + margin-top: 12px !important; + margin-bottom: 12px !important; } + +.m-3 { + margin: 24px !important; } + +.mt-3 { + margin-top: 24px !important; } + +.mr-3 { + margin-right: 24px !important; } + +.mb-3 { + margin-bottom: 24px !important; } + +.ml-3 { + margin-left: 24px !important; } + +.mx-3 { + margin-right: 24px !important; + margin-left: 24px !important; } + +.my-3 { + margin-top: 24px !important; + margin-bottom: 24px !important; } + +.m-4 { + margin: 36px !important; } + +.mt-4 { + margin-top: 36px !important; } + +.mr-4 { + margin-right: 36px !important; } + +.mb-4 { + margin-bottom: 36px !important; } + +.ml-4 { + margin-left: 36px !important; } + +.mx-4 { + margin-right: 36px !important; + margin-left: 36px !important; } + +.my-4 { + margin-top: 36px !important; + margin-bottom: 36px !important; } + +.m-5 { + margin: 72px !important; } + +.mt-5 { + margin-top: 72px !important; } + +.mr-5 { + margin-right: 72px !important; } + +.mb-5 { + margin-bottom: 72px !important; } + +.ml-5 { + margin-left: 72px !important; } + +.mx-5 { + margin-right: 72px !important; + margin-left: 72px !important; } + +.my-5 { + margin-top: 72px !important; + margin-bottom: 72px !important; } + +.p-0 { + padding: 0 !important; } + +.pt-0 { + padding-top: 0 !important; } + +.pr-0 { + padding-right: 0 !important; } + +.pb-0 { + padding-bottom: 0 !important; } + +.pl-0 { + padding-left: 0 !important; } + +.px-0 { + padding-right: 0 !important; + padding-left: 0 !important; } + +.py-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; } + +.p-1 { + padding: 6px !important; } + +.pt-1 { + padding-top: 6px !important; } + +.pr-1 { + padding-right: 6px !important; } + +.pb-1 { + padding-bottom: 6px !important; } + +.pl-1 { + padding-left: 6px !important; } + +.px-1 { + padding-right: 6px !important; + padding-left: 6px !important; } + +.py-1 { + padding-top: 6px !important; + padding-bottom: 6px !important; } + +.p-2 { + padding: 12px !important; } + +.pt-2 { + padding-top: 12px !important; } + +.pr-2 { + padding-right: 12px !important; } + +.pb-2 { + padding-bottom: 12px !important; } + +.pl-2 { + padding-left: 12px !important; } + +.px-2 { + padding-right: 12px !important; + padding-left: 12px !important; } + +.py-2 { + padding-top: 12px !important; + padding-bottom: 12px !important; } + +.p-3 { + padding: 24px !important; } + +.pt-3 { + padding-top: 24px !important; } + +.pr-3 { + padding-right: 24px !important; } + +.pb-3 { + padding-bottom: 24px !important; } + +.pl-3 { + padding-left: 24px !important; } + +.px-3 { + padding-right: 24px !important; + padding-left: 24px !important; } + +.py-3 { + padding-top: 24px !important; + padding-bottom: 24px !important; } + +.p-4 { + padding: 36px !important; } + +.pt-4 { + padding-top: 36px !important; } + +.pr-4 { + padding-right: 36px !important; } + +.pb-4 { + padding-bottom: 36px !important; } + +.pl-4 { + padding-left: 36px !important; } + +.px-4 { + padding-right: 36px !important; + padding-left: 36px !important; } + +.py-4 { + padding-top: 36px !important; + padding-bottom: 36px !important; } + +.p-5 { + padding: 72px !important; } + +.pt-5 { + padding-top: 72px !important; } + +.pr-5 { + padding-right: 72px !important; } + +.pb-5 { + padding-bottom: 72px !important; } + +.pl-5 { + padding-left: 72px !important; } + +.px-5 { + padding-right: 72px !important; + padding-left: 72px !important; } + +.py-5 { + padding-top: 72px !important; + padding-bottom: 72px !important; } + +.m-auto { + margin: auto !important; } + +.mt-auto { + margin-top: auto !important; } + +.mr-auto { + margin-right: auto !important; } + +.mb-auto { + margin-bottom: auto !important; } + +.ml-auto { + margin-left: auto !important; } + +.mx-auto { + margin-right: auto !important; + margin-left: auto !important; } + +.my-auto { + margin-top: auto !important; + margin-bottom: auto !important; } + +@media (min-width: 768px) { + .m-sm-0 { + margin: 0 !important; } + .mt-sm-0 { + margin-top: 0 !important; } + .mr-sm-0 { + margin-right: 0 !important; } + .mb-sm-0 { + margin-bottom: 0 !important; } + .ml-sm-0 { + margin-left: 0 !important; } + .mx-sm-0 { + margin-right: 0 !important; + margin-left: 0 !important; } + .my-sm-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; } + .m-sm-1 { + margin: 6px !important; } + .mt-sm-1 { + margin-top: 6px !important; } + .mr-sm-1 { + margin-right: 6px !important; } + .mb-sm-1 { + margin-bottom: 6px !important; } + .ml-sm-1 { + margin-left: 6px !important; } + .mx-sm-1 { + margin-right: 6px !important; + margin-left: 6px !important; } + .my-sm-1 { + margin-top: 6px !important; + margin-bottom: 6px !important; } + .m-sm-2 { + margin: 12px !important; } + .mt-sm-2 { + margin-top: 12px !important; } + .mr-sm-2 { + margin-right: 12px !important; } + .mb-sm-2 { + margin-bottom: 12px !important; } + .ml-sm-2 { + margin-left: 12px !important; } + .mx-sm-2 { + margin-right: 12px !important; + margin-left: 12px !important; } + .my-sm-2 { + margin-top: 12px !important; + margin-bottom: 12px !important; } + .m-sm-3 { + margin: 24px !important; } + .mt-sm-3 { + margin-top: 24px !important; } + .mr-sm-3 { + margin-right: 24px !important; } + .mb-sm-3 { + margin-bottom: 24px !important; } + .ml-sm-3 { + margin-left: 24px !important; } + .mx-sm-3 { + margin-right: 24px !important; + margin-left: 24px !important; } + .my-sm-3 { + margin-top: 24px !important; + margin-bottom: 24px !important; } + .m-sm-4 { + margin: 36px !important; } + .mt-sm-4 { + margin-top: 36px !important; } + .mr-sm-4 { + margin-right: 36px !important; } + .mb-sm-4 { + margin-bottom: 36px !important; } + .ml-sm-4 { + margin-left: 36px !important; } + .mx-sm-4 { + margin-right: 36px !important; + margin-left: 36px !important; } + .my-sm-4 { + margin-top: 36px !important; + margin-bottom: 36px !important; } + .m-sm-5 { + margin: 72px !important; } + .mt-sm-5 { + margin-top: 72px !important; } + .mr-sm-5 { + margin-right: 72px !important; } + .mb-sm-5 { + margin-bottom: 72px !important; } + .ml-sm-5 { + margin-left: 72px !important; } + .mx-sm-5 { + margin-right: 72px !important; + margin-left: 72px !important; } + .my-sm-5 { + margin-top: 72px !important; + margin-bottom: 72px !important; } + .p-sm-0 { + padding: 0 !important; } + .pt-sm-0 { + padding-top: 0 !important; } + .pr-sm-0 { + padding-right: 0 !important; } + .pb-sm-0 { + padding-bottom: 0 !important; } + .pl-sm-0 { + padding-left: 0 !important; } + .px-sm-0 { + padding-right: 0 !important; + padding-left: 0 !important; } + .py-sm-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; } + .p-sm-1 { + padding: 6px !important; } + .pt-sm-1 { + padding-top: 6px !important; } + .pr-sm-1 { + padding-right: 6px !important; } + .pb-sm-1 { + padding-bottom: 6px !important; } + .pl-sm-1 { + padding-left: 6px !important; } + .px-sm-1 { + padding-right: 6px !important; + padding-left: 6px !important; } + .py-sm-1 { + padding-top: 6px !important; + padding-bottom: 6px !important; } + .p-sm-2 { + padding: 12px !important; } + .pt-sm-2 { + padding-top: 12px !important; } + .pr-sm-2 { + padding-right: 12px !important; } + .pb-sm-2 { + padding-bottom: 12px !important; } + .pl-sm-2 { + padding-left: 12px !important; } + .px-sm-2 { + padding-right: 12px !important; + padding-left: 12px !important; } + .py-sm-2 { + padding-top: 12px !important; + padding-bottom: 12px !important; } + .p-sm-3 { + padding: 24px !important; } + .pt-sm-3 { + padding-top: 24px !important; } + .pr-sm-3 { + padding-right: 24px !important; } + .pb-sm-3 { + padding-bottom: 24px !important; } + .pl-sm-3 { + padding-left: 24px !important; } + .px-sm-3 { + padding-right: 24px !important; + padding-left: 24px !important; } + .py-sm-3 { + padding-top: 24px !important; + padding-bottom: 24px !important; } + .p-sm-4 { + padding: 36px !important; } + .pt-sm-4 { + padding-top: 36px !important; } + .pr-sm-4 { + padding-right: 36px !important; } + .pb-sm-4 { + padding-bottom: 36px !important; } + .pl-sm-4 { + padding-left: 36px !important; } + .px-sm-4 { + padding-right: 36px !important; + padding-left: 36px !important; } + .py-sm-4 { + padding-top: 36px !important; + padding-bottom: 36px !important; } + .p-sm-5 { + padding: 72px !important; } + .pt-sm-5 { + padding-top: 72px !important; } + .pr-sm-5 { + padding-right: 72px !important; } + .pb-sm-5 { + padding-bottom: 72px !important; } + .pl-sm-5 { + padding-left: 72px !important; } + .px-sm-5 { + padding-right: 72px !important; + padding-left: 72px !important; } + .py-sm-5 { + padding-top: 72px !important; + padding-bottom: 72px !important; } + .m-sm-auto { + margin: auto !important; } + .mt-sm-auto { + margin-top: auto !important; } + .mr-sm-auto { + margin-right: auto !important; } + .mb-sm-auto { + margin-bottom: auto !important; } + .ml-sm-auto { + margin-left: auto !important; } + .mx-sm-auto { + margin-right: auto !important; + margin-left: auto !important; } + .my-sm-auto { + margin-top: auto !important; + margin-bottom: auto !important; } } + +@media (min-width: 992px) { + .m-md-0 { + margin: 0 !important; } + .mt-md-0 { + margin-top: 0 !important; } + .mr-md-0 { + margin-right: 0 !important; } + .mb-md-0 { + margin-bottom: 0 !important; } + .ml-md-0 { + margin-left: 0 !important; } + .mx-md-0 { + margin-right: 0 !important; + margin-left: 0 !important; } + .my-md-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; } + .m-md-1 { + margin: 6px !important; } + .mt-md-1 { + margin-top: 6px !important; } + .mr-md-1 { + margin-right: 6px !important; } + .mb-md-1 { + margin-bottom: 6px !important; } + .ml-md-1 { + margin-left: 6px !important; } + .mx-md-1 { + margin-right: 6px !important; + margin-left: 6px !important; } + .my-md-1 { + margin-top: 6px !important; + margin-bottom: 6px !important; } + .m-md-2 { + margin: 12px !important; } + .mt-md-2 { + margin-top: 12px !important; } + .mr-md-2 { + margin-right: 12px !important; } + .mb-md-2 { + margin-bottom: 12px !important; } + .ml-md-2 { + margin-left: 12px !important; } + .mx-md-2 { + margin-right: 12px !important; + margin-left: 12px !important; } + .my-md-2 { + margin-top: 12px !important; + margin-bottom: 12px !important; } + .m-md-3 { + margin: 24px !important; } + .mt-md-3 { + margin-top: 24px !important; } + .mr-md-3 { + margin-right: 24px !important; } + .mb-md-3 { + margin-bottom: 24px !important; } + .ml-md-3 { + margin-left: 24px !important; } + .mx-md-3 { + margin-right: 24px !important; + margin-left: 24px !important; } + .my-md-3 { + margin-top: 24px !important; + margin-bottom: 24px !important; } + .m-md-4 { + margin: 36px !important; } + .mt-md-4 { + margin-top: 36px !important; } + .mr-md-4 { + margin-right: 36px !important; } + .mb-md-4 { + margin-bottom: 36px !important; } + .ml-md-4 { + margin-left: 36px !important; } + .mx-md-4 { + margin-right: 36px !important; + margin-left: 36px !important; } + .my-md-4 { + margin-top: 36px !important; + margin-bottom: 36px !important; } + .m-md-5 { + margin: 72px !important; } + .mt-md-5 { + margin-top: 72px !important; } + .mr-md-5 { + margin-right: 72px !important; } + .mb-md-5 { + margin-bottom: 72px !important; } + .ml-md-5 { + margin-left: 72px !important; } + .mx-md-5 { + margin-right: 72px !important; + margin-left: 72px !important; } + .my-md-5 { + margin-top: 72px !important; + margin-bottom: 72px !important; } + .p-md-0 { + padding: 0 !important; } + .pt-md-0 { + padding-top: 0 !important; } + .pr-md-0 { + padding-right: 0 !important; } + .pb-md-0 { + padding-bottom: 0 !important; } + .pl-md-0 { + padding-left: 0 !important; } + .px-md-0 { + padding-right: 0 !important; + padding-left: 0 !important; } + .py-md-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; } + .p-md-1 { + padding: 6px !important; } + .pt-md-1 { + padding-top: 6px !important; } + .pr-md-1 { + padding-right: 6px !important; } + .pb-md-1 { + padding-bottom: 6px !important; } + .pl-md-1 { + padding-left: 6px !important; } + .px-md-1 { + padding-right: 6px !important; + padding-left: 6px !important; } + .py-md-1 { + padding-top: 6px !important; + padding-bottom: 6px !important; } + .p-md-2 { + padding: 12px !important; } + .pt-md-2 { + padding-top: 12px !important; } + .pr-md-2 { + padding-right: 12px !important; } + .pb-md-2 { + padding-bottom: 12px !important; } + .pl-md-2 { + padding-left: 12px !important; } + .px-md-2 { + padding-right: 12px !important; + padding-left: 12px !important; } + .py-md-2 { + padding-top: 12px !important; + padding-bottom: 12px !important; } + .p-md-3 { + padding: 24px !important; } + .pt-md-3 { + padding-top: 24px !important; } + .pr-md-3 { + padding-right: 24px !important; } + .pb-md-3 { + padding-bottom: 24px !important; } + .pl-md-3 { + padding-left: 24px !important; } + .px-md-3 { + padding-right: 24px !important; + padding-left: 24px !important; } + .py-md-3 { + padding-top: 24px !important; + padding-bottom: 24px !important; } + .p-md-4 { + padding: 36px !important; } + .pt-md-4 { + padding-top: 36px !important; } + .pr-md-4 { + padding-right: 36px !important; } + .pb-md-4 { + padding-bottom: 36px !important; } + .pl-md-4 { + padding-left: 36px !important; } + .px-md-4 { + padding-right: 36px !important; + padding-left: 36px !important; } + .py-md-4 { + padding-top: 36px !important; + padding-bottom: 36px !important; } + .p-md-5 { + padding: 72px !important; } + .pt-md-5 { + padding-top: 72px !important; } + .pr-md-5 { + padding-right: 72px !important; } + .pb-md-5 { + padding-bottom: 72px !important; } + .pl-md-5 { + padding-left: 72px !important; } + .px-md-5 { + padding-right: 72px !important; + padding-left: 72px !important; } + .py-md-5 { + padding-top: 72px !important; + padding-bottom: 72px !important; } + .m-md-auto { + margin: auto !important; } + .mt-md-auto { + margin-top: auto !important; } + .mr-md-auto { + margin-right: auto !important; } + .mb-md-auto { + margin-bottom: auto !important; } + .ml-md-auto { + margin-left: auto !important; } + .mx-md-auto { + margin-right: auto !important; + margin-left: auto !important; } + .my-md-auto { + margin-top: auto !important; + margin-bottom: auto !important; } } + +@media (min-width: 1200px) { + .m-lg-0 { + margin: 0 !important; } + .mt-lg-0 { + margin-top: 0 !important; } + .mr-lg-0 { + margin-right: 0 !important; } + .mb-lg-0 { + margin-bottom: 0 !important; } + .ml-lg-0 { + margin-left: 0 !important; } + .mx-lg-0 { + margin-right: 0 !important; + margin-left: 0 !important; } + .my-lg-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; } + .m-lg-1 { + margin: 6px !important; } + .mt-lg-1 { + margin-top: 6px !important; } + .mr-lg-1 { + margin-right: 6px !important; } + .mb-lg-1 { + margin-bottom: 6px !important; } + .ml-lg-1 { + margin-left: 6px !important; } + .mx-lg-1 { + margin-right: 6px !important; + margin-left: 6px !important; } + .my-lg-1 { + margin-top: 6px !important; + margin-bottom: 6px !important; } + .m-lg-2 { + margin: 12px !important; } + .mt-lg-2 { + margin-top: 12px !important; } + .mr-lg-2 { + margin-right: 12px !important; } + .mb-lg-2 { + margin-bottom: 12px !important; } + .ml-lg-2 { + margin-left: 12px !important; } + .mx-lg-2 { + margin-right: 12px !important; + margin-left: 12px !important; } + .my-lg-2 { + margin-top: 12px !important; + margin-bottom: 12px !important; } + .m-lg-3 { + margin: 24px !important; } + .mt-lg-3 { + margin-top: 24px !important; } + .mr-lg-3 { + margin-right: 24px !important; } + .mb-lg-3 { + margin-bottom: 24px !important; } + .ml-lg-3 { + margin-left: 24px !important; } + .mx-lg-3 { + margin-right: 24px !important; + margin-left: 24px !important; } + .my-lg-3 { + margin-top: 24px !important; + margin-bottom: 24px !important; } + .m-lg-4 { + margin: 36px !important; } + .mt-lg-4 { + margin-top: 36px !important; } + .mr-lg-4 { + margin-right: 36px !important; } + .mb-lg-4 { + margin-bottom: 36px !important; } + .ml-lg-4 { + margin-left: 36px !important; } + .mx-lg-4 { + margin-right: 36px !important; + margin-left: 36px !important; } + .my-lg-4 { + margin-top: 36px !important; + margin-bottom: 36px !important; } + .m-lg-5 { + margin: 72px !important; } + .mt-lg-5 { + margin-top: 72px !important; } + .mr-lg-5 { + margin-right: 72px !important; } + .mb-lg-5 { + margin-bottom: 72px !important; } + .ml-lg-5 { + margin-left: 72px !important; } + .mx-lg-5 { + margin-right: 72px !important; + margin-left: 72px !important; } + .my-lg-5 { + margin-top: 72px !important; + margin-bottom: 72px !important; } + .p-lg-0 { + padding: 0 !important; } + .pt-lg-0 { + padding-top: 0 !important; } + .pr-lg-0 { + padding-right: 0 !important; } + .pb-lg-0 { + padding-bottom: 0 !important; } + .pl-lg-0 { + padding-left: 0 !important; } + .px-lg-0 { + padding-right: 0 !important; + padding-left: 0 !important; } + .py-lg-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; } + .p-lg-1 { + padding: 6px !important; } + .pt-lg-1 { + padding-top: 6px !important; } + .pr-lg-1 { + padding-right: 6px !important; } + .pb-lg-1 { + padding-bottom: 6px !important; } + .pl-lg-1 { + padding-left: 6px !important; } + .px-lg-1 { + padding-right: 6px !important; + padding-left: 6px !important; } + .py-lg-1 { + padding-top: 6px !important; + padding-bottom: 6px !important; } + .p-lg-2 { + padding: 12px !important; } + .pt-lg-2 { + padding-top: 12px !important; } + .pr-lg-2 { + padding-right: 12px !important; } + .pb-lg-2 { + padding-bottom: 12px !important; } + .pl-lg-2 { + padding-left: 12px !important; } + .px-lg-2 { + padding-right: 12px !important; + padding-left: 12px !important; } + .py-lg-2 { + padding-top: 12px !important; + padding-bottom: 12px !important; } + .p-lg-3 { + padding: 24px !important; } + .pt-lg-3 { + padding-top: 24px !important; } + .pr-lg-3 { + padding-right: 24px !important; } + .pb-lg-3 { + padding-bottom: 24px !important; } + .pl-lg-3 { + padding-left: 24px !important; } + .px-lg-3 { + padding-right: 24px !important; + padding-left: 24px !important; } + .py-lg-3 { + padding-top: 24px !important; + padding-bottom: 24px !important; } + .p-lg-4 { + padding: 36px !important; } + .pt-lg-4 { + padding-top: 36px !important; } + .pr-lg-4 { + padding-right: 36px !important; } + .pb-lg-4 { + padding-bottom: 36px !important; } + .pl-lg-4 { + padding-left: 36px !important; } + .px-lg-4 { + padding-right: 36px !important; + padding-left: 36px !important; } + .py-lg-4 { + padding-top: 36px !important; + padding-bottom: 36px !important; } + .p-lg-5 { + padding: 72px !important; } + .pt-lg-5 { + padding-top: 72px !important; } + .pr-lg-5 { + padding-right: 72px !important; } + .pb-lg-5 { + padding-bottom: 72px !important; } + .pl-lg-5 { + padding-left: 72px !important; } + .px-lg-5 { + padding-right: 72px !important; + padding-left: 72px !important; } + .py-lg-5 { + padding-top: 72px !important; + padding-bottom: 72px !important; } + .m-lg-auto { + margin: auto !important; } + .mt-lg-auto { + margin-top: auto !important; } + .mr-lg-auto { + margin-right: auto !important; } + .mb-lg-auto { + margin-bottom: auto !important; } + .ml-lg-auto { + margin-left: auto !important; } + .mx-lg-auto { + margin-right: auto !important; + margin-left: auto !important; } + .my-lg-auto { + margin-top: auto !important; + margin-bottom: auto !important; } } + +.table { + width: 100%; + border: 2px solid #ddd; + margin-bottom: 0; } + .table th { + padding: 8px; + border-right: 1px dotted #ddd; + border-bottom: 2px solid #ddd; + color: #FF7B7B; + font-weight: 700; + font-size: 16px; } + .table td { + line-height: inherit !important; + border-right: 1px dotted #ddd; + border-top: 1px solid #ddd; + font-size: 14px; } + +@media (max-width: 768px) { + .table-word-break td code { + word-break: break-word; + overflow-wrap: break-word; + -webkit-box-decoration-break: clone; + box-decoration-break: clone; } } + +.table-wrapper { + overflow-x: auto; + max-width: 100%; + width: 100%; + margin-bottom: 20px; } + +/* + * Sub-navigation (vertical) (aka "toc" or "Table of Contents") + * + * TODO: Rename this class and file name to something that's more generic + * + * Scrollspy and affixed enhanced navigation to highlight sections and secondary + * sections of docs content. + */ +/* First level of nav */ +.toc { + font-size: 14px; + font-weight: 400; + line-height: 1.4; + background-color: #f8f8f8; + margin-bottom: 30px; + max-height: calc(100% - 120px); + overflow-x: hidden; + overflow-y: auto; } + .toc::-webkit-scrollbar { + height: 6px; + width: 6px; } + .toc::-webkit-scrollbar-thumb { + background-color: rgba(99, 83, 120, 0.75); } + .toc.affix { + position: static; } + .toc.affix-bottom { + max-height: none; } + .toc a { + display: block; + padding: 6px 15px; + z-index: 1; + color: #635378; + font-weight: 400; + text-decoration: none; + -webkit-transition: box-shadow 100ms ease-in-out; + -moz-transition: box-shadow 100ms ease-in-out; + transition: box-shadow 100ms ease-in-out; } + .toc li.toc-top-level { + font-weight: 700; } + .toc li.toc-top-level > a { + font-weight: 700; } + .toc li.toc-top-level.toc-current > a { + background-color: #635378; + color: white; } + +@media (max-width: 768px) { + .toc a, + .nav > li > a { + min-height: 44px; + padding: 15px; } } + +@media (min-width: 992px) { + .toc .nav > .active > ul { + display: block; } + .toc.affix, + .toc.affix-bottom { + width: 210px; } + .toc.affix { + position: fixed; + top: 75px; } + .toc.affix-bottom { + position: absolute; } } + +/* +ul.nav > li:first-child:last-child { + display: none; +} +*/ +.toc-subnav { + list-style-type: none; + padding: 0; + max-height: 0; + overflow: hidden; + -webkit-transition: max-height 200ms ease-in-out; + -moz-transition: max-height 200ms ease-in-out; + transition: max-height 200ms ease-in-out; } + .toc-subnav.toc-expand { + max-height: 10000px; } + .toc-subnav a:hover, + .toc-subnav a:focus { + background-color: #eee; + color: #ef4c4b; } + .toc-subnav li.toc-current.active > a, + .toc-subnav li.toc-current:not(.active) li.active > a { + box-shadow: none; + background-color: transparent; + color: inherit; } + .toc-subnav li.toc-current:not(.active) > a, + .toc-subnav li.active > a { + background-color: #eee; + box-shadow: inset 4px 0 0 #635378; } + .toc-subnav .toc-subnav > li > a { + padding-left: 30px; } + +body { + font-family: "Open Sans", Helvetica, Arial, sans-serif; + font-weight: 400; + color: #2C1E3F; + font-size: 16px; + line-height: 1.5; } + +p { + margin-bottom: 1em; } + +h1, h2, h3 { + margin-top: 48px; + margin-bottom: 12px; } + @media (max-width: 768px) { + h1, h2, h3 { + margin-top: 24px; + margin-bottom: 6px; } } + +h1 { + font-size: 48px; } + @media (max-width: 768px) { + h1 { + font-size: 42px; } } + +h2 { + font-size: 36px; } + @media (max-width: 768px) { + h2 { + font-size: 30px; } } + +h3 { + font-size: 24px; } + @media (max-width: 768px) { + h3 { + font-size: 20px; } } + +h4, h5, h6 { + margin-top: 24px; + margin-bottom: 12px; } + @media (max-width: 768px) { + h4, h5, h6 { + margin-bottom: 6px; } } + +h4 { + font-size: 20px; } + @media (max-width: 768px) { + h4 { + font-size: 18px; } } + +h5, h6 { + font-size: 16px; } + +a { + color: #FF7B7B; + font-weight: 700; } + a:hover, a:focus { + color: #FF4947; } + +h1, h2, h3, h4, h5, h6 { + line-height: 1.2; } + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + font-weight: inherit; } + +.caption { + font-size: 16px; + font-weight: 300; + font-style: italic; + color: #1E0E33; } + +code { + padding: 4px 8px; + margin: 0 2px; + font-size: 14px; + line-height: 1.6em; + color: #1E0E33; + background-color: #f8f8f8; } + +pre { + margin: 20px auto; + padding: 20px; + border: 1px solid #f8f8f8; + border-radius: 0; + word-break: break-word; + white-space: pre-wrap; } + pre code { + display: block; + margin: -20px; + padding: 20px; + width: auto; + height: 100%; + white-space: pre; + word-wrap: normal; + word-break: normal; + overflow-x: auto; + overflow-y: hidden; + background-color: #f8f8f8; + background-size: 8px 8px; + background-image: linear-gradient(135deg, transparent 25%, rgba(0, 0, 0, 0.04) 25%, rgba(0, 0, 0, 0.04) 50%, transparent 50%, transparent 75%, rgba(0, 0, 0, 0.04) 75%, rgba(0, 0, 0, 0.04)); } + +quote { + font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; + font-size: 24px; + color: #1E0E33; } + @media (max-width: 768px) { + quote { + font-size: 18px; } } + +pullquote { + width: 100%; + margin-top: 1.5em; + margin-bottom: 1.5em; + display: block; + font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; + font-size: 24px; + font-style: italic; + text-align: center; + color: #1E0E33; } + @media (max-width: 768px) { + pullquote { + font-size: 18px; } } + +/* about page styles */ +.team .name { + font-size: 15px; } + +/* This style overrides rangeslider's style + we are using rangeslider to polyfill input[type="range"]*/ +.rangeslider, +.rangeslider__fill { + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; } + +.rangeslider { + background: #EEE7F8; } + +.rangeslider--horizontal { + height: 5px; } + +.rangeslider__fill { + background: #985FDD; } + +.rangeslider__handle { + background: #1E0E33; + border: none; + width: 15px; + height: 15px; + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; } + +.rangeslider__handle:after { + display: none; } + +.rangeslider--horizontal .rangeslider__handle { + top: -5px; } + +input[type="range"]:focus + .rangeslider .rangeslider__handle { + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; } + +/* Temp style for video */ +.index-main-hero { + height: auto; + overflow: hidden; + position: relative; + padding-bottom: 72px; + background-repeat: no-repeat; + background-position: center center; + background-size: cover; + background-image: url("/common/styleguide/images/background/contour_purple_xs.png"); + /* gradation on mobile */ } + @media (min-width: 768px) { + .index-main-hero { + min-height: 550px; + height: calc(100vh - 56px); + padding-bottom: 0; + background-image: none; + background-color: #1E0E33; } } + .index-main-hero:after { + content: ' '; + position: absolute; + left: 0; + bottom: 0; + width: 100%; + height: 64px; + background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.3), white); + pointer-events: none; } + @media (min-width: 768px) { + .index-main-hero:after { + content: none; } } + +.index-main-hero .hero-background-wrapper { + width: 100%; + height: calc(100% + 80px); + z-index: 0; + overflow: hidden; + position: absolute; + top: 0; + right: -40px; + /* to hide control*/ + pointer-events: none; } + .index-main-hero .hero-background-wrapper.video { + display: none; } + @media (min-width: 768px) { + .index-main-hero .hero-background-wrapper.video { + display: block; } } + .index-main-hero .hero-background-wrapper.mobile-image { + display: block; } + @media (min-width: 768px) { + .index-main-hero .hero-background-wrapper.mobile-image { + display: none; } } + +@keyframes fadein { + from { + opacity: 0.5; } + to { + opacity: 1; } } + +/* preview image before video cues up */ +.index-main-hero .preview-image { + display: none; } + @media (min-width: 768px) { + .index-main-hero .preview-image { + width: calc(100% + 40px); + height: calc(100% + 80px); + z-index: 0; + display: block; + overflow: hidden; + position: absolute; + top: 0; + right: -40px; + /* to hide control*/ + pointer-events: none; + transform: scale(1.004, 1); + background-image: url("/common/styleguide/images/main-preview.jpg"); + background-size: 100% 100%; + animation-name: fadein; + animation-duration: 1s; + animation-iteration-count: 1; } } + +@media (min-width: 768px) { + .index-hero-float-box { + position: absolute; + top: 150px; + width: 100%; + z-index: 1; + top: 50px; } } + +.index-hero-copy-wrapper { + width: auto; + display: inline-block; + padding-left: 36px; + padding-right: 36px; + max-width: 670px; } + @media (min-width: 768px) { + .index-hero-copy-wrapper { + background-color: rgba(255, 255, 255, 0.7); } } + @media (min-width: 1200px) { + .index-hero-copy-wrapper { + margin-left: -48px; } } + +.index-hero-copy-wrapper h1 { + margin-bottom: 18px; + font-size: 36px; + color: #fff; } + @media (min-width: 768px) { + .index-hero-copy-wrapper h1 { + font-size: 48px; + color: #1E0E33; } } + +.index-hero-copy-wrapper .btn-with-arrow { + margin-bottom: 24px; } + +.overflowing, .overflowing-left, .overflowing-right { + margin-left: -150px; + margin-right: -100px; + max-width: calc(100% + 250px); + position: relative; } + @media (min-width: 768px) { + .overflowing, .overflowing-left, .overflowing-right { + height: 100%; } } + +@media (max-width: 1492px) and (min-width: 768px) { + .overflowing-left.gradation:after { + content: ' '; + max-width: 100%; + width: 250px; + height: 100%; + position: absolute; + left: 0; + top: 0; + pointer-events: none; + background-image: linear-gradient(to left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 100%); + overflow: hidden; } } + +@media (min-width: 768px) { + .overflowing-left { + margin-right: 0; + margin-left: -250px; } } + +.overflowing-right { + margin: 0 0; } + @media (max-width: 1492px) and (min-width: 768px) { + .overflowing-right.gradation:after { + content: ' '; + max-width: 100%; + width: 250px; + height: 100%; + position: absolute; + right: 0; + top: 0; + pointer-events: none; + background-image: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 100%); + overflow: hidden; } } + @media (min-width: 768px) { + .overflowing-right { + margin-left: 0; + margin-right: -250px; } } + +.editor-wrapper { + width: 100%; + height: 406px; + border-radius: 5px; + overflow: hidden; } + .editor-wrapper::before { + content: ''; + width: 100%; + height: 100%; + border-radius: 5px; + background: -webkit-linear-gradient(rgba(30, 14, 51, 0) 25%, #1E0E33 97%); + background: linear-gradient(rgba(30, 14, 51, 0) 25%, #1E0E33 97%); + position: absolute; + pointer-events: none; } + +@media (min-width: 768px) { + .editor-snippet { + width: 100%; + height: 100%; + border: 0; + color: #fff; + background-color: #1e0f33; + overflow-x: hidden; + overflow-y: scroll; + margin: 0; + padding: 1.5em; + padding-right: 3em; } } + +.editor-snippet .cp, .editor-snippet .nt { + color: #ff112f; } + +.editor-snippet .na { + color: #F7BEB4; } + +.editor-snippet .s { + color: #985FDD; } + +.full-section { + padding-top: 48px; + padding-bottom: 48px; + text-align: center; + overflow: hidden; } + @media (min-width: 768px) { + .full-section { + padding-top: 72px; + padding-bottom: 72px; + position: relative; + text-align: left; } } + +/* For sections with contour image background */ +/* This section doesn't have default background-image */ +/* background-image can be added through additional image below */ +.with-background { + background-color: #FF7B7B; + background-repeat: no-repeat; + background-position: center center; + background-size: cover; } + @media (min-width: 768px) { + .with-background { + background-attachment: fixed; } } + +.full-section h1, .full-section h2, .full-section h3 { + margin-top: 0; } + +.with-background h1, .with-background h2, .with-background h3, .with-background h4, .with-background h5, .with-background h6, .with-background p { + color: #ffffff; } + +.purple-contour { + background-color: #985FDD; + background-image: url("/common/styleguide/images/background/contour_purple_xs.png"); } + @media (min-width: 480px) { + .purple-contour { + background-image: url("/common/styleguide/images/background/contour_purple_sm.png"); } } + @media (min-width: 768px) { + .purple-contour { + background-image: url("/common/styleguide/images/background/contour_purple_lg.png"); } } + +.with-background.scarlet-contour { + /* Improve readability adding slight contrast to the text */ } + .with-background.scarlet-contour h1, .with-background.scarlet-contour h2, .with-background.scarlet-contour h3, .with-background.scarlet-contour h4, .with-background.scarlet-contour h5, .with-background.scarlet-contour h6, .with-background.scarlet-contour p { + text-shadow: 1px 1px 2px #985FDD; } + +.scarlet-contour { + background-color: #FF7B7B; + background-image: url("/common/styleguide/images/background/contour_scarlet_xs.png"); } + @media (min-width: 480px) { + .scarlet-contour { + background-image: url("/common/styleguide/images/background/contour_scarlet_sm.png"); } } + @media (min-width: 768px) { + .scarlet-contour { + background-image: url("/common/styleguide/images/background/contour_scarlet_lg.png"); } } + +body.pricing-page footer { + margin-top: -24px; } + @media (min-width: 768px) { + body.pricing-page footer { + margin-top: -48px; } } + +.pricing-page-product { + border-bottom: 1px solid #ddd; + padding-top: 48px; + padding-bottom: 72px; } + .pricing-page-product:last-of-type { + border-bottom: 0; } + .pricing-page-product h4 { + color: #BDA2DD; + text-transform: uppercase; + margin-bottom: 0.25em; + font-weight: 400; } + .pricing-page-product h2 { + margin-top: 0; + margin-bottom: 36px; } + .pricing-page-product .list-checkmarks { + margin-top: 36px; } + +.billing-info-wrapper { + border: 1px solid #BDA2DD; + line-height: 1.2; } + .billing-info-wrapper .base-pricing-info { + padding: 12px; } + .billing-info-wrapper .additional-pricing-info { + background-color: #985FDD; + color: #fff; + padding: 12px; } + .billing-info-wrapper .price-text { + font-size: 48px; + font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; + font-weight: 700; } + .billing-info-wrapper .base-price.price-text { + color: #985FDD; } + +.billing-estimator-wrapper { + border: 1px solid #BDA2DD; } + .billing-estimator-wrapper input[type="range"] { + margin-top: 5px; } + .billing-estimator-wrapper h4 { + color: #1E0E33; + font-weight: 700; } + .billing-estimator-wrapper .request-based-text { + font-family: "Poppins", "Open Sans", Helvetica, Arial, sans-serif; + font-weight: 700; + color: #1E0E33; } + .billing-estimator-wrapper .estimated-price-box { + padding: 6px; + /* On "top" */ + background-color: #efefef; + background-image: repeating-linear-gradient(135deg, white, white 3px, #efefef 6px, #efefef 6px); } + .billing-estimator-wrapper + .scale-message-box { + height: 24px; } + +/* This hero index is outdated, not included in our index page design any more */ +/* This style will be removed from the repo after making sure this is not going to be used in future. */ +.hero-section-wrapper { + position: relative; } + +.hero-section-wrapper:after { + content: ' '; + position: absolute; + left: 0; + bottom: 0; + width: 100%; + height: 64px; + background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.3), white); + pointer-events: none; } + @media (min-width: 768px) { + .hero-section-wrapper:after { + height: 100px; } } + +.hero-section-wrapper > .hero-section { + overflow: hidden; + padding-top: 72px; + margin-bottom: 48px; } + @media (min-width: 768px) { + .hero-section-wrapper > .hero-section { + padding-top: 144px; + margin-bottom: 72px; } } + +.hero-section-wrapper > .hero-section img, video { + width: 100%; + height: auto; } + +.hero-section-wrapper h1, .hero-section-wrapper h2, .hero-section-wrapper h3 { + margin-top: 0; } + +.hero-section-wrapper.hero-section-secondary:after { + display: none; + /* Hides gradient */ } + +.hero-section-secondary .hero-section { + padding-bottom: 48px; } + +@media (min-width: 768px) { + .hero-section-secondary .hero-section { + padding-bottom: 72px; } } diff --git a/www/css/whosonfirst.api.css b/www/css/whosonfirst.api.css new file mode 100644 index 0000000..0a3e343 --- /dev/null +++ b/www/css/whosonfirst.api.css @@ -0,0 +1,60 @@ +#map { + width: 100%; + height: 400px; + border: 5px solid #000; + margin-bottom: 1em; +} + +.map-marker { + border: 2px solid #000; + width: 12px; + height: 12px; + margin-left: -6px; + margin-top: -6px; + background: #0BBDFF; + border-radius: 12px; +} + +.current-page { + font-weight: normal; + margin-left: 0.5em; +} + +#nearby-find { + margin-top: 56px; +} + +#go-form { + border: 1px solid rgba(0,0,0,.1); + border-radius: 0.3em; + margin: 1em 0 1.5em 0; + padding: 1em; +} + +#go-form .btn { + line-height: 16px; + margin-top: -5px; + margin-left: 5px; +} + +body.places #content ul li { + list-style: none; +} + +#venue-info h4 { + margin: 0; +} + +.venue-neighbourhood { + margin-top: -12px; + margin-bottom: 12px; +} + +@media (max-width: 768px) { + + #map { + margin-top: 1.5em; + height: 200px; + } + +} diff --git a/www/id.php b/www/id.php index acd7696..7446a0a 100644 --- a/www/id.php +++ b/www/id.php @@ -2,6 +2,7 @@ include("include/init.php"); loadlib("whosonfirst_places"); + loadlib("whosonfirst_placetypes"); if (! get_isset("id")){ header("location: {$GLOBALS['cfg']['abs_root_url']}"); @@ -16,15 +17,86 @@ error_404(); } + if (get_isset("nearby")){ + $url = whosonfirst_places_nearby_url_for_place($place); + header("location: {$url}"); + exit(); + } + $parent_id = $place["wof:parent_id"]; - if ($parent_id != -1){ + if ($parent_id > -1){ $parent = whosonfirst_places_get_by_id($parent_id); $place["wof:parent"] = $parent; } + else { + + $pt = $place["wof:placetype"]; + $hiers = $place["wof:hierarchy"]; + + $parent_ids = array(); + $parent_key = null; + + foreach (whosonfirst_placetypes_parents($pt) as $ppt){ + + $k = "{$ppt}_id"; + + if (isset($hiers[0][$k])){ + $parent_key = $k; + break; + } + } + + foreach ($hiers as $hier){ + $parent_ids[] = $hier[$parent_key]; + } + + $rsp = whosonfirst_places_get_by_id_multi($parent_ids); + + if ($rsp['ok']){ + $place["wof:parents"] = $rsp["rows"]; + } + } + + if ($place['wof:concordances'] && + $place['wof:concordances']['wk:page']){ + $GLOBALS['smarty']->assign('wikipedia_page', $place['wof:concordances']['wk:page']); + } + + $search_url = whosonfirst_places_search_referer_url($query, $filters, $args); + $GLOBALS['smarty']->assign("search_url", $search_url); + $GLOBALS['smarty']->assign_by_ref("place", $place); - $GLOBALS['smarty']->display("page_id.txt", $place); + $GLOBALS['smarty']->assign_by_ref("mz_hours", $place['mz:hours']); + + $links = array(); + $link_properties = array( + 'addr:website' => 'Website', + 'addr:twitter' => 'Twitter', + 'addr:facebook' => 'Facebook', + 'addr:instagram' => 'Instagram', + 'addr:youtube' => 'YouTube', + 'addr:github' => 'GitHub' + ); + foreach ($link_properties as $prop => $text){ + if ($place[$prop]){ + $url = $place[$prop]; + $links[$url] = $text; + } + } + if (isset($place['wof:concordances']['4sq:id'])) { + $id = $place['wof:concordances']['4sq:id']; + $url = "https://foursquare.com/v/$id"; + $links[$url] = 'FourSquare'; + } + $GLOBALS['smarty']->assign_by_ref("links", $links); + + if (get_bool('old')){ + $GLOBALS['smarty']->display("page_id_old.txt"); + } else { + $GLOBALS['smarty']->display("page_id.txt"); + } exit(); -?> \ No newline at end of file +?> diff --git a/www/images/favicons/apple-touch-icon.png b/www/images/favicons/apple-touch-icon.png new file mode 100644 index 0000000..2bd9743 Binary files /dev/null and b/www/images/favicons/apple-touch-icon.png differ diff --git a/www/images/favicons/favicon-16x16.png b/www/images/favicons/favicon-16x16.png new file mode 100644 index 0000000..8ad3586 Binary files /dev/null and b/www/images/favicons/favicon-16x16.png differ diff --git a/www/images/favicons/favicon-32x32.png b/www/images/favicons/favicon-32x32.png new file mode 100644 index 0000000..f683d35 Binary files /dev/null and b/www/images/favicons/favicon-32x32.png differ diff --git a/www/images/favicons/manifest.json b/www/images/favicons/manifest.json new file mode 100644 index 0000000..f784358 --- /dev/null +++ b/www/images/favicons/manifest.json @@ -0,0 +1,18 @@ +{ + "name": "", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-384x384.png", + "sizes": "384x384", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} \ No newline at end of file diff --git a/www/images/favicons/safari-pinned-tab.svg b/www/images/favicons/safari-pinned-tab.svg new file mode 100644 index 0000000..6ba6f4c --- /dev/null +++ b/www/images/favicons/safari-pinned-tab.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/www/images/pin.png b/www/images/pin.png new file mode 100644 index 0000000..24a696c Binary files /dev/null and b/www/images/pin.png differ diff --git a/www/include/config.php b/www/include/config.php index 7ed48d9..ba48513 100644 --- a/www/include/config.php +++ b/www/include/config.php @@ -4,11 +4,16 @@ # Things you may want to change in a hurry $GLOBALS['cfg']['site_name'] = 'Who\'s On First API'; - $GLOBALS['cfg']['environment'] = 'dev'; + $GLOBALS['cfg']['environment'] = 'prod'; $GLOBALS['cfg']['site_disabled'] = 0; $GLOBALS['cfg']['site_disabled_retry_after'] = 0; # seconds; if set will return HTTP Retry-After header + # See also init.php customizations for Mapzen Places + $GLOBALS['cfg']['enable_feature_places'] = 0; + + $GLOBALS['cfg']['enable_feature_routing'] = 0; + # Message is displayed in the nav header in inc_head.txt $GLOBALS['cfg']['display_message'] = 0; @@ -50,11 +55,11 @@ # hard coding this URL will ensure it works in cron mode too $GLOBALS['cfg']['server_scheme'] = 'https'; # (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on')) ? 'https' : 'http'; - $GLOBALS['cfg']['server_name'] = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'whosonfirst.mapzen.com'; + $GLOBALS['cfg']['server_name'] = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'whosonfirst.mapzen.com'; $GLOBALS['cfg']['server_force_https'] = 1; # for example, when you're running a Flamework app on port 80 behind a proxy on port 443; it happens... $GLOBALS['cfg']['server_ignore_port'] = 1; - $GLOBALS['cfg']['abs_root_url'] = ''; # "{$GLOBALS['cfg']['server_scheme']}://{$GLOBALS['cfg']['server_name']}/"; + $GLOBALS['cfg']['abs_root_url'] = ''; # "{$GLOBALS['cfg']['server_scheme']}://{$GLOBALS['cfg']['server_name']}/"; $GLOBALS['cfg']['safe_abs_root_url'] = $GLOBALS['cfg']['abs_root_url']; # See notes in include/init.php @@ -89,7 +94,7 @@ $GLOBALS['cfg']['enable_feature_cache_prefixes'] = 1; $GLOBALS['cfg']['cache_prefix'] = $GLOBALS['cfg']['environment']; - # Note: memcache stuff is not enabled by default but is + # Note: memcache stuff is not enabled by default but is # available in the 'extras' directory $GLOBALS['cfg']['auth_cookie_domain'] = parse_url($GLOBALS['cfg']['abs_root_url'], 1); @@ -162,7 +167,7 @@ # This will assign $pagination automatically for Smarty but # you probably don't want to do this for anything resembling # a complex application... - + $GLOBALS['cfg']['pagination_assign_smarty_variable'] = 0; $GLOBALS['cfg']['pagination_per_page'] = 10; @@ -197,7 +202,7 @@ # THINGS YOU SHOULD DEFINE IN YOUR secrets.php FILE WHICH IS NOT # MEANT TO BE CHECKED IN EVER. DON'T DO IT. AND DON'T DEFINE THESE - # THINGS HERE. REALLY. + # THINGS HERE. REALLY. $GLOBALS['cfg']['crypto_use_module'] = 'mcrypt'; @@ -222,18 +227,17 @@ $GLOBALS['cfg']['enable_feature_api_logging'] = 1; $GLOBALS['cfg']['enable_feature_api_throttling'] = 0; - $GLOBALS['cfg']['enable_feature_api_method_aliases'] = 0; - - # WET PAINT - don't be surprised if it all changes... - # (20170829/thisisaaronland) - - $GLOBALS['cfg']['enable_feature_api_require_keys'] = 0; # because oauth2... $GLOBALS['cfg']['enable_feature_api_register_keys'] = 1; $GLOBALS['cfg']['enable_feature_api_delegated_auth'] = 1; $GLOBALS['cfg']['enable_feature_api_authenticate_self'] = 1; + # PLEASE DISCUSS OVERRIDES AND ALIASES HERE... + + $GLOBALS['cfg']['enable_feature_api_method_overrides'] = 0; + $GLOBALS['cfg']['enable_feature_api_method_aliases'] = 0; + # API URLs and endpoints $GLOBALS['cfg']['api_abs_root_url'] = ''; # leave blank - set in api_config_init() @@ -304,7 +308,7 @@ 'formats' => array( 'chicken' => array('enabled' => 1, 'documented' => 1, 'alt' => array('🐔')), # no, really... 'csv' => array('enabled' => 1, 'documented' => 1), - 'geojson' => array('enabled' => 1, 'documented' => 1), + 'geojson' => array('enabled' => 1, 'documented' => 1), 'json' => array('enabled' => 1, 'documented' => 1), 'meta' => array('enabled' => 1, 'documented' => 1), ), @@ -321,7 +325,7 @@ # this is toggled on/off above with following config: # $GLOBALS['cfg']['enable_feature_api_method_aliases'] # - # and get slotted in to the general config with the + # and get slotted in to the general config with the # api_config_init_aliases() function which is in turn # invoked by the general api_config_init() function @@ -393,8 +397,8 @@ # START OF flamework-mapzen-sso stuff $GLOBALS['cfg']['mapzen_oauth_key'] = 'READ-FROM-SECRETS'; - $GLOBALS['cfg']['mapzen_oauth_secret'] = 'READ-FROM-SECRETS'; - $GLOBALS['cfg']['mapzen_oauth_callback'] = 'auth/'; + $GLOBALS['cfg']['mapzen_oauth_secret'] = 'READ-FROM-SECRETS'; + $GLOBALS['cfg']['mapzen_oauth_callback'] = 'auth/'; $GLOBALS['cfg']['crypto_oauth_cookie_secret'] = 'READ-FROM-SECRETS'; # (see notes in www/sign_oauth.php) $GLOBALS['cfg']['mapzen_api_perms'] = 'read'; @@ -414,6 +418,18 @@ # END OF elasticsearch-spelunker stuff + # START OF elasticsearch-brands stuff + + $GLOBALS['cfg']['elasticsearch_brands_host'] = 'http://localhost'; + $GLOBALS['cfg']['elasticsearch_brands_port'] = '9200'; + $GLOBALS['cfg']['elasticsearch_brands_index'] = 'brands'; + + $GLOBALS['cfg']['elasticsearch_brands_scroll'] = 1; + $GLOBALS['cfg']['elasticsearch_brands_scroll_ttl'] = '2m'; + $GLOBALS['cfg']['elasticsearch_brands_scroll_trigger'] = 10000; + + # END OF elasticsearch-brands stuff + # START of wof spatial stuff $GLOBALS['cfg']['enable_feature_spatial'] = 1; @@ -426,15 +442,25 @@ $GLOBALS['cfg']['spatial_nearby_default_radius'] = 100; $GLOBALS['cfg']['spatial_nearby_max_radius'] = 80467; # 50 miles because I miss Dopplr (20170707/thisisaaronland) + $GLOBALS['cfg']['spatial_tile38_endpoints'] = array( + 'localhost:9851' + ); + + $GLOBALS['cfg']['spatial_tile38_collection'] = 'whosonfirst'; + + # THESE TWO VARIABLES ARE DEPRECATED - PLEASE USE 'spatial_tile38_endpoints' + $GLOBALS['cfg']['spatial_tile38_host'] = 'localhost'; $GLOBALS['cfg']['spatial_tile38_port'] = '9851'; - $GLOBALS['cfg']['spatial_tile38_collection'] = 'whosonfirst'; + # END of wof spatial stuff # START OF pip stuff + # this assumes https://github.com/whosonfirst/go-whosonfirst-pip-v2 $GLOBALS['cfg']['enable_feature_pip'] = 1; + $GLOBALS['cfg']['enable_feature_pip_polyline'] = 0; $GLOBALS['cfg']["whosonfirst_pip_endpoint"] = ''; # END OF pip stuff @@ -457,4 +483,23 @@ $GLOBALS['cfg']['github_oauth_key'] = 'READ-FROM-SECRETS'; $GLOBALS['cfg']['github_oauth_secret'] = 'READ-FROM-SECRETS'; $GLOBALS['cfg']['github_api_scope'] = 'repo, user'; - $GLOBALS['cfg']['github_oauth_callback'] = 'auth/'; \ No newline at end of file + $GLOBALS['cfg']['github_oauth_callback'] = 'auth/'; + + # START OF flamework-redis stuff (used by the chatterbox stuff, below) + + $GLOBALS['cfg']['redis_scheme'] = 'tcp'; + $GLOBALS['cfg']['redis_host'] = 'localhost'; + $GLOBALS['cfg']['redis_port'] = 6379; + + # END OF flamework-redis stuff + + # START OF chatterbox stuff / https://github.com/whosonfirst/go-whosonfirst-chatterbox + + $GLOBALS['cfg']['enable_feature_chatterbox'] = 0; + + $GLOBALS['cfg']['chatterbox_host'] = '127.0.0.1'; + $GLOBALS['cfg']['chatterbox_port'] = '6379'; + $GLOBALS['cfg']['chatterbox_channel'] = 'chatterbox'; + $GLOBALS['cfg']['chatterbox_destination'] = ''; + + # END OF chatterbox stuff diff --git a/www/include/config_api_methods_whosonfirst.php b/www/include/config_api_methods_whosonfirst.php index 6ef0840..c827515 100644 --- a/www/include/config_api_methods_whosonfirst.php +++ b/www/include/config_api_methods_whosonfirst.php @@ -1,6 +1,113 @@ array( + array( + "name" => "min_lastmod", + "description" => "Limit results to places that have been modified on or since this date (encoded as a Unix timestamp).", + "documented" => 1, + "required" => 0, + "example" => 1493855252 + ), + array( + "name" => "max_lastmod", + "description" => "Limit results to places that have been modified on or before this date (encoded as a Unix timestamp).", + "documented" => 1, + "required" => 0, + "example" => 1496783757 + ), + ), + + 'filter_parameters_concordances' => array( + array( + "name" => "concordance", + "description" => "Query for places that have been concordified with this source.", + "documented" => 1, + "required" => 0, + "example" => "loc:id" + ), + ), + + 'filter_parameters_existential' => array( + array( + "name" => "is_current", + "description" => "Filter results by their 'mz:is_current' property. Valid options are: -1, 1, 0", + "documented" => 1, + "required" => 0, + "example" => "1" + ), + array( + "name" => "is_ceased", + "description" => "Filter results to include only those places that have a valid EDTF cessation date or not. Valid options are: 1, 0", + "documented" => 1, + "required" => 0, + "example" => "1" + ), + array( + "name" => "is_deprecated", + "description" => "Filter results to include only those places that have a valid EDTF deprecated date or not. Valid options are: 1, 0", + "documented" => 1, + "required" => 0, + "example" => "1" + ), + array( + "name" => "is_superseded", + "description" => "Filter results to include only those places that have (or have not) been superseded. Valid options are: 1, 0", + "documented" => 1, + "required" => 0, + "example" => "1" + ), + array( + "name" => "is_superseding", + "description" => "Filter results to include only those places that have (or have not) superseded other places. Valid options are: 1, 0", + "documented" => 1, + "required" => 0, + "example" => "1" + ), + ), + + 'filter_parameters_hierarchy' => array( + array( + "name" => "iso", + "description" => "Ensure places belong to this (ISO) country code.", + "documented" => 1, + "required" => 0, + "example" => "CA" + ), + array( + "name" => "country_id", + "description" => "Ensure places belong to this country Who's On First ID.", + "documented" => 1, + "required" => 0, + "example" => "85633147" + ), + array( + "name" => "region_id", + "description" => "Ensure places belong to this region Who's On First ID.", + "documented" => 1, + "required" => 0, + "example" => "85669831" + ), + array( + "name" => "locality_id", + "description" => "Ensure places belong to this locality Who's On First ID.", + "documented" => 1, + "required" => 0, + "example" => "101736545" + ), + array( + "name" => "neighbourhood_id", + "description" => "Ensure places belong to this neighbourhood Who's On First ID.", + "documented" => 1, + "required" => 0, + "example" => "102112179" + ), + ), + + # this is the set of parameters we use for search-type things - it used to be the only one and then there + # were all these others... (20171127/thisisaaronland) + 'filter_parameters' => array( array( "name" => "name", @@ -117,7 +224,7 @@ ), array( "name" => "is_current", - "description" => "Filter results by their 'mz:is_current' property.", + "description" => "Filter results by their 'mz:is_current' property. Valid options are: -1, 1, 0", "documented" => 1, "required" => 0, "example" => "1" @@ -187,46 +294,70 @@ ), ), - 'filter_parameters_tile38' => array( + 'filter_parameters_brands_sizes' => array( + array( + "name" => "brand_size", + "description" => "A valid brand size to scope queries by. You may prefix the brand size with <, <=, > or >= to define simple range queries.", + "documented" => 1, + "required" => 0, + "example" => "XXS" + ), + array( + "name" => "min_brand_size", + "description" => "A mininum (inclusive) brand size to scope queries to.", + "documented" => 1, + "required" => 0, + "example" => "M" + ), + array( + "name" => "max_brand_size", + "description" => "A maximum (inclusive) brand size to scope queries to.", + "documented" => 1, + "required" => 0, + "example" => "XL" + ), + ), + + 'filter_parameters_spatial' => array( array( "name" => "placetype", "description" => "A valid Who's On First placetype to limit the query by.", "documented" => 1, "required" => 0, - "example" => "venue" + "example" => "neighbourhood" ), array( "name" => "is_current", - "description" => "Filter results by their 'mz:is_current' property.", - "documented" => 0, + "description" => "Filter results by their 'mz:is_current' property. Valid options are: -1, 1, 0", + "documented" => 1, "required" => 0, "example" => "1" ), array( "name" => "is_ceased", "description" => "Filter results to include only those places that have a valid EDTF cessation date or not. Valid options are: 1, 0", - "documented" => 0, + "documented" => 1, "required" => 0, "example" => "1" ), array( "name" => "is_deprecated", "description" => "Filter results to include only those places that have a valid EDTF deprecated date or not. Valid options are: 1, 0", - "documented" => 0, + "documented" => 1, "required" => 0, "example" => "1" ), array( "name" => "is_superseded", "description" => "Filter results to include only those places that have (or have not) been superseded. Valid options are: 1, 0", - "documented" => 0, + "documented" => 1, "required" => 0, "example" => "1" ), array( "name" => "is_superseding", "description" => "Filter results to include only those places that have (or have not) superseded other places. Valid options are: 1, 0", - "documented" => 0, + "documented" => 1, "required" => 0, "example" => "1" ), @@ -237,6 +368,134 @@ $GLOBALS['cfg']['api']['methods'] = array_merge(array( + 'whosonfirst.brands.getInfo' => array( + "description" => "Return information about a specific brand", + "documented" => 1, + "enabled" => 1, + "experimental" => 1, + "paginated" => 0, + "library" => "api_whosonfirst_brands", + "parameters" => array( + array( + "name" => "id", + "documented" => 1, + "required" => 1, + "example" => 1125148929 + ) + ), + "errors" => array( + "434" => array("message" => "Missing brand ID"), + "435" => array("message" => "Invalid brand ID"), + ), + "disallow_formats" => array( "geojson", "meta" ), + ), + + 'whosonfirst.brands.getList' => array( + "description" => "Return a list of all the known brands", + "documented" => 1, + "enabled" => 1, + "experimental" => 1, + "paginated" => 1, + "library" => "api_whosonfirst_brands", + "parameters" => array_merge(array( + # nothing else yet... + ), $GLOBALS['api_methods_whosonfirst']['filter_parameters_brands_sizes']), + "errors" => array( + "432" => array("message" => "Invalid brand size"), + "433" => array("message" => "Invalid brand size range"), + "513" => array("message" => "Unable to retrieve brands"), + ), + "disallow_formats" => array( "geojson", "meta" ), + ), + + 'whosonfirst.brands.search' => array( + "description" => "Search for brands by name", + "documented" => 1, + "enabled" => 1, + "experimental" => 1, + "paginated" => 1, + "library" => "api_whosonfirst_brands", + "parameters" => array_merge(array( + array( + "name" => "q", + "documented" => 1, + "required" => 1, + "example" => "Kroger" + ), + ), $GLOBALS['api_methods_whosonfirst']['filter_parameters_brands_sizes']), + "errors" => array( + "432" => array("message" => "Invalid brand size"), + "433" => array("message" => "Invalid brand size range"), + "434" => array("message" => "Missing query"), + "513" => array("message" => "Unable to retrieve brands"), + ), + "disallow_formats" => array( "geojson", "meta" ), + ), + + 'whosonfirst.brands.sizes.getInfo' => array( + "description" => "Return details about a specific brand size", + "documented" => 1, + "enabled" => 1, + "experimental" => 1, + "paginated" => 0, + "library" => "api_whosonfirst_brands_sizes", + "parameters" => array( + array( + "name" => "brand_size", + "documented" => 1, + "required" => 1, + "example" => "M" + ), + ), + "errors" => array( + "432" => array("message" => "Invalid brand size"), + ), + "disallow_formats" => array( "geojson", "meta" ), + ), + + 'whosonfirst.brands.sizes.getList' => array( + "description" => "Return a list of all the brand sizes", + "documented" => 1, + "enabled" => 1, + "experimental" => 1, + "paginated" => 0, + "library" => "api_whosonfirst_brands_sizes", + "parameters" => array( + # none right now + ), + "errors" => array( + ), + "disallow_formats" => array( "geojson", "meta" ), + ), + + 'whosonfirst.brands.venues.getList' => array( + "description" => "Return a list of venues for a specific brand", + "documented" => 1, + "enabled" => 1, + "experimental" => 1, + "paginated" => 1, + "extras" => 1, + "library" => "api_whosonfirst_brands_venues", + "parameters" => array_merge(array( + array( + "name" => "brand_id", + "documented" => 1, + "required" => 1, + "example" => 1125148929 + )), + $GLOBALS['api_methods_whosonfirst']['filter_parameters_existential'], + $GLOBALS['api_methods_whosonfirst']['filter_parameters_hierarchy'], + $GLOBALS['api_methods_whosonfirst']['filter_parameters_concordances'], + $GLOBALS['api_methods_whosonfirst']['filter_parameters_lastmod'] + ), + "errors" => array( + "434" => array("message" => "Missing brand ID"), + "435" => array("message" => "Invalid brand ID"), + "513" => array("message" => "Unable to retrieve venues"), + ), + "disallow_formats" => array( "geojson", "meta" ), + ), + 'whosonfirst.categories.getNamespaces' => array( "description" => "Return the list of unique namespaces for all the categories in Who's On First.", "documented" => 1, @@ -453,11 +712,10 @@ "pagination" => "cursor", "extras" => 1, "library" => "api_whosonfirst_places", - "parameters" => array( + "parameters" => array_merge(array( array("name" => "latitude", "description" => "A valid latitude coordinate.", "documented" => 1, "required" => 1, "example" => "37.766633"), array("name" => "longitude", "description" => "A valid longitude coordinate.", "documented" => 1, "required" => 1, "example" => "-122.417693"), - array("name" => "placetype", "description" => "A valid Who's On First placetype to limit the query by.", "documented" => 1, "required" => 0, "example" => "neighbourhood"), - ), + ), $GLOBALS['api_methods_whosonfirst']['filter_parameters_spatial']), "errors" => array( "432" => array("message" => "Missing 'latitude' parameter"), "433" => array("message" => "Missing 'longitude' parameter"), @@ -471,6 +729,32 @@ ) ), + 'whosonfirst.places.getByPolyline' => array( + "description" => "Return Who's On First places intersecting each point along a polyline.", + "documented" => 1, + "enabled" => ($GLOBALS['cfg']['enable_feature_pip'] && $GLOBALS['cfg']['enable_feature_pip_polyline']), + "paginated" => 1, + "pagination" => "default", + "pagination_per_page_max" => 100, + "extras" => 1, + "library" => "api_whosonfirst_places", + "parameters" => array_merge(array( + array("name" => "polyline", "description" => "A valid polyline-encoded string.", "documented" => 1, "required" => 1, "example" => "e_teFdj_jV|OzS_NlRbNdRqFdHt`AdsAqWlEqAkSug@nFxMfqB`jAaOhSfvCqb@tHjMx}I"), + array("name" => "precision", "description" => "The decimal precision for your polyline, for example 5 (Google) or 6 (Mapzen Valhalla)", "documented" => 1, "required" => 0, "example" => "6", "default" => 5), + array("name" => "unique", "description" => "Signal that results should only contain the unique set of places that intersect all steps in the polyline)", "documented" => 1, "required" => 0, "example" => "1"), + + ), $GLOBALS['api_methods_whosonfirst']['filter_parameters_spatial']), + "errors" => array( + "432" => array("message" => "Missing 'polyline' parameter"), + "433" => array("message" => "Invalid 'precision' parameter"), + "436" => array("message" => "Invalid placetype"), + "513" => array("message" => "Failed to perform lookup"), + ), + "notes" => array( + "If you pass the 'unique' flag please note that the set of unique places will be for the paginated slice of the polyline rather than the entire polyline itself. This may cause pagination results to look a bit weird and why the 'total' pagination property will be set to null (since its count will reflect the total number of points in your polyline)." + ) + ), + 'whosonfirst.places.getHierarchiesByLatLon' => array( "description" => "Return the closest set of ancestors (hierarchies) for a latitude and longitude", "documented" => 1, @@ -482,7 +766,7 @@ array("name" => "latitude", "description" => "A valid latitude coordinate.", "documented" => 1, "required" => 1, "example" => "37.777228"), array("name" => "longitude", "description" => "A valid longitude coordinate.", "documented" => 1, "required" => 1, "example" => "-122.470779"), array("name" => "spr", "description" => "Format results as a standard place response (spr).", "documented" => 1, "required" => 0, "example" => 1), - ), $GLOBALS['api_methods_whosonfirst']['filter_parameters_tile38']), + ), $GLOBALS['api_methods_whosonfirst']['filter_parameters_spatial']), "errors" => array( "432" => array("message" => "Missing 'latitude' parameter"), "433" => array("message" => "Missing 'longitude' parameter"), @@ -591,7 +875,7 @@ array("name" => "min_longitude", "description" => "A valid longitude coordinate, representing the left (Western) edge of the bounding box.", "documented" => 1, "required" => 1, "example" => "-122.34374508"), array("name" => "max_latitude", "description" => "A valid latitude coordinate, representing the top (Northern) edge of the bounding box.", "documented" => 1, "required" => 1, "example" => "37.85749665"), array("name" => "max_longitude", "description" => "A valid longitude coordinate, representing the right (Eastern) edge of the bounding box.", "documented" => 1, "required" => 1, "example" => "-122.25585446"), - ), $GLOBALS['api_methods_whosonfirst']['filter_parameters_tile38']), + ), $GLOBALS['api_methods_whosonfirst']['filter_parameters_spatial']), "errors" => array( "432" => array("message" => "Missing 'min_latitude' parameter"), "433" => array("message" => "Missing 'min_longitude' parameter"), @@ -619,7 +903,7 @@ array("name" => "latitude", "description" => "A valid latitude coordinate.", "documented" => 1, "required" => 1, "example" => "40.784165"), array("name" => "longitude", "description" => "A valid longitude coordinate.", "documented" => 1, "required" => 1, "example" => "-73.958110"), array("name" => "radius", "description" => "A valid radius (in meters) to limit the query by. Default radius is 100. Maximum radius is 500.", "documented" => 1, "required" => 0, "example" => 25, "default" => 100, "max" => 500), - ), $GLOBALS['api_methods_whosonfirst']['filter_parameters_tile38']), + ), $GLOBALS['api_methods_whosonfirst']['filter_parameters_spatial']), "errors" => array( "432" => array("message" => "Missing 'latitude' parameter"), "433" => array("message" => "Missing 'longitude' parameter"), @@ -723,7 +1007,7 @@ "parameters" => array_merge(array( array("name" => "latitude", "description" => "A valid latitude coordinate.", "documented" => 1, "required" => 1, "example" => "37.766633"), array("name" => "longitude", "description" => "A valid longitude coordinate.", "documented" => 1, "required" => 1, "example" => "-122.417693"), - ), $GLOBALS['api_methods_whosonfirst']['filter_parameters_tile38']), + ), $GLOBALS['api_methods_whosonfirst']['filter_parameters_spatial']), "errors" => array( "432" => array("message" => "Missing 'latitude' parameter"), "433" => array("message" => "Missing 'longitude' parameter"), diff --git a/www/include/init.php b/www/include/init.php index a0ba0b0..c653d31 100644 --- a/www/include/init.php +++ b/www/include/init.php @@ -1,4 +1,4 @@ -"; @@ -233,7 +248,7 @@ function filter_strict_quot($str){ if ($disallow){ $status = "503 Service Unavailable"; - header("HTTP/1.1 {$status}"); + header("HTTP/1.1 {$status}"); header("Status: {$status}"); exit(); } @@ -263,7 +278,7 @@ function filter_strict_quot($str){ $server_url = "{$scheme}://{$_SERVER['SERVER_NAME']}"; } } - + if (! $server_url){ $server_url = "{$scheme}://{$_SERVER['SERVER_NAME']}"; } @@ -274,7 +289,7 @@ function filter_strict_quot($str){ # at some point or another. So we choose trailing slashes. $GLOBALS['cfg']['abs_root_url'] = rtrim($server_url, '/') . "/"; - + # Because sometimes you can't run your Flamework project off of the root path # of a domain and need to do stuff like this in your httpd.conf file # @@ -295,7 +310,7 @@ function filter_strict_quot($str){ # in either your httpd.conf or .htaccess file, like this: # # SetEnv FLAMEWORK_SUFFIX "/boundaryissues/ca" - # + # # The problem with doing that is if you're just _actually_ running your Flamework project # on / but serving it up on a nested path (and probably a different domain) via something # like nginx then by setting the environment locally then there is no way to introspect the @@ -304,7 +319,7 @@ function filter_strict_quot($str){ # $GLOBALS['cfg']['enable_feature_abs_root_suffix'] = 1; # $GLOBALS['cfg']['abs_root_suffix'] = "/api"; # $GLOBALS['cfg']['abs_root_suffix_env'] = 'HTTP_X_PROXY_PATH'; - # + # # (20160603/thisisaaronland) if ($GLOBALS['cfg']['enable_feature_abs_root_suffix']){ @@ -321,7 +336,7 @@ function filter_strict_quot($str){ $ok = 1; foreach (explode("/", $suffix) as $chunk){ - + if (chunk == ".."){ $ok = 0; break; @@ -535,13 +550,13 @@ function handle_error_notices($errno, $errstr){ # (unless you've disable the 'auto_connect' flag) and # will blow its brains out if there's a problem. # - + $start = microtime_ms(); db_init(); $end = microtime_ms(); - $time = $end - $start; + $time = $end - $start; $GLOBALS['timings']['db_init_time'] = $time; @@ -568,16 +583,16 @@ function handle_error_notices($errno, $errstr){ if ($this_is_webpage){ - # we assume login_check_login has been called above already + # we assume login_check_login has been called above already # (20160121/thisisaaronland) - # API site key/token stuff + # API site key/token stuff if (features_is_enabled("api")){ - loadlib("api"); + loadlib("api"); - if (features_is_enabled(array("api_site_keys", "api_site_tokens"))){ + if (features_is_enabled(array("api_site_keys", "api_site_tokens"))){ loadlib("api_keys"); loadlib("api_oauth2_access_tokens"); @@ -586,6 +601,7 @@ function handle_error_notices($errno, $errstr){ $GLOBALS['smarty']->assign_by_ref("site_token", $token['access_token']); } } + } - # end of flamework-api stuff for API site keys \ No newline at end of file + # end of flamework-api stuff for API site keys diff --git a/www/include/lib_api.php b/www/include/lib_api.php index e15ffd2..f91af4c 100644 --- a/www/include/lib_api.php +++ b/www/include/lib_api.php @@ -181,7 +181,10 @@ function api_dispatch($method){ api_output_error(499); } - call_user_func($func); + # see the way we're passing $method_row to the function? + # not much uses that yet... (20171101/thisisaaronland) + + call_user_func_array($func, array($method_row)); exit(); } diff --git a/www/include/lib_api_config.php b/www/include/lib_api_config.php index e3f4802..06413e7 100644 --- a/www/include/lib_api_config.php +++ b/www/include/lib_api_config.php @@ -106,6 +106,10 @@ function api_config_init(){ } } + if ($GLOBALS['cfg']['enable_feature_api_method_overrides']){ + api_config_init_overrides(); + } + if ($GLOBALS['cfg']['enable_feature_api_method_aliases']){ api_config_init_aliases(); } @@ -124,6 +128,33 @@ function api_config_init(){ ################################################################# + function api_config_init_overrides(){ + + foreach ($GLOBALS['cfg']['api']['method_overrides']['method_classes'] as $class_spec => $override){ + + foreach ($GLOBALS['cfg']['api']['methods'] as $method_name => $method_details){ + + if (! preg_match("/^{$class_spec}/", $method_name)){ + continue; + } + + $GLOBALS['cfg']['api']['methods'][$method_name] = array_merge($GLOBALS['cfg']['api']['methods'][$method_name], $override); + } + } + + foreach ($GLOBALS['cfg']['api']['method_overrides']['methods'] as $method_name => $override){ + + if (! isset($GLOBALS['cfg']['api']['methods'][$method_name])){ + continue; + } + + $GLOBALS['cfg']['api']['methods'][$method_name] = array_merge($GLOBALS['cfg']['api']['methods'][$method_name], $override); + } + + } + + ################################################################# + function api_config_init_aliases(){ foreach ($GLOBALS['cfg']['api']['method_aliases']['method_classes'] as $class_spec => $aliases){ diff --git a/www/include/lib_api_log.php b/www/include/lib_api_log.php index c988761..232e4c9 100644 --- a/www/include/lib_api_log.php +++ b/www/include/lib_api_log.php @@ -16,7 +16,7 @@ function api_log($data, $dispatch=0){ return array('ok' => 1); } - $func = $GLOBALS['api_log_hooks']['dispatch']; + $func = $GLOBALS['cfg']['api_log_hooks']['dispatch']; if ((! $func) || (! function_exists($func))){ return array('ok' => 0, 'error' => 'Dispatch function has not been declared'); diff --git a/www/include/lib_api_log_chatterbox.php b/www/include/lib_api_log_chatterbox.php new file mode 100644 index 0000000..21a6655 --- /dev/null +++ b/www/include/lib_api_log_chatterbox.php @@ -0,0 +1,31 @@ + "api", + "status" => $status, + "status_code" => $status_code, + ); + + return chatterbox_dispatch($data, $more); + } + + ######################################################################## + + # the end \ No newline at end of file diff --git a/www/include/lib_api_log_errorlog.php b/www/include/lib_api_log_errorlog.php index 89cb2b9..ccf3412 100644 --- a/www/include/lib_api_log_errorlog.php +++ b/www/include/lib_api_log_errorlog.php @@ -1,6 +1,6 @@ $GLOBALS['cfg']['api_per_page_max']){ - $args['per_page'] = $GLOBALS['cfg']['api_per_page_max']; + else if ($args['per_page'] > $per_page_max){ + $args['per_page'] = $per_page_max; } if ($cursor = request_str("cursor")){ @@ -44,12 +53,15 @@ function api_utils_ensure_pagination_results(&$out, &$pagination){ "method" => $method, ); - foreach ($method_row["parameters"] as $p){ + if (is_array($method_row["parameters"])){ + + foreach ($method_row["parameters"] as $p){ - $k = $p["name"]; + $k = $p["name"]; - if ($v = request_str($k)){ - $query[$k] = $v; + if ($v = request_str($k)){ + $query[$k] = $v; + } } } diff --git a/www/include/lib_api_whosonfirst_brands.php b/www/include/lib_api_whosonfirst_brands.php index e801f1b..6839572 100644 --- a/www/include/lib_api_whosonfirst_brands.php +++ b/www/include/lib_api_whosonfirst_brands.php @@ -1,11 +1,43 @@ $rows, + ); + + api_utils_ensure_pagination_results($out, $pagination); + + $more = array( + 'key' => 'brands', + ); + + api_output_ok($out, $more); } ######################################################################## @@ -15,13 +47,13 @@ function api_whosonfirst_brands_getInfo(){ $id = request_int64("id"); if (! $id){ - api_output_error(432); + api_output_error(434); } $brand = whosonfirst_brands_get_by_id($id); if (! $brand){ - api_output_error(513); + api_output_error(435); } $out = array( @@ -38,4 +70,140 @@ function api_whosonfirst_brands_getInfo(){ ######################################################################## + + function api_whosonfirst_brands_getList(){ + + $args = array(); + api_utils_ensure_pagination_args($args); + + $sz = api_whosonfirst_brands_ensure_brand_sizes(); + + $rsp = whosonfirst_brands_get_brands($sz, $args); + + if (! $rsp["ok"]){ + api_output_error(513); + } + + $rows = $rsp["rows"]; + $pagination = $rsp["pagination"]; + + $out = array( + 'brands' => $rows, + ); + + api_utils_ensure_pagination_results($out, $pagination); + + $more = array( + 'key' => 'brands', + ); + + api_output_ok($out, $more); + } + + ######################################################################## + + function api_whosonfirst_brands_ensure_brand_sizes(){ + + $sizes = array(); + + $min_sz = request_str("min_brand_size"); + $max_sz = request_str("max_brand_size"); + $sz = request_str("brand_size"); + + $min_sz = trim($min_sz); + $max_sz = trim($max_sz); + $sz = trim($sz); + + if ($sz){ + + if (! preg_match("/^(?:(>|<)(=)?)?(?:\s*)?([A-Z]+)$/i", $sz, $m)){ + api_output_error(432); + } + + $condition = $m[1]; + $inclusive = $m[2]; + $sz = $m[3]; + + if (! whosonfirst_brands_sizes_is_valid_size($sz)){ + api_output_error(432); + } + + if ($condition == "<"){ + $sizes = whosonfirst_brands_sizes_lt($sz); + } + + else if ($condition == ">"){ + $sizes = whosonfirst_brands_sizes_gt($sz); + } + + else {} + + if ((! $condition) || ($inclusive)){ + $sizes[] = $sz; + } + } + + if (($min_sz) && (! whosonfirst_brands_sizes_is_valid_size($min_sz))){ + api_output_error(432); + } + + if (($max_sz) && (! whosonfirst_brands_sizes_is_valid_size($max_sz))){ + api_output_error(432); + } + + if (($min_sz) && ($max_sz)){ + + $min_details = whosonfirst_brands_sizes_get_by_size($min_sz); + $max_details = whosonfirst_brands_sizes_get_by_size($max_sz); + + if ($min_details["max"] > $max_details["min"]){ + api_output_error(433); + } + } + + if ($min_sz){ + + foreach (whosonfirst_brands_sizes_gt($min_sz) as $other_sz){ + + # echo "compare {$max_sz} >? {$other_sz}\n"; + + if (($max_sz) && (whosonfirst_brands_sizes_is_larger($max_sz, $other_sz))){ + continue; + } + + if (! in_array($other_sz, $sizes)){ + $sizes[] = $other_sz; + } + } + + if (! in_array($min_sz, $sizes)){ + $sizes[] = $min_sz; + } + } + + if ($max_sz){ + + foreach (whosonfirst_brands_sizes_lt($max_sz) as $other_sz){ + + # echo "compare {$min_sz} $details, + ); + + $more = array( + 'is_singleton' => 1, + 'key' => 'size', + ); + + api_output_ok($out); + } + + ######################################################################## + + function api_whosonfirst_brands_sizes_getList(){ + + $sizes = array_values($GLOBALS['whosonfirst_brands_sizes']['brands_sizes']); + usort($sizes, "whosonfirst_brands_sizes_sort"); + + $out = array( + 'sizes' => $sizes, + ); + + $more = array( + 'key' => 'sizes', + ); + + api_output_ok($out); + } + + ######################################################################## + + # the end \ No newline at end of file diff --git a/www/include/lib_api_whosonfirst_brands_venues.php b/www/include/lib_api_whosonfirst_brands_venues.php new file mode 100644 index 0000000..b9de350 --- /dev/null +++ b/www/include/lib_api_whosonfirst_brands_venues.php @@ -0,0 +1,68 @@ + $rsp['rows'], + ); + + if ($GLOBALS['cfg']['environment'] == 'dev'){ + $out['_query'] = $rsp['_query']; + } + + api_utils_ensure_pagination_results($out, $pagination); + + $more = array( + 'key' => 'places', + ); + + api_output_ok($out, $more); + } + + ######################################################################## + + # the end + + \ No newline at end of file diff --git a/www/include/lib_api_whosonfirst_places.php b/www/include/lib_api_whosonfirst_places.php index 7efac80..55db6bd 100644 --- a/www/include/lib_api_whosonfirst_places.php +++ b/www/include/lib_api_whosonfirst_places.php @@ -94,6 +94,12 @@ function api_whosonfirst_places_getHierarchiesByLatLon(){ api_output_error(436); } + $flags_more = array( + "prefix" => null, + ); + + $flags = api_whosonfirst_ensure_existential_flags($flags_more); + $placetypes = whosonfirst_placetypes_ancestors($pt); array_unshift($placetypes, $pt); @@ -102,6 +108,8 @@ function api_whosonfirst_places_getHierarchiesByLatLon(){ foreach ($placetypes as $pt){ $more = array("placetype" => $pt); + $more = array_merge($more, $flags); + $rsp = whosonfirst_pip_get_by_latlon($lat, $lon, $more); if (! $rsp["ok"]){ @@ -119,7 +127,7 @@ function api_whosonfirst_places_getHierarchiesByLatLon(){ foreach ($possible as $pip_row) { - $row = whosonfirst_places_get_by_id($pip_row["Id"]); + $row = whosonfirst_places_get_by_id($pip_row["wof:id"]); foreach ($row["wof:hierarchy"] as $hier){ @@ -187,8 +195,11 @@ function api_whosonfirst_places_getHierarchiesByLatLon(){ api_whosonfirst_output_enpublicify($places['rows'], $more); - foreach ($places['rows'] as $row){ - $lookup[$row['wof:id']] = $row; + if (is_array($places['rows'])){ + + foreach ($places['rows'] as $row){ + $lookup[$row['wof:id']] = $row; + } } $results_spr = array(); @@ -323,6 +334,101 @@ function api_whosonfirst_places_getParentByLatlon(){ ######################################################################## + function api_whosonfirst_places_getByPolyline($method_row){ + + api_utils_features_ensure_enabled(array( + "pip", + "pip_polyline" + )); + + $polyline = request_str("polyline"); + + if (! $polyline){ + api_output_error(432); + } + + $args = array(); + + if ($p = request_int32("precision")){ + + if (! in_array($p, array(5, 6))){ + api_output_error(433); + } + + $args["precision"] = $p; + } + + if (request_int32("unique")){ + $args["unique"] = 1; + } + + if ($placetype = request_str("placetype")){ + api_whosonfirst_places_ensure_valid_placetype($placetype); + $args["placetype"] = $placetype; + } + + $flags_more = array( + "prefix" => null, + ); + + $flags = api_whosonfirst_ensure_existential_flags($flags_more); + $args = array_merge($args, $flags); + + api_utils_ensure_pagination_args($args, $method_row); + + $rsp = whosonfirst_pip_get_by_polyline($polyline, $args); + + if (! $rsp["ok"]){ + api_output_error(513); + } + + $more = array(); + + if ($extras = api_whosonfirst_utils_get_extras()){ + $more["extras"] = $extras; + } + + $results = array(); + + foreach ($rsp["rows"] as $step){ + + $places = array(); + + foreach ($step as $pip_row){ + + $row = whosonfirst_places_get_by_id($pip_row["wof:id"]); + + $public = api_whosonfirst_output_enpublicify_single($row, $more); + $places[] = $public; + } + + $results[] = $places; + } + + $pagination = $rsp["pagination"]; + + $out = array( + "places" => $results, + ); + + # see notes in method spec in config_api_methods_whosonfirst.php + # (20171101/thisisaaronland) + + if ($args["unique"]){ + $pagination["total_count"] = null; + } + + api_utils_ensure_pagination_results($out, $pagination); + + $more = array( + 'key' => 'places', + ); + + api_output_ok($out, $more); + } + + ######################################################################## + function api_whosonfirst_places_getByLatLon(){ api_utils_features_ensure_enabled(array( @@ -360,6 +466,13 @@ function api_whosonfirst_places_getByLatLon(){ $more["placetype"] = $pt; } + $flags_more = array( + "prefix" => null, + ); + + $flags = api_whosonfirst_ensure_existential_flags($flags_more); + $more = array_merge($more, $flags); + $rsp = whosonfirst_pip_get_by_latlon($lat, $lon, $more); if (! $rsp["ok"]){ @@ -373,12 +486,12 @@ function api_whosonfirst_places_getByLatLon(){ } $results = array(); - + foreach ($rsp["rows"] as $pip_row){ - - $row = whosonfirst_places_get_by_id($pip_row["Id"]); - $public = api_whosonfirst_output_enpublicify_single($row, $more); + $row = whosonfirst_places_get_by_id($pip_row["wof:id"]); + + $public = api_whosonfirst_output_enpublicify_single($row, $more); $results[] = $public; } @@ -861,8 +974,12 @@ function api_whosonfirst_ensure_existential_flags($more=array()){ } } - $fq_k = $more["prefix"] . ":" . $k; + $fq_k = $k; + if ($more["prefix"]){ + $fq_k = $more["prefix"] . ":" . $k; + } + $flags[ $fq_k ] = $v; } diff --git a/www/include/lib_api_whosonfirst_utils.php b/www/include/lib_api_whosonfirst_utils.php index 6c6840a..8a870d1 100644 --- a/www/include/lib_api_whosonfirst_utils.php +++ b/www/include/lib_api_whosonfirst_utils.php @@ -96,7 +96,7 @@ function api_whosonfirst_utils_search_filters(){ $variant = request_str("variant"); # names_variant $concordance = request_str("concordance"); - + $brand = request_int64("brand_id"); $has_brand = request_str("has_brand"); @@ -113,20 +113,20 @@ function api_whosonfirst_utils_search_filters(){ $max_lastmod = request_int32("max_lastmod"); # it is assumed that these have all been validate by now - + $swlat = request_float("min_latitude"); $swlon = request_float("min_longitude"); $nelat = request_float("max_latitude"); $nelon = request_float("max_longitude"); - - $swlat = trim($swlat); + + $swlat = trim($swlat); $swlon = trim($swlon); $nelat = trim($nelat); $nelon = trim($nelon); $nullisland = true; $deprecated = false; - + $filters = array(); $must_not = array(); @@ -164,7 +164,7 @@ function api_whosonfirst_utils_search_filters(){ if (! $nullisland){ $must_not[] = array('term' => array('geom:latitude' => 0.0)); - $must_not[] = array('term' => array('geom:longitude' => 0.0)); + $must_not[] = array('term' => array('geom:longitude' => 0.0)); } if (request_isset("is_deprecated")){ @@ -174,7 +174,7 @@ function api_whosonfirst_utils_search_filters(){ if (! $deprecated){ $must_not[] = array('exists' => array('field' => 'edtf:deprecated')); } - + # end of TBD... (20170722/thisisaaronland) # } @@ -192,7 +192,7 @@ function api_whosonfirst_utils_search_filters(){ $must_not = array( 'exists' => array( 'field' => 'wof:brand_id' ) - ); + ); $filters[] = array('bool' => array( 'must_not' => $must_not, @@ -203,7 +203,7 @@ function api_whosonfirst_utils_search_filters(){ $must = array( 'exists' => array( 'field' => 'wof:brand_id' ) - ); + ); $filters[] = array('bool' => array( 'must' => $must, @@ -220,7 +220,7 @@ function api_whosonfirst_utils_search_filters(){ else if ($is_current == "0"){ $filters[] = array('term' => array('mz:is_current' => 0)); - } + } else if ($is_current == "1"){ $filters[] = array('term' => array('mz:is_current' => 1)); @@ -243,13 +243,13 @@ function api_whosonfirst_utils_search_filters(){ # so far as I can tell there is no way to write an ES query # that says either field (x) doesn't exist or if it does exist - # does not have a value of (a, b, c) ... + # does not have a value of (a, b, c) ... # (20170724/thisisaaronland) $should = array( array("exists" => array( 'field' => 'edtf:deprecated' )), array("terms" => array("edtf:deprecated" => array ("", "u", "uuuu" ) )) - ); + ); # $filters[] = array("bool" => array( # "should" => $should @@ -260,7 +260,7 @@ function api_whosonfirst_utils_search_filters(){ $must = array( 'exists' => array( 'field' => 'edtf:deprecated' ) - ); + ); $must_not = array( array("terms" => array("edtf:deprecated" => array ("", "u", "uuuu" ) )) @@ -283,7 +283,7 @@ function api_whosonfirst_utils_search_filters(){ $must = array( array("terms" => array("edtf:cessation" => array ("", "u", "uuuu" ) )) - ); + ); $must_not = array(); @@ -299,7 +299,7 @@ function api_whosonfirst_utils_search_filters(){ $must = array( 'exists' => array( 'field' => 'edtf:cessation' ) - ); + ); $must_not = array( array("terms" => array("edtf:cessation" => array ("", "u", "uuuu" ) )) @@ -322,18 +322,18 @@ function api_whosonfirst_utils_search_filters(){ $must_not = array( 'exists' => array( 'field' => 'wof:superseded_by' ) - ); + ); $filters[] = array('bool' => array( 'must_not' => $must_not, )); - } + } else if ($is_superseded == "1"){ $must = array( 'exists' => array( 'field' => 'wof:superseded_by' ) - ); + ); $filters[] = array('bool' => array( 'must' => $must, @@ -350,18 +350,18 @@ function api_whosonfirst_utils_search_filters(){ $must_not = array( 'exists' => array( 'field' => 'wof:supersedes' ) - ); + ); $filters[] = array('bool' => array( 'must_not' => $must_not, )); - } + } else if ($is_superseding == "1"){ $must = array( 'exists' => array( 'field' => 'wof:supersedes' ) - ); + ); $filters[] = array('bool' => array( 'must' => $must, @@ -535,7 +535,7 @@ function api_whosonfirst_utils_search_filters(){ if (($swlat) && ($swlon) && ($nelat) && ($nelon)){ # PLEASE WRITE ME... need to index geom:bbox I think? - # https://github.com/whosonfirst/whosonfirst-www-api/issues/33 + # https://github.com/whosonfirst/whosonfirst-www-api/issues/33 # https://github.com/whosonfirst/whosonfirst-www-api/issues/34 } @@ -561,18 +561,96 @@ function api_whosonfirst_utils_search_filters(){ if ($input){ + /* + Aaron Straup Cope [5:25 PM] + oh, there is the problem: + ``` + query":{ + "match":{"wof:concordances_sources":{"query":"","operator":"and"}}}}, + ``` + + Dan Phiffer [5:25 PM] + Schema? + + Aaron Straup Cope [5:26 PM] + apparently I did this somehow... + `"query":""` + + Dan Phiffer [5:26 PM] + Huh + + Aaron Straup Cope [5:26 PM] + oh god, it's probably this... https://github.com/whosonfirst/whosonfirst-www-api/commit/e10bf8429119287da33fa3f67dca48c7d73335a0#diff-f85a4221598a9839b4bf8493ec24cb03R99 + go, me! + + Dan Phiffer [5:27 PM] + Oh like it should be a string instead of an array? + + Aaron Straup Cope [5:28 PM] + no, it's the test here: + https://github.com/whosonfirst/whosonfirst-www-api/blob/e10bf8429119287da33fa3f67dca48c7d73335a0/www/include/lib_api_whosonfirst_utils.php#L558-L563 + + Dan Phiffer [5:28 PM] + Well this does make me feel less uneasy that ES just started + being weird about stuff all of a sudden + + Aaron Straup Cope [5:28 PM] + this shouldn't have anything to do with indexing + can you add a conditional here: https://github.com/whosonfirst/whosonfirst-www-api/blob/e10bf8429119287da33fa3f67dca48c7d73335a0/www/include/lib_api_whosonfirst_utils.php#L564 + to the effect of: if $field == "wof:concordances_sources" + then $input = explode(",", $input) + and remnove this line: https://github.com/whosonfirst/whosonfirst-www-api/blob/e10bf8429119287da33fa3f67dca48c7d73335a0/www/include/lib_api_whosonfirst_utils.php#L99 + + Dan Phiffer [5:29 PM] + Ok will do + + Aaron Straup Cope [5:29 PM] + and see if that fixes the problem + in general exploding on all (most?) of the strings would be + useful but one thing at a time... + basically I had to do this so you can query for + `?concordance=osm:node,osm:way` in a single query... + + Dan Phiffer [5:32 PM] + Got it + Yep, seems to do the trick: (snip) + Want me to commit/deploy that? + + Aaron Straup Cope [5:33 PM] + yes, please + sorry about that + + Dan Phiffer [5:33 PM] + No problem + This explains the bundler thing that Stephen was seeing too + + Aaron Straup Cope [5:34 PM] + would you also copy/paste this conversation from "oh, there is + the problem:" onwards above the fix + + Dan Phiffer [5:34 PM] + Sure thing + + (20171121/dphiffer) + */ + if ($field == 'wof:concordances_sources'){ + $input = explode(",", $input); + } + $input = api_whosonfirst_utils_ensure_array($input); - $filters[] = api_whosonfirst_utils_enfilterify_simple($field, $input); + $filter = api_whosonfirst_utils_enfilterify_simple($field, $input); + + $filters[] = $filter; } } - + if (count($must_not)){ $filters[] = array('bool' => array('must_not' => $must_not)); } return $filters; } - + ######################################################################## function api_whosonfirst_utils_enfilterify_simple($field, $terms){ @@ -599,13 +677,18 @@ function api_whosonfirst_utils_enfilterify_simple($field, $terms){ ))); } - $must = array(); - + $cond = "must"; + $matches = array(); + + if ($field == "wof:concordances_sources"){ + $cond = "should"; + } + foreach ($terms as $term){ $esc_term = elasticsearch_escape($term, $more); - - $must[] = array('query' => array( + + $matches[] = array('query' => array( 'match' => array($field => array( 'query' => $esc_term, 'operator' => 'and' ) @@ -613,12 +696,12 @@ function api_whosonfirst_utils_enfilterify_simple($field, $terms){ } return array('bool' => array( - 'must' => $must + $cond => $matches )); } - + ######################################################################## - + function api_whosonfirst_utils_ensure_array($thing, $sep=","){ if (! is_array($thing)){ @@ -653,7 +736,7 @@ function api_whosonfirst_utils_get_extras(){ $extras = api_whosonfirst_utils_ensure_geojson_extras($extras); } - return $extras; + return $extras; } ######################################################################## @@ -664,14 +747,14 @@ function api_whosonfirst_utils_ensure_geojson_extras($extras){ # these are required in order to include coordinates # in lib_api_output_geojson - + $ensure_centroids = array( "geom:latitude", "geom:longitude", "lbl:latitude", "lbl:longitude", ); foreach ($ensure_centroids as $ex){ - + if (! in_array($ex, $extras)){ $extras[] = $ex; } diff --git a/www/include/lib_chatterbox.php b/www/include/lib_chatterbox.php new file mode 100644 index 0000000..37a2281 --- /dev/null +++ b/www/include/lib_chatterbox.php @@ -0,0 +1,58 @@ + 0, "error" => "chatterbox is disabled"); + } + + $hostname = gethostname(); + + $defaults = array( + "host" => $hostname, + "application" => $GLOBALS["cfg"]["site_name"], + "context" => $GLOBALS["cfg"]["environment"], + "status" => "ok", + "status_code" => 1, + ); + + $data = array_merge($defaults, $more); + $data["details"] = $msg; + + $host = $GLOBALS["cfg"]["chatterbox_host"]; + $port = $GLOBALS["cfg"]["chatterbox_port"]; + $channel = $GLOBALS["cfg"]["chatterbox_channel"]; + $destination = $GLOBALS["cfg"]["chatterbox_destination"]; + + $data["destination"] = $destination; + + $msg = json_encode($data); + + $redis_more = array( + "host" => $host, + "port" => $port, + ); + + try { + $rsp = redis_publish($channel, $msg, $redis_more); + return $rsp; + } + + catch (Exception $e) { + return array( "ok" => 0, "error" => $e->getMessage() ); + } + } + + ######################################################################## + + # the end \ No newline at end of file diff --git a/www/include/lib_elasticsearch_brands.php b/www/include/lib_elasticsearch_brands.php new file mode 100644 index 0000000..81ed86a --- /dev/null +++ b/www/include/lib_elasticsearch_brands.php @@ -0,0 +1,43 @@ + $GLOBALS['cfg']['elasticsearch_brands_host'], + 'port' => $GLOBALS['cfg']['elasticsearch_brands_port'], + 'index' => $GLOBALS['cfg']['elasticsearch_brands_index'], + 'scroll' => false, # PLEASE PUT ME IN A CONFIG, also see notes in brands.php (20171109/thisisaaronland) + ); + + $more = array_merge($defaults, $more); + + # pass by ref + } + + ######################################################################## + + # the end diff --git a/www/include/lib_elasticsearch_spelunker.php b/www/include/lib_elasticsearch_spelunker.php index e608fe6..4a4b2c1 100644 --- a/www/include/lib_elasticsearch_spelunker.php +++ b/www/include/lib_elasticsearch_spelunker.php @@ -14,6 +14,16 @@ function elasticsearch_spelunker_search($query, $more=array()){ ######################################################################## + function elasticsearch_spelunker_facet($query, $more=array()){ + + elasticsearch_spelunker_append_config($more); + + $rsp = elasticsearch_facet($query, $more); + return $rsp; + } + + ######################################################################## + function elasticsearch_spelunker_mget($ids, $more=array()){ elasticsearch_spelunker_append_config($more); diff --git a/www/include/lib_redis.php b/www/include/lib_redis.php new file mode 100644 index 0000000..1c9d516 --- /dev/null +++ b/www/include/lib_redis.php @@ -0,0 +1,119 @@ + $GLOBALS['cfg']['redis_scheme'], + 'host' => $GLOBALS['cfg']['redis_host'], + 'port' => $GLOBALS['cfg']['redis_port'], + ); + + $args = array_merge($defaults, $args); + + $uri = "{$args['scheme']}://{$args['host']}:{$args['port']}"; + + if (! isset($redis_conns[$uri])){ + + $client = new Predis\Client($uri); + + try { + $now = time(); + $rsp = $client->echo($now); + + if ($rsp != $now){ + return array('ok' => 0, 'error' => 'Connection established but is full of weird'); + } + } + + catch (Exception $e) { + return array('ok' => 0, 'error' => $e->getMessage()); + } + + $GLOBALS['redis_conns'][$uri] = $client; + } + + $client = $GLOBALS['redis_conns'][$uri]; + return array('ok' => 1, 'client' => $client); + } + + ######################################################################## + + # See what's going on here? It's basically what Go does. Because it turns + # out that it's not a bad way to do things... (20160408/thisisaaronland) + + function redis_connect($more=array()){ + + $rsp = redis_client($more); + + if (! $rsp['ok']){ + return array(null, $rsp); + } + + return array($rsp['client'], null); + } + + ######################################################################## + + function redis_get($key, $more=array()){ + + list($client, $err) = redis_connect($more); + + if ($err){ + return $err; + } + + $value = $client->get($key); + + return array('ok' => 1, 'value' => $value); + } + + ######################################################################## + + function redis_set($key, $value, $more=array()){ + + list($client, $err) = redis_connect($more); + + if ($err){ + return $err; + } + + # How best to test for errors? + + $client->set($key, $value); + + return array('ok' => 1); + } + + ######################################################################## + + function redis_publish($channel, $msg, $more=array()){ + + list($client, $err) = redis_connect($more); + + if ($err){ + return $err; + } + + $ok = $client->publish($channel, $msg); + + # get last error? + + return array('ok' => $ok); + } + + ######################################################################## + + # the end diff --git a/www/include/lib_search_utils.php b/www/include/lib_search_utils.php new file mode 100644 index 0000000..bb01c8c --- /dev/null +++ b/www/include/lib_search_utils.php @@ -0,0 +1,33 @@ + $q, + 'page' => $pagination['page'] - 1 + ); + $next_args = array( + 'q' => $q, + 'page' => $pagination['page'] + 1 + ); + + $args = explode('&', $out['next_query']); + foreach ($args as $arg) { + $arg = explode('=', $arg); + $key = rawurlencode($arg[0]); + $val = rawurlencode($arg[1]); + $prev_args[$key] = $val; + $next_args[$key] = $val; + } + + $pagination['has_next'] = $pagination['page'] < $pagination['page_count']; + if ($pagination['has_next']) { + $pagination['next_url'] = '/search/' . http_build_query($next_args); + } + + $pagination['has_prev'] = $pagination['page'] > 1; + if ($pagination['has_prev']) { + $pagination['prev_url'] = '/search/' . http_build_query($next_args); + } + + } diff --git a/www/include/lib_tile38.php b/www/include/lib_tile38.php index 313f1df..c275933 100644 --- a/www/include/lib_tile38.php +++ b/www/include/lib_tile38.php @@ -6,10 +6,9 @@ function tile38_do($cmd, $more=array()){ - $host = $more['host']; - $port = $more['port']; + $endpoint = $more['endpoint']; - $url = "http://{$host}:{$port}"; + $url = "http://{$endpoint}"; # dumper($url); # dumper($cmd); diff --git a/www/include/lib_whosonfirst_brands.php b/www/include/lib_whosonfirst_brands.php index 3c6ba81..96eaf7d 100644 --- a/www/include/lib_whosonfirst_brands.php +++ b/www/include/lib_whosonfirst_brands.php @@ -1,10 +1,170 @@ array( + "_all" => array( + "query" => $esc_q, + "operator" => "and", + ) + )); + + # please reconcile me with whosonfirst_brands_get_brands + # and generally put somewhere modular and abstract... + # (20171123/thisisaaronland) + + $filter = array(); + + if ($sz){ + + $must = array('terms' => array( + 'wof:brand_size' => $sz + )); + + $filter['and'] = array( + array('bool' => array('must' => $must)) + ); + } + + $sort = array(array( + "wof:brand_name" => array("order" => "asc") + )); + + $query = array("filtered" => array( + "filter" => $filter, + "query" => $query, + )); + + $req = array( + "query" => $query, + "sort" => $sort, + ); + + $rsp = elasticsearch_brands_search($req, $more); + return $rsp; + } + + ######################################################################## + + # this function signature _will_ change (20171123/thisisaaronland) + + function whosonfirst_brands_get_brands($sz, $more=array()){ + + $query = array( + "match_all" => array() + ); + + # please reconcile me with whosonfirst_brands_search + # and generally put somewhere modular and abstract... + # (20171123/thisisaaronland) + + $filter = array(); + + if ($sz){ + + $must = array('terms' => array( + 'wof:brand_size' => $sz + )); + + $filter['and'] = array( + array('bool' => array('must' => $must)) + ); + } + + $sort = array(array( + "wof:brand_name" => array("order" => "asc") + )); + + $query = array("filtered" => array( + "filter" => $filter, + "query" => $query, + )); + + $req = array( + "query" => $query, + "sort" => $sort, + ); + + $rsp = elasticsearch_brands_search($req, $more); + return $rsp; + } + + ######################################################################## + + function whosonfirst_brands_get_by_id_multi($ids, $more=array()){ + + return elasticsearch_brands_mget($ids, $more); + } + + ######################################################################## + + function whosonfirst_brands_get_by_id($id, $more=array()){ + + $cache_key = "whosonfirst_brand_{$id}"; + + $cache = cache_get($cache_key); + + if ($cache['ok']){ + return $cache['data']; + } + + $query = array('ids' => array( + 'values' => array($id) + )); + + $req = array( + 'query' => $query + ); + + $rsp = elasticsearch_brands_search($req, $more); + + if (! $rsp['ok']){ + return null; + } + + $row = $rsp['rows'][0]; + + cache_set($cache_key, $row); + return $row; + } + + ######################################################################## + + function whosonfirst_brands_property($brand, $path){ + + $property = null; + + foreach (explode(".", $path) as $p){ + + if (! isset($brand[$p])){ + return null; + } + + $property = $brand[$p]; + + if (is_array($property)){ + $brand = $property; + } + } + + return $property; + } + + ######################################################################## + + function whosonfirst_brands_url_for_brand($brand){ + + $enc_id = urlencode($brand["wof:brand_id"]); + return $GLOBALS["cfg"]["abs_root_url"] . "brands/{$enc_id}/"; } ######################################################################## diff --git a/www/include/lib_whosonfirst_brands_sizes.php b/www/include/lib_whosonfirst_brands_sizes.php new file mode 100644 index 0000000..36d0b94 --- /dev/null +++ b/www/include/lib_whosonfirst_brands_sizes.php @@ -0,0 +1,152 @@ + $details){ + + $sz = $details['size']; + + $GLOBALS['whosonfirst_brands_sizes']['brands_sizes_by_id'][$id] = $sz; + $GLOBALS['whosonfirst_brands_sizes']['brands_sizes'][$sz] = $details; + } + + ######################################################################## + + function whosonfirst_brands_sizes_is_valid_size($sz){ + + $sz = strtoupper($sz); + return isset($GLOBALS['whosonfirst_brands_sizes']['brands_sizes'][$sz]); + } + + ######################################################################## + + function whosonfirst_brands_sizes_get_by_size($sz){ + + $sz = strtoupper($sz); + + if (! whosonfirst_brands_sizes_is_valid_size($sz)){ + return null; + } + + return $GLOBALS['whosonfirst_brands_sizes']['brands_sizes'][$sz]; + } + + ######################################################################## + + function whosonfirst_brands_sizes_get_by_id($id){ + + $sz = $GLOBALS['whosonfirst_brands_sizes']['brands_sizes_by_id'][$id]; + return whosonfirst_brands_sizes_get_by_size($sz); + } + + ######################################################################## + + # is $other_sz > $sz + + function whosonfirst_brands_sizes_is_larger($sz, $other_sz){ + + $sz_details = whosonfirst_brands_sizes_get_by_size($sz); + $other_details = whosonfirst_brands_sizes_get_by_size($other_sz); + + if ($other_details["min"] > $sz_details["max"]){ + return 1; + } + + return 0; + } + + ######################################################################## + + # is $other_sz < $sz + + function whosonfirst_brands_sizes_is_smaller($sz, $other_sz){ + + $sz_details = whosonfirst_brands_sizes_get_by_size($sz); + $other_details = whosonfirst_brands_sizes_get_by_size($other_sz); + + if ($other_details["max"] < $sz_details["min"]){ + return 1; + } + + return 0; + } + + ######################################################################## + + function whosonfirst_brands_sizes_lt($sz){ + + $sizes = array(); + + $details = whosonfirst_brands_sizes_get_by_size($sz); + + if ($details){ + + $min = $details["min"]; + + foreach ($GLOBALS['whosonfirst_brands_sizes']['brands_sizes'] as $other_sz => $other_details){ + + if ($other_details["max"] < $min){ + $sizes[] = $other_sz; + } + } + } + + return $sizes; + } + + ######################################################################## + + function whosonfirst_brands_sizes_gt($sz){ + + $sizes = array(); + + $details = whosonfirst_brands_sizes_get_by_size($sz); + + if ($details){ + + $max = $details["max"]; + + foreach ($GLOBALS['whosonfirst_brands_sizes']['brands_sizes'] as $other_sz => $other_details){ + + if ($other_details["min"] > $max){ + $sizes[] = $other_sz; + } + } + } + + return $sizes; + } + + ######################################################################## + + function whosonfirst_brands_sizes_sort($a, $b){ + + if ($a["min"] == $b["min"]){ + return 0; + } + + return ($a["min"] < $b["min"]) ? -1 : 1; + } + + ######################################################################## + + # the end \ No newline at end of file diff --git a/www/include/lib_whosonfirst_brands_sizes_spec.php b/www/include/lib_whosonfirst_brands_sizes_spec.php new file mode 100644 index 0000000..4cce99c --- /dev/null +++ b/www/include/lib_whosonfirst_brands_sizes_spec.php @@ -0,0 +1,16 @@ + array( + 'wof:id' => 85632715, + 'wof:name' => 'Antarctica' + ), + 'RU' => array( + 'wof:id' => 85632685, + 'wof:name' => 'Russia' + ), + 'CA' => array( + 'wof:id' => 85633041, + 'wof:name' => 'Canada' + ), + 'US' => array( + 'wof:id' => 85633793, + 'wof:name' => 'United States' + ), + 'CN' => array( + 'wof:id' => 85632695, + 'wof:name' => 'China' + ), + 'BR' => array( + 'wof:id' => 85633009, + 'wof:name' => 'Brazil' + ), + 'AU' => array( + 'wof:id' => 85632793, + 'wof:name' => 'Australia' + ), + 'GL' => array( + 'wof:id' => 85633217, + 'wof:name' => 'Greenland' + ), + 'KZ' => array( + 'wof:id' => 85632307, + 'wof:name' => 'Kazakhstan' + ), + 'AR' => array( + 'wof:id' => 85632505, + 'wof:name' => 'Argentina' + ), + 'IN' => array( + 'wof:id' => 85632469, + 'wof:name' => 'India' + ), + 'DZ' => array( + 'wof:id' => 85632451, + 'wof:name' => 'Algeria' + ), + 'CD' => array( + 'wof:id' => 85632643, + 'wof:name' => 'Democratic Republic of the Congo' + ), + 'MN' => array( + 'wof:id' => 85632439, + 'wof:name' => 'Mongolia' + ), + 'MX' => array( + 'wof:id' => 85633293, + 'wof:name' => 'Mexico' + ), + 'SA' => array( + 'wof:id' => 85632253, + 'wof:name' => 'Saudi Arabia' + ), + 'SD' => array( + 'wof:id' => 85632751, + 'wof:name' => 'Sudan' + ), + 'IR' => array( + 'wof:id' => 85632361, + 'wof:name' => 'Iran' + ), + 'ID' => array( + 'wof:id' => 85632203, + 'wof:name' => 'Indonesia' + ), + 'LY' => array( + 'wof:id' => 85632627, + 'wof:name' => 'Libya' + ), + 'ZA' => array( + 'wof:id' => 85633813, + 'wof:name' => 'South Africa' + ), + 'TD' => array( + 'wof:id' => 85632325, + 'wof:name' => 'Chad' + ), + 'ML' => array( + 'wof:id' => 85632553, + 'wof:name' => 'Mali' + ), + 'PE' => array( + 'wof:id' => 85632521, + 'wof:name' => 'Peru' + ), + 'AO' => array( + 'wof:id' => 85632281, + 'wof:name' => 'Angola' + ), + 'NE' => array( + 'wof:id' => 85632269, + 'wof:name' => 'Niger' + ), + 'ET' => array( + 'wof:id' => 85632257, + 'wof:name' => 'Ethiopia' + ), + 'CO' => array( + 'wof:id' => 85632519, + 'wof:name' => 'Colombia' + ), + 'BO' => array( + 'wof:id' => 85632623, + 'wof:name' => 'Bolivia' + ), + 'MR' => array( + 'wof:id' => 85632679, + 'wof:name' => 'Mauritania' + ), + 'EG' => array( + 'wof:id' => 85632581, + 'wof:name' => 'Egypt' + ), + 'NO' => array( + 'wof:id' => 85633341, + 'wof:name' => 'Norway' + ), + 'PK' => array( + 'wof:id' => 85632659, + 'wof:name' => 'Pakistan' + ), + 'TR' => array( + 'wof:id' => 85632393, + 'wof:name' => 'Turkey' + ), + 'CL' => array( + 'wof:id' => 85633057, + 'wof:name' => 'Chile' + ), + 'SE' => array( + 'wof:id' => 85633789, + 'wof:name' => 'Sweden' + ), + 'TZ' => array( + 'wof:id' => 85632227, + 'wof:name' => 'Tanzania' + ), + 'NG' => array( + 'wof:id' => 85632735, + 'wof:name' => 'Nigeria' + ), + 'VE' => array( + 'wof:id' => 85632317, + 'wof:name' => 'Venezuela' + ), + 'UA' => array( + 'wof:id' => 85633805, + 'wof:name' => 'Ukraine' + ), + 'NA' => array( + 'wof:id' => 85632535, + 'wof:name' => 'Namibia' + ), + 'FR' => array( + 'wof:id' => 85633147, + 'wof:name' => 'France' + ), + 'MZ' => array( + 'wof:id' => 85632729, + 'wof:name' => 'Mozambique' + ), + 'ZM' => array( + 'wof:id' => 85632559, + 'wof:name' => 'Zambia' + ), + 'AF' => array( + 'wof:id' => 85632229, + 'wof:name' => 'Afghanistan' + ), + 'FI' => array( + 'wof:id' => 85633143, + 'wof:name' => 'Finland' + ), + 'MM' => array( + 'wof:id' => 85632181, + 'wof:name' => 'Myanmar' + ), + 'MA' => array( + 'wof:id' => 85632693, + 'wof:name' => 'Morocco' + ), + 'ES' => array( + 'wof:id' => 85633129, + 'wof:name' => 'Spain' + ), + 'SS' => array( + 'wof:id' => 85632657, + 'wof:name' => 'South Sudan' + ), + 'MG' => array( + 'wof:id' => 85632223, + 'wof:name' => 'Madagascar' + ), + 'CF' => array( + 'wof:id' => 85632391, + 'wof:name' => 'Central African Republic' + ), + 'BW' => array( + 'wof:id' => 85632235, + 'wof:name' => 'Botswana' + ), + 'TM' => array( + 'wof:id' => 85632671, + 'wof:name' => 'Turkmenistan' + ), + 'UZ' => array( + 'wof:id' => 85632645, + 'wof:name' => 'Uzbekistan' + ), + 'KE' => array( + 'wof:id' => 85632329, + 'wof:name' => 'Kenya' + ), + 'DE' => array( + 'wof:id' => 85633111, + 'wof:name' => 'Germany' + ), + 'TH' => array( + 'wof:id' => 85632293, + 'wof:name' => 'Thailand' + ), + 'PL' => array( + 'wof:id' => 85633723, + 'wof:name' => 'Poland' + ), + 'SO' => array( + 'wof:id' => 85632379, + 'wof:name' => 'Somalia' + ), + 'IQ' => array( + 'wof:id' => 85632191, + 'wof:name' => 'Iraq' + ), + 'YE' => array( + 'wof:id' => 85632499, + 'wof:name' => 'Yemen' + ), + 'JP' => array( + 'wof:id' => 85632429, + 'wof:name' => 'Japan' + ), + 'PG' => array( + 'wof:id' => 85632347, + 'wof:name' => 'Papua New Guinea' + ), + 'CM' => array( + 'wof:id' => 85632245, + 'wof:name' => 'Cameroon' + ), + 'PY' => array( + 'wof:id' => 85632355, + 'wof:name' => 'Paraguay' + ), + 'GB' => array( + 'wof:id' => 85633159, + 'wof:name' => 'United Kingdom' + ), + 'ZW' => array( + 'wof:id' => 85632243, + 'wof:name' => 'Zimbabwe' + ), + 'IT' => array( + 'wof:id' => 85633253, + 'wof:name' => 'Italy' + ), + 'NZ' => array( + 'wof:id' => 85633345, + 'wof:name' => 'New Zealand' + ), + 'XX' => array( + 'wof:id' => 1126113567, + 'wof:name' => 'Socialist Federal Republic of Yugoslavia' + ), + 'XX' => array( + 'wof:id' => 1108955789, + 'wof:name' => 'Kingdom of Yugoslavia' + ), + 'BY' => array( + 'wof:id' => 85632395, + 'wof:name' => 'Belarus' + ), + 'CG' => array( + 'wof:id' => 85632541, + 'wof:name' => 'Republic of Congo' + ), + 'VN' => array( + 'wof:id' => 85632763, + 'wof:name' => 'Vietnam' + ), + 'RO' => array( + 'wof:id' => 85633745, + 'wof:name' => 'Romania' + ), + 'MY' => array( + 'wof:id' => 85632739, + 'wof:name' => 'Malaysia' + ), + 'OM' => array( + 'wof:id' => 85632207, + 'wof:name' => 'Oman' + ), + 'CI' => array( + 'wof:id' => 85632449, + 'wof:name' => 'Ivory Coast' + ), + 'PH' => array( + 'wof:id' => 85632509, + 'wof:name' => 'Philippines' + ), + 'BF' => array( + 'wof:id' => 85632213, + 'wof:name' => 'Burkina Faso' + ), + 'KG' => array( + 'wof:id' => 85632761, + 'wof:name' => 'Kyrgyzstan' + ), + 'GA' => array( + 'wof:id' => 85632407, + 'wof:name' => 'Gabon' + ), + 'EC' => array( + 'wof:id' => 85632261, + 'wof:name' => 'Ecuador' + ), + 'GN' => array( + 'wof:id' => 85632691, + 'wof:name' => 'Guinea' + ), + 'XX' => array( + 'wof:id' => 1108955787, + 'wof:name' => 'Socialist Federal Republic of Yugoslavia' + ), + 'LA' => array( + 'wof:id' => 85632241, + 'wof:name' => 'Laos' + ), + 'UG' => array( + 'wof:id' => 85632625, + 'wof:name' => 'Uganda' + ), + 'GH' => array( + 'wof:id' => 85632189, + 'wof:name' => 'Ghana' + ), + 'IS' => array( + 'wof:id' => 85633249, + 'wof:name' => 'Iceland' + ), + 'SY' => array( + 'wof:id' => 85632413, + 'wof:name' => 'Syria' + ), + 'XX' => array( + 'wof:id' => 1108955785, + 'wof:name' => 'Socialist Federal Republic of Yugoslavia' + ), + 'UY' => array( + 'wof:id' => 85632511, + 'wof:name' => 'Uruguay' + ), + 'SN' => array( + 'wof:id' => 85632365, + 'wof:name' => 'Senegal' + ), + 'GY' => array( + 'wof:id' => 85632397, + 'wof:name' => 'Guyana' + ), + 'TN' => array( + 'wof:id' => 85632703, + 'wof:name' => 'Tunisia' + ), + 'KH' => array( + 'wof:id' => 85632359, + 'wof:name' => 'Cambodia' + ), + 'TJ' => array( + 'wof:id' => 85632513, + 'wof:name' => 'Tajikistan' + ), + 'GR' => array( + 'wof:id' => 85633171, + 'wof:name' => 'Greece' + ), + 'XS' => array( + 'wof:id' => 85632733, + 'wof:name' => 'Somaliland' + ), + 'NP' => array( + 'wof:id' => 85632465, + 'wof:name' => 'Nepal' + ), + 'KP' => array( + 'wof:id' => 85632639, + 'wof:name' => 'North Korea' + ), + 'BD' => array( + 'wof:id' => 85632475, + 'wof:name' => 'Bangladesh' + ), + 'BG' => array( + 'wof:id' => 85633001, + 'wof:name' => 'Bulgaria' + ), + 'SR' => array( + 'wof:id' => 85632443, + 'wof:name' => 'Suriname' + ), + 'XX' => array( + 'wof:id' => 1108955783, + 'wof:name' => 'Federal Republic of Yugoslavia' + ), + 'HU' => array( + 'wof:id' => 85633237, + 'wof:name' => 'Hungary' + ), + 'NI' => array( + 'wof:id' => 85632599, + 'wof:name' => 'Nicaragua' + ), + 'ER' => array( + 'wof:id' => 85632781, + 'wof:name' => 'Eritrea' + ), + 'AT' => array( + 'wof:id' => 85632785, + 'wof:name' => 'Austria' + ), + 'KR' => array( + 'wof:id' => 85632231, + 'wof:name' => 'South Korea' + ), + 'MW' => array( + 'wof:id' => 85632383, + 'wof:name' => 'Malawi' + ), + 'CZ' => array( + 'wof:id' => 85633105, + 'wof:name' => 'Czech Republic' + ), + 'CU' => array( + 'wof:id' => 85632675, + 'wof:name' => 'Cuba' + ), + 'PT' => array( + 'wof:id' => 85633735, + 'wof:name' => 'Portugal' + ), + 'LV' => array( + 'wof:id' => 85633279, + 'wof:name' => 'Latvia' + ), + 'BJ' => array( + 'wof:id' => 85632247, + 'wof:name' => 'Benin' + ), + 'HN' => array( + 'wof:id' => 85632323, + 'wof:name' => 'Honduras' + ), + 'IE' => array( + 'wof:id' => 85633241, + 'wof:name' => 'Ireland' + ), + 'GT' => array( + 'wof:id' => 85632385, + 'wof:name' => 'Guatemala' + ), + 'LT' => array( + 'wof:id' => 85633269, + 'wof:name' => 'Lithuania' + ), + 'AZ' => array( + 'wof:id' => 85632717, + 'wof:name' => 'Azerbaijan' + ), + 'RS' => array( + 'wof:id' => 85633755, + 'wof:name' => 'Serbia' + ), + 'JO' => array( + 'wof:id' => 85632425, + 'wof:name' => 'Jordan' + ), + 'EH' => array( + 'wof:id' => 85632217, + 'wof:name' => 'Western Sahara' + ), + 'LR' => array( + 'wof:id' => 85632249, + 'wof:name' => 'Liberia' + ), + 'GE' => array( + 'wof:id' => 85633163, + 'wof:name' => 'Georgia' + ), + 'EE' => array( + 'wof:id' => 85633135, + 'wof:name' => 'Estonia' + ), + 'GF' => array( + 'wof:id' => 85632233, + 'wof:name' => 'French Guiana' + ), + 'HR' => array( + 'wof:id' => 85633229, + 'wof:name' => 'Croatia' + ), + 'AE' => array( + 'wof:id' => 85632573, + 'wof:name' => 'United Arab Emirates' + ), + 'PA' => array( + 'wof:id' => 85632179, + 'wof:name' => 'Panama' + ), + 'DK' => array( + 'wof:id' => 85633121, + 'wof:name' => 'Denmark' + ), + 'SK' => array( + 'wof:id' => 85633769, + 'wof:name' => 'Slovakia' + ), + 'SL' => array( + 'wof:id' => 85632467, + 'wof:name' => 'Sierra Leone' + ), + 'BA' => array( + 'wof:id' => 85632609, + 'wof:name' => 'Bosnia and Herzegovina' + ), + 'NL' => array( + 'wof:id' => 85633337, + 'wof:name' => 'Netherlands' + ), + 'LK' => array( + 'wof:id' => 85632313, + 'wof:name' => 'Sri Lanka' + ), + 'CH' => array( + 'wof:id' => 85633051, + 'wof:name' => 'Switzerland' + ), + 'TG' => array( + 'wof:id' => 85632647, + 'wof:name' => 'Togo' + ), + 'CR' => array( + 'wof:id' => 85632487, + 'wof:name' => 'Costa Rica' + ), + 'DO' => array( + 'wof:id' => 85632713, + 'wof:name' => 'Dominican Republic' + ), + 'MD' => array( + 'wof:id' => 85633287, + 'wof:name' => 'Moldova' + ), + 'BE' => array( + 'wof:id' => 85632997, + 'wof:name' => 'Belgium' + ), + 'BT' => array( + 'wof:id' => 85632171, + 'wof:name' => 'Bhutan' + ), + 'TW' => array( + 'wof:id' => 85632403, + 'wof:name' => 'Taiwan' + ), + 'AM' => array( + 'wof:id' => 85632773, + 'wof:name' => 'Armenia' + ), + 'AL' => array( + 'wof:id' => 85632405, + 'wof:name' => 'Albania' + ), + 'LS' => array( + 'wof:id' => 85632173, + 'wof:name' => 'Lesotho' + ), + 'GW' => array( + 'wof:id' => 85632757, + 'wof:name' => 'Guinea Bissau' + ), + 'MK' => array( + 'wof:id' => 85632373, + 'wof:name' => 'Macedonia' + ), + 'SB' => array( + 'wof:id' => 85632591, + 'wof:name' => 'Solomon Islands' + ), + 'SI' => array( + 'wof:id' => 85633779, + 'wof:name' => 'Slovenia' + ), + 'HT' => array( + 'wof:id' => 85632433, + 'wof:name' => 'Haiti' + ), + 'GQ' => array( + 'wof:id' => 85632287, + 'wof:name' => 'Equatorial Guinea' + ), + 'BI' => array( + 'wof:id' => 85632285, + 'wof:name' => 'Burundi' + ), + 'RW' => array( + 'wof:id' => 85632303, + 'wof:name' => 'Rwanda' + ), + 'IL' => array( + 'wof:id' => 85632315, + 'wof:name' => 'Israel' + ), + 'BZ' => array( + 'wof:id' => 85632571, + 'wof:name' => 'Belize' + ), + 'DJ' => array( + 'wof:id' => 85632319, + 'wof:name' => 'Djibouti' + ), + 'SV' => array( + 'wof:id' => 85632545, + 'wof:name' => 'El Salvador' + ), + 'FJ' => array( + 'wof:id' => 85632755, + 'wof:name' => 'Fiji' + ), + 'KW' => array( + 'wof:id' => 85632401, + 'wof:name' => 'Kuwait' + ), + 'SZ' => array( + 'wof:id' => 85632635, + 'wof:name' => 'Swaziland' + ), + 'ME' => array( + 'wof:id' => 85632667, + 'wof:name' => 'Montenegro' + ), + 'TL' => array( + 'wof:id' => 85632583, + 'wof:name' => 'East Timor' + ), + 'XK' => array( + 'wof:id' => 85633259, + 'wof:name' => 'Kosovo' + ), + 'BS' => array( + 'wof:id' => 85632339, + 'wof:name' => 'The Bahamas' + ), + 'VU' => array( + 'wof:id' => 85632263, + 'wof:name' => 'Vanuatu' + ), + 'QA' => array( + 'wof:id' => 85632299, + 'wof:name' => 'Qatar' + ), + 'LB' => array( + 'wof:id' => 85632533, + 'wof:name' => 'Lebanon' + ), + 'JM' => array( + 'wof:id' => 85632215, + 'wof:name' => 'Jamaica' + ), + 'GM' => array( + 'wof:id' => 85632603, + 'wof:name' => 'Gambia' + ), + 'PS' => array( + 'wof:id' => 85633739, + 'wof:name' => 'Palestine' + ), + 'CY' => array( + 'wof:id' => 85632437, + 'wof:name' => 'Cyprus' + ), + 'BN' => array( + 'wof:id' => 85632749, + 'wof:name' => 'Brunei' + ), + 'TT' => array( + 'wof:id' => 85632271, + 'wof:name' => 'Trinidad and Tobago' + ), + 'CV' => array( + 'wof:id' => 85632721, + 'wof:name' => 'Cape Verde' + ), + 'LU' => array( + 'wof:id' => 85633275, + 'wof:name' => 'Luxembourg' + ), + 'RE' => array( + 'wof:id' => 85632351, + 'wof:name' => 'Reunion' + ), + 'WS' => array( + 'wof:id' => 85632681, + 'wof:name' => 'Samoa' + ), + 'MU' => array( + 'wof:id' => 85632357, + 'wof:name' => 'Mauritius' + ), + 'GP' => array( + 'wof:id' => 85632423, + 'wof:name' => 'Guadeloupe' + ), + 'KM' => array( + 'wof:id' => 85632259, + 'wof:name' => 'Comoros' + ), + 'MQ' => array( + 'wof:id' => 85632531, + 'wof:name' => 'Martinique' + ), + 'HK' => array( + 'wof:id' => 85632483, + 'wof:name' => 'Hong Kong S.A.R.' + ), + 'KI' => array( + 'wof:id' => 85632709, + 'wof:name' => 'Kiribati' + ), + 'IM' => array( + 'wof:id' => 85632461, + 'wof:name' => 'Isle of Man' + ), + 'ST' => array( + 'wof:id' => 85632765, + 'wof:name' => 'Sao Tome and Principe' + ), + 'FM' => array( + 'wof:id' => 85632431, + 'wof:name' => 'Federated States of Micronesia' + ), + 'TO' => array( + 'wof:id' => 85632455, + 'wof:name' => 'Tonga' + ), + 'DM' => array( + 'wof:id' => 85632503, + 'wof:name' => 'Dominica' + ), + 'BH' => array( + 'wof:id' => 85632167, + 'wof:name' => 'Bahrain' + ), + 'LC' => array( + 'wof:id' => 85632369, + 'wof:name' => 'Saint Lucia' + ), + 'AD' => array( + 'wof:id' => 85632343, + 'wof:name' => 'Andorra' + ), + 'SG' => array( + 'wof:id' => 85632605, + 'wof:name' => 'Singapore' + ), + 'PW' => array( + 'wof:id' => 85632331, + 'wof:name' => 'Palau' + ), + 'SC' => array( + 'wof:id' => 85632661, + 'wof:name' => 'Seychelles' + ), + 'AG' => array( + 'wof:id' => 85632529, + 'wof:name' => 'Antigua and Barbuda' + ), + 'CW' => array( + 'wof:id' => 85632441, + 'wof:name' => 'Curacao' + ), + 'BB' => array( + 'wof:id' => 85632491, + 'wof:name' => 'Barbados' + ), + 'VC' => array( + 'wof:id' => 85632569, + 'wof:name' => 'Saint Vincent and the Grenadines' + ), + 'YT' => array( + 'wof:id' => 85632523, + 'wof:name' => 'Mayotte' + ), + 'MT' => array( + 'wof:id' => 85633331, + 'wof:name' => 'Malta' + ), + 'GD' => array( + 'wof:id' => 85632335, + 'wof:name' => 'Grenada' + ), + 'PM' => array( + 'wof:id' => 85632371, + 'wof:name' => 'Saint Pierre and Miquelon' + ), + 'AN' => array( + 'wof:id' => 85632727, + 'wof:name' => 'Netherlands' + ), + 'MV' => array( + 'wof:id' => 85632305, + 'wof:name' => 'Maldives' + ), + 'KN' => array( + 'wof:id' => 85632551, + 'wof:name' => 'Saint Kitts and Nevis' + ), + 'MH' => array( + 'wof:id' => 85632663, + 'wof:name' => 'Marshall Islands' + ), + 'LI' => array( + 'wof:id' => 85633267, + 'wof:name' => 'Liechtenstein' + ), + 'JE' => array( + 'wof:id' => 85632593, + 'wof:name' => 'Jersey' + ), + 'AW' => array( + 'wof:id' => 85632295, + 'wof:name' => 'Aruba' + ), + 'CC' => array( + 'wof:id' => 85632495, + 'wof:name' => 'Indian Ocean Territories' + ), + 'GG' => array( + 'wof:id' => 85632547, + 'wof:name' => 'Guernsey' + ), + 'SM' => array( + 'wof:id' => 85633763, + 'wof:name' => 'San Marino' + ), + 'TV' => array( + 'wof:id' => 85632607, + 'wof:name' => 'Tuvalu' + ), + 'SX' => array( + 'wof:id' => 85632185, + 'wof:name' => 'Sint Maarten' + ), + 'NR' => array( + 'wof:id' => 85632747, + 'wof:name' => 'Nauru' + ), + 'MO' => array( + 'wof:id' => 85632161, + 'wof:name' => 'Macao S.A.R' + ), + 'MC' => array( + 'wof:id' => 85633285, + 'wof:name' => 'Monaco' + ), + 'VA' => array( + 'wof:id' => 85632187, + 'wof:name' => 'Vatican' + ), + 'UN' => array( + 'wof:id' => 102312305, + 'wof:name' => 'United Nations' + ), + 'XN' => array( + 'wof:id' => 1, + 'wof:name' => 'Null Island' + ), + ); + + # the end \ No newline at end of file diff --git a/www/include/lib_whosonfirst_existential.php b/www/include/lib_whosonfirst_existential.php new file mode 100644 index 0000000..2f90e7a --- /dev/null +++ b/www/include/lib_whosonfirst_existential.php @@ -0,0 +1,82 @@ + 0){ + return 1; + } + else { + return 0; + } + } + + ######################################################################## + + function whosonfirst_existential_is_superseding($place){ + + if (isset($place['wof:supersedes']) && + count($place['wof:supersedes']) > 0){ + return 1; + } + else { + return 0; + } + } + + # the end diff --git a/www/include/lib_whosonfirst_pip.php b/www/include/lib_whosonfirst_pip.php index d9756d7..e3209a7 100644 --- a/www/include/lib_whosonfirst_pip.php +++ b/www/include/lib_whosonfirst_pip.php @@ -2,28 +2,56 @@ loadlib("http"); + # see also: + # https://github.com/whosonfirst/go-whosonfirst-pip-v2 + ######################################################################## function whosonfirst_pip_get_by_latlon($lat, $lon, $more=array()){ - $defaults = array( - "placetype" => null, - ); - - $more = array_merge($defaults, $more); - $query = array( "latitude" => $lat, "longitude" => $lon, ); - if ($pt = $more["placetype"]){ - $query["placetype"] = $pt; + $query = array_merge($query, $more); + $query = http_build_query($query); + + $endpoint = whosonfirst_pip_endpoint(); + $url = $endpoint . "?" . $query; + + $rsp = http_get($url); + + if (! $rsp["ok"]){ + return $rsp; + } + + $data = json_decode($rsp["body"], "as hash"); + + # because an empty array is "false" in php... (20170127/thisisaaronland) + + if ((! $data) && (! is_array($data))){ + return array("ok" => 0, "error" => "Failed to parse response"); } + $rows = $data["places"]; + + return array("ok" => 1, "rows" => $rows); + } + + ######################################################################## + + function whosonfirst_pip_get_by_polyline($polyline, $more=array()){ + + $query = array( + "polyline" => $polyline, + ); + + $query = array_merge($query, $more); $query = http_build_query($query); - $url = $GLOBALS["cfg"]["whosonfirst_pip_endpoint"] . "?{$query}"; + $endpoint = whosonfirst_pip_endpoint(); + $url = $endpoint . "/polyline?" . $query; $rsp = http_get($url); @@ -39,7 +67,27 @@ function whosonfirst_pip_get_by_latlon($lat, $lon, $more=array()){ return array("ok" => 0, "error" => "Failed to parse response"); } - return array("ok" => 1, "rows" => $data); + $rows = $data["places"]; + $pagination = $data["pagination"]; + + return array("ok" => 1, "rows" => $rows, "pagination" => $pagination); + } + + ######################################################################## + + function whosonfirst_pip_endpoint(){ + + # deprecated + + if (! isset($GLOBALS["cfg"]["whosonfirst_pip_endpoints"])){ + return $GLOBALS["cfg"]["whosonfirst_pip_endpoint"]; + } + + $possible = $GLOBALS["cfg"]["whosonfirst_pip_endpoints"]; + shuffle($possible); + shuffle($possible); + + return $possible[0]; } ######################################################################## diff --git a/www/include/lib_whosonfirst_places.php b/www/include/lib_whosonfirst_places.php index 0245791..24387d3 100644 --- a/www/include/lib_whosonfirst_places.php +++ b/www/include/lib_whosonfirst_places.php @@ -4,6 +4,8 @@ loadlib("elasticsearch"); loadlib("elasticsearch_spelunker"); + loadlib("whosonfirst_countries"); + loadlib("whosonfirst_existential"); ######################################################################## @@ -41,7 +43,7 @@ function whosonfirst_places_get_by_id($id, $more=array()){ function whosonfirst_places_get_by_id_multi($ids, $more=array()){ - return elasticsearch_spelunker_mget($ids, $more); + return elasticsearch_spelunker_mget($ids, $more); } ######################################################################## @@ -116,7 +118,7 @@ function whosonfirst_places_search($q, $filters, $more=array()){ else { $esc_q = elasticsearch_escape($q); - + $query = array( 'match' => array( '_all' => array( 'operator' => 'and', @@ -220,6 +222,11 @@ function whosonfirst_places_get_tagged($tag, $filters, $more=array()){ $esc_tag = elasticsearch_escape($tag); + $defaults = array( + 'per_page' => 36 + ); + $more = array_merge($defaults, $more); + $query = array("match" => array( "wof:tags" => $esc_tag )); @@ -235,12 +242,60 @@ function whosonfirst_places_get_tagged($tag, $filters, $more=array()){ ######################################################################## + function whosonfirst_places_get_by_brand(&$brand, $filters, $more=array()){ + + $query = array('term' => array( + # 'wof:brand_id' => $brand["wof:brand_id"], + 'wof:placetype' => 'venue' + )); + + $filter_query = array('filtered' => array( + 'query' => $query, + 'filter' => array('and' => $filters), + )); + + $functions = array( + array( + 'filter' => array('term' => array('mz:is_current' => 1)), + 'weight' => 2.0 + ), + array( + 'filter' => array('term' => array('mz:is_current' => -1)), + 'weight' => 0.5 + ), + ); + + $es_query = array('function_score' => array( + 'query' => $filter_query, + 'functions' => $functions, + 'boost_mode' => 'multiply', + 'score_mode' => 'multiply', + )); + + $req = array( + 'query' => $es_query, + ); + + $rsp = elasticsearch_spelunker_search($req, $more); + return $rsp; + } + + ######################################################################## + + function whosonfirst_places_get_brands($more=array()){ + + $rsp = elasticsearch_spelunker_facet("wof:brand_id", $more); + return $rsp; + } + + ######################################################################## + function whosonfirst_places_property($place, $path){ $property = null; foreach (explode(".", $path) as $p){ - + if (! isset($place[$p])){ return null; } @@ -257,6 +312,118 @@ function whosonfirst_places_property($place, $path){ ######################################################################## + function whosonfirst_places_placetype_pronoun($place) { + + $an_placetypes = array( + 'address', + 'empire', + 'intersection', + 'ocean' + ); + if (in_array($place['wof:placetype'], $an_placetypes)) { + return 'an'; + } else { + return 'a'; + } + + } + + ######################################################################## + + function whosonfirst_places_country_link($place) { + + $code = strtoupper($place['iso:country']); + $country = $GLOBALS['whosonfirst_countries'][$code]; + + if ($country) { + $esc_id = htmlspecialchars($country['wof:id']); + $esc_name = htmlspecialchars($country['wof:name']); + $url = $GLOBALS['cfg']['abs_root_url'] . "id/$esc_id/"; + return "$esc_name"; + } else { + return $code; + } + + } + + ######################################################################## + + function whosonfirst_places_search_referer_url() { + + // This is used to link back to search results from id.php. + // We'll inspect the HTTP Referer header and if it looks exactly + // like a search results URL, we reconstruct our own version + // of it using a whitelist of acceptable query args. + // If not, we return null. (20170927/dphiffer) + + $referer = $_SERVER['HTTP_REFERER']; + $referer_url = parse_url($referer); + $referer_query = array(); + parse_str($referer_url['query'], $referer_query); + + $allowable_args = array( + 'q', + 'scope', + 'page' + ); + + $args = array(); + if ($referer_query) { + foreach ($referer_query as $arg => $val) { + if (in_array($arg, $allowable_args)) { + $args[$arg] = $val; + } + } + } + + if (preg_match('/^\/search\/?$/', $referer_url['path']) && + $args) { + $query = http_build_query($args); + $search_url = $GLOBALS['cfg']['abs_root_url'] . "search/?$query"; + return $search_url; + } + + return null; + + } + + ######################################################################## + + function whosonfirst_places_currentness($place){ + + if (whosonfirst_existential_is_current($place) == 1){ + return 'current'; + } + else if (whosonfirst_existential_is_ceased($place) == 1){ + return 'ceased'; + } + else if (whosonfirst_existential_is_superseded($place) == 1){ + return 'superseded'; + } + else if (whosonfirst_existential_is_deprecated($place) == 1){ + return 'deprecated'; + } + return 'unknown'; + } + + ######################################################################## + + function whosonfirst_places_format_time($time){ + + if (preg_match('/^(\d\d):(\d\d)$/', $time, $matches)){ + $hh = intval($matches[1]); + $mm = $matches[2]; + if ($hh > 12){ + return ($hh - 12) . ":{$mm}pm"; + } else { + return "$hh:{$mm}am"; + } + } + return $time; + } + + ######################################################################## + function whosonfirst_places_url_for_place($place){ $enc_id = urlencode($place["wof:id"]); @@ -265,6 +432,14 @@ function whosonfirst_places_url_for_place($place){ ######################################################################## + function whosonfirst_places_nearby_url_for_place($place){ + + $enc_id = urlencode($place["wof:id"]); + return $GLOBALS["cfg"]["abs_root_url"] . "nearby/{$enc_id}/"; + } + + ######################################################################## + function whosonfirst_places_data_url_for_place($place){ loadlib("whosonfirst_uri"); @@ -273,4 +448,19 @@ function whosonfirst_places_data_url_for_place($place){ ######################################################################## - # the end \ No newline at end of file + function whosonfirst_places_coordinate($place, $coord){ + + $property = null; + + if ($place["lbl:$coord"]) { + $property = $place["lbl:$coord"]; + } else if ($place["geom:$coord"]) { + $property = $place["geom:$coord"]; + } + + return $property; + } + + ######################################################################## + + # the end diff --git a/www/include/lib_whosonfirst_placetypes_spec.php b/www/include/lib_whosonfirst_placetypes_spec.php index 3be00e7..c7dd45a 100644 --- a/www/include/lib_whosonfirst_placetypes_spec.php +++ b/www/include/lib_whosonfirst_placetypes_spec.php @@ -4,13 +4,13 @@ ######################################################################## - # this file was also generated by robots on 2017-08-25T11:37:14.373786 + # this file was also generated by robots on 2017-11-17T13:33:51.910472 # https://github.com/whosonfirst/flamework-whosonfirst/blob/master/utils/mk-spec.py # https://github.com/whosonfirst/flamework-whosonfirst/blob/master/Makefile ######################################################################## - $GLOBALS['whosonfirst_placetypes']['__SPEC__'] = '{"102312321": {"role": "optional", "name": "microhood", "parent": [102312319], "names": {}}, "421205763": {"role": "common_optional", "name": "borough", "parent": [102312317, 404221409], "names": {}}, "102312325": {"role": "common_optional", "name": "venue", "parent": [102312327, 102312329, 1108906905, 102312331, 102312321, 102312319], "names": {}}, "102312327": {"role": "common_optional", "name": "building", "parent": [102312329, 1108906905, 102312331, 102312321, 102312319], "names": {}}, "102312329": {"role": "common_optional", "name": "address", "parent": [1108906905, 102312331, 102312321, 102312319], "names": {}}, "102312331": {"role": "common_optional", "name": "campus", "parent": [102312321, 102312319, 102312323, 102312317, 404221409], "names": {}}, "404528653": {"role": "common_optional", "name": "ocean", "parent": [102312341], "names": {}}, "102312335": {"role": "common_optional", "name": "empire", "parent": [102312309], "names": {}}, "102312323": {"role": "optional", "name": "macrohood", "parent": [421205763, 102312317], "names": {}}, "102312341": {"role": "common_optional", "name": "planet", "parent": [], "names": {}}, "1108906905": {"role": "common_optional", "name": "intersection", "parent": [102312331, 102312321, 102312319], "names": {}}, "470996387": {"role": "common_optional", "name": "postalcode", "parent": [102312317, 404221409, 102312313, 102312311], "names": {}}, "1108746739": {"role": "common_optional", "name": "constituency", "parent": [], "names": {}}, "102320821": {"role": "common_optional", "name": "dependency", "parent": [102312307], "names": {}}, "136057795": {"role": "common_optional", "name": "timezone", "parent": [102312307, 102312309, 102312341], "names": {}}, "404528655": {"role": "common_optional", "name": "marinearea", "parent": [102312307, 102312309, 102312341], "names": {}}, "102371933": {"role": "optional", "name": "metroarea", "parent": [], "names": {}}, "404221409": {"role": "common_optional", "name": "localadmin", "parent": [102312313, 102312311], "names": {}}, "404221411": {"role": "optional", "name": "macroregion", "parent": [102320821, 102322043, 102312307], "names": {}}, "404221413": {"role": "optional", "name": "macrocounty", "parent": [102312311], "names": {}}, "102312307": {"role": "common", "name": "country", "parent": [102312309, 102312335], "names": {}}, "102312309": {"role": "common", "name": "continent", "parent": [102312341], "names": {}}, "102312311": {"role": "common", "name": "region", "parent": [404221411, 102320821, 102322043, 102312307], "names": {}}, "102312313": {"role": "common_optional", "name": "county", "parent": [404221413, 102312311], "names": {}}, "102322043": {"role": "common_optional", "name": "disputed", "parent": [102312307], "names": {}}, "102312317": {"role": "common", "name": "locality", "parent": [404221409, 102312313, 102312311], "names": {}}, "102312319": {"role": "common", "name": "neighbourhood", "parent": [102312323, 421205763, 102312317], "names": {"eng_p": ["neighbourhood", "neighborhood"]}}}'; + $GLOBALS['whosonfirst_placetypes']['__SPEC__'] = '{"102312321": {"role": "optional", "name": "microhood", "parent": [102312319], "names": {}}, "421205763": {"role": "common_optional", "name": "borough", "parent": [102312317, 404221409], "names": {}}, "102312325": {"role": "common_optional", "name": "venue", "parent": [102312327, 102312329, 1108906905, 102312331, 102312321, 102312319], "names": {}}, "102312327": {"role": "common_optional", "name": "building", "parent": [102312329, 1108906905, 102312331, 102312321, 102312319], "names": {}}, "102312329": {"role": "common_optional", "name": "address", "parent": [1108906905, 102312331, 102312321, 102312319], "names": {}}, "102312331": {"role": "common_optional", "name": "campus", "parent": [102312321, 102312319, 102312323, 102312317, 404221409], "names": {}}, "404528653": {"role": "common_optional", "name": "ocean", "parent": [102312341], "names": {}}, "102312335": {"role": "common_optional", "name": "empire", "parent": [102312309], "names": {}}, "102312323": {"role": "optional", "name": "macrohood", "parent": [421205763, 102312317], "names": {}}, "102312341": {"role": "common_optional", "name": "planet", "parent": [], "names": {}}, "1108906905": {"role": "common_optional", "name": "intersection", "parent": [102312331, 102312321, 102312319], "names": {}}, "470996387": {"role": "common_optional", "name": "postalcode", "parent": [102312317, 404221409, 102312313, 102312311], "names": {}}, "1108746739": {"role": "common_optional", "name": "constituency", "parent": [], "names": {}}, "102320821": {"role": "common_optional", "name": "dependency", "parent": [102312335], "names": {}}, "136057795": {"role": "common_optional", "name": "timezone", "parent": [102312307, 102312309, 102312341], "names": {}}, "404528655": {"role": "common_optional", "name": "marinearea", "parent": [102312307, 102312309, 102312341], "names": {}}, "102371933": {"role": "optional", "name": "metroarea", "parent": [], "names": {}}, "404221409": {"role": "common_optional", "name": "localadmin", "parent": [102312313, 102312311], "names": {}}, "404221411": {"role": "optional", "name": "macroregion", "parent": [102320821, 102322043, 102312307], "names": {}}, "404221413": {"role": "optional", "name": "macrocounty", "parent": [102312311], "names": {}}, "102312307": {"role": "common", "name": "country", "parent": [102312309, 102312335], "names": {}}, "102312309": {"role": "common", "name": "continent", "parent": [102312341], "names": {}}, "102312311": {"role": "common", "name": "region", "parent": [404221411, 102320821, 102322043, 102312307], "names": {}}, "102312313": {"role": "common_optional", "name": "county", "parent": [404221413, 102312311], "names": {}}, "102322043": {"role": "common_optional", "name": "disputed", "parent": [102312307], "names": {}}, "102312317": {"role": "common", "name": "locality", "parent": [404221409, 102312313, 102312311], "names": {}}, "102312319": {"role": "common", "name": "neighbourhood", "parent": [102312323, 421205763, 102312317], "names": {"eng_p": ["neighbourhood", "neighborhood"]}}}'; ######################################################################## # the end diff --git a/www/include/lib_whosonfirst_sources_spec.php b/www/include/lib_whosonfirst_sources_spec.php index b275207..a911f9d 100644 --- a/www/include/lib_whosonfirst_sources_spec.php +++ b/www/include/lib_whosonfirst_sources_spec.php @@ -4,13 +4,13 @@ ######################################################################## - # this file was also generated by robots on 2017-08-25T11:37:14.577672 + # this file was also generated by robots on 2017-11-17T13:33:53.973970 # https://github.com/whosonfirst/flamework-whosonfirst/blob/master/utils/mk-spec.py # https://github.com/whosonfirst/flamework-whosonfirst/blob/master/Makefile ######################################################################## - $GLOBALS['whosonfirst_sources']['__SPEC__'] = '{"1108728833": {"name": "oulugov", "license": "http://www.ouka.fi/oulu/oulu-tietoa/kayttoehdot", "url": "http://www.ouka.fi/oulu/oulu-tietoa/avoin-data-aineisto", "license_text": "The license allows you to share, copy and distribute the material remains in any medium and in the form of, and Modify, combine and edit the material and create the basis for new materials.", "prefix": "oulugov", "key": "", "license_type": "CC BY 4.0", "fullname": "City of Oulu", "id": 1108728833, "description": "Official website for the City of Oulu, Finland."}, "1108839435": {"name": "Austria Open Data", "license": "http://creativecommons.org/licenses/by/3.0/at/", "url": "https://www.data.gv.at/katalog/dataset/c33d36b0-f184-4f2a-89cc-839ca7fcf88a", "license_text": "The data in our catalog are freely available under CC BY 3.0 or CC0 license. The catalog can be sorted according to topic areas. The exact data guidelines can be found in the individual data sets.", "prefix": "austriaod", "key": "id", "license_type": "CC BY 3.0", "fullname": "Austria Open Data", "id": 1108839435, "description": ""}, "1108830733": {"name": "geom", "license": "CC0", "url": "", "prefix": "geom", "key": "id", "fullname": "geom", "id": 1108830733, "description": "Property prefix."}, "1024497679": {"name": "lacity", "license": "https://data.lacity.org/A-Well-Run-City/Neighborhood-Councils-Certified-/fu65-dz2f/about", "url": "https://data.lacity.org/A-Well-Run-City/Neighborhood-Councils-Certified-/fu65-dz2f", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "lacity", "key": "", "license_type": "CC0", "fullname": "City of Los Angeles Neighborhood Councils (Certified)", "id": 1024497679, "description": "Official Certified Neighborhood Council boundaries in the City of Los Angeles created and maintained by the Bureau of Engineering / GIS Mapping Division."}, "1108794385": {"name": "baltomoit", "license": "https://data.baltimorecity.gov/Geographic/Baltimore-Study-Area/cdrh-gpzc/about", "url": "https://data.baltimorecity.gov/Geographic/Baltimore-Study-Area/cdrh-gpzc", "license_text": "THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE (\'CCPL\' OR \'LICENSE\'). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.", "prefix": "baltomoit", "key": "", "license_type": "Attribution 3.0 Unported", "fullname": "Baltimore Mayor\'s Office of Information Technology", "id": 1108794385, "description": "City of Baltimore Open Data Portal. This website is operated by the Mayor and City Council of Baltimore (the \'City\') and the data is provided as a service to the public."}, "1108833305": {"name": "torsdfa", "license": "http://www1.toronto.ca/wps/portal/contentonly?vgnextoid=4a37e03bb8d1e310VgnVCM10000071d60f89RCRD", "url": "http://www1.toronto.ca/wps/portal/contentonly?vgnextoid=04b489fe9c18b210VgnVCM1000003dd60f89RCRD&vgnextchannel=75d6e03bb8d1e310VgnVCM10000071d60f89RCRD", "license_text": "You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", "prefix": "torsdfa", "key": "", "license_type": "Open Government Licence, Ontario, v1.0", "fullname": "Toronto Social Development, Finance & Administration Department", "id": 1108833305, "description": "Open Data portal for Toronto, ON."}, "1108726815": {"name": "hkigis", "license": "http://www.hri.fi/dataset/paakaupunkiseudun-aluejakokartat", "url": "http://www.hel2.fi/tietokeskus/data/kartta_aineistot/PKS_Kartta_Rajat_KML2011.zip", "license_text": "You are free to: Share, copy and redistribute the material in any medium or format and Adapt, remix, transform, and build upon the material for any purpose, even commercially.", "prefix": "hkigis", "key": "", "license_type": "CC BY 4.0", "fullname": "Helsinki City Real Estate Department", "id": 1108726815, "description": "HRI is a web service for fast and easy access to open data sources between the cities of Helsinki, Espoo, Vantaa and Kauniainen."}, "1108828507": {"name": "name", "license": "N/A", "url": "", "license_text": "", "prefix": "name", "key": "id", "license_type": "CC0", "fullname": "name", "id": 1108828507, "description": "Property prefix."}, "1108830757": {"name": "unknown", "license": "N/A", "url": "", "license_text": "", "prefix": "unknown", "key": "id", "license_type": "", "fullname": "unknown", "id": 1108830757, "description": "Unknown."}, "1108963891": {"name": "can-calcai", "license": "https://data.calgary.ca/stories/s/u45n-7awa", "url": "https://data.calgary.ca/Base-Maps/Community-Boundaries/ab7m-fwn6", "license_text": "Copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose...Acknowledge the source of the Information by including any attribution statement specified by the Information Provider(s) and, where possible, provide a link to this license.", "prefix": "can-calcai", "key": "", "license_type": "Open Government License - City of Calgary", "fullname": "City of Calgary, Corporate Analytics and Innovation", "id": 1108963891, "description": "Community boundary data generated by the City of Calgary Department of Corporate Analytics and Innovation for use in community planning."}, "1108725001": {"name": "frgov", "license": "https://www.data.gouv.fr/en/terms/", "url": "https://www.data.gouv.fr/en/datasets/fond-de-carte-des-codes-postaux/", "license_text": "The Open License is part of an international context and is compatible with the standards of open data licenses developed abroad, in particular those of the Government of the United Kingdom (Open Government License) and other international standards (ODC-BY, CC-BY 2.0).", "prefix": "frgov", "key": "id", "license_type": "CC BY 2.0", "fullname": "Open Data France", "id": 1108725001, "description": "Open platform for French public data."}, "404734191": {"name": "zetashapes", "license": "http://www.zetashapes.com/license", "url": "http://www.zetashapes.com", "license_text": "The polygons generated by this site do not have any added restrictions beyond the base data from tiger and flickr. The basic source data is from US TIGER/Line Census Data which is public domain (Q10). This site also makes use of data scraped from the flickr api -- you should probably mention on your site if you reuse this data that there is flickr data associated with it.", "remarks": "https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/zetashapes_remarks.md", "prefix": "zs", "key": "id", "license_type": "Public domain", "fullname": "Zetashapes", "id": 404734191, "description": "Zetashapes is an experiment in crowdsourced US neighborhood polygons."}, "823312445": {"name": "atgov", "license": "http://creativecommons.org/licenses/by/3.0/at/", "url": "https://www.data.gv.at", "license_text": "You are free to Share, copy and redistribute the material in any medium or format. Adapt, remix, transform, and build upon the material for any purpose, even commercially. The licensor cannot revoke these freedoms as long as you follow the license terms.", "prefix": "atgov", "key": "", "license_type": "CC BY 3.0", "fullname": "data.gv.at", "id": 823312445, "description": ""}, "1108739789": {"name": "uscensus", "license": "https://www.census.gov/data/developers/about/terms-of-service.html", "data_sources": [{"default": "https://www.census.gov/cgi-bin/geo/shapefiles/index.php", "alt-uscensus-display-terrestrial-zoom-10": "http://www2.census.gov/geo/tiger/GENZ2015/shp/cb_2015_us_state_500k.zip"}], "url": "https://www.census.gov/", "license_text": "All U.S. Census Bureau materials, regardless of the media, are entirely in the public domain. There are no user fees, site licenses, or any special agreements etc for the public or private use, and or reuse of any census title. As tax funded product, it\'s all in the public record.", "prefix": "uscensus", "key": "", "alt": [{"function": "display", "extras": ["scope", "detail"]}], "license_type": "CC0", "fullname": "United States Census Bureau", "id": 1108739789, "description": "The leading source of quality data about the nation\'s people and economy from the United States Census Bureau."}, "1141961795": {"name": "lieu", "license": "", "url": "https://github.com/openvenues/lieu", "prefix": "lieu", "key": "guid", "fullname": "lieu", "id": 1141961795, "description": "Property prefix."}, "1108974149": {"name": "can-abog", "license": "https://open.alberta.ca/documentation/ogp-licence", "url": "https://open.alberta.ca/opendata/property-municipal-boundaries", "license_text": "Copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose...Acknowledge the source of the Information by including any attribution statement specified by the Information Provider(s) and, where possible, provide a link to this licence...", "prefix": "can-abog", "key": "", "license_type": "Open Government Licence - Alberta", "fullname": "Alberta Open Government - Municipal Boundaries", "id": 1108974149, "description": "Open municipal boundary data provided by the Alberta Open Government program."}, "1108969549": {"name": "arg-caba", "license": "https://data.buenosaires.gob.ar/tyc", "url": "https://data.buenosaires.gob.ar/dataset/barrios", "license_text": "La reutilizaci\u00f3n autorizada puede incluir la copia, difusi\u00f3n, modificaci\u00f3n, adaptaci\u00f3n, extracci\u00f3n, reordenamiento y combinaci\u00f3n de la informaci\u00f3n contenida en el sitio ... Debe citarse la fuente de los documentos objeto de la reutilizaci\u00f3n.", "prefix": "arg-caba", "key": "", "license_type": "CC BY", "fullname": "Ciudad Aut\u00f3noma de Buenos Aires, Iniciativa de Datos P\u00fablicos y Transparencia", "id": 1108969549, "description": "Open Data portal for the City of Buenos Aires, Argentina."}, "874455653": {"name": "seagv", "license": "https://data.seattle.gov/data-policy", "url": "https://data.seattle.gov/dataset/data-seattle-gov-GIS-shapefile-datasets/f7tb-rnup", "license_text": "The Open Data Program makes the data generated by the City of Seattle openly available to the public.", "prefix": "seagv", "key": "", "license_type": "Public Domain", "fullname": "Seattle City GIS Program", "id": 874455653, "description": "Official data portal for the City of Seattle, WA."}, "1108797031": {"name": "atldpcd", "license": "https://www.arcgis.com/home/item.html?id=716f417a1990446389ef7fd2c381d09f", "url": "http://dpcd.coaplangis.opendata.arcgis.com/datasets/neighborhoods", "license_text": "Share, copy and redistribute the material in any medium or format. Adapt, remix, transform, and build upon the material for any purpose, even commercially.", "prefix": "atldpcd", "key": "", "license_type": "CC BY 4.0", "fullname": "Atlanta Department of Planning and Community Development", "id": 1108797031, "description": "Neighborhoods within the City of Atlanta."}, "1108952683": {"name": "outgoing", "license": "N/A", "url": "http://outgoingnyc.com/", "license_text": "Data is assumed to be in the Public Domain.", "prefix": "out", "key": "", "license_type": "Public Domain (assumed)", "fullname": "OUTgoing", "id": 1108952683, "description": "OUTgoing: The Hidden History of New York\'s Gay Nightlife by Jeff Ferzoco."}, "1108784751": {"name": "sjp", "license": "http://www.sanjoseca.gov/DocumentCenter/View/55954", "url": "https://www.sanjoseca.gov/DocumentCenter/View/11287", "license_text": "Data made open and freely available to the public to be republished, manipulated, or used in any other way without restriction.", "prefix": "sjp", "key": "", "license_type": "CC0", "fullname": "San Jose Planning Department", "id": 1108784751, "description": "The City of San Jose, CA\'s Planning Department website."}, "1108973687": {"name": "thelist", "license": "http://www.calweb.net/~skoepke/", "url": "http://www.calweb.net/~skoepke/", "license_text": "Public domain per email conversation on May 30th, 2017.", "prefix": "thelist", "key": "", "license_type": "Public Domain", "fullname": "The List - Bay Area Concert Guide", "id": 1108973687, "description": "The list is an online concert guide for Northern California and the west coast."}, "1108970625": {"name": "quattroshapes_pg", "license": "https://github.com/foursquare/quattroshapes/blob/master/LICENSE.md", "url": "http://www.quattroshapes.com/", "license_text": "Please include attribution in your app, site, or printed work.", "prefix": "qs_pg", "key": "", "license_type": "CC BY 2.0", "fullname": "Quattroshapes Point Gazetteer", "id": 1108970625, "description": "The Quattroshapes point gazetteer. A big list of point locations that supplements the polygons gazetteer."}, "1108800107": {"name": "stpaulgov", "license": "https://information.stpaul.gov/City-Administration/Establishing-an-Open-Information-Program-Resolutio/v7qy-vtzb", "url": "https://information.stpaul.gov/City-Administration/District-Council-Shapefile-Map/dq4n-yj8b", "license_text": "The City shall develop and implement practices allowing it to prioritize the proactive release of high quality, machine-readable, disclosable city data, making it freely available via an open license without restrictions on use, reuse, or redistribution, ensuring it is fully accessible to the broadest range of users possible.", "prefix": "stpaulgov", "key": "", "license_type": "CC0 (assumed)", "fullname": "Open Information Saint Paul", "id": 1108800107, "description": "The Open Information portal for the Saint Paul, MN government."}, "1108694665": {"name": "bra", "license": "https://data.cityofboston.gov/City-Services/Boston-Neighborhood-Shapefiles/af56-j7tb", "url": "https://data.cityofboston.gov/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "bra", "key": "", "license_type": "CC0", "fullname": "Boston Redevelopment Authority", "id": 1108694665, "description": "Neighborhood boundaries are created based on zip code, zoning district boundaries and census tract boundaries. This GIS data layer was produced by the BRA Office of Digital Cartography and GIS."}, "1126109975": {"name": "can-gatsudd", "license": "http://www3.gatineau.ca/Infoterritoire/WebInterface/help/fr/Content/1_About/1_About_FR.htm", "url": "http://www3.gatineau.ca/Infoterritoire/WebInterface/views/index.aspx", "license_text": "Confirmed open source availability by Maurin Dabbadie of the Gatineau Department of Planning and Sustainable Development on 2017-06-07 .", "prefix": "can-gatsudd", "key": "", "license_type": "CC BY equivalent", "fullname": "Gatineau Service de l\'urbanisme et du developpement durable (SUDD)", "id": 1126109975, "description": "Community portrait data created by the city of Gatineau for use in planning and sustainable development (Data provided by request from )."}, "1108962957": {"name": "latimes", "license": "http://www.tronc.com/central-terms-of-service/", "url": "http://www.latimes.com/", "license_text": "If you operate a Web site and wish to link to the Site, you may do so provided you agree to cease such link upon request from us. No other use is permitted without prior written permission of tronc.", "prefix": "latimes", "key": "id", "license_type": "Restricted", "fullname": "Los Angeles Times", "id": 1108962957, "description": "The Los Angeles Times."}, "1158784149": {"name": "lacity_oof", "license": "", "url": "https://data.lacity.org/A-Prosperous-City/Listing-of-Active-Businesses/6rrh-rzua", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "lacity_oof", "key": "id", "license_type": "CC0", "fullname": "City of Los Angeles Office of Finance", "id": 1158784149, "description": ""}, "1158784151": {"name": "companieshouse", "license": "", "url": "https://data.london.gov.uk/dataset/directory-of-london-businesses", "license_text": "", "prefix": "companieshouse", "key": "number", "license_type": "", "fullname": "City of London Companies House", "id": 1158784151, "description": ""}, "907219099": {"name": "zolk", "license": "http://chicagomap.zolk.com/about.html", "url": "http://chicagomap.zolk.com/", "license_text": "The resulting KML source data is licensed under a Creative Commons Attribution License. This means that you\'re free to use the data from this map as you wish, but credit to either Kevin Zolkiewicz or this web site is appreciated.", "prefix": "zolk", "key": "", "license_type": "CC BY 3.0 US", "fullname": "Zolk Chicago Neighborhoods Map", "id": 907219099, "description": "An overlay of boundaries for Chicago\'s 228 neighborhoods."}, "656342179": {"name": "nycgov", "license": "http://legistar.council.nyc.gov/ViewReport.ashx?M=R&N=Text&GID=61&ID=1090992&GUID=B1263195-66B9-48AD-A381-57584D623443&Title=Legislation+Text", "url": "https://data.cityofnewyork.us/", "license_text": "Such public data sets shall be made available without any registration requirement, license requirement or restrictions on their use provided that the department may require a third party providing to the public any public data set, or application utilizing such data set, to explicitly identify the source and version of the public data set, and a description of any modifications made to such public data set.", "prefix": "nycgov", "key": "id", "license_type": "CC0 (assumed)", "fullname": "NYC OpenData", "id": 656342179, "description": "Open Data portal for New York City, NY."}, "1108732585": {"name": "nolagis", "license": "https://data.nola.gov/Geographic-Base-Layers/Neighborhoods/92zg-wzkq", "url": "https://data.nola.gov/Geographic-Base-Layers/Neighborhoods/92zg-wzkq", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "nolagis", "key": "", "license_type": "CC0", "fullname": "City of New Orleans, Office of Information Technology and Innovation, Enterprise Information Team", "id": 1108732585, "description": "Open Data portal for the City of New Orleans, LA."}, "1108748977": {"name": "denvercpd", "license": "https://www.denvergov.org/opendata/termsofuse", "url": "https://www.denvergov.org/opendata/dataset/city-and-county-of-denver-statistical-neighborhoods", "license_text": "You are free to: Share, copy and redistribute the material in any medium or format. Adapt, remix, transform, and build upon the material for any purpose, even commercially. The licensor cannot revoke these freedoms as long as you follow the license terms.", "prefix": "denvercpd", "key": "", "license_type": "CC BY 3.0", "fullname": "Denver Department of Community Planning and Development", "id": 1108748977, "description": "Open Data portal for the City of Denver, CO."}, "1108804789": {"name": "cbsnl", "license": "https://data.overheid.nl/data/dataset/wijk-en-buurtkaart-2016-versie-1", "url": "https://data.overheid.nl/data/dataset/wijk-en-buurtkaart-2016-versie-1/resource/7f32452a-f035-4a23-bce9-1972f5189beb", "license_text": "With this license, a re-user is free to share, copy, distribute and transmit the dataset through any medium or file format. The dataset may be edited and may be used for commercial purposes. A reference to the creator of the data is required.", "prefix": "cbsnl", "key": "", "license_type": "CC BY 3.0", "fullname": "Centraal Bureau voor de Statistiek", "id": 1108804789, "description": "This data portal consists of a register containing information about and references to data sets by Dutch authorities."}, "772974267": {"name": "sfgov", "license": "https://data.sfgov.org/terms-of-use", "url": "https://data.sfgov.org/", "license_text": "The Open Data Commons, Public Domain Dedication & Licence is a document intended to allow you to freely share, modify, and use this work for any purpose and without any restrictions. This licence is intended for use on databases or their contents (\'data\'), either together or individually.", "prefix": "sfgov", "key": "", "license_type": "PDDL 1.0", "fullname": "City of San Francisco", "id": 772974267, "description": "Open Data portal for the City of San Francisco, CA."}, "1126113989": {"name": "can-saskodp", "license": "http://opendata-saskatoon.cloudapp.net/TermsOfUse/TermsOfUse", "url": "http://opendata-saskatoon.cloudapp.net/DataBrowser/SaskatoonOpenDataCatalogueBeta/NeighbourhoodArea#param=NOFILTER--DataView--Results", "license_text": "...a broad license to use the currently published data on the City of Saskatoon website (\u201cInformation\u201d) for your own analysis and applications...appreciate credit for provision of the Information, this is not a strict requirement.", "prefix": "can-saskodp", "key": "", "license_type": "CC0 equivalent", "fullname": "City of Saskatoon Open Data Portal - Neighbourhood Areas", "id": 1126113989, "description": "Neighbourhood regions provided by the city of Saskatoon, used for demographic purposes."}, "1108960969": {"name": "nycgov_subway", "license": "http://legistar.council.nyc.gov/ViewReport.ashx?M=R&N=Text&GID=61&ID=1090992&GUID=B1263195-66B9-48AD-A381-57584D623443&Title=Legislation+Text", "url": "https://data.cityofnewyork.us/Transportation/Subway-Stations/arq3-7z49", "license_text": "Such public data sets shall be made available without any registration requirement, license requirement or restrictions on their use provided that the department may require a third party providing to the public any public data set, or application utilizing such data set, to explicitly identify the source and version of the public data set, and a description of any modifications made to such public data set.", "prefix": "nycgov_subway", "key": "objectid", "license_type": "CC0 (assumed)", "fullname": "NYC OpenData - Subway Stations", "id": 1108960969, "description": "Open Data portal for New York City, NY."}, "1108960971": {"name": "can-lvlsu", "license": "https://www.donneesquebec.ca/fr/licence/#cc-by", "url": "https://www.donneesquebec.ca/recherche/fr/dataset/limites-des-anciennes-municipalites", "license_text": "This license allows other people to distribute, remix, arrange and adapt your work, even for commercial purposes, as long as you are credited with the original creation by quoting your name.", "prefix": "can-lvlsu", "key": "", "license_type": "CC BY", "fullname": "Laval Service de l\'urbanisme", "id": 1108960971, "description": "The collaborative crossroads in Quebec open data."}, "1108721357": {"name": "azavea", "license": "https://www.opendataphilly.org/dataset/philadelphia-neighborhoods", "url": "https://www.opendataphilly.org/dataset/philadelphia-neighborhoods/resource/06e8d380-821f-44ce-8718-a0f2f7902318", "license_text": "You are free to: Share, copy and redistribute the material in any medium or format. Adapt, remix, transform, and build upon the material for any purpose, even commercially.", "prefix": "azavea", "key": "", "license_type": "CC BY 3.0 US", "fullname": "Azavea, Inc.", "id": 1108721357, "description": "Azavea is a civic technology firm based in Philadelphia. Azavea applies geospatial technology for civic and social impact."}, "1108955855": {"name": "lbl", "license": "CC0", "url": "", "prefix": "lbl", "key": "id", "fullname": "label", "id": 1108955855, "description": ""}, "1108728529": {"name": "tkugov", "license": "http://www.lounaistieto.fi/blog/2015/08/18/turun-palvelualuejakotilastoalueet/", "url": "http://opendata.lounaistieto.fi/aineistoja/Turku_pienalueet.zip", "license_text": "You are free to: Share - copy and redistribute the material in any medium or format and Adapt - remix, transform, and build upon the material for any purpose, even commercially.", "prefix": "tkugov", "key": "", "license_type": "CC BY 4.0", "fullname": "Turku City Government", "id": 1108728529, "description": "Open Data portal for the City of Turku, Finland."}, "1126129879": {"name": "can-vicodc", "license": "http://www.victoria.ca/EN/main/online-services/open-data-catalogue/open-data-licence.html", "url": "http://www.victoria.ca/EN/main/online-services/open-data-catalogue.html", "license_text": "Copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose...Acknowledge the source of the Information by including any attribution statement specified by the Information Provider and, where possible, provide a link to this licence.", "prefix": "can-vicodc", "key": "", "license_type": "Open Government Licence \u2013 City of Victoria", "fullname": "City of Victoria Open Data Catalogue", "id": 1126129879, "description": "Neighbourhood boundary data provided by the City of Victoria Open Data Catalogue."}, "1108906615": {"name": "vanpds", "license": "http://vancouver.ca/your-government/open-data-catalogue.aspx#tab19099", "url": "http://data.vancouver.ca/datacatalogue/localAreaBoundary.htm", "license_text": "you are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", "prefix": "vanpds", "key": "", "license_type": "Open Government Licence, British Columbia, v2.0", "fullname": "Vancouver Planning and Development Services", "id": 1108906615, "description": "Open Data portal for the City of Vancouver."}, "404734173": {"name": "edtf", "license": "https://www.loc.gov/legal/", "url": "http://loc.gov/standards/datetime/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "edtf", "key": "", "license_type": "CC0 1.0 Universal", "fullname": "Extended Date/Time Format", "id": 404734173, "description": "Property prefix. This website describes the current effort to develop a reasonably comprehensive date/time definition for the bibliographic community, as well as other interested communities, and submitting it for standardization or some other mode of formalization, for example a W3C note or an amendment to ISO 8601."}, "404734175": {"name": "geonames", "license": "http://www.geonames.org/about.html", "url": "http://www.geonames.org/", "license_text": "The GeoNames geographical database is available for download free of charge under a creative commons attribution license.", "remarks": "https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/geonames_remarks.md", "prefix": "gn", "key": "id", "license_type": "CC BY", "fullname": "GeoNames", "id": 404734175, "description": "The GeoNames geographical database covers all countries and contains over eleven million placenames that are available for download free of charge."}, "907131617": {"name": "pedia", "license": "http://catalog.opendata.city/dataset/pediacities-nyc-neighborhoods/resource/91778048-3c58-449c-a3f9-365ed203e914", "url": "http://catalog.opendata.city/dataset/pediacities-nyc-neighborhoods", "license_text": "Subject to the terms and conditions of this License, the Licensor grants to You a worldwide, royalty-free, non-exclusive, terminable (but only under Section 9) license to Use the Database for the duration of any applicable copyright and Database Rights.", "prefix": "pedia", "key": "", "license_type": "ODC-By, v1.0", "fullname": "Pediacities", "id": 907131617, "description": "An open dataset of administrative areas in New York City."}, "404734179": {"name": "naturalearth", "license": "http://www.naturalearthdata.com/about/terms-of-use/", "url": "http://www.naturalearthdata.com/", "license_text": "No permission is needed to use Natural Earth. Crediting the authors is unnecessary.", "remarks": "https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/naturalearth_remarks.md", "prefix": "ne", "key": "", "license_type": "Public Domain (assumed)", "fullname": "Natural Earth", "id": 404734179, "description": "Natural Earth is a public domain map dataset available at 1:10m, 1:50m, and 1:110 million scales, which features tightly integrated vector and raster data."}, "404734181": {"name": "ourairports", "license": "http://ourairports.com/", "url": "http://ourairports.com/data/", "license_text": "OurAirports is a public site, and by \'public\', we mean PUBLIC.", "remarks": "https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/ourairports_remarks.md", "prefix": "oa", "key": "id", "license_type": "Public domain", "fullname": "OurAirports", "id": 404734181, "description": "OurAirports is a free site where visitors can explore the world\'s airports. [...] This is an open-data web site, after all, and we don\'t believe that \'open\' means \'we can benefit from it, but we\'ll hide it from everyone else."}, "404734183": {"name": "quattroshapes", "license": "https://github.com/foursquare/quattroshapes/blob/master/LICENSE.md", "url": "http://www.quattroshapes.com/", "license_text": "Please include attribution in your app, site, or printed work.", "remarks": "https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/quattroshapes_remarks.md", "prefix": "qs", "key": "id", "license_type": "CC BY 2.0", "fullname": "Quattroshapes", "id": 404734183, "description": "A gazetteer of non-overlapping, authoritative polygons around a curated list of places. Quattroshapes includes open data from government and other sources, many of which require attribution. See [remarks](https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/quattroshapes_remarks.md) for detail."}, "1108968171": {"name": "can-wpgppd", "license": "https://data.winnipeg.ca/open-data-licence", "url": "https://data.winnipeg.ca/City-Planning/Neighbourhood/fen6-iygi", "license_text": "Copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose...Acknowledge the source of the Information by including any attribution statement specified by the Information Provider(s) and, where possible, provide a link to this licence.", "prefix": "can-wpgppd", "key": "", "license_type": "Open Government License - Winnipeg", "fullname": "City of Winnipeg Department of Planning, Property, and Development", "id": 1108968171, "description": "Neighbourhood planning districts provided by the City of Winnipeg on their open data portal."}, "404734189": {"name": "wikipedia", "license": "https://en.wikipedia.org/wiki/Wikipedia:Copyrights", "url": "http://www.wikipedia.org/", "license_text": "Most of Wikipedia\'s text and many of its images are co-licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License (CC BY-SA) and the GNU Free Documentation License (GFDL) (unversioned, with no invariant sections, front-cover texts, or back-cover texts).", "prefix": "wk", "key": "page", "license_type": "CC BY-SA 3.0", "fullname": "Wikipedia", "id": 404734189}, "857075439": {"name": "foursquare", "license": "https://foursquare.com/legal/terms", "url": "http://www.foursquare.com", "license_text": "Subject to these Terms of Use, Foursquare grants each user of the Site and/or Service a worldwide, non-exclusive, non-sublicensable and non-transferable license to use, modify and reproduce the Content, solely for personal, non-commercial use.", "prefix": "4sq", "key": "id", "license_type": "CC BY", "fullname": "Foursquare", "id": 857075439, "description": "A search-and-discovery service that compiles a database of locations and places worldwide."}, "1108794097": {"name": "oakced", "license": "https://data.oaklandnet.com/Property/Oakland-Neighborhoods/7zky-kcq9/about", "url": "https://data.oaklandnet.com/Property/Oakland-Neighborhoods/7zky-kcq9", "license_text": "", "prefix": "oakced", "key": "", "license_type": "Public Domain", "fullname": "Oakland Community and Economic Development Department", "id": 1108794097, "description": "Open Data portal for the City of Oakland, CA."}, "404734195": {"name": "mapshaper", "license": "http://mozilla.org/MPL/2.0/", "url": "https://github.com/mbloch/mapshaper", "license_text": "This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.", "prefix": "ms", "key": "", "license_type": "MPL, v2.0", "fullname": "Mapshaper", "id": 404734195, "description": "Mapshaper is software for editing Shapefile, GeoJSON, TopoJSON and several other data formats, written in JavaScript."}, "404734197": {"name": "mapzen", "license": "https://mapzen.com/terms/", "url": "https://www.mapzen.com/", "license_text": "Subject to these Terms, Mapzen hereby grants to you a non-exclusive, non-transferable, non-sublicensable license during the Term to: (i) copy and use the Tools solely to develop products and services to be made available by you (\'Your Products\'), and to distribute elements of the Tools as incorporated into Your Products; (ii) use and access the Services as provided by Mapzen subject to the Rate Limits; and (iii) if you\'ve ordered Mapzen Data Products, use the Mapzen Data Products for your internal use and only as part of Your Products which are provided directly to end users, and not for resale or for redistribution or use in conjunction with, or as part of, the products or services of others. Except for the foregoing license, Mapzen and its suppliers own all right, title and interest in and to the Services, Tools and Mapzen Data Products, and no other licenses are granted to you, whether express or implied.", "prefix": "mz", "key": "", "license_type": "CC0", "fullname": "Mapzen", "id": 404734197, "description": " Mapzen is an open, sustainable, and accessible mapping platform. Our tools let you display, search, and navigate your world."}, "404734199": {"name": "simplegeo", "license": "https://creativecommons.org/publicdomain/zero/1.0/", "url": "https://www.simplegeo.com", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "sg", "key": "id", "license_type": "CC0", "fullname": "SimpleGeo", "id": 404734199, "description": "SimpleGeo was a location aware services company that operated between 2009 and 2011. It is no longer an active company."}, "404734201": {"name": "yerbashapes", "license": "N/A", "url": "", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "ys", "key": "", "license_type": "CC0", "fullname": "Yerbashapes", "id": 404734201, "description": "Weighted means from Quattroshapes. Yerbashapes are a product of Mapzen for Who\'s On First."}, "404734205": {"name": "burritojustice", "license": "http://burritojustice.com", "url": "http://burritojustice.com/la-lengua/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "bj", "key": "id", "license_type": "CC0", "fullname": "Burrito Justice", "id": 404734205, "description": "Burrito Justice - La Lengua, San Francisco, CA."}, "1108693461": {"name": "ausstat", "license": "http://www.abs.gov.au/websitedbs/D3310114.nsf/Home/%A9+Copyright?opendocument", "url": "http://www.abs.gov.au/AUSSTATS/abs@.nsf/DetailsPage/1270.0.55.003July%202011?OpenDocument", "license_text": "Unless otherwise noted, all material on this website, except the ABS logo, the Commonwealth Coat of Arms, and any material protected by a trade mark, is licensed under a Creative Commons Attribution 2.5 Australia licence.", "prefix": "ausstat", "key": "", "license_type": "CC BY 2.5 AU", "fullname": "Australian Bureau of Statistics", "id": 1108693461, "description": "The ABS is Australia\'s national statistical agency, providing trusted official statistics on a wide range of economic, social, population and environmental matters of importance to Australia."}, "404734209": {"name": "minitenders", "license": "http://www.thebolditalic.com/articles/1101-mini-tenders", "url": "http://www.thebolditalic.com/articles/1101-mini-tenders", "license_text": "Data is assumed to be in the Public Domain.", "prefix": "mt", "key": "id", "license_type": "Public domain (assumed)", "fullname": "Mini Tenders", "id": 404734209, "description": "A Tenderloin of many neighbourhoods."}, "404734211": {"name": "nullisland", "license": "N/A", "url": "http://www.nullisland.com/", "license_text": "", "prefix": "ni", "key": "", "license_type": "", "fullname": "Null Island", "id": 404734211, "description": "Home of Null Island."}, "404734212": {"name": "btvneighborhoods", "license": "http://geosprocket.blogspot.com/2012/10/results-of-burlington-neighborhoods.html", "url": "https://gist.github.com/wboykinm/dfe44481d8ff759c4f1afea223a7c070", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "btv", "key": "id", "license_type": "CC0 equivalent", "fullname": "Burlington VT Neighborhoods Project", "id": 404734212, "description": "Crowdsourced by the locals: http://geosprocket.blogspot.com/2012/10/results-of-burlington-neighborhoods.html"}, "404734213": {"name": "missing", "license": "N/A", "url": "", "license_text": "", "prefix": "xx", "key": "", "license_type": "", "fullname": "Missing", "id": 404734213, "description": "Missing - as in a placeholder for WOF records without a geometry."}, "404734215": {"name": "whosonfirst", "license": "https://github.com/whosonfirst-data/whosonfirst-data/blob/master/LICENSE.md", "url": "http://whosonfirst.mapzen.com/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. Note that some included work is available under CC BY.", "prefix": "wof", "key": "id", "license_type": "CC0", "fullname": "Who\'s On First", "id": 404734215, "description": "Who\'s On First is a gazetteer of places. Not quite all the places in the world but a whole lot of them and, we hope, the kinds of places that we mostly share in common."}, "1108906761": {"name": "can-mtlsmvt", "license": "https://creativecommons.org/licenses/by/4.0/", "url": "http://donnees.ville.montreal.qc.ca/dataset/quartiers", "license_text": "You are free to Share, copy and redistribute the material in any medium or format and Adapt, remix, transform, and build upon the material for any purpose, even commercially. ", "prefix": "can-mtlsmvt", "key": "", "license_type": "CC BY 4.0", "fullname": "Montreal Service de la Mise en Valeur du Territoire", "id": 1108906761, "description": "Open Data portal for the Ville de Montreal."}, "1108906765": {"name": "can-dnvgov", "license": "http://geoweb.dnv.org/data/metadata.php?dataset=RegNeighbourhood", "url": "http://geoweb.dnv.org/Products/Data/SHP/RegNeighbourhood_shp.zip", "license_text": "you are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", "prefix": "can-dnvgov", "key": "", "license_type": "Open Government License, British Columbia, v2.0", "fullname": "District of North Vancouver Government", "id": 1108906765, "description": "Open Data Portal for the District of North Vancouver."}, "1108931861": {"name": "iso", "license": "https://www.iso.org/privacy-and-copyright.html", "url": "http://www.iso.org/", "license_text": "All content on ISO Online is copyright protected. The copyright is owned by ISO. Any use of the content, including copying of it in whole or in part, for example to another Internet site, is prohibited and would require written permission from ISO.", "prefix": "iso", "key": "id", "license_type": "Restricted", "fullname": "International Organization for Standardization", "id": 1108931861, "description": "ISO is an independent, non-governmental international organization with a membership of 163 national standards bodies."}, "1108973847": {"name": "can-ons", "license": "http://neighbourhoodstudy.ca/ons-terms-of-use/", "url": "Data provided by request at http://neighbourhoodstudy.ca/contact/", "license_text": "....publicly available and accessible data...must give ONS credit for each use or reproduction of the datasets...", "prefix": "can-ons", "key": "", "license_type": "CC BY equivalent", "fullname": "Ottawa Neighbourhood Study (ONS)", "id": 1108973847, "description": "Custom neighbourhood data provided by the Ottawa Neighbourhood Study organization for community enrichment."}, "1108962077": {"name": "canvec-hydro", "license": "http://open.canada.ca/en/open-government-licence-canada", "url": "http://open.canada.ca/data/en/dataset/9d96e8c9-22fe-4ad2-b5e8-94a6991b744b", "license_text": "You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", "prefix": "canvec-hydro", "key": "", "license_type": "Open Government Licence, Canada", "fullname": "Natural Resources Canada, CanVec Hydrographic Features", "id": 1108962077, "description": "Datasets can be found under the shapefile or geodatabase directories, sorted by precision and location."}, "420573473": {"name": "unlocode", "license": "http://www.unece.org/cefact/locode/locode_since1981.html", "url": "http://www.unece.org/cefact/locode/welcome.html", "license_text": "UN/LOCODE is freely available to all interested users.", "prefix": "unlc", "key": "id", "license_type": "CC0", "fullname": "UN/LOCODE (United Nations Code for Trade and Transport Locations)", "id": 420573473, "description": "UN/LOCODE is based on a code structure set up by ECLAC and a list of locations originating in ESCAP, developed in UNCTAD in co-operation with transport organisations like IATA and the ICS and with active contributions from national governments and commercial bodies. Note: Who\'s On First concatenates the UN/LOCODE two-character country code and three-character feature code with a deliminator and names the result the \'id\'."}, "1108955939": {"name": "transitland", "license": "https://transit.land/an-open-project/contributor-agreement.html", "url": "https://transit.land/", "license_text": "Mapzen hereby grants to You and You hereby accept a limited, non-exclusive, royalty free, non-transferable, non-sublicensable, freely revocable, worldwide license solely to use the Licensed Material to develop Products.", "prefix": "transitland", "key": "onestop_id", "license_type": "CC0", "fullname": "Transitland", "id": 1108955939, "description": "Transitland brings together many sources of transit data to build a directory of operators and feeds that can be edited by transit enthusiasts and developers."}, "1108914995": {"name": "can-bbygov", "license": "https://www.burnaby.ca/opendata/licence.html", "url": "http://data.burnaby.ca/datasets/0023da089ff746bfb688e2531d1f2beb_9", "license_text": "you are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", "prefix": "can-bbygov", "key": "", "license_type": "Open Government License, British Columbia, v2.0", "fullname": "City of Burnaby GIS Department", "id": 1108914995, "description": "Open Data Portal for Burnaby, B.C."}, "1108827445": {"name": "hasc", "license": "http://www.statoids.com/ihasc.html", "url": "http://www.statoids.com/", "license_text": "CC0 per email with Gwillim Law of Statoids on August 11, 2015.", "prefix": "hasc", "key": "id", "license_type": "CC0", "fullname": "Statoids HASC", "id": 1108827445, "description": "Administrative subdivisions of countries; a comprehensive world reference, 1900 to 1998. Gwillim Law: \'As far as I\'m concerned, HASC codes are in the public domain - to encourage people or organizations to use them for data communication.\'"}, "772975927": {"name": "chgov", "license": "http://data.geo.admin.ch/ch.swisstopo-vd.ortschaftenverzeichnis_plz/", "url": "http://data.geo.admin.ch", "license_text": "The information contained on the websites of the Federal Authorities is made available to the public.", "prefix": "chgov", "key": "", "license_type": "CC0", "fullname": "Swiss Confederation", "id": 772975927, "description": "The Geoportal of the Swiss Federation."}, "772974303": {"name": "sfac", "license": "http://www.sfartscommission.org/terms-use", "url": "http://www.sfartscommission.org/", "license_text": "As a convenience to potential users, the City and County of San Francisco (\'City\') makes a variety of datasets (\'Data\') available for download through this website. Your use of the Data is subject to these terms of use, which constitute a legal agreement between You and the City and County of San Francisco (\'City\'). This legal agreement is referred to as the \'Terms of Use.\'", "prefix": "sfac", "key": "accession_id", "license_type": "CC BY (assumed)", "fullname": "San Francisco Arts Commission", "id": 772974303, "description": "Official website for the San Francisco Arts Commission."}, "1158783297": {"name": "nycgov_dohmh", "license": "http://legistar.council.nyc.gov/ViewReport.ashx?M=R&N=Text&GID=61&ID=1090992&GUID=B1263195-66B9-48AD-A381-57584D623443&Title=Legislation+Text", "url": "https://data.cityofnewyork.us/Health/DOHMH-New-York-City-Restaurant-Inspection-Results/xx67-kt59", "license_text": "Such public data sets shall be made available without any registration requirement, license requirement or restrictions on their use provided that the department may require a third party providing to the public any public data set, or application utilizing such data set, to explicitly identify the source and version of the public data set, and a description of any modifications made to such public data set.", "prefix": "nycgov_dohmh", "key": "camis", "license_type": "CC0 (assumed)", "fullname": "New York City Department of Health and Mental Hygiene", "id": 1158783297, "description": "Open Data portal for New York City, NY."}, "1108962955": {"name": "ebc", "license": "http://142.34.128.33/docs/EBC-Open-Data-Licence.pdf", "url": "http://elections.bc.ca/", "license_text": "You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose", "prefix": "ebc", "key": "id", "license_type": "Elections BC Open Data Licence", "fullname": "Elections BC", "id": 1108962955, "description": "Elections BC is an independent and non-partisan Office of the Legislature, British Colombia."}, "1158783301": {"name": "sfgov_rbl", "license": "https://data.sfgov.org/terms-of-use", "url": "https://data.sfgov.org/", "license_text": "The Open Data Commons, Public Domain Dedication & Licence is a document intended to allow you to freely share, modify, and use this work for any purpose and without any restrictions. This licence is intended for use on databases or their contents (\'data\'), either together or individually.", "prefix": "sfgov_rbl", "key": "id", "license_type": "PDDL 1.0", "fullname": "City of San Francisco Treasurer & Tax Collector\'s Office (Registered Business Locations)", "id": 1158783301, "description": "Open Data portal for the City of San Francisco, CA."}, "404734177": {"name": "geoplanet", "license": "http://developer.yahoo.com/geo/geoplanet/data/", "url": "http://developer.yahoo.com/geo/geoplanet/", "license_text": "This page provides open access to the underlying data under a Creative Commons Attribution license so that you can incorporate WOEIDs and the GeoPlanet hierarchy into your own applications.", "remarks": "https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/geoplanet_remarks.md", "prefix": "gp", "key": "id", "license_type": "CC BY", "fullname": "Yahoo! GeoPlanet", "id": 404734177, "description": "GeoPlanet provides an open, permanent, and intelligent infrastructure for geo-referencing data on the Internet. (Cached, accessed: 2017-05-11, via: https://web.archive.org/web/20111028163611/http://developer.yahoo.com/geo/geoplanet/data/)."}, "1126113619": {"name": "can-rodca", "license": "http://www.regina.ca/residents/open-government/open-government-licence/", "url": "http://open.regina.ca/dataset/community-associations", "license_text": "Copy, modify, publish, translate, adapt, distribute or otherwise use the data sets in any medium, mode or format for any lawful purpose... Acknowledge the source of the Information by including any attribution statement specified by the Information Provider and, where possible, provide a link to this licence.", "prefix": "can-rodca", "key": "", "license_type": "Open Government Licence - City of Regina", "fullname": "City of Regina Open Data - Community Associations", "id": 1126113619, "description": "Boundaries provided by the City of Regina to delineate community associations."}, "1108955989": {"name": "svn-sma", "license": "https://creativecommons.org/licenses/by/2.5/si/legalcode", "url": "http://egp.gu.gov.si/egp/", "license_text": "Licensor in accordance with the terms and conditions of this License grants the user free, nonexclusive, territorial and unlimited (for the duration of the rights stipulated by the Law on copyright) license to exercise the rights at work.", "prefix": "svn-sma", "key": "", "license_type": "CC BY 2.5 SI", "fullname": "Surveying and Mapping Authority of the Republic of Slovenia", "id": 1108955989, "description": "The Surveying and Mapping Authority of the Republic of Slovenia\'s Open Data portal."}, "1108916059": {"name": "can-nwds", "license": "http://opendata.newwestcity.ca/licence", "url": "http://opendata.newwestcity.ca/datasets/neighbourhoods", "license_text": "You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", "prefix": "can-nwds", "key": "", "license_type": "OGL - City of New Westminster", "fullname": "City of New Westminster Development Services Department", "id": 1108916059, "description": "Open Data portal for the City of New Westminster, BC."}, "1108724061": {"name": "wapo", "license": "http://opendatadc.org/dataset/neighborhood-boundaries-217-neighborhoods-washpost-justgrimes", "url": "http://opendatadc.org/dataset/neighborhood-boundaries-217-neighborhoods-washpost-justgrimes", "license_text": "The Creative Commons Attribution license allows re-distribution and re-use of a licensed work on the condition that the creator is appropriately credited.", "prefix": "wapo", "key": "", "license_type": "CC-BY", "fullname": "Washington Post", "id": 1108724061, "description": "A map of neighborhood boundaries in the District of Columbia."}, "840464229": {"name": "fips", "license": "https://www.usa.gov/government-works", "url": "http://www.nist.gov/itl/fips.cfm", "license_text": "United States government creative works, including writing, images, and computer code, are usually prepared by officers or employees of the United States government as part of their official duties. A government work is generally not subject to copyright in the United States and there is generally no copyright restriction on reproduction, derivative works, distribution, performance, or display of a government work.", "prefix": "fips", "key": "code", "license_type": "CC0", "fullname": "Federal Information Processing Standards", "id": 840464229, "description": "The American National Standards Institute (ANSI) operates the National Standards System Network (NSSN). This powerful reference tool provides 24-hour access to over 65,000 references to standards and specifications from the U.S. government, U.S. private sector organizations and international standards organizations."}, "840464241": {"name": "iata", "license": "http://www.iata.org/Pages/terms.aspx", "url": "http://www.iata.org/", "license_text": "All rights are reserved.", "prefix": "iata", "key": "code", "license_type": "Restricted", "fullname": "International Air Transport Association", "id": 840464241, "description": "The International Air Transport Association (IATA) is the trade association for the world\'s airlines, representing some 265 airlines or 83% of total air traffic."}, "840464249": {"name": "icao", "license": "http://www.icao.int/Pages/Disclaimer.aspx", "url": "http://www.icao.int/", "license_text": "ICAO grants permission to Users to visit the Site and to download, preprint and copy the information, documents and materials (collectively, \'Materials\') from the Site for the User\'s personal, non-commercial use, without any right to resell or redistribute them or to compile or create derivative works therefrom, subject to the terms and conditions outlined below, and also subject to more specific restrictions that may apply to specific Material within this Site. ", "prefix": "icao", "key": "code", "license_type": "Restricted", "fullname": "International Civil Aviation Organization", "id": 840464249, "description": "The International Civil Aviation Organization (ICAO) is a UN specialized agency, established by States in 1944 to manage the administration and governance of the Convention on International Civil Aviation (Chicago Convention)."}, "1126115707": {"name": "can-qcodp", "license": "http://donnees.ville.quebec.qc.ca/licence.aspx", "url": "http://donnees.ville.quebec.qc.ca/donne_details.aspx?jdid=9", "license_text": "...copy and redistribute the material in any medium or format...remix, transform, and build upon the material for any purpose, even commercially...You must give appropriate credit, provide a link to the license, and indicate if changes were made.", "prefix": "can-qcodp", "key": "", "license_type": "CC BY 4.0", "fullname": "Quebec City Open Data Portal", "id": 1126115707, "description": "Neighbourhood (district) data provided by Quebec City."}, "1108808939": {"name": "ssuberlin", "license": "http://www.stadtentwicklung.berlin.de/geoinformation/download/nutzIII.pdf", "url": "http://daten.berlin.de/datensaetze?field_category_tid%5B%5D=231", "license_text": "Geodata and geodata services, including associated metadata, shall be used for: All currently known as well as for all future known commercial and not. Commercial use, as far as possible by special. Legal provisions, or contractual or legal rights. Third does not oppose it.", "prefix": "ssuberlin", "key": "", "license_type": "CC0 (assumed)", "fullname": "Senatsverwaltung fur Stadtentwicklung und Umwelt Berlin", "id": 1108808939, "description": "Bezirke (districts) and Ortsteile (localities) provided under an open data license."}, "840464261": {"name": "tgn", "license": "http://opendatacommons.org/licenses/by/1-0/", "url": "https://www.getty.edu/research/tools/vocabularies/tgn/index.html", "license_text": "The Open Data Commons Attribution License is a license agreement intended to allow users to freely share, modify, and use this Database subject only to the attribution requirements set out in Section 4.", "prefix": "tgn", "key": "id", "license_type": "ODC-By v1.0", "fullname": "Getty Thesaurus of Geographic Names", "id": 840464261, "description": "The TGN is an evolving vocabulary, growing and changing thanks to contributions from Getty projects and other institutions."}, "840464273": {"name": "nytimes", "license": "https://www.nytimes.com/content/help/rights/terms/terms-of-service.html", "url": "http://www.nytimes.com/", "license_text": "You may not sublicense, assign or transfer any licenses granted by NYTimes.com, and any attempt at such sublicense, assignment or transfer shall be null and void.", "prefix": "nyt", "key": "id", "license_type": "Restricted", "fullname": "The New York Times", "id": 840464273, "description": "The New York Times."}, "1158783299": {"name": "nycgov_dca", "license": "http://legistar.council.nyc.gov/ViewReport.ashx?M=R&N=Text&GID=61&ID=1090992&GUID=B1263195-66B9-48AD-A381-57584D623443&Title=Legislation+Text", "url": "https://data.cityofnewyork.us/Business/Legally-Operating-Businesses/w7w3-xahh/data", "license_text": "Such public data sets shall be made available without any registration requirement, license requirement or restrictions on their use provided that the department may require a third party providing to the public any public data set, or application utilizing such data set, to explicitly identify the source and version of the public data set, and a description of any modifications made to such public data set.", "prefix": "nycgov_dca", "key": "license", "license_type": "CC0 (assumed)", "fullname": "New York City Department of Consumer Affairs", "id": 1158783299, "description": "Open Data portal for New York City, NY."}, "1108802967": {"name": "amsgis", "license": "https://kaart.amsterdam.nl/datasets", "url": "https://kaart.amsterdam.nl", "license_text": "", "prefix": "amsgis", "key": "", "license_type": "", "fullname": "Amsterdam Open Datakaart", "id": 1108802967, "description": "Layers are viewable from the link in the url field as Buurten (microhoods), Buurtcombinaties (neighbourhoods), and Stadsdelen en Haven (boroughs). Open source information as well as downloadable datasets are available from the link in the license field."}, "840464281": {"name": "dbpedia", "license": "http://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License", "url": "http://dbpedia.org/", "license_text": "You are free to Share, to copy, distribute and transmit the work, and to Remix, to adapt the work for any purpose, even commercially.", "prefix": "dbp", "key": "id", "license_type": "CC BY-SA 3.0 Unported License", "fullname": "DBpedia", "id": 840464281, "description": "Towards a Public Data Infrastructure for a Large, Multilingual, Semantic Knowledge Graph."}, "857004783": {"name": "begov", "license": "http://www.geopunt.be/nl/over-geopunt/disclaimer", "url": "http://www.geopunt.be/download?container=referentiebestand-gemeenten&title=Voorlopig%20referentiebestand%20gemeentegrenzen", "license_text": "The licensee is given the non-exclusive, worldwide right to reuse the product for each legitimate purpose, including reproducing, transmitting, publishing, adapting and commercial exploitation of the product.", "prefix": "begov", "key": "id", "license_type": "Free Open Data License Flanders v.1.0", "fullname": "Voorlopig Referentiebestand Gemeentegrenzen", "id": 857004783, "description": "Geopunt is the central Flesmish gateway to geographic government information. The geoportal makes geographical information accessible to government agencies, citizens, organizations and companies."}, "404734207": {"name": "woedb", "license": "N/A", "url": "http://woe.spum.org/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "woedb", "key": "id", "license_type": "CC0", "fullname": "WOE DB", "id": 404734207, "description": "Clickable database of Where On Earth (woe) ids."}, "840464287": {"name": "freebase", "license": "https://developers.google.com/freebase/", "url": "https://developers.google.com/freebase/", "license_text": "Freebase constitutes a snapshot of the data stored in Freebase and the Schema that structures it, and are provided under the same CC-BY license. The Freebase/Wikidata mappings are provided under the CC0 license.", "prefix": "fb", "key": "id", "license_type": "CC BY", "fullname": "Freebase", "id": 840464287, "description": "Freebase was a large collaborative knowledge base consisting of data composed mainly by its community members. It was an online collection of structured data harvested from many sources, including individual, user-submitted wiki contributions. See also: http://creativecommons.org/licenses/by/2.5/."}, "1108729077": {"name": "kuogov", "license": "https://www.avoindata.fi/data/fi/dataset/kuopion-kaupunginosat", "url": "https://www.avoindata.fi/data/fi/dataset/kuopion-kaupunginosat/resource/6ca89290-3743-4832-9ed6-03d8cf9b2d5f", "license_text": "You are free to: Share, copy and redistribute the material in any medium or format and Adapt, remix, transform, and build upon the material for any purpose, even commercially.", "prefix": "kuogov", "key": "", "license_type": "CC BY 4.0", "fullname": "City of Kuopio", "id": 1108729077, "description": "Official website for the City of Kuopio, Finland."}, "840464293": {"name": "faa", "license": "https://www.usa.gov/government-works", "url": "http://www.faa.gov/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "faa", "key": "code", "license_type": "CC0 1.0 Universal", "fullname": "Federal Aviation Administration", "id": 840464293, "description": "Homepage for the Federal Aviation Administration."}, "404734193": {"name": "factual", "license": "http://factual.com/tos", "url": "https://github.com/Factual/places", "license_text": "All of the information and data made available via the Sites (\'Site Data\') is provided solely to enable you to learn about Factual and the Services. You are not licensed to store, copy, or use any Site Data for any other purpose.", "prefix": "fct", "key": "id", "license_type": "Restricted", "fullname": "Factual", "id": 404734193, "description": "Location data for Mobile Advertising, Developers, and Enterprise solutions."}, "857125801": {"name": "figov", "license": "http://www.maanmittauslaitos.fi/en/professionals/digital-products/datasets-free-charge/open-data-licence.zip", "url": "http://www.maanmittauslaitos.fi/en/digituotteet/municipal-division-finland", "license_text": "", "prefix": "figov", "key": "id", "license_type": "", "fullname": "NLS National Land Survey of Finland", "id": 857125801, "description": ""}, "1108756907": {"name": "meso", "license": "https://github.com/whosonfirst-data/whosonfirst-data/blob/master/LICENSE.md", "url": "https://github.com/whosonfirst-data/whosonfirst-data/blob/master/LICENSE.md", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "remarks": "https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/meso_remarks.md", "prefix": "meso", "key": "", "license_type": "CC0", "fullname": "Mesoshapes", "id": 1108756907, "description": "Mesoshapes are a product of Mapzen for Who\'s On First."}, "840464301": {"name": "loc", "license": "https://www.usa.gov/government-works", "url": "http://www.loc.gov", "license_text": "Most U.S. government creative works such as writing or images are copyright-free.", "prefix": "loc", "key": "id", "license_type": "CC0", "fullname": "Library of Congress", "id": 840464301, "description": "The Library of Congress is the largest library in the world, with millions of books, recordings, photographs, newspapers, maps and manuscripts in its collections. The Library is the main research arm of the U.S. Congress and the home of the U.S. Copyright Office."}, "840464303": {"name": "mapzenborders", "license": "https://mapzen.com/terms/", "url": "https://mapzen.com/data/borders/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "mzb", "key": "id", "license_type": "CC0", "fullname": "Mapzen Borders", "id": 840464303, "description": "Country, region and city boundary data from OpenStreetMap, served monthly until October 2016."}, "1108832191": {"name": "addr", "license": "N/A", "url": "", "license_text": "", "prefix": "addr", "key": "id", "license_type": "N/A", "fullname": "addr", "id": 1108832191, "description": "Property prefix."}, "554867137": {"name": "uszcta", "license": "https://www.census.gov/data/developers/about/terms-of-service.html", "url": "http://www.census.gov/geo/reference/zctas.html", "license_text": "All U.S. Census Bureau materials, regardless of the media, are entirely in the public domain. There are no user fees, site licenses, or any special agreements etc for the public or private use, and or reuse of any census title. As tax funded product, it\'s all in the public record.", "prefix": "uszcta", "key": "id", "license_type": "CC0", "fullname": "US ZIP Code Tabulation Area", "id": 554867137, "description": "ZIP Code Tabulation Areas (ZCTAs) are generalized areal representations of United States Postal Service (USPS) ZIP Code service areas."}, "874342855": {"name": "hsgov", "license": "http://www.hri.fi/en/dataset/helsingin-kaupunginosat", "url": "http://ptp.hel.fi/avoindata/aineistot/Helsingin_kaupunginosat.zip", "license_text": "You are free to: Share, copy and redistribute the material in any medium or format and Adapt, remix, transform, and build upon the material for any purpose, even commercially.", "prefix": "hsgov", "key": "id", "license_type": "CC BY 4.0", "fullname": "Helsinki Region Infoshare", "id": 874342855, "description": "HRI is a web service for fast and easy access to open data sources between the cities of Helsinki, Espoo, Vantaa and Kauniainen."}, "554906275": {"name": "statcan", "license": "http://www.statcan.gc.ca/eng/reference/licence-eng", "url": "http://statcan.gc.ca/", "license_text": "Subject to this agreement, Statistics Canada grants you a worldwide, royalty-free, non-exclusive licence to: use, reproduce, publish, freely distribute, or sell the Information; use, reproduce, publish, freely distribute, or sell Value-added Products; and, sublicence any or all such rights, under terms consistent with this agreement.", "prefix": "statcan", "key": "", "license_type": "CC-BY (assumed)", "fullname": "Statistics Canada", "id": 554906275, "description": "Statistics Canada produces statistics that help Canadians better understand their country,its population, resources, economy, society and culture."}, "874390485": {"name": "ordnancesurvey", "license": "https://www.ordnancesurvey.co.uk/business-and-government/licensing/using-creating-data-with-os-products/os-opendata.html", "url": "https://www.ordnancesurvey.co.uk", "license_text": "You are free to: copy, publish, distribute and transmit the Information; adapt the Information; exploit the Information commercially and non-commercially for example, by combining it with other Information, or by including it in your own product or application. You must (where you do any of the above): acknowledge the source of the Information in your product or application by including or linking to any attribution statement specified by the Information Provider(s) and, where possible, provide a link to this licence.", "remarks": "https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/os_remarks.md", "prefix": "os", "key": "", "license_type": "OGL, v3.0", "fullname": "Ordnance Survey", "id": 874390485, "description": "A non-ministerial government agency that acts as the national mapping agency for Great Britain."}, "1108728281": {"name": "tmpgov", "license": "http://www.tampere.fi/tampereen-kaupunki/tietoa-tampereesta/avoin-data/avoin-data-lisenssi.html", "url": "http://opendata.navici.com/tampere/opendata/ows?service=WFS&version=2.0.0&request=GetFeature&typeName=opendata:KH_TILASTO&outputFormat=json", "license_text": "This is a worldwide, royalty-free, irrevocable, parallel license allowing the above-mentioned material to be freely available to 1. Copy and distribute. 2. Modify and utilize commercially and non-commercially to combine with other products. 3. Used as part of an application or service.", "prefix": "tmpgov", "key": "", "license_type": "CC0 (assumed)", "fullname": "Tampere City Survey GIS", "id": 1108728281, "description": "Open Data portal for the City of Tampere, Finland."}, "1108713437": {"name": "camgov", "license": "https://data.cambridgema.gov/download/tif9-pmiw/application/pdf", "url": "http://www.cambridgema.gov/GIS/gisdatadictionary/Boundary/BOUNDARY_CDDNeighborhoods", "license_text": "Any user of Data distributed by the City may modify, use and publish such Data without charge.", "prefix": "camgov", "key": "", "license_type": "CC BY", "fullname": "City of Cambridge Geographic Information System Department", "id": 1108713437, "description": "Neighbourhood data for the City of Cambrige, MA."}, "1108970467": {"name": "can-edmdsd", "license": "https://www.edmonton.ca/city_government/documents/Web-version2.1-OpenDataAgreement.pdf", "url": "https://data.edmonton.ca/Geospatial-Boundaries/City-of-Edmonton-Neighbourhood-Boundaries-with-War/jfvj-x253", "license_text": "The City of Edmonton (the City) grants you a worldwide, royalty-free, non-exclusive licence to use, modify, and distribute the datasets in all current and future media and formats for any lawful purpose, including for commercial purposes. You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the datasets in any medium, mode or format for any lawful purpose.", "prefix": "can-edmdsd", "key": "", "license_type": "Open Government License - Edmonton", "fullname": "City of Edmonton Department of Sustainable Development", "id": 1108970467, "description": "Neighbourhood/Ward data provided by the City of Edmonton Department of Sustainable Development."}, "404734187": {"name": "whereonearth", "license": "http://developer.yahoo.com/geo/geoplanet/data/", "url": "http://developer.yahoo.com/geo/geoplanet/", "license_text": "This page provides open access to the underlying data under a Creative Commons Attribution license so that you can incorporate WOEIDs and the GeoPlanet hierarchy into your own applications.", "prefix": "woe", "key": "id", "license_type": "CC BY", "fullname": "Yahoo! GeoPlanet (formerly Where On Earth)", "id": 404734187, "description": "Cached, accessed: 2017-05-11, via: https://web.archive.org/web/20111028163611/http://developer.yahoo.com/geo/geoplanet/data/."}, "1108961115": {"name": "acme", "license": "https://acme.com/license.html", "url": "https://acme.com/", "license_text": "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.", "prefix": "acme", "key": "id", "license_type": "BSD (modified)", "fullname": "Acme Laboratories", "id": 1108961115, "description": "Purveyors of fine freeware since 1972. On the net since 1991."}, "874397693": {"name": "acgov", "license": "https://data.acgov.org/terms-of-use", "url": "https://data.acgov.org/", "license_text": "You understand and agree that Your use of the Data is at Your sole risk. The Data is made available on an \'as is\' and \'as available\' basis without any warranties of any kind, whether express or implied, including without limitation implied warranties of merchantability, fitness for a particular purpose, and non-infringement. Should there be an error, inaccuracy, or other defect in the Data, You assume the full cost of correcting any such error, inaccuracy or defect.", "prefix": "acgov", "key": "", "license_type": "Public Domain", "fullname": "Alameda County Data Sharing Initiative", "id": 874397693, "description": "Official GIS Data for Alameda County, CA."}, "1108800651": {"name": "sdgis", "license": "http://www.sangis.org/Legal_Notice.htm", "url": "http://rdw.sandag.org/Account/GetFSFile.aspx?dir=Law&Name=SDPD_BEATS.zip", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "sdgis", "key": "", "license_type": "CC0", "fullname": "SanGIS/SANDAG GIS Data Warehouse", "id": 1108800651, "description": "The San Diego Geographic Information Source (SanGIS) is a Joint Powers Authority (JPA) of the City of San Diego and the County of San Diego responsible for maintaining a regional geographic information system (GIS) landbase and data warehouse."}, "1108713463": {"name": "porbps", "license": "https://www.arcgis.com/home/item.html?id=c11815647b3949faa20b16cf50ab214d", "url": "http://gis.pdx.opendata.arcgis.com/datasets/c11815647b3949faa20b16cf50ab214d_125", "license_text": "\'Intention is free and open use, licensed for the public domain. For now, you can assume the data is completely open.\'", "prefix": "porbps", "key": "", "license_type": "Public Domain", "fullname": "City of Portland Bureau of Planning and Sustainability", "id": 1108713463, "description": "Confirmed Public Domain by Kevin Martin of the Portland BPS on 2016-10-07 "}, "420577535": {"name": "wikidata", "license": "https://creativecommons.org/publicdomain/zero/1.0/", "url": "https://www.wikidata.org/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "wd", "key": "id", "license_type": "CC0", "fullname": "Wikidata", "id": 420577535, "description": "Concordances against Wikidata; public domain structured data."}, "1108951549": {"name": "can-surgis", "license": "http://data.surrey.ca/pages/open-government-licence-surrey", "url": "https://data.surrey.ca/dataset/surrey-city-boundary", "license_text": "You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", "prefix": "can-surgis", "key": "", "license_type": "OGL - City of Surrey", "fullname": "City of Surrey GIS Section", "id": 1108951549, "description": "Open data portal for the City of Surrey, BC."}, "874397695": {"name": "smcgov", "license": "https://creativecommons.org/publicdomain/zero/1.0/legalcode", "url": "https://data.smcgov.org/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "smcgov", "key": "", "license_type": "CC0", "fullname": "Open San Mateo County", "id": 874397695, "description": "Open San Mateo County contains data published by the County of San Mateo."}}'; + $GLOBALS['whosonfirst_sources']['__SPEC__'] = '{"1108728833": {"name": "oulugov", "license": "http://www.ouka.fi/oulu/oulu-tietoa/kayttoehdot", "url": "http://www.ouka.fi/oulu/oulu-tietoa/avoin-data-aineisto", "license_text": "The license allows you to share, copy and distribute the material remains in any medium and in the form of, and Modify, combine and edit the material and create the basis for new materials.", "prefix": "oulugov", "key": "", "license_type": "CC BY 4.0", "fullname": "City of Oulu", "id": 1108728833, "description": "Official website for the City of Oulu, Finland."}, "1108839435": {"name": "Austria Open Data", "license": "http://creativecommons.org/licenses/by/3.0/at/", "url": "https://www.data.gv.at/katalog/dataset/c33d36b0-f184-4f2a-89cc-839ca7fcf88a", "license_text": "The data in our catalog are freely available under CC BY 3.0 or CC0 license. The catalog can be sorted according to topic areas. The exact data guidelines can be found in the individual data sets.", "prefix": "austriaod", "key": "id", "license_type": "CC BY 3.0", "fullname": "Austria Open Data", "id": 1108839435, "description": ""}, "420577535": {"name": "wikidata", "license": "https://creativecommons.org/publicdomain/zero/1.0/", "url": "https://www.wikidata.org/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "wd", "key": "id", "license_type": "CC0", "fullname": "Wikidata", "id": 420577535, "description": "Concordances against Wikidata; public domain structured data."}, "1108830733": {"name": "geom", "license": "CC0", "url": "", "prefix": "geom", "key": "id", "fullname": "geom", "id": 1108830733, "description": "Property prefix."}, "1024497679": {"name": "lacity", "license": "https://data.lacity.org/A-Well-Run-City/Neighborhood-Councils-Certified-/fu65-dz2f/about", "url": "https://data.lacity.org/A-Well-Run-City/Neighborhood-Councils-Certified-/fu65-dz2f", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "lacity", "key": "", "license_type": "CC0", "fullname": "City of Los Angeles Neighborhood Councils (Certified)", "id": 1024497679, "description": "Official Certified Neighborhood Council boundaries in the City of Los Angeles created and maintained by the Bureau of Engineering / GIS Mapping Division."}, "1108794385": {"name": "baltomoit", "license": "https://data.baltimorecity.gov/Geographic/Baltimore-Study-Area/cdrh-gpzc/about", "url": "https://data.baltimorecity.gov/Geographic/Baltimore-Study-Area/cdrh-gpzc", "license_text": "THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE (\'CCPL\' OR \'LICENSE\'). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.", "prefix": "baltomoit", "key": "", "license_type": "Attribution 3.0 Unported", "fullname": "Baltimore Mayor\'s Office of Information Technology", "id": 1108794385, "description": "City of Baltimore Open Data Portal. This website is operated by the Mayor and City Council of Baltimore (the \'City\') and the data is provided as a service to the public."}, "1108833305": {"name": "torsdfa", "license": "http://www1.toronto.ca/wps/portal/contentonly?vgnextoid=4a37e03bb8d1e310VgnVCM10000071d60f89RCRD", "url": "http://www1.toronto.ca/wps/portal/contentonly?vgnextoid=04b489fe9c18b210VgnVCM1000003dd60f89RCRD&vgnextchannel=75d6e03bb8d1e310VgnVCM10000071d60f89RCRD", "license_text": "You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", "prefix": "torsdfa", "key": "", "license_type": "Open Government Licence - Ontario, v1.0", "fullname": "Toronto Social Development, Finance & Administration Department", "id": 1108833305, "description": "Open Data portal for Toronto, ON."}, "1108726815": {"name": "hkigis", "license": "http://www.hri.fi/dataset/paakaupunkiseudun-aluejakokartat", "url": "http://www.hel2.fi/tietokeskus/data/kartta_aineistot/PKS_Kartta_Rajat_KML2011.zip", "license_text": "You are free to: Share, copy and redistribute the material in any medium or format and Adapt, remix, transform, and build upon the material for any purpose, even commercially.", "prefix": "hkigis", "key": "", "license_type": "CC BY 4.0", "fullname": "Helsinki City Real Estate Department", "id": 1108726815, "description": "HRI is a web service for fast and easy access to open data sources between the cities of Helsinki, Espoo, Vantaa and Kauniainen."}, "1108828507": {"name": "name", "license": "N/A", "url": "", "license_text": "", "prefix": "name", "key": "id", "license_type": "CC0", "fullname": "name", "id": 1108828507, "description": "Property prefix."}, "1108830757": {"name": "unknown", "license": "N/A", "url": "", "license_text": "N/A", "prefix": "unknown", "key": "id", "license_type": "N/A", "fullname": "unknown", "id": 1108830757, "description": "Used when a property value is not known. A placeholder for \'we do not know\'."}, "1108963891": {"name": "can-calcai", "license": "https://data.calgary.ca/stories/s/u45n-7awa", "url": "https://data.calgary.ca/Base-Maps/Community-Boundaries/ab7m-fwn6", "license_text": "Copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose...Acknowledge the source of the Information by including any attribution statement specified by the Information Provider(s) and, where possible, provide a link to this license.", "prefix": "can-calcai", "key": "", "license_type": "Open Government Licence - City of Calgary", "fullname": "City of Calgary, Corporate Analytics and Innovation", "id": 1108963891, "description": "Community boundary data generated by the City of Calgary Department of Corporate Analytics and Innovation for use in community planning."}, "1108725001": {"name": "frgov", "license": "https://www.data.gouv.fr/en/terms/", "url": "https://www.data.gouv.fr/en/datasets/fond-de-carte-des-codes-postaux/", "license_text": "The Open License is part of an international context and is compatible with the standards of open data licenses developed abroad, in particular those of the Government of the United Kingdom (Open Government License) and other international standards (ODC-BY, CC-BY 2.0).", "prefix": "frgov", "key": "id", "license_type": "CC BY 2.0", "fullname": "Open Data France", "id": 1108725001, "description": "Open platform for French public data."}, "404734191": {"name": "zetashapes", "license": "http://www.zetashapes.com/license", "url": "http://www.zetashapes.com", "license_text": "The polygons generated by this site do not have any added restrictions beyond the base data from tiger and flickr. The basic source data is from US TIGER/Line Census Data which is public domain (Q10). This site also makes use of data scraped from the flickr api -- you should probably mention on your site if you reuse this data that there is flickr data associated with it.", "remarks": "https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/zetashapes_remarks.md", "prefix": "zs", "key": "id", "license_type": "Public domain", "fullname": "Zetashapes", "id": 404734191, "description": "Zetashapes is an experiment in crowdsourced US neighborhood polygons."}, "823312445": {"name": "atgov", "license": "http://creativecommons.org/licenses/by/3.0/at/", "url": "https://www.data.gv.at", "license_text": "You are free to Share, copy and redistribute the material in any medium or format. Adapt, remix, transform, and build upon the material for any purpose, even commercially. The licensor cannot revoke these freedoms as long as you follow the license terms.", "prefix": "atgov", "key": "", "license_type": "CC BY 3.0", "fullname": "data.gv.at", "id": 823312445, "description": ""}, "1158832821": {"name": "itu", "license": "https://www.itu.int/en/Pages/copyright.aspx", "url": "https://www.itu.int/online/mm/scripts/gensel8", "license_text": "ITU holds copyright in the information available on this Web site, unless otherwise stated. Copyright in any third-party materials found on this Web site must also be respected.", "prefix": "itu", "key": "id", "license_type": "Restricted", "fullname": "International Telecommunications Union", "id": 1158832821, "description": "ITU country codes are used to identify radio transmitter locations."}, "1108739789": {"name": "uscensus", "license": "https://www.census.gov/data/developers/about/terms-of-service.html", "data_sources": [{"default": "https://www.census.gov/cgi-bin/geo/shapefiles/index.php", "alt-uscensus-display-terrestrial-zoom-10": "http://www2.census.gov/geo/tiger/GENZ2015/shp/cb_2015_us_state_500k.zip"}], "url": "https://www.census.gov/", "license_text": "All U.S. Census Bureau materials, regardless of the media, are entirely in the public domain. There are no user fees, site licenses, or any special agreements etc for the public or private use, and or reuse of any census title. As tax funded product, it\'s all in the public record.", "prefix": "uscensus", "key": "", "alt": [{"function": "display", "extras": ["scope", "detail"]}], "license_type": "CC0", "fullname": "United States Census Bureau", "id": 1108739789, "description": "The leading source of quality data about the nation\'s people and economy from the United States Census Bureau."}, "1141961795": {"name": "lieu", "license": "", "url": "https://github.com/openvenues/lieu", "prefix": "lieu", "key": "guid", "fullname": "lieu", "id": 1141961795, "description": "Property prefix."}, "1108974149": {"name": "can-abog", "license": "https://open.alberta.ca/documentation/ogp-licence", "url": "https://open.alberta.ca/opendata/property-municipal-boundaries", "license_text": "Copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose...Acknowledge the source of the Information by including any attribution statement specified by the Information Provider(s) and, where possible, provide a link to this licence...", "prefix": "can-abog", "key": "", "license_type": "Open Government Licence - Alberta", "fullname": "Alberta Open Government - Municipal Boundaries", "id": 1108974149, "description": "Open municipal boundary data provided by the Alberta Open Government program."}, "1108969549": {"name": "arg-caba", "license": "https://data.buenosaires.gob.ar/tyc", "url": "https://data.buenosaires.gob.ar/dataset/barrios", "license_text": "La reutilizaci\u00f3n autorizada puede incluir la copia, difusi\u00f3n, modificaci\u00f3n, adaptaci\u00f3n, extracci\u00f3n, reordenamiento y combinaci\u00f3n de la informaci\u00f3n contenida en el sitio ... Debe citarse la fuente de los documentos objeto de la reutilizaci\u00f3n.", "prefix": "arg-caba", "key": "", "license_type": "CC BY", "fullname": "Ciudad Aut\u00f3noma de Buenos Aires, Iniciativa de Datos P\u00fablicos y Transparencia", "id": 1108969549, "description": "Open Data portal for the City of Buenos Aires, Argentina."}, "874455653": {"name": "seagv", "license": "https://data.seattle.gov/data-policy", "url": "https://data.seattle.gov/dataset/data-seattle-gov-GIS-shapefile-datasets/f7tb-rnup", "license_text": "The Open Data Program makes the data generated by the City of Seattle openly available to the public.", "prefix": "seagv", "key": "", "license_type": "Public Domain", "fullname": "Seattle City GIS Program", "id": 874455653, "description": "Official data portal for the City of Seattle, WA."}, "1108797031": {"name": "atldpcd", "license": "https://www.arcgis.com/home/item.html?id=716f417a1990446389ef7fd2c381d09f", "url": "http://dpcd.coaplangis.opendata.arcgis.com/datasets/neighborhoods", "license_text": "Share, copy and redistribute the material in any medium or format. Adapt, remix, transform, and build upon the material for any purpose, even commercially.", "prefix": "atldpcd", "key": "", "license_type": "CC BY 4.0", "fullname": "Atlanta Department of Planning and Community Development", "id": 1108797031, "description": "Neighborhoods within the City of Atlanta."}, "1108952683": {"name": "outgoing", "license": "N/A", "url": "http://outgoingnyc.com/", "license_text": "Data is assumed to be in the Public Domain.", "prefix": "out", "key": "", "license_type": "Public Domain (assumed)", "fullname": "OUTgoing", "id": 1108952683, "description": "OUTgoing: The Hidden History of New York\'s Gay Nightlife by Jeff Ferzoco."}, "1108784751": {"name": "sjp", "license": "http://www.sanjoseca.gov/DocumentCenter/View/55954", "url": "https://www.sanjoseca.gov/DocumentCenter/View/11287", "license_text": "Data made open and freely available to the public to be republished, manipulated, or used in any other way without restriction.", "prefix": "sjp", "key": "", "license_type": "CC0", "fullname": "San Jose Planning Department", "id": 1108784751, "description": "The City of San Jose, CA\'s Planning Department website."}, "1108973687": {"name": "thelist", "license": "http://www.calweb.net/~skoepke/", "url": "http://www.calweb.net/~skoepke/", "license_text": "Public domain per email conversation on May 30th, 2017.", "prefix": "thelist", "key": "", "license_type": "Public Domain", "fullname": "The List - Bay Area Concert Guide", "id": 1108973687, "description": "The list is an online concert guide for Northern California and the west coast."}, "1158808187": {"name": "inegi", "license": "http://www.beta.inegi.org.mx/inegi/terminos.html", "url": "http://http://www.inegi.org.mx/", "license_text": "You can make and distribute copies of the information, without altering or deleting metadata. You can disseminate and publish the information.", "prefix": "inegi", "key": "id", "license_type": "CC BY (equivalent)", "fullname": "Instituto Nacional de Estad\u00edstica y Geograf\u00eda (INEGI)", "id": 1158808187, "description": "The public body responsible for regulating and coordinating the National Statistical System and Geographic Information, as well as to capture and disseminate information of Mexico."}, "1108970625": {"name": "quattroshapes_pg", "license": "https://github.com/foursquare/quattroshapes/blob/master/LICENSE.md", "url": "http://www.quattroshapes.com/", "license_text": "Please include attribution in your app, site, or printed work.", "prefix": "qs_pg", "key": "id", "license_type": "CC BY 2.0", "fullname": "Quattroshapes Point Gazetteer", "id": 1108970625, "description": "The Quattroshapes point gazetteer. A big list of point locations that supplements the polygons gazetteer."}, "1108800107": {"name": "stpaulgov", "license": "https://information.stpaul.gov/City-Administration/Establishing-an-Open-Information-Program-Resolutio/v7qy-vtzb", "url": "https://information.stpaul.gov/City-Administration/District-Council-Shapefile-Map/dq4n-yj8b", "license_text": "The City shall develop and implement practices allowing it to prioritize the proactive release of high quality, machine-readable, disclosable city data, making it freely available via an open license without restrictions on use, reuse, or redistribution, ensuring it is fully accessible to the broadest range of users possible.", "prefix": "stpaulgov", "key": "", "license_type": "CC0 (assumed)", "fullname": "Open Information Saint Paul", "id": 1108800107, "description": "The Open Information portal for the Saint Paul, MN government."}, "1108694665": {"name": "bra", "license": "https://data.cityofboston.gov/City-Services/Boston-Neighborhood-Shapefiles/af56-j7tb", "url": "https://data.cityofboston.gov/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "bra", "key": "", "license_type": "CC0", "fullname": "Boston Redevelopment Authority", "id": 1108694665, "description": "Neighborhood boundaries are created based on zip code, zoning district boundaries and census tract boundaries. This GIS data layer was produced by the BRA Office of Digital Cartography and GIS."}, "1126109975": {"name": "can-gatsudd", "license": "http://www3.gatineau.ca/Infoterritoire/WebInterface/help/fr/Content/1_About/1_About_FR.htm", "url": "http://www3.gatineau.ca/Infoterritoire/WebInterface/views/index.aspx", "license_text": "Confirmed open source availability by Maurin Dabbadie of the Gatineau Department of Planning and Sustainable Development on 2017-06-07 .", "prefix": "can-gatsudd", "key": "", "license_type": "CC BY (equivalent)", "fullname": "Gatineau Service de l\'urbanisme et du developpement durable (SUDD)", "id": 1126109975, "description": "Community portrait data created by the city of Gatineau for use in planning and sustainable development (Data provided by request from )."}, "1108962957": {"name": "latimes", "license": "http://www.tronc.com/central-terms-of-service/", "url": "http://www.latimes.com/", "license_text": "If you operate a Web site and wish to link to the Site, you may do so provided you agree to cease such link upon request from us. No other use is permitted without prior written permission of tronc.", "prefix": "latimes", "key": "id", "license_type": "Restricted", "fullname": "Los Angeles Times", "id": 1108962957, "description": "The Los Angeles Times."}, "1158784149": {"name": "lacity_oof", "license": "", "url": "https://data.lacity.org/A-Prosperous-City/Listing-of-Active-Businesses/6rrh-rzua", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "lacity_oof", "key": "id", "license_type": "CC0", "fullname": "City of Los Angeles Office of Finance", "id": 1158784149, "description": ""}, "1158784151": {"name": "companieshouse", "license": "https://data.london.gov.uk/about/terms-and-conditions/", "url": "https://data.london.gov.uk/dataset/directory-of-london-businesses", "license_text": "May use the data contained in this site for any purpose, providing it does not infringe the terms and conditions.", "prefix": "companieshouse", "key": "number", "license_type": "CC0", "fullname": "City of London Companies House", "id": 1158784151, "description": "A directory of business listings in London."}, "907219099": {"name": "zolk", "license": "http://chicagomap.zolk.com/about.html", "url": "http://chicagomap.zolk.com/", "license_text": "The resulting KML source data is licensed under a Creative Commons Attribution License. This means that you\'re free to use the data from this map as you wish, but credit to either Kevin Zolkiewicz or this web site is appreciated.", "prefix": "zolk", "key": "", "license_type": "CC BY 3.0 US", "fullname": "Zolk Chicago Neighborhoods Map", "id": 907219099, "description": "An overlay of boundaries for Chicago\'s 228 neighborhoods."}, "1158832837": {"name": "marc", "license": "https://www.loc.gov/legal/", "url": "http://www.loc.gov/marc/countries/cou_home.html", "license_text": "Unless otherwise indicated on this site, the Library of Congress has no objection to the international use and reuse of Library U.S. Government works on loc.gov. These works are also available for worldwide use and reuse under CC0 1.0 Universal.", "prefix": "marc", "key": "id", "license_type": "CC0", "fullname": "Machine-Readable Cataloging - Library of Congress", "id": 1158832837, "description": "MARC is a standard for encoding bibliographic materials in electronic form. The Library of Congress maintains the MARC code list for countries."}, "656342179": {"name": "nycgov", "license": "http://legistar.council.nyc.gov/ViewReport.ashx?M=R&N=Text&GID=61&ID=1090992&GUID=B1263195-66B9-48AD-A381-57584D623443&Title=Legislation+Text", "url": "https://data.cityofnewyork.us/", "license_text": "Such public data sets shall be made available without any registration requirement, license requirement or restrictions on their use provided that the department may require a third party providing to the public any public data set, or application utilizing such data set, to explicitly identify the source and version of the public data set, and a description of any modifications made to such public data set.", "prefix": "nycgov", "key": "id", "license_type": "CC0 (assumed)", "fullname": "NYC OpenData", "id": 656342179, "description": "Open Data portal for New York City, NY."}, "1108732585": {"name": "nolagis", "license": "https://data.nola.gov/Geographic-Base-Layers/Neighborhoods/92zg-wzkq", "url": "https://data.nola.gov/Geographic-Base-Layers/Neighborhoods/92zg-wzkq", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "nolagis", "key": "", "license_type": "CC0", "fullname": "City of New Orleans, Office of Information Technology and Innovation, Enterprise Information Team", "id": 1108732585, "description": "Open Data portal for the City of New Orleans, LA."}, "1108748977": {"name": "denvercpd", "license": "https://www.denvergov.org/opendata/termsofuse", "url": "https://www.denvergov.org/opendata/dataset/city-and-county-of-denver-statistical-neighborhoods", "license_text": "You are free to: Share, copy and redistribute the material in any medium or format. Adapt, remix, transform, and build upon the material for any purpose, even commercially. The licensor cannot revoke these freedoms as long as you follow the license terms.", "prefix": "denvercpd", "key": "", "license_type": "CC BY 3.0", "fullname": "Denver Department of Community Planning and Development", "id": 1108748977, "description": "Open Data portal for the City of Denver, CO."}, "1108804789": {"name": "cbsnl", "license": "https://data.overheid.nl/data/dataset/wijk-en-buurtkaart-2016-versie-1", "url": "https://data.overheid.nl/data/dataset/wijk-en-buurtkaart-2016-versie-1/resource/7f32452a-f035-4a23-bce9-1972f5189beb", "license_text": "With this license, a re-user is free to share, copy, distribute and transmit the dataset through any medium or file format. The dataset may be edited and may be used for commercial purposes. A reference to the creator of the data is required.", "prefix": "cbsnl", "key": "", "license_type": "CC BY 3.0", "fullname": "Centraal Bureau voor de Statistiek", "id": 1108804789, "description": "This data portal consists of a register containing information about and references to data sets by Dutch authorities."}, "1158832823": {"name": "gec", "license": "http://geonames.nga.mil/gns/html/namefiles.html", "url": "http://geonames.nga.mil/gns/html/countrycodes.html", "license_text": "Foreign geographic names data is freely available.", "prefix": "gec", "key": "", "license_type": "CC0", "fullname": "Geopolitical Entities and Codes", "id": 1158832823, "description": "Formerly FIPS PUB 10-4, these country codes were used by the National Geospatial-Intelligence Agency (NGA) to define \'Countries, Dependencies, Areas of Special Sovereignty, and Their Principal Administrative Divisions\'. GEC maintenance was discontinued on 31 December 2014."}, "1158832825": {"name": "ioc", "license": "https://www.olympic.org/terms-of-service", "url": "https://www.olympic.org/the-ioc", "license_text": "All elements of the Site, including the IOC Content, are protected by copyright, trade dress, moral rights, trademark and other laws relating to the protection of intellectual property.", "prefix": "ioc", "key": "id", "license_type": "Restricted", "fullname": "International Olympics Committee", "id": 1158832825, "description": "These codes identify the nationality of athletes and teams during Olympic events."}, "772974267": {"name": "sfgov", "license": "https://data.sfgov.org/terms-of-use", "url": "https://data.sfgov.org/", "license_text": "The Open Data Commons, Public Domain Dedication & Licence is a document intended to allow you to freely share, modify, and use this work for any purpose and without any restrictions. This licence is intended for use on databases or their contents (\'data\'), either together or individually.", "prefix": "sfgov", "key": "", "license_type": "PDDL 1.0", "fullname": "City of San Francisco", "id": 772974267, "description": "Open Data portal for the City of San Francisco, CA."}, "1158832829": {"name": "fifa", "license": "http://www.rsssf.com/miscellaneous/fifa-codes.html", "url": "http://www.rsssf.com/miscellaneous/fifa-codes.html", "license_text": "You are free to copy this document in whole or part provided that proper acknowledgement is given to the author. All rights reserved.", "prefix": "fifa", "key": "id", "license_type": "CC BY 1.0", "fullname": "Federation Internationale de Football Association", "id": 1158832829, "description": "Country codes for each member (and non-member) country, used by FIFA during competition."}, "1158832831": {"name": "ds", "license": "http://www.unece.org/legal_notice/copyrightnotice.html", "url": "https://www.unece.org/trans/roadsafe/distinguishing_signs.html", "license_text": "All rights reserved.", "prefix": "ds", "key": "", "license_type": "Restricted", "fullname": "Distinguishing Signs - United Nations Economic Commission for Europe", "id": 1158832831, "description": "These codes are provided for by Article 20 of the Convention on Road Traffic (Geneva, 1949). Therein, they are called \'distinguishing signs of the place of registration\' of vehicles."}, "1158832833": {"name": "wmo", "license": "https://public.wmo.int/en/copyright", "url": "http://icoads.noaa.gov/metadata/wmo47/wmo_quarterly/47CodeTables9903.html", "license_text": "Reproduction of short excerpts of WMO materials, figures and photographs on this website is authorized free of charge and without formal written permission provided that the original source is acknowledged. Reproduction of videos files are authorized free of charge and without formal written permission provided that the original source is acknowledged and subject to the standard creative commons licensing conditions Creative Commons License.", "prefix": "wmo", "key": "id", "license_type": "CC BY-NC-ND 4.0", "fullname": "World Meteorological Organization", "id": 1158832833, "description": "Country abbreviations used in weather reports from the World Meteorological Organization."}, "1158832835": {"name": "gaul", "license": "http://www.fao.org/contact-us/terms/en/", "url": "http://www.fao.org/countryprofiles/iso3list/en/", "license_text": "FAO encourages unrestricted use of news releases provided on the FAO website, and no formal permission is required to reproduce these materials.", "prefix": "gaul", "key": "id", "license_type": "CC0", "fullname": "Global Administrative Unit Layers - Food and Agriculture Organization", "id": 1158832835, "description": "Country codes used be the Global Administrative Unit Layers from the Food and Agriculture Organization. The entity codes are integers, assigned sequentially, with no duplication between layers; that is, no country has the same code as any primary subdivision, and so on."}, "1126113989": {"name": "can-saskodp", "license": "http://opendata-saskatoon.cloudapp.net/TermsOfUse/TermsOfUse", "url": "http://opendata-saskatoon.cloudapp.net/DataBrowser/SaskatoonOpenDataCatalogueBeta/NeighbourhoodArea#param=NOFILTER--DataView--Results", "license_text": "...a broad license to use the currently published data on the City of Saskatoon website (\u201cInformation\u201d) for your own analysis and applications...appreciate credit for provision of the Information, this is not a strict requirement.", "prefix": "can-saskodp", "key": "", "license_type": "CC0 (equivalent)", "fullname": "City of Saskatoon Open Data Portal - Neighbourhood Areas", "id": 1126113989, "description": "Neighbourhood regions provided by the city of Saskatoon, used for demographic purposes."}, "1158832839": {"name": "dial", "license": "https://www.itu.int/en/Pages/copyright.aspx", "url": "https://www.itu.int/itudoc/itu-t/ob-lists/icc/e164_763.html", "license_text": "ITU holds copyright in the information available on this Web site, unless otherwise stated. Copyright in any third-party materials found on this Web site must also be respected.", "prefix": "dial", "key": "", "license_type": "Restricted", "fullname": "Dial Codes", "id": 1158832839, "description": "In most places that allow direct-dialed international calls, you must first dial an international access code. These access codes are maintained for the member countries or regions by the International Telecommunication Union (ITU)."}, "1108960969": {"name": "nycgov_subway", "license": "http://legistar.council.nyc.gov/ViewReport.ashx?M=R&N=Text&GID=61&ID=1090992&GUID=B1263195-66B9-48AD-A381-57584D623443&Title=Legislation+Text", "url": "https://data.cityofnewyork.us/Transportation/Subway-Stations/arq3-7z49", "license_text": "Such public data sets shall be made available without any registration requirement, license requirement or restrictions on their use provided that the department may require a third party providing to the public any public data set, or application utilizing such data set, to explicitly identify the source and version of the public data set, and a description of any modifications made to such public data set.", "prefix": "nycgov_subway", "key": "objectid", "license_type": "CC0 (assumed)", "fullname": "NYC OpenData - Subway Stations", "id": 1108960969, "description": "Open Data portal for New York City, NY."}, "1108960971": {"name": "can-lvlsu", "license": "https://www.donneesquebec.ca/fr/licence/#cc-by", "url": "https://www.donneesquebec.ca/recherche/fr/dataset/limites-des-anciennes-municipalites", "license_text": "This license allows other people to distribute, remix, arrange and adapt your work, even for commercial purposes, as long as you are credited with the original creation by quoting your name.", "prefix": "can-lvlsu", "key": "", "license_type": "CC BY", "fullname": "Laval Service de l\'urbanisme", "id": 1108960971, "description": "The collaborative crossroads in Quebec open data."}, "1108721357": {"name": "azavea", "license": "https://www.opendataphilly.org/dataset/philadelphia-neighborhoods", "url": "https://www.opendataphilly.org/dataset/philadelphia-neighborhoods/resource/06e8d380-821f-44ce-8718-a0f2f7902318", "license_text": "You are free to: Share, copy and redistribute the material in any medium or format. Adapt, remix, transform, and build upon the material for any purpose, even commercially.", "prefix": "azavea", "key": "", "license_type": "CC BY 3.0 US", "fullname": "Azavea, Inc.", "id": 1108721357, "description": "Azavea is a civic technology firm based in Philadelphia. Azavea applies geospatial technology for civic and social impact."}, "1108955855": {"name": "lbl", "license": "CC0", "url": "", "prefix": "lbl", "key": "id", "fullname": "label", "id": 1108955855, "description": ""}, "1108728529": {"name": "tkugov", "license": "http://www.lounaistieto.fi/blog/2015/08/18/turun-palvelualuejakotilastoalueet/", "url": "http://opendata.lounaistieto.fi/aineistoja/Turku_pienalueet.zip", "license_text": "You are free to: Share - copy and redistribute the material in any medium or format and Adapt - remix, transform, and build upon the material for any purpose, even commercially.", "prefix": "tkugov", "key": "", "license_type": "CC BY 4.0", "fullname": "Turku City Government", "id": 1108728529, "description": "Open Data portal for the City of Turku, Finland."}, "1126129879": {"name": "can-vicodc", "license": "http://www.victoria.ca/EN/main/online-services/open-data-catalogue/open-data-licence.html", "url": "http://www.victoria.ca/EN/main/online-services/open-data-catalogue.html", "license_text": "Copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose...Acknowledge the source of the Information by including any attribution statement specified by the Information Provider and, where possible, provide a link to this licence.", "prefix": "can-vicodc", "key": "", "license_type": "Open Government Licence - City of Victoria", "fullname": "City of Victoria Open Data Catalogue", "id": 1126129879, "description": "Neighbourhood boundary data provided by the City of Victoria Open Data Catalogue."}, "1108906615": {"name": "vanpds", "license": "http://vancouver.ca/your-government/open-data-catalogue.aspx#tab19099", "url": "http://data.vancouver.ca/datacatalogue/localAreaBoundary.htm", "license_text": "you are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", "prefix": "vanpds", "key": "", "license_type": "Open Government Licence - British Columbia, v2.0", "fullname": "Vancouver Planning and Development Services", "id": 1108906615, "description": "Open Data portal for the City of Vancouver."}, "404734173": {"name": "edtf", "license": "https://www.loc.gov/legal/", "url": "http://loc.gov/standards/datetime/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "edtf", "key": "", "license_type": "CC0 1.0 Universal", "fullname": "Extended Date/Time Format", "id": 404734173, "description": "Property prefix. This website describes the current effort to develop a reasonably comprehensive date/time definition for the bibliographic community, as well as other interested communities, and submitting it for standardization or some other mode of formalization, for example a W3C note or an amendment to ISO 8601."}, "1158844639": {"name": "localwiki", "license": "https://localwiki.org/main/Copyrights", "url": "https://localwiki.org/", "license_text": "All of the media and written content in LocalWiki is licensed under the Creative Commons Attribution 4.0 license (CC BY 4.0), unless noted otherwise.", "prefix": "localwiki", "key": "", "license_type": "CC BY 4.0", "fullname": "LocalWiki", "id": 1158844639, "description": "LocalWiki is a grassroots effort to collect, share and open the world\u2019s local knowledge. Includes data on local governments, neighborhoods, streets, social movements, noteworthy local figures, social services, schools, etc."}, "404734177": {"name": "geoplanet", "license": "http://developer.yahoo.com/geo/geoplanet/data/", "url": "http://developer.yahoo.com/geo/geoplanet/", "license_text": "This page provides open access to the underlying data under a Creative Commons Attribution license so that you can incorporate WOEIDs and the GeoPlanet hierarchy into your own applications.", "remarks": "https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/geoplanet_remarks.md", "prefix": "gp", "key": "id", "license_type": "CC BY", "fullname": "Yahoo! GeoPlanet", "id": 404734177, "description": "GeoPlanet provides an open, permanent, and intelligent infrastructure for geo-referencing data on the Internet. (Cached, accessed: 2017-05-11, via: https://web.archive.org/web/20111028163611/http://developer.yahoo.com/geo/geoplanet/data/)."}, "404734179": {"name": "naturalearth", "license": "http://www.naturalearthdata.com/about/terms-of-use/", "url": "http://www.naturalearthdata.com/", "license_text": "No permission is needed to use Natural Earth. Crediting the authors is unnecessary.", "remarks": "https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/naturalearth_remarks.md", "prefix": "ne", "key": "", "license_type": "Public Domain (assumed)", "fullname": "Natural Earth", "id": 404734179, "description": "Natural Earth is a public domain map dataset available at 1:10m, 1:50m, and 1:110 million scales, which features tightly integrated vector and raster data."}, "404734181": {"name": "ourairports", "license": "http://ourairports.com/", "url": "http://ourairports.com/data/", "license_text": "OurAirports is a public site, and by \'public\', we mean PUBLIC.", "remarks": "https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/ourairports_remarks.md", "prefix": "oa", "key": "id", "license_type": "Public domain", "fullname": "OurAirports", "id": 404734181, "description": "OurAirports is a free site where visitors can explore the world\'s airports. [...] This is an open-data web site, after all, and we don\'t believe that \'open\' means \'we can benefit from it, but we\'ll hide it from everyone else."}, "404734183": {"name": "quattroshapes", "license": "https://github.com/foursquare/quattroshapes/blob/master/LICENSE.md", "url": "http://www.quattroshapes.com/", "license_text": "Please include attribution in your app, site, or printed work.", "remarks": "https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/quattroshapes_remarks.md", "prefix": "qs", "key": "id", "license_type": "CC BY 2.0", "fullname": "Quattroshapes", "id": 404734183, "description": "A gazetteer of non-overlapping, authoritative polygons around a curated list of places. Quattroshapes includes open data from government and other sources, many of which require attribution. See [remarks](https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/quattroshapes_remarks.md) for detail."}, "1108968171": {"name": "can-wpgppd", "license": "https://data.winnipeg.ca/open-data-licence", "url": "https://data.winnipeg.ca/City-Planning/Neighbourhood/fen6-iygi", "license_text": "Copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose...Acknowledge the source of the Information by including any attribution statement specified by the Information Provider(s) and, where possible, provide a link to this licence.", "prefix": "can-wpgppd", "key": "", "license_type": "Open Government License - Winnipeg", "fullname": "City of Winnipeg Department of Planning, Property, and Development", "id": 1108968171, "description": "Neighbourhood planning districts provided by the City of Winnipeg on their open data portal."}, "404734189": {"name": "wikipedia", "license": "https://en.wikipedia.org/wiki/Wikipedia:Copyrights", "url": "http://www.wikipedia.org/", "license_text": "Most of Wikipedia\'s text and many of its images are co-licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License (CC BY-SA) and the GNU Free Documentation License (GFDL) (unversioned, with no invariant sections, front-cover texts, or back-cover texts).", "prefix": "wk", "key": "page", "license_type": "CC BY-SA 3.0", "fullname": "Wikipedia", "id": 404734189}, "857075439": {"name": "foursquare", "license": "https://foursquare.com/legal/terms", "url": "http://www.foursquare.com", "license_text": "Subject to these Terms of Use, Foursquare grants each user of the Site and/or Service a worldwide, non-exclusive, non-sublicensable and non-transferable license to use, modify and reproduce the Content, solely for personal, non-commercial use.", "prefix": "4sq", "key": "id", "license_type": "CC BY", "fullname": "Foursquare", "id": 857075439, "description": "A search-and-discovery service that compiles a database of locations and places worldwide."}, "404734193": {"name": "factual", "license": "http://factual.com/tos", "url": "https://github.com/Factual/places", "license_text": "All of the information and data made available via the Sites (\'Site Data\') is provided solely to enable you to learn about Factual and the Services. You are not licensed to store, copy, or use any Site Data for any other purpose.", "prefix": "fct", "key": "id", "license_type": "Restricted", "fullname": "Factual", "id": 404734193, "description": "Location data for Mobile Advertising, Developers, and Enterprise solutions."}, "404734195": {"name": "mapshaper", "license": "http://mozilla.org/MPL/2.0/", "url": "https://github.com/mbloch/mapshaper", "license_text": "This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.", "prefix": "ms", "key": "", "license_type": "MPL, v2.0", "fullname": "Mapshaper", "id": 404734195, "description": "Mapshaper is software for editing Shapefile, GeoJSON, TopoJSON and several other data formats, written in JavaScript."}, "404734197": {"name": "mapzen", "license": "https://mapzen.com/terms/", "url": "https://www.mapzen.com/", "license_text": "Subject to these Terms, Mapzen hereby grants to you a non-exclusive, non-transferable, non-sublicensable license during the Term to: (i) copy and use the Tools solely to develop products and services to be made available by you (\'Your Products\'), and to distribute elements of the Tools as incorporated into Your Products; (ii) use and access the Services as provided by Mapzen subject to the Rate Limits; and (iii) if you\'ve ordered Mapzen Data Products, use the Mapzen Data Products for your internal use and only as part of Your Products which are provided directly to end users, and not for resale or for redistribution or use in conjunction with, or as part of, the products or services of others. Except for the foregoing license, Mapzen and its suppliers own all right, title and interest in and to the Services, Tools and Mapzen Data Products, and no other licenses are granted to you, whether express or implied.", "prefix": "mz", "key": "", "license_type": "CC0", "fullname": "Mapzen", "id": 404734197, "description": " Mapzen is an open, sustainable, and accessible mapping platform. Our tools let you display, search, and navigate your world."}, "404734199": {"name": "simplegeo", "license": "https://creativecommons.org/publicdomain/zero/1.0/", "url": "https://www.simplegeo.com", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "sg", "key": "id", "license_type": "CC0", "fullname": "SimpleGeo", "id": 404734199, "description": "SimpleGeo was a location aware services company that operated between 2009 and 2011. It is no longer an active company."}, "404734201": {"name": "yerbashapes", "license": "N/A", "url": "", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "ys", "key": "", "license_type": "CC0", "fullname": "Yerbashapes", "id": 404734201, "description": "Weighted means from Quattroshapes. Yerbashapes are a product of Mapzen for Who\'s On First."}, "404734205": {"name": "burritojustice", "license": "http://burritojustice.com", "url": "http://burritojustice.com/la-lengua/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "bj", "key": "id", "license_type": "CC0", "fullname": "Burrito Justice", "id": 404734205, "description": "Burrito Justice - La Lengua, San Francisco, CA."}, "874390485": {"name": "ordnancesurvey", "license": "https://www.ordnancesurvey.co.uk/business-and-government/licensing/using-creating-data-with-os-products/os-opendata.html", "url": "https://www.ordnancesurvey.co.uk", "license_text": "You are free to: copy, publish, distribute and transmit the Information; adapt the Information; exploit the Information commercially and non-commercially for example, by combining it with other Information, or by including it in your own product or application. You must (where you do any of the above): acknowledge the source of the Information in your product or application by including or linking to any attribution statement specified by the Information Provider(s) and, where possible, provide a link to this licence.", "remarks": "https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/os_remarks.md", "prefix": "os", "key": "", "license_type": "OGL, v3.0", "fullname": "Ordnance Survey", "id": 874390485, "description": "A non-ministerial government agency that acts as the national mapping agency for Great Britain."}, "404734209": {"name": "minitenders", "license": "http://www.thebolditalic.com/articles/1101-mini-tenders", "url": "http://www.thebolditalic.com/articles/1101-mini-tenders", "license_text": "Data is assumed to be in the Public Domain.", "prefix": "mt", "key": "id", "license_type": "Public domain (assumed)", "fullname": "Mini Tenders", "id": 404734209, "description": "A Tenderloin of many neighbourhoods."}, "404734211": {"name": "nullisland", "license": "N/A", "url": "http://www.nullisland.com/", "license_text": "", "prefix": "ni", "key": "", "license_type": "", "fullname": "Null Island", "id": 404734211, "description": "Home of Null Island."}, "404734212": {"name": "btvneighborhoods", "license": "http://geosprocket.blogspot.com/2012/10/results-of-burlington-neighborhoods.html", "url": "https://gist.github.com/wboykinm/dfe44481d8ff759c4f1afea223a7c070", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "btv", "key": "id", "license_type": "CC0 (equivalent)", "fullname": "Burlington VT Neighborhoods Project", "id": 404734212, "description": "Crowdsourced by the locals: http://geosprocket.blogspot.com/2012/10/results-of-burlington-neighborhoods.html"}, "404734213": {"name": "missing", "license": "N/A", "url": "N/A", "license_text": "N/A", "prefix": "xx", "key": "", "license_type": "N/A", "fullname": "Missing", "id": 404734213, "description": "The source for this property is missing. For example, if a record in Who\'s On First was imported without a src:geom property, the source would be considered \'missing\'."}, "404734215": {"name": "whosonfirst", "license": "https://github.com/whosonfirst-data/whosonfirst-data/blob/master/LICENSE.md", "url": "http://whosonfirst.mapzen.com/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. Note that some included work is available under CC BY.", "prefix": "wof", "key": "id", "license_type": "CC0", "fullname": "Who\'s On First", "id": 404734215, "description": "Who\'s On First is a gazetteer of places. Not quite all the places in the world but a whole lot of them and, we hope, the kinds of places that we mostly share in common."}, "1108906761": {"name": "can-mtlsmvt", "license": "https://creativecommons.org/licenses/by/4.0/", "url": "http://donnees.ville.montreal.qc.ca/dataset/quartiers", "license_text": "You are free to Share, copy and redistribute the material in any medium or format and Adapt, remix, transform, and build upon the material for any purpose, even commercially. ", "prefix": "can-mtlsmvt", "key": "", "license_type": "CC BY 4.0", "fullname": "Montreal Service de la Mise en Valeur du Territoire", "id": 1108906761, "description": "Open Data portal for the Ville de Montreal."}, "1108906765": {"name": "can-dnvgov", "license": "http://geoweb.dnv.org/data/metadata.php?dataset=RegNeighbourhood", "url": "http://geoweb.dnv.org/Products/Data/SHP/RegNeighbourhood_shp.zip", "license_text": "you are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", "prefix": "can-dnvgov", "key": "", "license_type": "Open Government Licence - British Columbia, v2.0", "fullname": "District of North Vancouver Government", "id": 1108906765, "description": "Open Data Portal for the District of North Vancouver."}, "1158846735": {"name": "santabar", "license": "https://www.santabarbaraca.gov/howdoi/get/webhelp/policy.asp", "url": "https://maps.santabarbaraca.gov/Html5Viewer/Index.html?configBase=/Geocortex/Essentials/REST/sites/City_of_Santa_Barbara__Public/viewers/SantaBarbaraPublic/virtualdirectory/Resources/Config/Default", "license_text": "", "prefix": "santabar", "key": "", "license_type": "Public Domain", "fullname": "The City of Santa Barbara", "id": 1158846735, "description": "Open Data portal for the City of Santa Barbara, CA."}, "1108931861": {"name": "iso", "license": "https://www.iso.org/privacy-and-copyright.html", "url": "http://www.iso.org/", "license_text": "All content on ISO Online is copyright protected. The copyright is owned by ISO. Any use of the content, including copying of it in whole or in part, for example to another Internet site, is prohibited and would require written permission from ISO.", "prefix": "iso", "key": "id", "license_type": "Restricted", "fullname": "International Organization for Standardization", "id": 1108931861, "description": "ISO is an independent, non-governmental international organization with a membership of 163 national standards bodies."}, "1108973847": {"name": "can-ons", "license": "http://neighbourhoodstudy.ca/ons-terms-of-use/", "url": "Data provided by request at http://neighbourhoodstudy.ca/contact/", "license_text": "....publicly available and accessible data...must give ONS credit for each use or reproduction of the datasets...", "prefix": "can-ons", "key": "", "license_type": "CC BY (equivalent)", "fullname": "Ottawa Neighbourhood Study (ONS)", "id": 1108973847, "description": "Custom neighbourhood data provided by the Ottawa Neighbourhood Study organization for community enrichment."}, "1108962077": {"name": "canvec-hydro", "license": "http://open.canada.ca/en/open-government-licence-canada", "url": "http://open.canada.ca/data/en/dataset/9d96e8c9-22fe-4ad2-b5e8-94a6991b744b", "license_text": "You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", "prefix": "canvec-hydro", "key": "", "license_type": "Open Government Licence - Canada", "fullname": "Natural Resources Canada, CanVec Hydrographic Features", "id": 1108962077, "description": "Datasets can be found under the shapefile or geodatabase directories, sorted by precision and location."}, "1158856069": {"name": "unsd", "license": "http://www.un.org/en/sections/about-website/terms-use/", "url": "https://unstats.un.org/unsd/methodology/m49/", "license_text": "The United Nations reserves the right to deny in its sole discretion any user access to this Site or any portion thereof without notice.", "prefix": "m49", "key": "code", "license_type": "Restricted", "fullname": "UNSD (United Nations Statistics Division)", "id": 1158856069, "description": "The United Nations Statistics Division compiles and disseminates global statistical information, develops standards and norms for statistical activities, and supports efforts to strengthen national statistical systems."}, "420573473": {"name": "unlocode", "license": "http://www.unece.org/cefact/locode/locode_since1981.html", "url": "http://www.unece.org/cefact/locode/welcome.html", "license_text": "UN/LOCODE is freely available to all interested users.", "prefix": "unlc", "key": "id", "license_type": "CC0", "fullname": "UN/LOCODE (United Nations Code for Trade and Transport Locations)", "id": 420573473, "description": "UN/LOCODE is based on a code structure set up by ECLAC and a list of locations originating in ESCAP, developed in UNCTAD in co-operation with transport organisations like IATA and the ICS and with active contributions from national governments and commercial bodies. Note: Who\'s On First concatenates the UN/LOCODE two-character country code and three-character feature code with a deliminator and names the result the \'id\'."}, "1108955939": {"name": "transitland", "license": "https://transit.land/an-open-project/contributor-agreement.html", "url": "https://transit.land/", "license_text": "Mapzen hereby grants to You and You hereby accept a limited, non-exclusive, royalty free, non-transferable, non-sublicensable, freely revocable, worldwide license solely to use the Licensed Material to develop Products.", "prefix": "transitland", "key": "onestop_id", "license_type": "CC0", "fullname": "Transitland", "id": 1108955939, "description": "Transitland brings together many sources of transit data to build a directory of operators and feeds that can be edited by transit enthusiasts and developers."}, "1108914995": {"name": "can-bbygov", "license": "https://www.burnaby.ca/opendata/licence.html", "url": "http://data.burnaby.ca/datasets/0023da089ff746bfb688e2531d1f2beb_9", "license_text": "you are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", "prefix": "can-bbygov", "key": "", "license_type": "Open Government License - British Columbia, v2.0", "fullname": "City of Burnaby GIS Department", "id": 1108914995, "description": "Open Data Portal for Burnaby, B.C."}, "1108827445": {"name": "hasc", "license": "http://www.statoids.com/ihasc.html", "url": "http://www.statoids.com/", "license_text": "CC0 per email with Gwillim Law of Statoids on August 11, 2015.", "prefix": "hasc", "key": "id", "license_type": "CC0", "fullname": "Statoids HASC", "id": 1108827445, "description": "Administrative subdivisions of countries; a comprehensive world reference, 1900 to 1998. Gwillim Law: \'As far as I\'m concerned, HASC codes are in the public domain - to encourage people or organizations to use them for data communication.\' The \'hasc:id\' is a variable property mapping, depending on the placetype of a record."}, "772975927": {"name": "chgov", "license": "http://data.geo.admin.ch/ch.swisstopo-vd.ortschaftenverzeichnis_plz/", "url": "http://data.geo.admin.ch", "license_text": "The information contained on the websites of the Federal Authorities is made available to the public.", "prefix": "chgov", "key": "", "license_type": "CC0", "fullname": "Swiss Confederation", "id": 772975927, "description": "The Geoportal of the Swiss Federation."}, "404734175": {"name": "geonames", "license": "http://www.geonames.org/about.html", "url": "http://www.geonames.org/", "license_text": "The GeoNames geographical database is available for download free of charge under a creative commons attribution license.", "remarks": "https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/geonames_remarks.md", "prefix": "gn", "key": "id", "license_type": "CC BY", "fullname": "GeoNames", "id": 404734175, "description": "The GeoNames geographical database covers all countries and contains over eleven million placenames that are available for download free of charge."}, "1158860607": {"name": "United Nations Convention for Road Traffic", "license": "http://www.un.org/en/sections/about-website/copyright/index.html", "url": "https://treaties.un.org/doc/Publication/MTDSG/Volume%20I/Chapter%20XI/xi-b-1.en.pdf", "license_text": "All rights reserved. None of the materials provided on this web site may be used, reproduced or transmitted, in whole or in part, in any form or by any means, electronic or mechanical, including photocopying, recording or the use of any information storage and retrieval system, except as provided for in the Terms and Conditions of Use of United Nations Web Sites, without permission in writing from the publisher.", "prefix": "uncrt", "key": "id", "license_type": "Restricted", "fullname": "United Nations Convention for Road Traffic", "id": 1158860607, "description": "The internation organization that manages the distinguishing signs of the place of registration of vehicles."}, "1158783297": {"name": "nycgov_dohmh", "license": "http://legistar.council.nyc.gov/ViewReport.ashx?M=R&N=Text&GID=61&ID=1090992&GUID=B1263195-66B9-48AD-A381-57584D623443&Title=Legislation+Text", "url": "https://data.cityofnewyork.us/Health/DOHMH-New-York-City-Restaurant-Inspection-Results/xx67-kt59", "license_text": "Such public data sets shall be made available without any registration requirement, license requirement or restrictions on their use provided that the department may require a third party providing to the public any public data set, or application utilizing such data set, to explicitly identify the source and version of the public data set, and a description of any modifications made to such public data set.", "prefix": "nycgov_dohmh", "key": "camis", "license_type": "CC0 (assumed)", "fullname": "New York City Department of Health and Mental Hygiene", "id": 1158783297, "description": "Open Data portal for New York City, NY."}, "1108962955": {"name": "ebc", "license": "http://142.34.128.33/docs/EBC-Open-Data-Licence.pdf", "url": "http://elections.bc.ca/", "license_text": "You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose", "prefix": "ebc", "key": "id", "license_type": "Elections BC Open Data Licence", "fullname": "Elections BC", "id": 1108962955, "description": "Elections BC is an independent and non-partisan Office of the Legislature, British Colombia."}, "1158783301": {"name": "sfgov_rbl", "license": "https://data.sfgov.org/terms-of-use", "url": "https://data.sfgov.org/", "license_text": "The Open Data Commons, Public Domain Dedication & Licence is a document intended to allow you to freely share, modify, and use this work for any purpose and without any restrictions. This licence is intended for use on databases or their contents (\'data\'), either together or individually.", "prefix": "sfgov_rbl", "key": "id", "license_type": "PDDL 1.0", "fullname": "City of San Francisco Treasurer & Tax Collector\'s Office (Registered Business Locations)", "id": 1158783301, "description": "Open Data portal for the City of San Francisco, CA."}, "907131617": {"name": "pedia", "license": "http://catalog.opendata.city/dataset/pediacities-nyc-neighborhoods/resource/91778048-3c58-449c-a3f9-365ed203e914", "url": "http://catalog.opendata.city/dataset/pediacities-nyc-neighborhoods", "license_text": "Subject to the terms and conditions of this License, the Licensor grants to You a worldwide, royalty-free, non-exclusive, terminable (but only under Section 9) license to Use the Database for the duration of any applicable copyright and Database Rights.", "prefix": "pedia", "key": "", "license_type": "ODC-By, v1.0", "fullname": "Pediacities", "id": 907131617, "description": "An open dataset of administrative areas in New York City."}, "1126113619": {"name": "can-rodca", "license": "http://www.regina.ca/residents/open-government/open-government-licence/", "url": "http://open.regina.ca/dataset/community-associations", "license_text": "Copy, modify, publish, translate, adapt, distribute or otherwise use the data sets in any medium, mode or format for any lawful purpose... Acknowledge the source of the Information by including any attribution statement specified by the Information Provider and, where possible, provide a link to this licence.", "prefix": "can-rodca", "key": "", "license_type": "Open Government Licence - City of Regina", "fullname": "City of Regina Open Data - Community Associations", "id": 1126113619, "description": "Boundaries provided by the City of Regina to delineate community associations."}, "1108955989": {"name": "svn-sma", "license": "https://creativecommons.org/licenses/by/2.5/si/legalcode", "url": "http://egp.gu.gov.si/egp/", "license_text": "Licensor in accordance with the terms and conditions of this License grants the user free, nonexclusive, territorial and unlimited (for the duration of the rights stipulated by the Law on copyright) license to exercise the rights at work.", "prefix": "svn-sma", "key": "", "license_type": "CC BY 2.5 SI", "fullname": "Surveying and Mapping Authority of the Republic of Slovenia", "id": 1108955989, "description": "The Surveying and Mapping Authority of the Republic of Slovenia\'s Open Data portal."}, "1108916059": {"name": "can-nwds", "license": "http://opendata.newwestcity.ca/licence", "url": "http://opendata.newwestcity.ca/datasets/neighbourhoods", "license_text": "You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", "prefix": "can-nwds", "key": "", "license_type": "OGL - City of New Westminster", "fullname": "City of New Westminster Development Services Department", "id": 1108916059, "description": "Open Data portal for the City of New Westminster, BC."}, "1108724061": {"name": "wapo", "license": "http://opendatadc.org/dataset/neighborhood-boundaries-217-neighborhoods-washpost-justgrimes", "url": "http://opendatadc.org/dataset/neighborhood-boundaries-217-neighborhoods-washpost-justgrimes", "license_text": "The Creative Commons Attribution license allows re-distribution and re-use of a licensed work on the condition that the creator is appropriately credited.", "prefix": "wapo", "key": "", "license_type": "CC-BY", "fullname": "Washington Post", "id": 1108724061, "description": "A map of neighborhood boundaries in the District of Columbia."}, "772974303": {"name": "sfac", "license": "http://www.sfartscommission.org/terms-use", "url": "http://www.sfartscommission.org/", "license_text": "As a convenience to potential users, the City and County of San Francisco (\'City\') makes a variety of datasets (\'Data\') available for download through this website. Your use of the Data is subject to these terms of use, which constitute a legal agreement between You and the City and County of San Francisco (\'City\'). This legal agreement is referred to as the \'Terms of Use.\'", "prefix": "sfac", "key": "accession_id", "license_type": "CC BY (assumed)", "fullname": "San Francisco Arts Commission", "id": 772974303, "description": "Official website for the San Francisco Arts Commission."}, "840464229": {"name": "fips", "license": "https://www.usa.gov/government-works", "url": "http://www.nist.gov/itl/fips.cfm", "license_text": "United States government creative works, including writing, images, and computer code, are usually prepared by officers or employees of the United States government as part of their official duties. A government work is generally not subject to copyright in the United States and there is generally no copyright restriction on reproduction, derivative works, distribution, performance, or display of a government work.", "prefix": "fips", "key": "code", "license_type": "CC0", "fullname": "Federal Information Processing Standards", "id": 840464229, "description": "The American National Standards Institute (ANSI) operates the National Standards System Network (NSSN). This powerful reference tool provides 24-hour access to over 65,000 references to standards and specifications from the U.S. government, U.S. private sector organizations and international standards organizations."}, "1158861161": {"name": "osm", "license": "ODbL", "url": "https://openstreetmap.org", "prefix": "osm", "key": "id", "fullname": "OpenStreetMap", "id": 1158861161, "description": "Property prefix (for concordances)."}, "840464241": {"name": "iata", "license": "http://www.iata.org/Pages/terms.aspx", "url": "http://www.iata.org/", "license_text": "All rights are reserved.", "prefix": "iata", "key": "code", "license_type": "Restricted", "fullname": "International Air Transport Association", "id": 840464241, "description": "The International Air Transport Association (IATA) is the trade association for the world\'s airlines, representing some 265 airlines or 83% of total air traffic."}, "840464249": {"name": "icao", "license": "http://www.icao.int/Pages/Disclaimer.aspx", "url": "http://www.icao.int/", "license_text": "ICAO grants permission to Users to visit the Site and to download, preprint and copy the information, documents and materials (collectively, \'Materials\') from the Site for the User\'s personal, non-commercial use, without any right to resell or redistribute them or to compile or create derivative works therefrom, subject to the terms and conditions outlined below, and also subject to more specific restrictions that may apply to specific Material within this Site. ", "prefix": "icao", "key": "code", "license_type": "Restricted", "fullname": "International Civil Aviation Organization", "id": 840464249, "description": "The International Civil Aviation Organization (ICAO) is a UN specialized agency, established by States in 1944 to manage the administration and governance of the Convention on International Civil Aviation (Chicago Convention)."}, "1126115707": {"name": "can-qcodp", "license": "http://donnees.ville.quebec.qc.ca/licence.aspx", "url": "http://donnees.ville.quebec.qc.ca/donne_details.aspx?jdid=9", "license_text": "...copy and redistribute the material in any medium or format...remix, transform, and build upon the material for any purpose, even commercially...You must give appropriate credit, provide a link to the license, and indicate if changes were made.", "prefix": "can-qcodp", "key": "", "license_type": "CC BY 4.0", "fullname": "Quebec City Open Data Portal", "id": 1126115707, "description": "Neighbourhood (district) data provided by Quebec City."}, "1108808939": {"name": "ssuberlin", "license": "http://www.stadtentwicklung.berlin.de/geoinformation/download/nutzIII.pdf", "url": "http://daten.berlin.de/datensaetze?field_category_tid%5B%5D=231", "license_text": "Geodata and geodata services, including associated metadata, shall be used for: All currently known as well as for all future known commercial and not. Commercial use, as far as possible by special. Legal provisions, or contractual or legal rights. Third does not oppose it.", "prefix": "ssuberlin", "key": "", "license_type": "CC0 (assumed)", "fullname": "Senatsverwaltung fur Stadtentwicklung und Umwelt Berlin", "id": 1108808939, "description": "Bezirke (districts) and Ortsteile (localities) provided under an open data license."}, "840464261": {"name": "tgn", "license": "http://opendatacommons.org/licenses/by/1-0/", "url": "https://www.getty.edu/research/tools/vocabularies/tgn/index.html", "license_text": "The Open Data Commons Attribution License is a license agreement intended to allow users to freely share, modify, and use this Database subject only to the attribution requirements set out in Section 4.", "prefix": "tgn", "key": "id", "license_type": "ODC-By, v1.0", "fullname": "Getty Thesaurus of Geographic Names", "id": 840464261, "description": "The TGN is an evolving vocabulary, growing and changing thanks to contributions from Getty projects and other institutions."}, "840464273": {"name": "nytimes", "license": "https://www.nytimes.com/content/help/rights/terms/terms-of-service.html", "url": "http://www.nytimes.com/", "license_text": "You may not sublicense, assign or transfer any licenses granted by NYTimes.com, and any attempt at such sublicense, assignment or transfer shall be null and void.", "prefix": "nyt", "key": "id", "license_type": "Restricted", "fullname": "The New York Times", "id": 840464273, "description": "The New York Times."}, "1158783299": {"name": "nycgov_dca", "license": "http://legistar.council.nyc.gov/ViewReport.ashx?M=R&N=Text&GID=61&ID=1090992&GUID=B1263195-66B9-48AD-A381-57584D623443&Title=Legislation+Text", "url": "https://data.cityofnewyork.us/Business/Legally-Operating-Businesses/w7w3-xahh/data", "license_text": "Such public data sets shall be made available without any registration requirement, license requirement or restrictions on their use provided that the department may require a third party providing to the public any public data set, or application utilizing such data set, to explicitly identify the source and version of the public data set, and a description of any modifications made to such public data set.", "prefix": "nycgov_dca", "key": "license", "license_type": "CC0 (assumed)", "fullname": "New York City Department of Consumer Affairs", "id": 1158783299, "description": "Open Data portal for New York City, NY."}, "1108802967": {"name": "amsgis", "license": "https://kaart.amsterdam.nl/datasets", "url": "https://kaart.amsterdam.nl", "license_text": "N/A", "prefix": "amsgis", "key": "", "license_type": "CC BY (assumed)", "fullname": "Amsterdam Open Datakaart", "id": 1108802967, "description": "Layers are viewable from the link in the url field as Buurten (microhoods), Buurtcombinaties (neighbourhoods), and Stadsdelen en Haven (boroughs). Open source information as well as downloadable datasets are available from the link in the license field."}, "840464281": {"name": "dbpedia", "license": "http://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License", "url": "http://dbpedia.org/", "license_text": "You are free to Share, to copy, distribute and transmit the work, and to Remix, to adapt the work for any purpose, even commercially.", "prefix": "dbp", "key": "id", "license_type": "CC BY-SA 3.0 Unported License", "fullname": "DBpedia", "id": 840464281, "description": "Towards a Public Data Infrastructure for a Large, Multilingual, Semantic Knowledge Graph."}, "857004783": {"name": "begov", "license": "http://www.geopunt.be/nl/over-geopunt/disclaimer", "url": "http://www.geopunt.be/download?container=referentiebestand-gemeenten&title=Voorlopig%20referentiebestand%20gemeentegrenzen", "license_text": "The licensee is given the non-exclusive, worldwide right to reuse the product for each legitimate purpose, including reproducing, transmitting, publishing, adapting and commercial exploitation of the product.", "prefix": "begov", "key": "id", "license_type": "Free Open Data License Flanders v1.0", "fullname": "Voorlopig Referentiebestand Gemeentegrenzen", "id": 857004783, "description": "Geopunt is the central Flesmish gateway to geographic government information. The geoportal makes geographical information accessible to government agencies, citizens, organizations and companies."}, "404734207": {"name": "woedb", "license": "N/A", "url": "http://woe.spum.org/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "woedb", "key": "id", "license_type": "CC0", "fullname": "WOE DB", "id": 404734207, "description": "Clickable database of Where On Earth (woe) ids."}, "840464287": {"name": "freebase", "license": "https://developers.google.com/freebase/", "url": "https://developers.google.com/freebase/", "license_text": "Freebase constitutes a snapshot of the data stored in Freebase and the Schema that structures it, and are provided under the same CC-BY license. The Freebase/Wikidata mappings are provided under the CC0 license.", "prefix": "fb", "key": "id", "license_type": "CC BY", "fullname": "Freebase", "id": 840464287, "description": "Freebase was a large collaborative knowledge base consisting of data composed mainly by its community members. It was an online collection of structured data harvested from many sources, including individual, user-submitted wiki contributions. See also: http://creativecommons.org/licenses/by/2.5/."}, "1108729077": {"name": "kuogov", "license": "https://www.avoindata.fi/data/fi/dataset/kuopion-kaupunginosat", "url": "https://www.avoindata.fi/data/fi/dataset/kuopion-kaupunginosat/resource/6ca89290-3743-4832-9ed6-03d8cf9b2d5f", "license_text": "You are free to: Share, copy and redistribute the material in any medium or format and Adapt, remix, transform, and build upon the material for any purpose, even commercially.", "prefix": "kuogov", "key": "", "license_type": "CC BY 4.0", "fullname": "City of Kuopio", "id": 1108729077, "description": "Official website for the City of Kuopio, Finland."}, "840464293": {"name": "faa", "license": "https://www.usa.gov/government-works", "url": "http://www.faa.gov/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "faa", "key": "code", "license_type": "CC0 1.0 Universal", "fullname": "Federal Aviation Administration", "id": 840464293, "description": "Homepage for the Federal Aviation Administration."}, "1108794097": {"name": "oakced", "license": "https://data.oaklandnet.com/Property/Oakland-Neighborhoods/7zky-kcq9/about", "url": "https://data.oaklandnet.com/Property/Oakland-Neighborhoods/7zky-kcq9", "license_text": "", "prefix": "oakced", "key": "", "license_type": "Public Domain", "fullname": "Oakland Community and Economic Development Department", "id": 1108794097, "description": "Open Data portal for the City of Oakland, CA."}, "857125801": {"name": "figov", "license": "http://www.maanmittauslaitos.fi/en/opendata-licence-cc40", "url": "http://www.maanmittauslaitos.fi/en/digituotteet/municipal-division-finland", "license_text": "Mention the name of the Licensor, the name of the dataset(s) and the time when the National Land Survey has delivered the dataset(s) (e.g.: contains data from the National Land Survey of Finland Topographic Database", "prefix": "figov", "key": "id", "license_type": "CC BY 4.0", "fullname": "NLS National Land Survey of Finland", "id": 857125801, "description": "National Land Survey of Finland performs various kinds of cadastral surveys such as parcelling and reallocations of pieces of land, produces map data and promotes the joint use of such data."}, "1108756907": {"name": "meso", "license": "https://github.com/whosonfirst-data/whosonfirst-data/blob/master/LICENSE.md", "url": "https://github.com/whosonfirst-data/whosonfirst-data/blob/master/LICENSE.md", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "remarks": "https://github.com/whosonfirst/whosonfirst-sources/blob/master/sources/meso_remarks.md", "prefix": "meso", "key": "", "license_type": "CC0", "fullname": "Mesoshapes", "id": 1108756907, "description": "Mesoshapes are a product of Mapzen for Who\'s On First."}, "840464301": {"name": "loc", "license": "https://www.loc.gov/legal/", "url": "http://www.loc.gov", "license_text": "Unless otherwise indicated on this site, the Library of Congress has no objection to the international use and reuse of Library U.S. Government works on loc.gov. These works are also available for worldwide use and reuse under CC0 1.0 Universal.", "prefix": "loc", "key": "id", "license_type": "CC0", "fullname": "Library of Congress", "id": 840464301, "description": "The Library of Congress is the largest library in the world, with millions of books, recordings, photographs, newspapers, maps and manuscripts in its collections. The Library is the main research arm of the U.S. Congress and the home of the U.S. Copyright Office."}, "840464303": {"name": "mapzenborders", "license": "https://mapzen.com/terms/", "url": "https://mapzen.com/data/borders/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "mzb", "key": "id", "license_type": "CC0", "fullname": "Mapzen Borders", "id": 840464303, "description": "Country, region and city boundary data from OpenStreetMap, served monthly until October 2016."}, "1108832191": {"name": "addr", "license": "N/A", "url": "", "license_text": "", "prefix": "addr", "key": "id", "license_type": "N/A", "fullname": "addr", "id": 1108832191, "description": "Property prefix."}, "554867137": {"name": "uszcta", "license": "https://www.census.gov/data/developers/about/terms-of-service.html", "url": "http://www.census.gov/geo/reference/zctas.html", "license_text": "All U.S. Census Bureau materials, regardless of the media, are entirely in the public domain. There are no user fees, site licenses, or any special agreements etc for the public or private use, and or reuse of any census title. As tax funded product, it\'s all in the public record.", "prefix": "uszcta", "key": "id", "license_type": "CC0", "fullname": "US ZIP Code Tabulation Area", "id": 554867137, "description": "ZIP Code Tabulation Areas (ZCTAs) are generalized areal representations of United States Postal Service (USPS) ZIP Code service areas."}, "874342855": {"name": "hsgov", "license": "http://www.hri.fi/en/dataset/helsingin-kaupunginosat", "url": "http://ptp.hel.fi/avoindata/aineistot/Helsingin_kaupunginosat.zip", "license_text": "You are free to: Share, copy and redistribute the material in any medium or format and Adapt, remix, transform, and build upon the material for any purpose, even commercially.", "prefix": "hsgov", "key": "id", "license_type": "CC BY 4.0", "fullname": "Helsinki Region Infoshare", "id": 874342855, "description": "HRI is a web service for fast and easy access to open data sources between the cities of Helsinki, Espoo, Vantaa and Kauniainen."}, "554906275": {"name": "statcan", "license": "http://www.statcan.gc.ca/eng/reference/licence-eng", "url": "http://statcan.gc.ca/", "license_text": "Subject to this agreement, Statistics Canada grants you a worldwide, royalty-free, non-exclusive licence to: use, reproduce, publish, freely distribute, or sell the Information; use, reproduce, publish, freely distribute, or sell Value-added Products; and, sublicence any or all such rights, under terms consistent with this agreement.", "prefix": "statcan", "key": "", "license_type": "CC BY (assumed)", "fullname": "Statistics Canada", "id": 554906275, "description": "Statistics Canada produces statistics that help Canadians better understand their country,its population, resources, economy, society and culture."}, "1108693461": {"name": "ausstat", "license": "http://www.abs.gov.au/websitedbs/D3310114.nsf/Home/%A9+Copyright?opendocument", "url": "http://www.abs.gov.au/AUSSTATS/abs@.nsf/DetailsPage/1270.0.55.003July%202011?OpenDocument", "license_text": "Unless otherwise noted, all material on this website, except the ABS logo, the Commonwealth Coat of Arms, and any material protected by a trade mark, is licensed under a Creative Commons Attribution 2.5 Australia licence.", "prefix": "ausstat", "key": "", "license_type": "CC BY 2.5 AU", "fullname": "Australian Bureau of Statistics", "id": 1108693461, "description": "The ABS is Australia\'s national statistical agency, providing trusted official statistics on a wide range of economic, social, population and environmental matters of importance to Australia."}, "1108728281": {"name": "tmpgov", "license": "http://www.tampere.fi/tampereen-kaupunki/tietoa-tampereesta/avoin-data/avoin-data-lisenssi.html", "url": "http://opendata.navici.com/tampere/opendata/ows?service=WFS&version=2.0.0&request=GetFeature&typeName=opendata:KH_TILASTO&outputFormat=json", "license_text": "This is a worldwide, royalty-free, irrevocable, parallel license allowing the above-mentioned material to be freely available to 1. Copy and distribute. 2. Modify and utilize commercially and non-commercially to combine with other products. 3. Used as part of an application or service.", "prefix": "tmpgov", "key": "", "license_type": "CC0 (assumed)", "fullname": "Tampere City Survey GIS", "id": 1108728281, "description": "Open Data portal for the City of Tampere, Finland."}, "1108713437": {"name": "camgov", "license": "https://data.cambridgema.gov/download/tif9-pmiw/application/pdf", "url": "http://www.cambridgema.gov/GIS/gisdatadictionary/Boundary/BOUNDARY_CDDNeighborhoods", "license_text": "Any user of Data distributed by the City may modify, use and publish such Data without charge.", "prefix": "camgov", "key": "", "license_type": "CC BY", "fullname": "City of Cambridge Geographic Information System Department", "id": 1108713437, "description": "Neighbourhood data for the City of Cambrige, MA."}, "1108970467": {"name": "can-edmdsd", "license": "https://www.edmonton.ca/city_government/documents/Web-version2.1-OpenDataAgreement.pdf", "url": "https://data.edmonton.ca/Geospatial-Boundaries/City-of-Edmonton-Neighbourhood-Boundaries-with-War/jfvj-x253", "license_text": "The City of Edmonton (the City) grants you a worldwide, royalty-free, non-exclusive licence to use, modify, and distribute the datasets in all current and future media and formats for any lawful purpose, including for commercial purposes. You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the datasets in any medium, mode or format for any lawful purpose.", "prefix": "can-edmdsd", "key": "", "license_type": "Open Government Licence - Edmonton", "fullname": "City of Edmonton Department of Sustainable Development", "id": 1108970467, "description": "Neighbourhood/Ward data provided by the City of Edmonton Department of Sustainable Development."}, "404734187": {"name": "whereonearth", "license": "http://developer.yahoo.com/geo/geoplanet/data/", "url": "http://developer.yahoo.com/geo/geoplanet/", "license_text": "This page provides open access to the underlying data under a Creative Commons Attribution license so that you can incorporate WOEIDs and the GeoPlanet hierarchy into your own applications.", "prefix": "woe", "key": "id", "license_type": "CC BY", "fullname": "Yahoo! GeoPlanet (formerly Where On Earth)", "id": 404734187, "description": "Cached, accessed: 2017-05-11, via: https://web.archive.org/web/20111028163611/http://developer.yahoo.com/geo/geoplanet/data/."}, "874397693": {"name": "acgov", "license": "https://data.acgov.org/terms-of-use", "url": "https://data.acgov.org/", "license_text": "You understand and agree that Your use of the Data is at Your sole risk. The Data is made available on an \'as is\' and \'as available\' basis without any warranties of any kind, whether express or implied, including without limitation implied warranties of merchantability, fitness for a particular purpose, and non-infringement. Should there be an error, inaccuracy, or other defect in the Data, You assume the full cost of correcting any such error, inaccuracy or defect.", "prefix": "acgov", "key": "", "license_type": "Public Domain", "fullname": "Alameda County Data Sharing Initiative", "id": 874397693, "description": "Official GIS Data for Alameda County, CA."}, "1108961115": {"name": "acme", "license": "https://acme.com/license.html", "url": "https://acme.com/", "license_text": "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.", "prefix": "acme", "key": "id", "license_type": "BSD (modified)", "fullname": "Acme Laboratories", "id": 1108961115, "description": "Purveyors of fine freeware since 1972. On the net since 1991."}, "1108951549": {"name": "can-surgis", "license": "http://data.surrey.ca/pages/open-government-licence-surrey", "url": "https://data.surrey.ca/dataset/surrey-city-boundary", "license_text": "You are free to copy, modify, publish, translate, adapt, distribute or otherwise use the Information in any medium, mode or format for any lawful purpose.", "prefix": "can-surgis", "key": "", "license_type": "OGL - City of Surrey", "fullname": "City of Surrey GIS Section", "id": 1108951549, "description": "Open data portal for the City of Surrey, BC."}, "1158818289": {"name": "statoids", "license": "Data provided under special license agreement with http://www.statoids.com", "url": "http://www.statoids.com", "license_text": "The Licensed Materials are licensed, not sold to Mapzen. Statoids grants to Mapzen world-wide, fully-paid, perpetual, non-exclusive right to use the Licensed Materials for any purpose. The parties acknowledge and agree that such rights include, but are not limited to the right to (a) copy, duplicate, reproduce or publish the Licensed Materials or any of their contents; (b) distribute, assign transfer, sub-license the Licensed Materials, the contents of the Licensed Materials or copies thereof, to third parties by any means whatsoever; (d) change, modify, adapt, translate, reverse engineer, disassemble or decompile the Licensed Materials or create derivative works based on the Licensed Materials, or copies thereof, or (e) bundle, repackage, or include the Licensed Materials with any software in any way. By way of explanation, and not limitation, the parties acknowledge that the intent of this license is to give Mapzen all rights in the data other than title. Mapzen agrees that it shall use commercially reasonable efforts to attribute Statoids\' ownership of the Licensed Material whenever it publishes the Licensed Materials.", "prefix": "statoids", "key": "", "license_type": "CC BY", "fullname": "Statoids", "id": 1158818289, "description": "Statoids is an online database that organizes the primary and secondary administrative divisions for all countries, dependencies, and disputed areas of the world. Properties imported under CC-BY license from Statoids via special arrangement with the author."}, "1108800651": {"name": "sdgis", "license": "http://www.sangis.org/Legal_Notice.htm", "url": "http://rdw.sandag.org/Account/GetFSFile.aspx?dir=Law&Name=SDPD_BEATS.zip", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "sdgis", "key": "", "license_type": "CC0", "fullname": "SanGIS/SANDAG GIS Data Warehouse", "id": 1108800651, "description": "The San Diego Geographic Information Source (SanGIS) is a Joint Powers Authority (JPA) of the City of San Diego and the County of San Diego responsible for maintaining a regional geographic information system (GIS) landbase and data warehouse."}, "1108713463": {"name": "porbps", "license": "https://www.arcgis.com/home/item.html?id=c11815647b3949faa20b16cf50ab214d", "url": "http://gis.pdx.opendata.arcgis.com/datasets/c11815647b3949faa20b16cf50ab214d_125", "license_text": "\'Intention is free and open use, licensed for the public domain. For now, you can assume the data is completely open.\'", "prefix": "porbps", "key": "", "license_type": "Public Domain", "fullname": "City of Portland Bureau of Planning and Sustainability", "id": 1108713463, "description": "Confirmed Public Domain by Kevin Martin of the Portland BPS on 2016-10-07 "}, "874397695": {"name": "smcgov", "license": "https://creativecommons.org/publicdomain/zero/1.0/legalcode", "url": "https://data.smcgov.org/", "license_text": "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.", "prefix": "smcgov", "key": "", "license_type": "CC0", "fullname": "Open San Mateo County", "id": 874397695, "description": "Open San Mateo County contains data published by the County of San Mateo."}, "1158844413": {"name": "esp-cartobcn", "license": "http://w133.bcn.cat/geoportal/descargas/en_gb_cond_us_carto.pdf", "url": "http://w20.bcn.cat/cartobcn/", "license_text": "...their use for commercial and non-commercial purposes...their modification, transformation and adaptation...so long as reference is made to Barcelona City Council\'s authorship...", "prefix": "esp-cartobcn", "key": "", "license_type": "CC BY", "fullname": "CartoBCN", "id": 1158844413, "description": "Neighbourhood (district) data as provided by the Barcelona City Council (CartoBCN)."}, "1158844927": {"name": "esp-aytomad", "license": "http://datos.madrid.es/egob/catalogo/aviso-legal", "url": "http://datos.madrid.es/portal/site/egob/menuitem.c05c1f754a33a9fbe4b2e4b284f1a5a0/?vgnextoid=46b55cde99be2410VgnVCM1000000b205a0aRCRD&vgnextchannel=374512b9ace9f310VgnVCM100000171f5a0aRCRD&vgnextfmt=default", "license_text": "Las condiciones generales permiten la reutilizaci\u00f3n de los documentos para fines comerciales y no comerciales. Se entiende por reutilizaci\u00f3n el uso de documentos que obran en poder del Ayuntamiento de Madrid, siempre que dicho uso no constituya una actividad administrativa p\u00fablica.", "prefix": "esp-aytomad", "key": "", "license_type": "CC0 (equivalent)", "fullname": "Portal de datos abiertos del Ayuntamiento de Madrid", "id": 1158844927, "description": "Neighbourhood and district data provided by the City of Madrid."}}'; ######################################################################## # the end diff --git a/www/include/lib_whosonfirst_spatial.php b/www/include/lib_whosonfirst_spatial.php index 0bff41b..80ad2a8 100644 --- a/www/include/lib_whosonfirst_spatial.php +++ b/www/include/lib_whosonfirst_spatial.php @@ -56,19 +56,24 @@ function whosonfirst_spatial_index_feature(&$feature, $more=array()){ $cmd = implode(" ", $cmd); - $rsp = whosonfirst_spatial_do($cmd, $more); + foreach ($GLOBALS['cfg']['spatial_tile38_endpoints'] as $endpoint){ - if (! $rsp['ok']){ - return $rsp; - } + $more['endpoint'] = $endpoint; - $rsp2 = whosonfirst_spatial_index_meta($props, $more); + $rsp = whosonfirst_spatial_do($cmd, $more); - if (! $rsp2['ok']){ - return $rsp2; + if (! $rsp['ok']){ + return $rsp; + } + + $rsp2 = whosonfirst_spatial_index_meta($props, $more); + + if (! $rsp2['ok']){ + return $rsp2; + } } - return $rsp; + return array('ok' => 1); } ######################################################################## @@ -100,6 +105,8 @@ function whosonfirst_spatial_nearby_latlon($lat, $lon, $r, $more=array()){ $where = array(); + # see also: api_whosonfirst_ensure_existential_flags() + $possible = array( "wof:id", "wof:placetype_id", @@ -315,9 +322,10 @@ function whosonfirst_spatial_append_meta(&$rsp, $more=array()){ function whosonfirst_spatial_do($cmd, $more=array()){ + $endpoint = whosonfirst_spatial_endpoint(); + $defaults = array( - 'host' => $GLOBALS['cfg']['spatial_tile38_host'], - 'port' => $GLOBALS['cfg']['spatial_tile38_port'], + 'endpoint' => $endpoint, 'collection' => $GLOBALS['cfg']['spatial_tile38_collection'], ); @@ -407,4 +415,14 @@ function whosonfirst_spatial_inflate_results($rsp){ ######################################################################## + function whosonfirst_spatial_endpoint(){ + + shuffle($GLOBALS['cfg']['spatial_tile38_endpoints']); + $endpoint = $GLOBALS['cfg']['spatial_tile38_endpoints'][0]; + + return $endpoint; + } + + ######################################################################## + # the end diff --git a/www/javascript/L.Control.Locate.js b/www/javascript/L.Control.Locate.js new file mode 100644 index 0000000..8544e17 --- /dev/null +++ b/www/javascript/L.Control.Locate.js @@ -0,0 +1,591 @@ +/*! +Copyright (c) 2016 Dominik Moritz + +This file is part of the leaflet locate control. It is licensed under the MIT license. +You can find the project at: https://github.com/domoritz/leaflet-locatecontrol +*/ +(function (factory, window) { + // see https://github.com/Leaflet/Leaflet/blob/master/PLUGIN-GUIDE.md#module-loaders + // for details on how to structure a leaflet plugin. + + // define an AMD module that relies on 'leaflet' + if (typeof define === 'function' && define.amd) { + define(['leaflet'], factory); + + // define a Common JS module that relies on 'leaflet' + } else if (typeof exports === 'object') { + if (typeof window !== 'undefined' && window.L) { + module.exports = factory(L); + } else { + module.exports = factory(require('leaflet')); + } + } + + // attach your plugin to the global 'L' variable + if (typeof window !== 'undefined' && window.L){ + window.L.Control.Locate = factory(L); + } +} (function (L) { + var LDomUtilApplyClassesMethod = function(method, element, classNames) { + classNames = classNames.split(' '); + classNames.forEach(function(className) { + L.DomUtil[method].call(this, element, className); + }); + }; + + var addClasses = function(el, names) { LDomUtilApplyClassesMethod('addClass', el, names); }; + var removeClasses = function(el, names) { LDomUtilApplyClassesMethod('removeClass', el, names); }; + + var LocateControl = L.Control.extend({ + options: { + /** Position of the control */ + position: 'topleft', + /** The layer that the user's location should be drawn on. By default creates a new layer. */ + layer: undefined, + /** + * Automatically sets the map view (zoom and pan) to the user's location as it updates. + * While the map is following the user's location, the control is in the `following` state, + * which changes the style of the control and the circle marker. + * + * Possible values: + * - false: never updates the map view when location changes. + * - 'once': set the view when the location is first determined + * - 'always': always updates the map view when location changes. + * The map view follows the users location. + * - 'untilPan': (default) like 'always', except stops updating the + * view if the user has manually panned the map. + * The map view follows the users location until she pans. + */ + setView: 'untilPan', + /** Keep the current map zoom level when setting the view and only pan. */ + keepCurrentZoomLevel: false, + /** Smooth pan and zoom to the location of the marker. Only works in Leaflet 1.0+. */ + flyTo: false, + /** + * The user location can be inside and outside the current view when the user clicks on the + * control that is already active. Both cases can be configures separately. + * Possible values are: + * - 'setView': zoom and pan to the current location + * - 'stop': stop locating and remove the location marker + */ + clickBehavior: { + /** What should happen if the user clicks on the control while the location is within the current view. */ + inView: 'stop', + /** What should happen if the user clicks on the control while the location is outside the current view. */ + outOfView: 'setView', + }, + /** + * If set, save the map bounds just before centering to the user's + * location. When control is disabled, set the view back to the + * bounds that were saved. + */ + returnToPrevBounds: false, + /** + * Keep a cache of the location after the user deactivates the control. If set to false, the user has to wait + * until the locate API returns a new location before they see where they are again. + */ + cacheLocation: true, + /** If set, a circle that shows the location accuracy is drawn. */ + drawCircle: true, + /** If set, the marker at the users' location is drawn. */ + drawMarker: true, + /** The class to be used to create the marker. For example L.CircleMarker or L.Marker */ + markerClass: L.CircleMarker, + /** Accuracy circle style properties. */ + circleStyle: { + color: '#136AEC', + fillColor: '#136AEC', + fillOpacity: 0.15, + weight: 2, + opacity: 0.5 + }, + /** Inner marker style properties. Only works if your marker class supports `setStyle`. */ + markerStyle: { + color: '#136AEC', + fillColor: '#2A93EE', + fillOpacity: 0.7, + weight: 2, + opacity: 0.9, + radius: 5 + }, + /** + * Changes to accuracy circle and inner marker while following. + * It is only necessary to provide the properties that should change. + */ + followCircleStyle: {}, + followMarkerStyle: { + // color: '#FFA500', + // fillColor: '#FFB000' + }, + /** The CSS class for the icon. For example fa-location-arrow or fa-map-marker */ + icon: 'fa fa-map-marker', + iconLoading: 'fa fa-spinner fa-spin', + /** The element to be created for icons. For example span or i */ + iconElementTag: 'span', + /** Padding around the accuracy circle. */ + circlePadding: [0, 0], + /** Use metric units. */ + metric: true, + /** + * This callback can be used in case you would like to override button creation behavior. + * This is useful for DOM manipulation frameworks such as angular etc. + * This function should return an object with HtmlElement for the button (link property) and the icon (icon property). + */ + createButtonCallback: function (container, options) { + var link = L.DomUtil.create('a', 'leaflet-bar-part leaflet-bar-part-single', container); + link.title = options.strings.title; + var icon = L.DomUtil.create(options.iconElementTag, options.icon, link); + return { link: link, icon: icon }; + }, + /** This event is called in case of any location error that is not a time out error. */ + onLocationError: function(err, control) { + alert(err.message); + }, + /** + * This even is called when the user's location is outside the bounds set on the map. + * The event is called repeatedly when the location changes. + */ + onLocationOutsideMapBounds: function(control) { + control.stop(); + alert(control.options.strings.outsideMapBoundsMsg); + }, + /** Display a pop-up when the user click on the inner marker. */ + showPopup: true, + strings: { + title: "Show me where I am", + metersUnit: "meters", + feetUnit: "feet", + popup: "You are within {distance} {unit} from this point", + outsideMapBoundsMsg: "You seem located outside the boundaries of the map" + }, + /** The default options passed to leaflets locate method. */ + locateOptions: { + maxZoom: Infinity, + watch: true, // if you overwrite this, visualization cannot be updated + setView: false // have to set this to false because we have to + // do setView manually + } + }, + + initialize: function (options) { + // set default options if nothing is set (merge one step deep) + for (var i in options) { + if (typeof this.options[i] === 'object') { + L.extend(this.options[i], options[i]); + } else { + this.options[i] = options[i]; + } + } + + // extend the follow marker style and circle from the normal style + this.options.followMarkerStyle = L.extend({}, this.options.markerStyle, this.options.followMarkerStyle); + this.options.followCircleStyle = L.extend({}, this.options.circleStyle, this.options.followCircleStyle); + }, + + /** + * Add control to map. Returns the container for the control. + */ + onAdd: function (map) { + var container = L.DomUtil.create('div', + 'leaflet-control-locate leaflet-bar leaflet-control'); + + this._layer = this.options.layer || new L.LayerGroup(); + this._layer.addTo(map); + this._event = undefined; + this._prevBounds = null; + + var linkAndIcon = this.options.createButtonCallback(container, this.options); + this._link = linkAndIcon.link; + this._icon = linkAndIcon.icon; + + L.DomEvent + .on(this._link, 'click', L.DomEvent.stopPropagation) + .on(this._link, 'click', L.DomEvent.preventDefault) + .on(this._link, 'click', this._onClick, this) + .on(this._link, 'dblclick', L.DomEvent.stopPropagation); + + this._resetVariables(); + + this._map.on('unload', this._unload, this); + + return container; + }, + + /** + * This method is called when the user clicks on the control. + */ + _onClick: function() { + this._justClicked = true; + this._userPanned = false; + + if (this._active && !this._event) { + // click while requesting + this.stop(); + } else if (this._active && this._event !== undefined) { + var behavior = this._map.getBounds().contains(this._event.latlng) ? + this.options.clickBehavior.inView : this.options.clickBehavior.outOfView; + switch (behavior) { + case 'setView': + this.setView(); + break; + case 'stop': + this.stop(); + if (this.options.returnToPrevBounds) { + var f = this.options.flyTo ? this._map.flyToBounds : this._map.fitBounds; + f.bind(this._map)(this._prevBounds); + } + break; + } + } else { + if (this.options.returnToPrevBounds) { + this._prevBounds = this._map.getBounds(); + } + this.start(); + } + + this._updateContainerStyle(); + }, + + /** + * Starts the plugin: + * - activates the engine + * - draws the marker (if coordinates available) + */ + start: function() { + this._activate(); + + if (this._event) { + this._drawMarker(this._map); + + // if we already have a location but the user clicked on the control + if (this.options.setView) { + this.setView(); + } + } + this._updateContainerStyle(); + }, + + /** + * Stops the plugin: + * - deactivates the engine + * - reinitializes the button + * - removes the marker + */ + stop: function() { + this._deactivate(); + + this._cleanClasses(); + this._resetVariables(); + + this._removeMarker(); + }, + + /** + * This method launches the location engine. + * It is called before the marker is updated, + * event if it does not mean that the event will be ready. + * + * Override it if you want to add more functionalities. + * It should set the this._active to true and do nothing if + * this._active is true. + */ + _activate: function() { + if (!this._active) { + this._map.locate(this.options.locateOptions); + this._active = true; + + // bind event listeners + this._map.on('locationfound', this._onLocationFound, this); + this._map.on('locationerror', this._onLocationError, this); + this._map.on('dragstart', this._onDrag, this); + } + }, + + /** + * Called to stop the location engine. + * + * Override it to shutdown any functionalities you added on start. + */ + _deactivate: function() { + this._map.stopLocate(); + this._active = false; + + if (!this.options.cacheLocation) { + this._event = undefined; + } + + // unbind event listeners + this._map.off('locationfound', this._onLocationFound, this); + this._map.off('locationerror', this._onLocationError, this); + this._map.off('dragstart', this._onDrag, this); + }, + + /** + * Zoom (unless we should keep the zoom level) and an to the current view. + */ + setView: function() { + this._drawMarker(); + if (this._isOutsideMapBounds()) { + this._event = undefined; // clear the current location so we can get back into the bounds + this.options.onLocationOutsideMapBounds(this); + } else { + if (this.options.keepCurrentZoomLevel) { + var f = this.options.flyTo ? this._map.flyTo : this._map.panTo; + f.bind(this._map)([this._event.latitude, this._event.longitude]); + } else { + var f = this.options.flyTo ? this._map.flyToBounds : this._map.fitBounds; + f.bind(this._map)(this._event.bounds, { + padding: this.options.circlePadding, + maxZoom: this.options.locateOptions.maxZoom + }); + } + } + }, + + /** + * Draw the marker and accuracy circle on the map. + * + * Uses the event retrieved from onLocationFound from the map. + */ + _drawMarker: function() { + if (this._event.accuracy === undefined) { + this._event.accuracy = 0; + } + + var radius = this._event.accuracy; + var latlng = this._event.latlng; + + // circle with the radius of the location's accuracy + if (this.options.drawCircle) { + var style = this._isFollowing() ? this.options.followCircleStyle : this.options.circleStyle; + + if (!this._circle) { + this._circle = L.circle(latlng, radius, style).addTo(this._layer); + } else { + this._circle.setLatLng(latlng).setRadius(radius).setStyle(style); + } + } + + var distance, unit; + if (this.options.metric) { + distance = radius.toFixed(0); + unit = this.options.strings.metersUnit; + } else { + distance = (radius * 3.2808399).toFixed(0); + unit = this.options.strings.feetUnit; + } + + // small inner marker + if (this.options.drawMarker) { + var mStyle = this._isFollowing() ? this.options.followMarkerStyle : this.options.markerStyle; + if (!this._marker) { + this._marker = new this.options.markerClass(latlng, mStyle).addTo(this._layer); + } else { + this._marker.setLatLng(latlng); + // If the markerClass can be updated with setStyle, update it. + if (this._marker.setStyle) { + this._marker.setStyle(mStyle); + } + } + } + + var t = this.options.strings.popup; + if (this.options.showPopup && t && this._marker) { + this._marker + .bindPopup(L.Util.template(t, {distance: distance, unit: unit})) + ._popup.setLatLng(latlng); + } + }, + + /** + * Remove the marker from map. + */ + _removeMarker: function() { + this._layer.clearLayers(); + this._marker = undefined; + this._circle = undefined; + }, + + /** + * Unload the plugin and all event listeners. + * Kind of the opposite of onAdd. + */ + _unload: function() { + this.stop(); + this._map.off('unload', this._unload, this); + }, + + /** + * Calls deactivate and dispatches an error. + */ + _onLocationError: function(err) { + // ignore time out error if the location is watched + if (err.code == 3 && this.options.locateOptions.watch) { + return; + } + + this.stop(); + this.options.onLocationError(err, this); + }, + + /** + * Stores the received event and updates the marker. + */ + _onLocationFound: function(e) { + // no need to do anything if the location has not changed + if (this._event && + (this._event.latlng.lat === e.latlng.lat && + this._event.latlng.lng === e.latlng.lng && + this._event.accuracy === e.accuracy)) { + return; + } + + if (!this._active) { + // we may have a stray event + return; + } + + this._event = e; + + this._drawMarker(); + this._updateContainerStyle(); + + switch (this.options.setView) { + case 'once': + if (this._justClicked) { + this.setView(); + } + break; + case 'untilPan': + if (!this._userPanned) { + this.setView(); + } + break; + case 'always': + this.setView(); + break; + case false: + // don't set the view + break; + } + + this._justClicked = false; + }, + + /** + * When the user drags. Need a separate even so we can bind and unbind even listeners. + */ + _onDrag: function() { + // only react to drags once we have a location + if (this._event) { + this._userPanned = true; + this._updateContainerStyle(); + this._drawMarker(); + } + }, + + /** + * Compute whether the map is following the user location with pan and zoom. + */ + _isFollowing: function() { + if (!this._active) { + return false; + } + + if (this.options.setView === 'always') { + return true; + } else if (this.options.setView === 'untilPan') { + return !this._userPanned; + } + }, + + /** + * Check if location is in map bounds + */ + _isOutsideMapBounds: function() { + if (this._event === undefined) { + return false; + } + return this._map.options.maxBounds && + !this._map.options.maxBounds.contains(this._event.latlng); + }, + + /** + * Toggles button class between following and active. + */ + _updateContainerStyle: function() { + if (!this._container) { + return; + } + + if (this._active && !this._event) { + // active but don't have a location yet + this._setClasses('requesting'); + } else if (this._isFollowing()) { + this._setClasses('following'); + } else if (this._active) { + this._setClasses('active'); + } else { + this._cleanClasses(); + } + }, + + /** + * Sets the CSS classes for the state. + */ + _setClasses: function(state) { + if (state == 'requesting') { + removeClasses(this._container, "active following"); + addClasses(this._container, "requesting"); + + removeClasses(this._icon, this.options.icon); + addClasses(this._icon, this.options.iconLoading); + } else if (state == 'active') { + removeClasses(this._container, "requesting following"); + addClasses(this._container, "active"); + + removeClasses(this._icon, this.options.iconLoading); + addClasses(this._icon, this.options.icon); + } else if (state == 'following') { + removeClasses(this._container, "requesting"); + addClasses(this._container, "active following"); + + removeClasses(this._icon, this.options.iconLoading); + addClasses(this._icon, this.options.icon); + } + }, + + /** + * Removes all classes from button. + */ + _cleanClasses: function() { + L.DomUtil.removeClass(this._container, "requesting"); + L.DomUtil.removeClass(this._container, "active"); + L.DomUtil.removeClass(this._container, "following"); + + removeClasses(this._icon, this.options.iconLoading); + addClasses(this._icon, this.options.icon); + }, + + /** + * Reinitializes state variables. + */ + _resetVariables: function() { + // whether locate is active or not + this._active = false; + + // true if the control was clicked for the first time + // we need this so we can pan and zoom once we have the location + this._justClicked = false; + + // true if the user has panned the map after clicking the control + this._userPanned = false; + } + }); + + L.control.locate = function (options) { + return new L.Control.Locate(options); + }; + + return LocateControl; +}, window)); diff --git a/www/javascript/L.Control.Locate.min.js b/www/javascript/L.Control.Locate.min.js new file mode 100644 index 0000000..376d3a3 --- /dev/null +++ b/www/javascript/L.Control.Locate.min.js @@ -0,0 +1,5 @@ +/*! Version: 0.62.0 +Copyright (c) 2016 Dominik Moritz */ + +!function(t,i){"function"==typeof define&&define.amd?define(["leaflet"],t):"object"==typeof exports&&(void 0!==i&&i.L?module.exports=t(L):module.exports=t(require("leaflet"))),void 0!==i&&i.L&&(i.L.Control.Locate=t(L))}(function(t){var i=function(i,o,s){(s=s.split(" ")).forEach(function(s){t.DomUtil[i].call(this,o,s)})},o=function(t,o){i("addClass",t,o)},s=function(t,o){i("removeClass",t,o)},e=t.Control.extend({options:{position:"topleft",layer:void 0,setView:"untilPan",keepCurrentZoomLevel:!1,flyTo:!1,clickBehavior:{inView:"stop",outOfView:"setView"},returnToPrevBounds:!1,cacheLocation:!0,drawCircle:!0,drawMarker:!0,markerClass:t.CircleMarker,circleStyle:{color:"#136AEC",fillColor:"#136AEC",fillOpacity:.15,weight:2,opacity:.5},markerStyle:{color:"#136AEC",fillColor:"#2A93EE",fillOpacity:.7,weight:2,opacity:.9,radius:5},followCircleStyle:{},followMarkerStyle:{},icon:"fa fa-map-marker",iconLoading:"fa fa-spinner fa-spin",iconElementTag:"span",circlePadding:[0,0],metric:!0,createButtonCallback:function(i,o){var s=t.DomUtil.create("a","leaflet-bar-part leaflet-bar-part-single",i);return s.title=o.strings.title,{link:s,icon:t.DomUtil.create(o.iconElementTag,o.icon,s)}},onLocationError:function(t,i){alert(t.message)},onLocationOutsideMapBounds:function(t){t.stop(),alert(t.options.strings.outsideMapBoundsMsg)},showPopup:!0,strings:{title:"Show me where I am",metersUnit:"meters",feetUnit:"feet",popup:"You are within {distance} {unit} from this point",outsideMapBoundsMsg:"You seem located outside the boundaries of the map"},locateOptions:{maxZoom:1/0,watch:!0,setView:!1}},initialize:function(i){for(var o in i)"object"==typeof this.options[o]?t.extend(this.options[o],i[o]):this.options[o]=i[o];this.options.followMarkerStyle=t.extend({},this.options.markerStyle,this.options.followMarkerStyle),this.options.followCircleStyle=t.extend({},this.options.circleStyle,this.options.followCircleStyle)},onAdd:function(i){var o=t.DomUtil.create("div","leaflet-control-locate leaflet-bar leaflet-control");this._layer=this.options.layer||new t.LayerGroup,this._layer.addTo(i),this._event=void 0,this._prevBounds=null;var s=this.options.createButtonCallback(o,this.options);return this._link=s.link,this._icon=s.icon,t.DomEvent.on(this._link,"click",t.DomEvent.stopPropagation).on(this._link,"click",t.DomEvent.preventDefault).on(this._link,"click",this._onClick,this).on(this._link,"dblclick",t.DomEvent.stopPropagation),this._resetVariables(),this._map.on("unload",this._unload,this),o},_onClick:function(){if(this._justClicked=!0,this._userPanned=!1,this._active&&!this._event)this.stop();else if(this._active&&void 0!==this._event)switch(this._map.getBounds().contains(this._event.latlng)?this.options.clickBehavior.inView:this.options.clickBehavior.outOfView){case"setView":this.setView();break;case"stop":this.stop(),this.options.returnToPrevBounds&&(this.options.flyTo?this._map.flyToBounds:this._map.fitBounds).bind(this._map)(this._prevBounds)}else this.options.returnToPrevBounds&&(this._prevBounds=this._map.getBounds()),this.start();this._updateContainerStyle()},start:function(){this._activate(),this._event&&(this._drawMarker(this._map),this.options.setView&&this.setView()),this._updateContainerStyle()},stop:function(){this._deactivate(),this._cleanClasses(),this._resetVariables(),this._removeMarker()},_activate:function(){this._active||(this._map.locate(this.options.locateOptions),this._active=!0,this._map.on("locationfound",this._onLocationFound,this),this._map.on("locationerror",this._onLocationError,this),this._map.on("dragstart",this._onDrag,this))},_deactivate:function(){this._map.stopLocate(),this._active=!1,this.options.cacheLocation||(this._event=void 0),this._map.off("locationfound",this._onLocationFound,this),this._map.off("locationerror",this._onLocationError,this),this._map.off("dragstart",this._onDrag,this)},setView:function(){if(this._drawMarker(),this._isOutsideMapBounds())this._event=void 0,this.options.onLocationOutsideMapBounds(this);else if(this.options.keepCurrentZoomLevel)(t=this.options.flyTo?this._map.flyTo:this._map.panTo).bind(this._map)([this._event.latitude,this._event.longitude]);else{var t=this.options.flyTo?this._map.flyToBounds:this._map.fitBounds;t.bind(this._map)(this._event.bounds,{padding:this.options.circlePadding,maxZoom:this.options.locateOptions.maxZoom})}},_drawMarker:function(){void 0===this._event.accuracy&&(this._event.accuracy=0);var i=this._event.accuracy,o=this._event.latlng;if(this.options.drawCircle){var s=this._isFollowing()?this.options.followCircleStyle:this.options.circleStyle;this._circle?this._circle.setLatLng(o).setRadius(i).setStyle(s):this._circle=t.circle(o,i,s).addTo(this._layer)}var e,n;if(this.options.metric?(e=i.toFixed(0),n=this.options.strings.metersUnit):(e=(3.2808399*i).toFixed(0),n=this.options.strings.feetUnit),this.options.drawMarker){var a=this._isFollowing()?this.options.followMarkerStyle:this.options.markerStyle;this._marker?(this._marker.setLatLng(o),this._marker.setStyle&&this._marker.setStyle(a)):this._marker=new this.options.markerClass(o,a).addTo(this._layer)}var r=this.options.strings.popup;this.options.showPopup&&r&&this._marker&&this._marker.bindPopup(t.Util.template(r,{distance:e,unit:n}))._popup.setLatLng(o)},_removeMarker:function(){this._layer.clearLayers(),this._marker=void 0,this._circle=void 0},_unload:function(){this.stop(),this._map.off("unload",this._unload,this)},_onLocationError:function(t){3==t.code&&this.options.locateOptions.watch||(this.stop(),this.options.onLocationError(t,this))},_onLocationFound:function(t){if((!this._event||this._event.latlng.lat!==t.latlng.lat||this._event.latlng.lng!==t.latlng.lng||this._event.accuracy!==t.accuracy)&&this._active){switch(this._event=t,this._drawMarker(),this._updateContainerStyle(),this.options.setView){case"once":this._justClicked&&this.setView();break;case"untilPan":this._userPanned||this.setView();break;case"always":this.setView()}this._justClicked=!1}},_onDrag:function(){this._event&&(this._userPanned=!0,this._updateContainerStyle(),this._drawMarker())},_isFollowing:function(){return!!this._active&&("always"===this.options.setView||("untilPan"===this.options.setView?!this._userPanned:void 0))},_isOutsideMapBounds:function(){return void 0!==this._event&&(this._map.options.maxBounds&&!this._map.options.maxBounds.contains(this._event.latlng))},_updateContainerStyle:function(){this._container&&(this._active&&!this._event?this._setClasses("requesting"):this._isFollowing()?this._setClasses("following"):this._active?this._setClasses("active"):this._cleanClasses())},_setClasses:function(t){"requesting"==t?(s(this._container,"active following"),o(this._container,"requesting"),s(this._icon,this.options.icon),o(this._icon,this.options.iconLoading)):"active"==t?(s(this._container,"requesting following"),o(this._container,"active"),s(this._icon,this.options.iconLoading),o(this._icon,this.options.icon)):"following"==t&&(s(this._container,"requesting"),o(this._container,"active following"),s(this._icon,this.options.iconLoading),o(this._icon,this.options.icon))},_cleanClasses:function(){t.DomUtil.removeClass(this._container,"requesting"),t.DomUtil.removeClass(this._container,"active"),t.DomUtil.removeClass(this._container,"following"),s(this._icon,this.options.iconLoading),o(this._icon,this.options.icon)},_resetVariables:function(){this._active=!1,this._justClicked=!1,this._userPanned=!1}});return t.control.locate=function(i){return new t.Control.Locate(i)},e},window); +//# sourceMappingURL=L.Control.Locate.min.js.map \ No newline at end of file diff --git a/www/javascript/flamework.api.js b/www/javascript/flamework.api.js index 6766b2d..2b05882 100644 --- a/www/javascript/flamework.api.js +++ b/www/javascript/flamework.api.js @@ -18,7 +18,7 @@ flamework.api = function(){ '_handlers': { 'endpoint': null_handler, - 'accesstoken': null_handler, + 'authentication': null_handler, }, 'set_handler': function(target, handler){ @@ -90,18 +90,12 @@ flamework.api = function(){ form_data.append('method', method); - if (! form_data.has('access_token')){ + var set_auth = self.get_handler('authentication'); - var get_accesstoken = self.get_handler('accesstoken'); - - if (! get_accesstoken){ - dothis_onerror(self.destruct("there is no accesstoken handler")); - return false; - } - - form_data.append('access_token', get_accesstoken()); + if (set_auth){ + form_data = set_auth(form_data); } - + var onload = function(rsp){ var target = rsp.target; diff --git a/www/javascript/leaflet.markercluster.js b/www/javascript/leaflet.markercluster.js new file mode 100644 index 0000000..95edd3f --- /dev/null +++ b/www/javascript/leaflet.markercluster.js @@ -0,0 +1,2677 @@ +/* + Leaflet.markercluster, Provides Beautiful Animated Marker Clustering functionality for Leaflet, a JS library for interactive maps. + https://github.com/Leaflet/Leaflet.markercluster + (c) 2012-2013, Dave Leaver, smartrak +*/ +(function (window, document, undefined) {/* + * L.MarkerClusterGroup extends L.FeatureGroup by clustering the markers contained within + */ + +L.MarkerClusterGroup = L.FeatureGroup.extend({ + + options: { + maxClusterRadius: 80, //A cluster will cover at most this many pixels from its center + iconCreateFunction: null, + + spiderfyOnMaxZoom: true, + showCoverageOnHover: true, + zoomToBoundsOnClick: true, + singleMarkerMode: false, + + disableClusteringAtZoom: null, + + // Setting this to false prevents the removal of any clusters outside of the viewpoint, which + // is the default behaviour for performance reasons. + removeOutsideVisibleBounds: true, + + // Set to false to disable all animations (zoom and spiderfy). + // If false, option animateAddingMarkers below has no effect. + // If L.DomUtil.TRANSITION is falsy, this option has no effect. + animate: true, + + //Whether to animate adding markers after adding the MarkerClusterGroup to the map + // If you are adding individual markers set to true, if adding bulk markers leave false for massive performance gains. + animateAddingMarkers: false, + + //Increase to increase the distance away that spiderfied markers appear from the center + spiderfyDistanceMultiplier: 1, + + // Make it possible to specify a polyline options on a spider leg + spiderLegPolylineOptions: { weight: 1.5, color: '#222', opacity: 0.5 }, + + // When bulk adding layers, adds markers in chunks. Means addLayers may not add all the layers in the call, others will be loaded during setTimeouts + chunkedLoading: false, + chunkInterval: 200, // process markers for a maximum of ~ n milliseconds (then trigger the chunkProgress callback) + chunkDelay: 50, // at the end of each interval, give n milliseconds back to system/browser + chunkProgress: null, // progress callback: function(processed, total, elapsed) (e.g. for a progress indicator) + + //Options to pass to the L.Polygon constructor + polygonOptions: {} + }, + + initialize: function (options) { + L.Util.setOptions(this, options); + if (!this.options.iconCreateFunction) { + this.options.iconCreateFunction = this._defaultIconCreateFunction; + } + if (!this.options.clusterPane) { + this.options.clusterPane = L.Marker.prototype.options.pane; + } + + this._featureGroup = L.featureGroup(); + this._featureGroup.addEventParent(this); + + this._nonPointGroup = L.featureGroup(); + this._nonPointGroup.addEventParent(this); + + this._inZoomAnimation = 0; + this._needsClustering = []; + this._needsRemoving = []; //Markers removed while we aren't on the map need to be kept track of + //The bounds of the currently shown area (from _getExpandedVisibleBounds) Updated on zoom/move + this._currentShownBounds = null; + + this._queue = []; + + this._childMarkerEventHandlers = { + 'dragstart': this._childMarkerDragStart, + 'move': this._childMarkerMoved, + 'dragend': this._childMarkerDragEnd, + }; + + // Hook the appropriate animation methods. + var animate = L.DomUtil.TRANSITION && this.options.animate; + L.extend(this, animate ? this._withAnimation : this._noAnimation); + // Remember which MarkerCluster class to instantiate (animated or not). + this._markerCluster = animate ? L.MarkerCluster : L.MarkerClusterNonAnimated; + }, + + addLayer: function (layer) { + + if (layer instanceof L.LayerGroup) { + return this.addLayers([layer]); + } + + //Don't cluster non point data + if (!layer.getLatLng) { + this._nonPointGroup.addLayer(layer); + this.fire('layeradd', { layer: layer }); + return this; + } + + if (!this._map) { + this._needsClustering.push(layer); + this.fire('layeradd', { layer: layer }); + return this; + } + + if (this.hasLayer(layer)) { + return this; + } + + + //If we have already clustered we'll need to add this one to a cluster + + if (this._unspiderfy) { + this._unspiderfy(); + } + + this._addLayer(layer, this._maxZoom); + this.fire('layeradd', { layer: layer }); + + // Refresh bounds and weighted positions. + this._topClusterLevel._recalculateBounds(); + + this._refreshClustersIcons(); + + //Work out what is visible + var visibleLayer = layer, + currentZoom = this._zoom; + if (layer.__parent) { + while (visibleLayer.__parent._zoom >= currentZoom) { + visibleLayer = visibleLayer.__parent; + } + } + + if (this._currentShownBounds.contains(visibleLayer.getLatLng())) { + if (this.options.animateAddingMarkers) { + this._animationAddLayer(layer, visibleLayer); + } else { + this._animationAddLayerNonAnimated(layer, visibleLayer); + } + } + return this; + }, + + removeLayer: function (layer) { + + if (layer instanceof L.LayerGroup) { + return this.removeLayers([layer]); + } + + //Non point layers + if (!layer.getLatLng) { + this._nonPointGroup.removeLayer(layer); + this.fire('layerremove', { layer: layer }); + return this; + } + + if (!this._map) { + if (!this._arraySplice(this._needsClustering, layer) && this.hasLayer(layer)) { + this._needsRemoving.push({ layer: layer, latlng: layer._latlng }); + } + this.fire('layerremove', { layer: layer }); + return this; + } + + if (!layer.__parent) { + return this; + } + + if (this._unspiderfy) { + this._unspiderfy(); + this._unspiderfyLayer(layer); + } + + //Remove the marker from clusters + this._removeLayer(layer, true); + this.fire('layerremove', { layer: layer }); + + // Refresh bounds and weighted positions. + this._topClusterLevel._recalculateBounds(); + + this._refreshClustersIcons(); + + layer.off(this._childMarkerEventHandlers, this); + + if (this._featureGroup.hasLayer(layer)) { + this._featureGroup.removeLayer(layer); + if (layer.clusterShow) { + layer.clusterShow(); + } + } + + return this; + }, + + //Takes an array of markers and adds them in bulk + addLayers: function (layersArray, skipLayerAddEvent) { + if (!L.Util.isArray(layersArray)) { + return this.addLayer(layersArray); + } + + var fg = this._featureGroup, + npg = this._nonPointGroup, + chunked = this.options.chunkedLoading, + chunkInterval = this.options.chunkInterval, + chunkProgress = this.options.chunkProgress, + l = layersArray.length, + offset = 0, + originalArray = true, + m; + + if (this._map) { + var started = (new Date()).getTime(); + var process = L.bind(function () { + var start = (new Date()).getTime(); + for (; offset < l; offset++) { + if (chunked && offset % 200 === 0) { + // every couple hundred markers, instrument the time elapsed since processing started: + var elapsed = (new Date()).getTime() - start; + if (elapsed > chunkInterval) { + break; // been working too hard, time to take a break :-) + } + } + + m = layersArray[offset]; + + // Group of layers, append children to layersArray and skip. + // Side effects: + // - Total increases, so chunkProgress ratio jumps backward. + // - Groups are not included in this group, only their non-group child layers (hasLayer). + // Changing array length while looping does not affect performance in current browsers: + // http://jsperf.com/for-loop-changing-length/6 + if (m instanceof L.LayerGroup) { + if (originalArray) { + layersArray = layersArray.slice(); + originalArray = false; + } + this._extractNonGroupLayers(m, layersArray); + l = layersArray.length; + continue; + } + + //Not point data, can't be clustered + if (!m.getLatLng) { + npg.addLayer(m); + if (!skipLayerAddEvent) { + this.fire('layeradd', { layer: m }); + } + continue; + } + + if (this.hasLayer(m)) { + continue; + } + + this._addLayer(m, this._maxZoom); + if (!skipLayerAddEvent) { + this.fire('layeradd', { layer: m }); + } + + //If we just made a cluster of size 2 then we need to remove the other marker from the map (if it is) or we never will + if (m.__parent) { + if (m.__parent.getChildCount() === 2) { + var markers = m.__parent.getAllChildMarkers(), + otherMarker = markers[0] === m ? markers[1] : markers[0]; + fg.removeLayer(otherMarker); + } + } + } + + if (chunkProgress) { + // report progress and time elapsed: + chunkProgress(offset, l, (new Date()).getTime() - started); + } + + // Completed processing all markers. + if (offset === l) { + + // Refresh bounds and weighted positions. + this._topClusterLevel._recalculateBounds(); + + this._refreshClustersIcons(); + + this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds); + } else { + setTimeout(process, this.options.chunkDelay); + } + }, this); + + process(); + } else { + var needsClustering = this._needsClustering; + + for (; offset < l; offset++) { + m = layersArray[offset]; + + // Group of layers, append children to layersArray and skip. + if (m instanceof L.LayerGroup) { + if (originalArray) { + layersArray = layersArray.slice(); + originalArray = false; + } + this._extractNonGroupLayers(m, layersArray); + l = layersArray.length; + continue; + } + + //Not point data, can't be clustered + if (!m.getLatLng) { + npg.addLayer(m); + continue; + } + + if (this.hasLayer(m)) { + continue; + } + + needsClustering.push(m); + } + } + return this; + }, + + //Takes an array of markers and removes them in bulk + removeLayers: function (layersArray) { + var i, m, + l = layersArray.length, + fg = this._featureGroup, + npg = this._nonPointGroup, + originalArray = true; + + if (!this._map) { + for (i = 0; i < l; i++) { + m = layersArray[i]; + + // Group of layers, append children to layersArray and skip. + if (m instanceof L.LayerGroup) { + if (originalArray) { + layersArray = layersArray.slice(); + originalArray = false; + } + this._extractNonGroupLayers(m, layersArray); + l = layersArray.length; + continue; + } + + this._arraySplice(this._needsClustering, m); + npg.removeLayer(m); + if (this.hasLayer(m)) { + this._needsRemoving.push({ layer: m, latlng: m._latlng }); + } + this.fire('layerremove', { layer: m }); + } + return this; + } + + if (this._unspiderfy) { + this._unspiderfy(); + + // Work on a copy of the array, so that next loop is not affected. + var layersArray2 = layersArray.slice(), + l2 = l; + for (i = 0; i < l2; i++) { + m = layersArray2[i]; + + // Group of layers, append children to layersArray and skip. + if (m instanceof L.LayerGroup) { + this._extractNonGroupLayers(m, layersArray2); + l2 = layersArray2.length; + continue; + } + + this._unspiderfyLayer(m); + } + } + + for (i = 0; i < l; i++) { + m = layersArray[i]; + + // Group of layers, append children to layersArray and skip. + if (m instanceof L.LayerGroup) { + if (originalArray) { + layersArray = layersArray.slice(); + originalArray = false; + } + this._extractNonGroupLayers(m, layersArray); + l = layersArray.length; + continue; + } + + if (!m.__parent) { + npg.removeLayer(m); + this.fire('layerremove', { layer: m }); + continue; + } + + this._removeLayer(m, true, true); + this.fire('layerremove', { layer: m }); + + if (fg.hasLayer(m)) { + fg.removeLayer(m); + if (m.clusterShow) { + m.clusterShow(); + } + } + } + + // Refresh bounds and weighted positions. + this._topClusterLevel._recalculateBounds(); + + this._refreshClustersIcons(); + + //Fix up the clusters and markers on the map + this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds); + + return this; + }, + + //Removes all layers from the MarkerClusterGroup + clearLayers: function () { + //Need our own special implementation as the LayerGroup one doesn't work for us + + //If we aren't on the map (yet), blow away the markers we know of + if (!this._map) { + this._needsClustering = []; + delete this._gridClusters; + delete this._gridUnclustered; + } + + if (this._noanimationUnspiderfy) { + this._noanimationUnspiderfy(); + } + + //Remove all the visible layers + this._featureGroup.clearLayers(); + this._nonPointGroup.clearLayers(); + + this.eachLayer(function (marker) { + marker.off(this._childMarkerEventHandlers, this); + delete marker.__parent; + }, this); + + if (this._map) { + //Reset _topClusterLevel and the DistanceGrids + this._generateInitialClusters(); + } + + return this; + }, + + //Override FeatureGroup.getBounds as it doesn't work + getBounds: function () { + var bounds = new L.LatLngBounds(); + + if (this._topClusterLevel) { + bounds.extend(this._topClusterLevel._bounds); + } + + for (var i = this._needsClustering.length - 1; i >= 0; i--) { + bounds.extend(this._needsClustering[i].getLatLng()); + } + + bounds.extend(this._nonPointGroup.getBounds()); + + return bounds; + }, + + //Overrides LayerGroup.eachLayer + eachLayer: function (method, context) { + var markers = this._needsClustering.slice(), + needsRemoving = this._needsRemoving, + thisNeedsRemoving, i, j; + + if (this._topClusterLevel) { + this._topClusterLevel.getAllChildMarkers(markers); + } + + for (i = markers.length - 1; i >= 0; i--) { + thisNeedsRemoving = true; + + for (j = needsRemoving.length - 1; j >= 0; j--) { + if (needsRemoving[j].layer === markers[i]) { + thisNeedsRemoving = false; + break; + } + } + + if (thisNeedsRemoving) { + method.call(context, markers[i]); + } + } + + this._nonPointGroup.eachLayer(method, context); + }, + + //Overrides LayerGroup.getLayers + getLayers: function () { + var layers = []; + this.eachLayer(function (l) { + layers.push(l); + }); + return layers; + }, + + //Overrides LayerGroup.getLayer, WARNING: Really bad performance + getLayer: function (id) { + var result = null; + + id = parseInt(id, 10); + + this.eachLayer(function (l) { + if (L.stamp(l) === id) { + result = l; + } + }); + + return result; + }, + + //Returns true if the given layer is in this MarkerClusterGroup + hasLayer: function (layer) { + if (!layer) { + return false; + } + + var i, anArray = this._needsClustering; + + for (i = anArray.length - 1; i >= 0; i--) { + if (anArray[i] === layer) { + return true; + } + } + + anArray = this._needsRemoving; + for (i = anArray.length - 1; i >= 0; i--) { + if (anArray[i].layer === layer) { + return false; + } + } + + return !!(layer.__parent && layer.__parent._group === this) || this._nonPointGroup.hasLayer(layer); + }, + + //Zoom down to show the given layer (spiderfying if necessary) then calls the callback + zoomToShowLayer: function (layer, callback) { + + if (typeof callback !== 'function') { + callback = function () {}; + } + + var showMarker = function () { + if ((layer._icon || layer.__parent._icon) && !this._inZoomAnimation) { + this._map.off('moveend', showMarker, this); + this.off('animationend', showMarker, this); + + if (layer._icon) { + callback(); + } else if (layer.__parent._icon) { + this.once('spiderfied', callback, this); + layer.__parent.spiderfy(); + } + } + }; + + if (layer._icon && this._map.getBounds().contains(layer.getLatLng())) { + //Layer is visible ond on screen, immediate return + callback(); + } else if (layer.__parent._zoom < Math.round(this._map._zoom)) { + //Layer should be visible at this zoom level. It must not be on screen so just pan over to it + this._map.on('moveend', showMarker, this); + this._map.panTo(layer.getLatLng()); + } else { + this._map.on('moveend', showMarker, this); + this.on('animationend', showMarker, this); + layer.__parent.zoomToBounds(); + } + }, + + //Overrides FeatureGroup.onAdd + onAdd: function (map) { + this._map = map; + var i, l, layer; + + if (!isFinite(this._map.getMaxZoom())) { + throw "Map has no maxZoom specified"; + } + + this._featureGroup.addTo(map); + this._nonPointGroup.addTo(map); + + if (!this._gridClusters) { + this._generateInitialClusters(); + } + + this._maxLat = map.options.crs.projection.MAX_LATITUDE; + + //Restore all the positions as they are in the MCG before removing them + for (i = 0, l = this._needsRemoving.length; i < l; i++) { + layer = this._needsRemoving[i]; + layer.newlatlng = layer.layer._latlng; + layer.layer._latlng = layer.latlng; + } + //Remove them, then restore their new positions + for (i = 0, l = this._needsRemoving.length; i < l; i++) { + layer = this._needsRemoving[i]; + this._removeLayer(layer.layer, true); + layer.layer._latlng = layer.newlatlng; + } + this._needsRemoving = []; + + //Remember the current zoom level and bounds + this._zoom = Math.round(this._map._zoom); + this._currentShownBounds = this._getExpandedVisibleBounds(); + + this._map.on('zoomend', this._zoomEnd, this); + this._map.on('moveend', this._moveEnd, this); + + if (this._spiderfierOnAdd) { //TODO FIXME: Not sure how to have spiderfier add something on here nicely + this._spiderfierOnAdd(); + } + + this._bindEvents(); + + //Actually add our markers to the map: + l = this._needsClustering; + this._needsClustering = []; + this.addLayers(l, true); + }, + + //Overrides FeatureGroup.onRemove + onRemove: function (map) { + map.off('zoomend', this._zoomEnd, this); + map.off('moveend', this._moveEnd, this); + + this._unbindEvents(); + + //In case we are in a cluster animation + this._map._mapPane.className = this._map._mapPane.className.replace(' leaflet-cluster-anim', ''); + + if (this._spiderfierOnRemove) { //TODO FIXME: Not sure how to have spiderfier add something on here nicely + this._spiderfierOnRemove(); + } + + delete this._maxLat; + + //Clean up all the layers we added to the map + this._hideCoverage(); + this._featureGroup.remove(); + this._nonPointGroup.remove(); + + this._featureGroup.clearLayers(); + + this._map = null; + }, + + getVisibleParent: function (marker) { + var vMarker = marker; + while (vMarker && !vMarker._icon) { + vMarker = vMarker.__parent; + } + return vMarker || null; + }, + + //Remove the given object from the given array + _arraySplice: function (anArray, obj) { + for (var i = anArray.length - 1; i >= 0; i--) { + if (anArray[i] === obj) { + anArray.splice(i, 1); + return true; + } + } + }, + + /** + * Removes a marker from all _gridUnclustered zoom levels, starting at the supplied zoom. + * @param marker to be removed from _gridUnclustered. + * @param z integer bottom start zoom level (included) + * @private + */ + _removeFromGridUnclustered: function (marker, z) { + var map = this._map, + gridUnclustered = this._gridUnclustered, + minZoom = Math.floor(this._map.getMinZoom()); + + for (; z >= minZoom; z--) { + if (!gridUnclustered[z].removeObject(marker, map.project(marker.getLatLng(), z))) { + break; + } + } + }, + + _childMarkerDragStart: function (e) { + e.target.__dragStart = e.target._latlng; + }, + + _childMarkerMoved: function (e) { + if (!this._ignoreMove && !e.target.__dragStart) { + var isPopupOpen = e.target._popup && e.target._popup.isOpen(); + + this._moveChild(e.target, e.oldLatLng, e.latlng); + + if (isPopupOpen) { + e.target.openPopup(); + } + } + }, + + _moveChild: function (layer, from, to) { + layer._latlng = from; + this.removeLayer(layer); + + layer._latlng = to; + this.addLayer(layer); + }, + + _childMarkerDragEnd: function (e) { + if (e.target.__dragStart) { + this._moveChild(e.target, e.target.__dragStart, e.target._latlng); + } + delete e.target.__dragStart; + }, + + + //Internal function for removing a marker from everything. + //dontUpdateMap: set to true if you will handle updating the map manually (for bulk functions) + _removeLayer: function (marker, removeFromDistanceGrid, dontUpdateMap) { + var gridClusters = this._gridClusters, + gridUnclustered = this._gridUnclustered, + fg = this._featureGroup, + map = this._map, + minZoom = Math.floor(this._map.getMinZoom()); + + //Remove the marker from distance clusters it might be in + if (removeFromDistanceGrid) { + this._removeFromGridUnclustered(marker, this._maxZoom); + } + + //Work our way up the clusters removing them as we go if required + var cluster = marker.__parent, + markers = cluster._markers, + otherMarker; + + //Remove the marker from the immediate parents marker list + this._arraySplice(markers, marker); + + while (cluster) { + cluster._childCount--; + cluster._boundsNeedUpdate = true; + + if (cluster._zoom < minZoom) { + //Top level, do nothing + break; + } else if (removeFromDistanceGrid && cluster._childCount <= 1) { //Cluster no longer required + //We need to push the other marker up to the parent + otherMarker = cluster._markers[0] === marker ? cluster._markers[1] : cluster._markers[0]; + + //Update distance grid + gridClusters[cluster._zoom].removeObject(cluster, map.project(cluster._cLatLng, cluster._zoom)); + gridUnclustered[cluster._zoom].addObject(otherMarker, map.project(otherMarker.getLatLng(), cluster._zoom)); + + //Move otherMarker up to parent + this._arraySplice(cluster.__parent._childClusters, cluster); + cluster.__parent._markers.push(otherMarker); + otherMarker.__parent = cluster.__parent; + + if (cluster._icon) { + //Cluster is currently on the map, need to put the marker on the map instead + fg.removeLayer(cluster); + if (!dontUpdateMap) { + fg.addLayer(otherMarker); + } + } + } else { + cluster._iconNeedsUpdate = true; + } + + cluster = cluster.__parent; + } + + delete marker.__parent; + }, + + _isOrIsParent: function (el, oel) { + while (oel) { + if (el === oel) { + return true; + } + oel = oel.parentNode; + } + return false; + }, + + //Override L.Evented.fire + fire: function (type, data, propagate) { + if (data && data.layer instanceof L.MarkerCluster) { + //Prevent multiple clustermouseover/off events if the icon is made up of stacked divs (Doesn't work in ie <= 8, no relatedTarget) + if (data.originalEvent && this._isOrIsParent(data.layer._icon, data.originalEvent.relatedTarget)) { + return; + } + type = 'cluster' + type; + } + + L.FeatureGroup.prototype.fire.call(this, type, data, propagate); + }, + + //Override L.Evented.listens + listens: function (type, propagate) { + return L.FeatureGroup.prototype.listens.call(this, type, propagate) || L.FeatureGroup.prototype.listens.call(this, 'cluster' + type, propagate); + }, + + //Default functionality + _defaultIconCreateFunction: function (cluster) { + var childCount = cluster.getChildCount(); + + var c = ' marker-cluster-'; + if (childCount < 10) { + c += 'small'; + } else if (childCount < 100) { + c += 'medium'; + } else { + c += 'large'; + } + + return new L.DivIcon({ html: '
' + childCount + '
', className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) }); + }, + + _bindEvents: function () { + var map = this._map, + spiderfyOnMaxZoom = this.options.spiderfyOnMaxZoom, + showCoverageOnHover = this.options.showCoverageOnHover, + zoomToBoundsOnClick = this.options.zoomToBoundsOnClick; + + //Zoom on cluster click or spiderfy if we are at the lowest level + if (spiderfyOnMaxZoom || zoomToBoundsOnClick) { + this.on('clusterclick', this._zoomOrSpiderfy, this); + } + + //Show convex hull (boundary) polygon on mouse over + if (showCoverageOnHover) { + this.on('clustermouseover', this._showCoverage, this); + this.on('clustermouseout', this._hideCoverage, this); + map.on('zoomend', this._hideCoverage, this); + } + }, + + _zoomOrSpiderfy: function (e) { + var cluster = e.layer, + bottomCluster = cluster; + + while (bottomCluster._childClusters.length === 1) { + bottomCluster = bottomCluster._childClusters[0]; + } + + if (bottomCluster._zoom === this._maxZoom && + bottomCluster._childCount === cluster._childCount && + this.options.spiderfyOnMaxZoom) { + + // All child markers are contained in a single cluster from this._maxZoom to this cluster. + cluster.spiderfy(); + } else if (this.options.zoomToBoundsOnClick) { + cluster.zoomToBounds(); + } + + // Focus the map again for keyboard users. + if (e.originalEvent && e.originalEvent.keyCode === 13) { + this._map._container.focus(); + } + }, + + _showCoverage: function (e) { + var map = this._map; + if (this._inZoomAnimation) { + return; + } + if (this._shownPolygon) { + map.removeLayer(this._shownPolygon); + } + if (e.layer.getChildCount() > 2 && e.layer !== this._spiderfied) { + this._shownPolygon = new L.Polygon(e.layer.getConvexHull(), this.options.polygonOptions); + map.addLayer(this._shownPolygon); + } + }, + + _hideCoverage: function () { + if (this._shownPolygon) { + this._map.removeLayer(this._shownPolygon); + this._shownPolygon = null; + } + }, + + _unbindEvents: function () { + var spiderfyOnMaxZoom = this.options.spiderfyOnMaxZoom, + showCoverageOnHover = this.options.showCoverageOnHover, + zoomToBoundsOnClick = this.options.zoomToBoundsOnClick, + map = this._map; + + if (spiderfyOnMaxZoom || zoomToBoundsOnClick) { + this.off('clusterclick', this._zoomOrSpiderfy, this); + } + if (showCoverageOnHover) { + this.off('clustermouseover', this._showCoverage, this); + this.off('clustermouseout', this._hideCoverage, this); + map.off('zoomend', this._hideCoverage, this); + } + }, + + _zoomEnd: function () { + if (!this._map) { //May have been removed from the map by a zoomEnd handler + return; + } + this._mergeSplitClusters(); + + this._zoom = Math.round(this._map._zoom); + this._currentShownBounds = this._getExpandedVisibleBounds(); + }, + + _moveEnd: function () { + if (this._inZoomAnimation) { + return; + } + + var newBounds = this._getExpandedVisibleBounds(); + + this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), this._zoom, newBounds); + this._topClusterLevel._recursivelyAddChildrenToMap(null, Math.round(this._map._zoom), newBounds); + + this._currentShownBounds = newBounds; + return; + }, + + _generateInitialClusters: function () { + var maxZoom = Math.ceil(this._map.getMaxZoom()), + minZoom = Math.floor(this._map.getMinZoom()), + radius = this.options.maxClusterRadius, + radiusFn = radius; + + //If we just set maxClusterRadius to a single number, we need to create + //a simple function to return that number. Otherwise, we just have to + //use the function we've passed in. + if (typeof radius !== "function") { + radiusFn = function () { return radius; }; + } + + if (this.options.disableClusteringAtZoom !== null) { + maxZoom = this.options.disableClusteringAtZoom - 1; + } + this._maxZoom = maxZoom; + this._gridClusters = {}; + this._gridUnclustered = {}; + + //Set up DistanceGrids for each zoom + for (var zoom = maxZoom; zoom >= minZoom; zoom--) { + this._gridClusters[zoom] = new L.DistanceGrid(radiusFn(zoom)); + this._gridUnclustered[zoom] = new L.DistanceGrid(radiusFn(zoom)); + } + + // Instantiate the appropriate L.MarkerCluster class (animated or not). + this._topClusterLevel = new this._markerCluster(this, minZoom - 1); + }, + + //Zoom: Zoom to start adding at (Pass this._maxZoom to start at the bottom) + _addLayer: function (layer, zoom) { + var gridClusters = this._gridClusters, + gridUnclustered = this._gridUnclustered, + minZoom = Math.floor(this._map.getMinZoom()), + markerPoint, z; + + if (this.options.singleMarkerMode) { + this._overrideMarkerIcon(layer); + } + + layer.on(this._childMarkerEventHandlers, this); + + //Find the lowest zoom level to slot this one in + for (; zoom >= minZoom; zoom--) { + markerPoint = this._map.project(layer.getLatLng(), zoom); // calculate pixel position + + //Try find a cluster close by + var closest = gridClusters[zoom].getNearObject(markerPoint); + if (closest) { + closest._addChild(layer); + layer.__parent = closest; + return; + } + + //Try find a marker close by to form a new cluster with + closest = gridUnclustered[zoom].getNearObject(markerPoint); + if (closest) { + var parent = closest.__parent; + if (parent) { + this._removeLayer(closest, false); + } + + //Create new cluster with these 2 in it + + var newCluster = new this._markerCluster(this, zoom, closest, layer); + gridClusters[zoom].addObject(newCluster, this._map.project(newCluster._cLatLng, zoom)); + closest.__parent = newCluster; + layer.__parent = newCluster; + + //First create any new intermediate parent clusters that don't exist + var lastParent = newCluster; + for (z = zoom - 1; z > parent._zoom; z--) { + lastParent = new this._markerCluster(this, z, lastParent); + gridClusters[z].addObject(lastParent, this._map.project(closest.getLatLng(), z)); + } + parent._addChild(lastParent); + + //Remove closest from this zoom level and any above that it is in, replace with newCluster + this._removeFromGridUnclustered(closest, zoom); + + return; + } + + //Didn't manage to cluster in at this zoom, record us as a marker here and continue upwards + gridUnclustered[zoom].addObject(layer, markerPoint); + } + + //Didn't get in anything, add us to the top + this._topClusterLevel._addChild(layer); + layer.__parent = this._topClusterLevel; + return; + }, + + /** + * Refreshes the icon of all "dirty" visible clusters. + * Non-visible "dirty" clusters will be updated when they are added to the map. + * @private + */ + _refreshClustersIcons: function () { + this._featureGroup.eachLayer(function (c) { + if (c instanceof L.MarkerCluster && c._iconNeedsUpdate) { + c._updateIcon(); + } + }); + }, + + //Enqueue code to fire after the marker expand/contract has happened + _enqueue: function (fn) { + this._queue.push(fn); + if (!this._queueTimeout) { + this._queueTimeout = setTimeout(L.bind(this._processQueue, this), 300); + } + }, + _processQueue: function () { + for (var i = 0; i < this._queue.length; i++) { + this._queue[i].call(this); + } + this._queue.length = 0; + clearTimeout(this._queueTimeout); + this._queueTimeout = null; + }, + + //Merge and split any existing clusters that are too big or small + _mergeSplitClusters: function () { + var mapZoom = Math.round(this._map._zoom); + + //In case we are starting to split before the animation finished + this._processQueue(); + + if (this._zoom < mapZoom && this._currentShownBounds.intersects(this._getExpandedVisibleBounds())) { //Zoom in, split + this._animationStart(); + //Remove clusters now off screen + this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), this._zoom, this._getExpandedVisibleBounds()); + + this._animationZoomIn(this._zoom, mapZoom); + + } else if (this._zoom > mapZoom) { //Zoom out, merge + this._animationStart(); + + this._animationZoomOut(this._zoom, mapZoom); + } else { + this._moveEnd(); + } + }, + + //Gets the maps visible bounds expanded in each direction by the size of the screen (so the user cannot see an area we do not cover in one pan) + _getExpandedVisibleBounds: function () { + if (!this.options.removeOutsideVisibleBounds) { + return this._mapBoundsInfinite; + } else if (L.Browser.mobile) { + return this._checkBoundsMaxLat(this._map.getBounds()); + } + + return this._checkBoundsMaxLat(this._map.getBounds().pad(1)); // Padding expands the bounds by its own dimensions but scaled with the given factor. + }, + + /** + * Expands the latitude to Infinity (or -Infinity) if the input bounds reach the map projection maximum defined latitude + * (in the case of Web/Spherical Mercator, it is 85.0511287798 / see https://en.wikipedia.org/wiki/Web_Mercator#Formulas). + * Otherwise, the removeOutsideVisibleBounds option will remove markers beyond that limit, whereas the same markers without + * this option (or outside MCG) will have their position floored (ceiled) by the projection and rendered at that limit, + * making the user think that MCG "eats" them and never displays them again. + * @param bounds L.LatLngBounds + * @returns {L.LatLngBounds} + * @private + */ + _checkBoundsMaxLat: function (bounds) { + var maxLat = this._maxLat; + + if (maxLat !== undefined) { + if (bounds.getNorth() >= maxLat) { + bounds._northEast.lat = Infinity; + } + if (bounds.getSouth() <= -maxLat) { + bounds._southWest.lat = -Infinity; + } + } + + return bounds; + }, + + //Shared animation code + _animationAddLayerNonAnimated: function (layer, newCluster) { + if (newCluster === layer) { + this._featureGroup.addLayer(layer); + } else if (newCluster._childCount === 2) { + newCluster._addToMap(); + + var markers = newCluster.getAllChildMarkers(); + this._featureGroup.removeLayer(markers[0]); + this._featureGroup.removeLayer(markers[1]); + } else { + newCluster._updateIcon(); + } + }, + + /** + * Extracts individual (i.e. non-group) layers from a Layer Group. + * @param group to extract layers from. + * @param output {Array} in which to store the extracted layers. + * @returns {*|Array} + * @private + */ + _extractNonGroupLayers: function (group, output) { + var layers = group.getLayers(), + i = 0, + layer; + + output = output || []; + + for (; i < layers.length; i++) { + layer = layers[i]; + + if (layer instanceof L.LayerGroup) { + this._extractNonGroupLayers(layer, output); + continue; + } + + output.push(layer); + } + + return output; + }, + + /** + * Implements the singleMarkerMode option. + * @param layer Marker to re-style using the Clusters iconCreateFunction. + * @returns {L.Icon} The newly created icon. + * @private + */ + _overrideMarkerIcon: function (layer) { + var icon = layer.options.icon = this.options.iconCreateFunction({ + getChildCount: function () { + return 1; + }, + getAllChildMarkers: function () { + return [layer]; + } + }); + + return icon; + } +}); + +// Constant bounds used in case option "removeOutsideVisibleBounds" is set to false. +L.MarkerClusterGroup.include({ + _mapBoundsInfinite: new L.LatLngBounds(new L.LatLng(-Infinity, -Infinity), new L.LatLng(Infinity, Infinity)) +}); + +L.MarkerClusterGroup.include({ + _noAnimation: { + //Non Animated versions of everything + _animationStart: function () { + //Do nothing... + }, + _animationZoomIn: function (previousZoomLevel, newZoomLevel) { + this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), previousZoomLevel); + this._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds()); + + //We didn't actually animate, but we use this event to mean "clustering animations have finished" + this.fire('animationend'); + }, + _animationZoomOut: function (previousZoomLevel, newZoomLevel) { + this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), previousZoomLevel); + this._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds()); + + //We didn't actually animate, but we use this event to mean "clustering animations have finished" + this.fire('animationend'); + }, + _animationAddLayer: function (layer, newCluster) { + this._animationAddLayerNonAnimated(layer, newCluster); + } + }, + + _withAnimation: { + //Animated versions here + _animationStart: function () { + this._map._mapPane.className += ' leaflet-cluster-anim'; + this._inZoomAnimation++; + }, + + _animationZoomIn: function (previousZoomLevel, newZoomLevel) { + var bounds = this._getExpandedVisibleBounds(), + fg = this._featureGroup, + minZoom = Math.floor(this._map.getMinZoom()), + i; + + this._ignoreMove = true; + + //Add all children of current clusters to map and remove those clusters from map + this._topClusterLevel._recursively(bounds, previousZoomLevel, minZoom, function (c) { + var startPos = c._latlng, + markers = c._markers, + m; + + if (!bounds.contains(startPos)) { + startPos = null; + } + + if (c._isSingleParent() && previousZoomLevel + 1 === newZoomLevel) { //Immediately add the new child and remove us + fg.removeLayer(c); + c._recursivelyAddChildrenToMap(null, newZoomLevel, bounds); + } else { + //Fade out old cluster + c.clusterHide(); + c._recursivelyAddChildrenToMap(startPos, newZoomLevel, bounds); + } + + //Remove all markers that aren't visible any more + //TODO: Do we actually need to do this on the higher levels too? + for (i = markers.length - 1; i >= 0; i--) { + m = markers[i]; + if (!bounds.contains(m._latlng)) { + fg.removeLayer(m); + } + } + + }); + + this._forceLayout(); + + //Update opacities + this._topClusterLevel._recursivelyBecomeVisible(bounds, newZoomLevel); + //TODO Maybe? Update markers in _recursivelyBecomeVisible + fg.eachLayer(function (n) { + if (!(n instanceof L.MarkerCluster) && n._icon) { + n.clusterShow(); + } + }); + + //update the positions of the just added clusters/markers + this._topClusterLevel._recursively(bounds, previousZoomLevel, newZoomLevel, function (c) { + c._recursivelyRestoreChildPositions(newZoomLevel); + }); + + this._ignoreMove = false; + + //Remove the old clusters and close the zoom animation + this._enqueue(function () { + //update the positions of the just added clusters/markers + this._topClusterLevel._recursively(bounds, previousZoomLevel, minZoom, function (c) { + fg.removeLayer(c); + c.clusterShow(); + }); + + this._animationEnd(); + }); + }, + + _animationZoomOut: function (previousZoomLevel, newZoomLevel) { + this._animationZoomOutSingle(this._topClusterLevel, previousZoomLevel - 1, newZoomLevel); + + //Need to add markers for those that weren't on the map before but are now + this._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds()); + //Remove markers that were on the map before but won't be now + this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), previousZoomLevel, this._getExpandedVisibleBounds()); + }, + + _animationAddLayer: function (layer, newCluster) { + var me = this, + fg = this._featureGroup; + + fg.addLayer(layer); + if (newCluster !== layer) { + if (newCluster._childCount > 2) { //Was already a cluster + + newCluster._updateIcon(); + this._forceLayout(); + this._animationStart(); + + layer._setPos(this._map.latLngToLayerPoint(newCluster.getLatLng())); + layer.clusterHide(); + + this._enqueue(function () { + fg.removeLayer(layer); + layer.clusterShow(); + + me._animationEnd(); + }); + + } else { //Just became a cluster + this._forceLayout(); + + me._animationStart(); + me._animationZoomOutSingle(newCluster, this._map.getMaxZoom(), this._zoom); + } + } + } + }, + + // Private methods for animated versions. + _animationZoomOutSingle: function (cluster, previousZoomLevel, newZoomLevel) { + var bounds = this._getExpandedVisibleBounds(), + minZoom = Math.floor(this._map.getMinZoom()); + + //Animate all of the markers in the clusters to move to their cluster center point + cluster._recursivelyAnimateChildrenInAndAddSelfToMap(bounds, minZoom, previousZoomLevel + 1, newZoomLevel); + + var me = this; + + //Update the opacity (If we immediately set it they won't animate) + this._forceLayout(); + cluster._recursivelyBecomeVisible(bounds, newZoomLevel); + + //TODO: Maybe use the transition timing stuff to make this more reliable + //When the animations are done, tidy up + this._enqueue(function () { + + //This cluster stopped being a cluster before the timeout fired + if (cluster._childCount === 1) { + var m = cluster._markers[0]; + //If we were in a cluster animation at the time then the opacity and position of our child could be wrong now, so fix it + this._ignoreMove = true; + m.setLatLng(m.getLatLng()); + this._ignoreMove = false; + if (m.clusterShow) { + m.clusterShow(); + } + } else { + cluster._recursively(bounds, newZoomLevel, minZoom, function (c) { + c._recursivelyRemoveChildrenFromMap(bounds, minZoom, previousZoomLevel + 1); + }); + } + me._animationEnd(); + }); + }, + + _animationEnd: function () { + if (this._map) { + this._map._mapPane.className = this._map._mapPane.className.replace(' leaflet-cluster-anim', ''); + } + this._inZoomAnimation--; + this.fire('animationend'); + }, + + //Force a browser layout of stuff in the map + // Should apply the current opacity and location to all elements so we can update them again for an animation + _forceLayout: function () { + //In my testing this works, infact offsetWidth of any element seems to work. + //Could loop all this._layers and do this for each _icon if it stops working + + L.Util.falseFn(document.body.offsetWidth); + } +}); + +L.markerClusterGroup = function (options) { + return new L.MarkerClusterGroup(options); +}; + + +L.MarkerCluster = L.Marker.extend({ + initialize: function (group, zoom, a, b) { + + L.Marker.prototype.initialize.call(this, a ? (a._cLatLng || a.getLatLng()) : new L.LatLng(0, 0), + { icon: this, pane: group.options.clusterPane }); + + this._group = group; + this._zoom = zoom; + + this._markers = []; + this._childClusters = []; + this._childCount = 0; + this._iconNeedsUpdate = true; + this._boundsNeedUpdate = true; + + this._bounds = new L.LatLngBounds(); + + if (a) { + this._addChild(a); + } + if (b) { + this._addChild(b); + } + }, + + //Recursively retrieve all child markers of this cluster + getAllChildMarkers: function (storageArray) { + storageArray = storageArray || []; + + for (var i = this._childClusters.length - 1; i >= 0; i--) { + this._childClusters[i].getAllChildMarkers(storageArray); + } + + for (var j = this._markers.length - 1; j >= 0; j--) { + storageArray.push(this._markers[j]); + } + + return storageArray; + }, + + //Returns the count of how many child markers we have + getChildCount: function () { + return this._childCount; + }, + + //Zoom to the minimum of showing all of the child markers, or the extents of this cluster + zoomToBounds: function (fitBoundsOptions) { + var childClusters = this._childClusters.slice(), + map = this._group._map, + boundsZoom = map.getBoundsZoom(this._bounds), + zoom = this._zoom + 1, + mapZoom = map.getZoom(), + i; + + //calculate how far we need to zoom down to see all of the markers + while (childClusters.length > 0 && boundsZoom > zoom) { + zoom++; + var newClusters = []; + for (i = 0; i < childClusters.length; i++) { + newClusters = newClusters.concat(childClusters[i]._childClusters); + } + childClusters = newClusters; + } + + if (boundsZoom > zoom) { + this._group._map.setView(this._latlng, zoom); + } else if (boundsZoom <= mapZoom) { //If fitBounds wouldn't zoom us down, zoom us down instead + this._group._map.setView(this._latlng, mapZoom + 1); + } else { + this._group._map.fitBounds(this._bounds, fitBoundsOptions); + } + }, + + getBounds: function () { + var bounds = new L.LatLngBounds(); + bounds.extend(this._bounds); + return bounds; + }, + + _updateIcon: function () { + this._iconNeedsUpdate = true; + if (this._icon) { + this.setIcon(this); + } + }, + + //Cludge for Icon, we pretend to be an icon for performance + createIcon: function () { + if (this._iconNeedsUpdate) { + this._iconObj = this._group.options.iconCreateFunction(this); + this._iconNeedsUpdate = false; + } + return this._iconObj.createIcon(); + }, + createShadow: function () { + return this._iconObj.createShadow(); + }, + + + _addChild: function (new1, isNotificationFromChild) { + + this._iconNeedsUpdate = true; + + this._boundsNeedUpdate = true; + this._setClusterCenter(new1); + + if (new1 instanceof L.MarkerCluster) { + if (!isNotificationFromChild) { + this._childClusters.push(new1); + new1.__parent = this; + } + this._childCount += new1._childCount; + } else { + if (!isNotificationFromChild) { + this._markers.push(new1); + } + this._childCount++; + } + + if (this.__parent) { + this.__parent._addChild(new1, true); + } + }, + + /** + * Makes sure the cluster center is set. If not, uses the child center if it is a cluster, or the marker position. + * @param child L.MarkerCluster|L.Marker that will be used as cluster center if not defined yet. + * @private + */ + _setClusterCenter: function (child) { + if (!this._cLatLng) { + // when clustering, take position of the first point as the cluster center + this._cLatLng = child._cLatLng || child._latlng; + } + }, + + /** + * Assigns impossible bounding values so that the next extend entirely determines the new bounds. + * This method avoids having to trash the previous L.LatLngBounds object and to create a new one, which is much slower for this class. + * As long as the bounds are not extended, most other methods would probably fail, as they would with bounds initialized but not extended. + * @private + */ + _resetBounds: function () { + var bounds = this._bounds; + + if (bounds._southWest) { + bounds._southWest.lat = Infinity; + bounds._southWest.lng = Infinity; + } + if (bounds._northEast) { + bounds._northEast.lat = -Infinity; + bounds._northEast.lng = -Infinity; + } + }, + + _recalculateBounds: function () { + var markers = this._markers, + childClusters = this._childClusters, + latSum = 0, + lngSum = 0, + totalCount = this._childCount, + i, child, childLatLng, childCount; + + // Case where all markers are removed from the map and we are left with just an empty _topClusterLevel. + if (totalCount === 0) { + return; + } + + // Reset rather than creating a new object, for performance. + this._resetBounds(); + + // Child markers. + for (i = 0; i < markers.length; i++) { + childLatLng = markers[i]._latlng; + + this._bounds.extend(childLatLng); + + latSum += childLatLng.lat; + lngSum += childLatLng.lng; + } + + // Child clusters. + for (i = 0; i < childClusters.length; i++) { + child = childClusters[i]; + + // Re-compute child bounds and weighted position first if necessary. + if (child._boundsNeedUpdate) { + child._recalculateBounds(); + } + + this._bounds.extend(child._bounds); + + childLatLng = child._wLatLng; + childCount = child._childCount; + + latSum += childLatLng.lat * childCount; + lngSum += childLatLng.lng * childCount; + } + + this._latlng = this._wLatLng = new L.LatLng(latSum / totalCount, lngSum / totalCount); + + // Reset dirty flag. + this._boundsNeedUpdate = false; + }, + + //Set our markers position as given and add it to the map + _addToMap: function (startPos) { + if (startPos) { + this._backupLatlng = this._latlng; + this.setLatLng(startPos); + } + this._group._featureGroup.addLayer(this); + }, + + _recursivelyAnimateChildrenIn: function (bounds, center, maxZoom) { + this._recursively(bounds, this._group._map.getMinZoom(), maxZoom - 1, + function (c) { + var markers = c._markers, + i, m; + for (i = markers.length - 1; i >= 0; i--) { + m = markers[i]; + + //Only do it if the icon is still on the map + if (m._icon) { + m._setPos(center); + m.clusterHide(); + } + } + }, + function (c) { + var childClusters = c._childClusters, + j, cm; + for (j = childClusters.length - 1; j >= 0; j--) { + cm = childClusters[j]; + if (cm._icon) { + cm._setPos(center); + cm.clusterHide(); + } + } + } + ); + }, + + _recursivelyAnimateChildrenInAndAddSelfToMap: function (bounds, mapMinZoom, previousZoomLevel, newZoomLevel) { + this._recursively(bounds, newZoomLevel, mapMinZoom, + function (c) { + c._recursivelyAnimateChildrenIn(bounds, c._group._map.latLngToLayerPoint(c.getLatLng()).round(), previousZoomLevel); + + //TODO: depthToAnimateIn affects _isSingleParent, if there is a multizoom we may/may not be. + //As a hack we only do a animation free zoom on a single level zoom, if someone does multiple levels then we always animate + if (c._isSingleParent() && previousZoomLevel - 1 === newZoomLevel) { + c.clusterShow(); + c._recursivelyRemoveChildrenFromMap(bounds, mapMinZoom, previousZoomLevel); //Immediately remove our children as we are replacing them. TODO previousBounds not bounds + } else { + c.clusterHide(); + } + + c._addToMap(); + } + ); + }, + + _recursivelyBecomeVisible: function (bounds, zoomLevel) { + this._recursively(bounds, this._group._map.getMinZoom(), zoomLevel, null, function (c) { + c.clusterShow(); + }); + }, + + _recursivelyAddChildrenToMap: function (startPos, zoomLevel, bounds) { + this._recursively(bounds, this._group._map.getMinZoom() - 1, zoomLevel, + function (c) { + if (zoomLevel === c._zoom) { + return; + } + + //Add our child markers at startPos (so they can be animated out) + for (var i = c._markers.length - 1; i >= 0; i--) { + var nm = c._markers[i]; + + if (!bounds.contains(nm._latlng)) { + continue; + } + + if (startPos) { + nm._backupLatlng = nm.getLatLng(); + + nm.setLatLng(startPos); + if (nm.clusterHide) { + nm.clusterHide(); + } + } + + c._group._featureGroup.addLayer(nm); + } + }, + function (c) { + c._addToMap(startPos); + } + ); + }, + + _recursivelyRestoreChildPositions: function (zoomLevel) { + //Fix positions of child markers + for (var i = this._markers.length - 1; i >= 0; i--) { + var nm = this._markers[i]; + if (nm._backupLatlng) { + nm.setLatLng(nm._backupLatlng); + delete nm._backupLatlng; + } + } + + if (zoomLevel - 1 === this._zoom) { + //Reposition child clusters + for (var j = this._childClusters.length - 1; j >= 0; j--) { + this._childClusters[j]._restorePosition(); + } + } else { + for (var k = this._childClusters.length - 1; k >= 0; k--) { + this._childClusters[k]._recursivelyRestoreChildPositions(zoomLevel); + } + } + }, + + _restorePosition: function () { + if (this._backupLatlng) { + this.setLatLng(this._backupLatlng); + delete this._backupLatlng; + } + }, + + //exceptBounds: If set, don't remove any markers/clusters in it + _recursivelyRemoveChildrenFromMap: function (previousBounds, mapMinZoom, zoomLevel, exceptBounds) { + var m, i; + this._recursively(previousBounds, mapMinZoom - 1, zoomLevel - 1, + function (c) { + //Remove markers at every level + for (i = c._markers.length - 1; i >= 0; i--) { + m = c._markers[i]; + if (!exceptBounds || !exceptBounds.contains(m._latlng)) { + c._group._featureGroup.removeLayer(m); + if (m.clusterShow) { + m.clusterShow(); + } + } + } + }, + function (c) { + //Remove child clusters at just the bottom level + for (i = c._childClusters.length - 1; i >= 0; i--) { + m = c._childClusters[i]; + if (!exceptBounds || !exceptBounds.contains(m._latlng)) { + c._group._featureGroup.removeLayer(m); + if (m.clusterShow) { + m.clusterShow(); + } + } + } + } + ); + }, + + //Run the given functions recursively to this and child clusters + // boundsToApplyTo: a L.LatLngBounds representing the bounds of what clusters to recurse in to + // zoomLevelToStart: zoom level to start running functions (inclusive) + // zoomLevelToStop: zoom level to stop running functions (inclusive) + // runAtEveryLevel: function that takes an L.MarkerCluster as an argument that should be applied on every level + // runAtBottomLevel: function that takes an L.MarkerCluster as an argument that should be applied at only the bottom level + _recursively: function (boundsToApplyTo, zoomLevelToStart, zoomLevelToStop, runAtEveryLevel, runAtBottomLevel) { + var childClusters = this._childClusters, + zoom = this._zoom, + i, c; + + if (zoomLevelToStart <= zoom) { + if (runAtEveryLevel) { + runAtEveryLevel(this); + } + if (runAtBottomLevel && zoom === zoomLevelToStop) { + runAtBottomLevel(this); + } + } + + if (zoom < zoomLevelToStart || zoom < zoomLevelToStop) { + for (i = childClusters.length - 1; i >= 0; i--) { + c = childClusters[i]; + if (boundsToApplyTo.intersects(c._bounds)) { + c._recursively(boundsToApplyTo, zoomLevelToStart, zoomLevelToStop, runAtEveryLevel, runAtBottomLevel); + } + } + } + }, + + //Returns true if we are the parent of only one cluster and that cluster is the same as us + _isSingleParent: function () { + //Don't need to check this._markers as the rest won't work if there are any + return this._childClusters.length > 0 && this._childClusters[0]._childCount === this._childCount; + } +}); + + + +/* +* Extends L.Marker to include two extra methods: clusterHide and clusterShow. +* +* They work as setOpacity(0) and setOpacity(1) respectively, but +* they will remember the marker's opacity when hiding and showing it again. +* +*/ + + +L.Marker.include({ + + clusterHide: function () { + this.options.opacityWhenUnclustered = this.options.opacity || 1; + return this.setOpacity(0); + }, + + clusterShow: function () { + var ret = this.setOpacity(this.options.opacity || this.options.opacityWhenUnclustered); + delete this.options.opacityWhenUnclustered; + return ret; + } + +}); + + + + + +L.DistanceGrid = function (cellSize) { + this._cellSize = cellSize; + this._sqCellSize = cellSize * cellSize; + this._grid = {}; + this._objectPoint = { }; +}; + +L.DistanceGrid.prototype = { + + addObject: function (obj, point) { + var x = this._getCoord(point.x), + y = this._getCoord(point.y), + grid = this._grid, + row = grid[y] = grid[y] || {}, + cell = row[x] = row[x] || [], + stamp = L.Util.stamp(obj); + + this._objectPoint[stamp] = point; + + cell.push(obj); + }, + + updateObject: function (obj, point) { + this.removeObject(obj); + this.addObject(obj, point); + }, + + //Returns true if the object was found + removeObject: function (obj, point) { + var x = this._getCoord(point.x), + y = this._getCoord(point.y), + grid = this._grid, + row = grid[y] = grid[y] || {}, + cell = row[x] = row[x] || [], + i, len; + + delete this._objectPoint[L.Util.stamp(obj)]; + + for (i = 0, len = cell.length; i < len; i++) { + if (cell[i] === obj) { + + cell.splice(i, 1); + + if (len === 1) { + delete row[x]; + } + + return true; + } + } + + }, + + eachObject: function (fn, context) { + var i, j, k, len, row, cell, removed, + grid = this._grid; + + for (i in grid) { + row = grid[i]; + + for (j in row) { + cell = row[j]; + + for (k = 0, len = cell.length; k < len; k++) { + removed = fn.call(context, cell[k]); + if (removed) { + k--; + len--; + } + } + } + } + }, + + getNearObject: function (point) { + var x = this._getCoord(point.x), + y = this._getCoord(point.y), + i, j, k, row, cell, len, obj, dist, + objectPoint = this._objectPoint, + closestDistSq = this._sqCellSize, + closest = null; + + for (i = y - 1; i <= y + 1; i++) { + row = this._grid[i]; + if (row) { + + for (j = x - 1; j <= x + 1; j++) { + cell = row[j]; + if (cell) { + + for (k = 0, len = cell.length; k < len; k++) { + obj = cell[k]; + dist = this._sqDist(objectPoint[L.Util.stamp(obj)], point); + if (dist < closestDistSq) { + closestDistSq = dist; + closest = obj; + } + } + } + } + } + } + return closest; + }, + + _getCoord: function (x) { + return Math.floor(x / this._cellSize); + }, + + _sqDist: function (p, p2) { + var dx = p2.x - p.x, + dy = p2.y - p.y; + return dx * dx + dy * dy; + } +}; + + +/* Copyright (c) 2012 the authors listed at the following URL, and/or +the authors of referenced articles or incorporated external code: +http://en.literateprograms.org/Quickhull_(Javascript)?action=history&offset=20120410175256 + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Retrieved from: http://en.literateprograms.org/Quickhull_(Javascript)?oldid=18434 +*/ + +(function () { + L.QuickHull = { + + /* + * @param {Object} cpt a point to be measured from the baseline + * @param {Array} bl the baseline, as represented by a two-element + * array of latlng objects. + * @returns {Number} an approximate distance measure + */ + getDistant: function (cpt, bl) { + var vY = bl[1].lat - bl[0].lat, + vX = bl[0].lng - bl[1].lng; + return (vX * (cpt.lat - bl[0].lat) + vY * (cpt.lng - bl[0].lng)); + }, + + /* + * @param {Array} baseLine a two-element array of latlng objects + * representing the baseline to project from + * @param {Array} latLngs an array of latlng objects + * @returns {Object} the maximum point and all new points to stay + * in consideration for the hull. + */ + findMostDistantPointFromBaseLine: function (baseLine, latLngs) { + var maxD = 0, + maxPt = null, + newPoints = [], + i, pt, d; + + for (i = latLngs.length - 1; i >= 0; i--) { + pt = latLngs[i]; + d = this.getDistant(pt, baseLine); + + if (d > 0) { + newPoints.push(pt); + } else { + continue; + } + + if (d > maxD) { + maxD = d; + maxPt = pt; + } + } + + return { maxPoint: maxPt, newPoints: newPoints }; + }, + + + /* + * Given a baseline, compute the convex hull of latLngs as an array + * of latLngs. + * + * @param {Array} latLngs + * @returns {Array} + */ + buildConvexHull: function (baseLine, latLngs) { + var convexHullBaseLines = [], + t = this.findMostDistantPointFromBaseLine(baseLine, latLngs); + + if (t.maxPoint) { // if there is still a point "outside" the base line + convexHullBaseLines = + convexHullBaseLines.concat( + this.buildConvexHull([baseLine[0], t.maxPoint], t.newPoints) + ); + convexHullBaseLines = + convexHullBaseLines.concat( + this.buildConvexHull([t.maxPoint, baseLine[1]], t.newPoints) + ); + return convexHullBaseLines; + } else { // if there is no more point "outside" the base line, the current base line is part of the convex hull + return [baseLine[0]]; + } + }, + + /* + * Given an array of latlngs, compute a convex hull as an array + * of latlngs + * + * @param {Array} latLngs + * @returns {Array} + */ + getConvexHull: function (latLngs) { + // find first baseline + var maxLat = false, minLat = false, + maxLng = false, minLng = false, + maxLatPt = null, minLatPt = null, + maxLngPt = null, minLngPt = null, + maxPt = null, minPt = null, + i; + + for (i = latLngs.length - 1; i >= 0; i--) { + var pt = latLngs[i]; + if (maxLat === false || pt.lat > maxLat) { + maxLatPt = pt; + maxLat = pt.lat; + } + if (minLat === false || pt.lat < minLat) { + minLatPt = pt; + minLat = pt.lat; + } + if (maxLng === false || pt.lng > maxLng) { + maxLngPt = pt; + maxLng = pt.lng; + } + if (minLng === false || pt.lng < minLng) { + minLngPt = pt; + minLng = pt.lng; + } + } + + if (minLat !== maxLat) { + minPt = minLatPt; + maxPt = maxLatPt; + } else { + minPt = minLngPt; + maxPt = maxLngPt; + } + + var ch = [].concat(this.buildConvexHull([minPt, maxPt], latLngs), + this.buildConvexHull([maxPt, minPt], latLngs)); + return ch; + } + }; +}()); + +L.MarkerCluster.include({ + getConvexHull: function () { + var childMarkers = this.getAllChildMarkers(), + points = [], + p, i; + + for (i = childMarkers.length - 1; i >= 0; i--) { + p = childMarkers[i].getLatLng(); + points.push(p); + } + + return L.QuickHull.getConvexHull(points); + } +}); + + +//This code is 100% based on https://github.com/jawj/OverlappingMarkerSpiderfier-Leaflet +//Huge thanks to jawj for implementing it first to make my job easy :-) + +L.MarkerCluster.include({ + + _2PI: Math.PI * 2, + _circleFootSeparation: 25, //related to circumference of circle + _circleStartAngle: Math.PI / 6, + + _spiralFootSeparation: 28, //related to size of spiral (experiment!) + _spiralLengthStart: 11, + _spiralLengthFactor: 5, + + _circleSpiralSwitchover: 9, //show spiral instead of circle from this marker count upwards. + // 0 -> always spiral; Infinity -> always circle + + spiderfy: function () { + if (this._group._spiderfied === this || this._group._inZoomAnimation) { + return; + } + + var childMarkers = this.getAllChildMarkers(), + group = this._group, + map = group._map, + center = map.latLngToLayerPoint(this._latlng), + positions; + + this._group._unspiderfy(); + this._group._spiderfied = this; + + //TODO Maybe: childMarkers order by distance to center + + if (childMarkers.length >= this._circleSpiralSwitchover) { + positions = this._generatePointsSpiral(childMarkers.length, center); + } else { + center.y += 10; // Otherwise circles look wrong => hack for standard blue icon, renders differently for other icons. + positions = this._generatePointsCircle(childMarkers.length, center); + } + + this._animationSpiderfy(childMarkers, positions); + }, + + unspiderfy: function (zoomDetails) { + /// Argument from zoomanim if being called in a zoom animation or null otherwise + if (this._group._inZoomAnimation) { + return; + } + this._animationUnspiderfy(zoomDetails); + + this._group._spiderfied = null; + }, + + _generatePointsCircle: function (count, centerPt) { + var circumference = this._group.options.spiderfyDistanceMultiplier * this._circleFootSeparation * (2 + count), + legLength = circumference / this._2PI, //radius from circumference + angleStep = this._2PI / count, + res = [], + i, angle; + + res.length = count; + + for (i = count - 1; i >= 0; i--) { + angle = this._circleStartAngle + i * angleStep; + res[i] = new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle))._round(); + } + + return res; + }, + + _generatePointsSpiral: function (count, centerPt) { + var spiderfyDistanceMultiplier = this._group.options.spiderfyDistanceMultiplier, + legLength = spiderfyDistanceMultiplier * this._spiralLengthStart, + separation = spiderfyDistanceMultiplier * this._spiralFootSeparation, + lengthFactor = spiderfyDistanceMultiplier * this._spiralLengthFactor * this._2PI, + angle = 0, + res = [], + i; + + res.length = count; + + // Higher index, closer position to cluster center. + for (i = count - 1; i >= 0; i--) { + angle += separation / legLength + i * 0.0005; + res[i] = new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle))._round(); + legLength += lengthFactor / angle; + } + return res; + }, + + _noanimationUnspiderfy: function () { + var group = this._group, + map = group._map, + fg = group._featureGroup, + childMarkers = this.getAllChildMarkers(), + m, i; + + group._ignoreMove = true; + + this.setOpacity(1); + for (i = childMarkers.length - 1; i >= 0; i--) { + m = childMarkers[i]; + + fg.removeLayer(m); + + if (m._preSpiderfyLatlng) { + m.setLatLng(m._preSpiderfyLatlng); + delete m._preSpiderfyLatlng; + } + if (m.setZIndexOffset) { + m.setZIndexOffset(0); + } + + if (m._spiderLeg) { + map.removeLayer(m._spiderLeg); + delete m._spiderLeg; + } + } + + group.fire('unspiderfied', { + cluster: this, + markers: childMarkers + }); + group._ignoreMove = false; + group._spiderfied = null; + } +}); + +//Non Animated versions of everything +L.MarkerClusterNonAnimated = L.MarkerCluster.extend({ + _animationSpiderfy: function (childMarkers, positions) { + var group = this._group, + map = group._map, + fg = group._featureGroup, + legOptions = this._group.options.spiderLegPolylineOptions, + i, m, leg, newPos; + + group._ignoreMove = true; + + // Traverse in ascending order to make sure that inner circleMarkers are on top of further legs. Normal markers are re-ordered by newPosition. + // The reverse order trick no longer improves performance on modern browsers. + for (i = 0; i < childMarkers.length; i++) { + newPos = map.layerPointToLatLng(positions[i]); + m = childMarkers[i]; + + // Add the leg before the marker, so that in case the latter is a circleMarker, the leg is behind it. + leg = new L.Polyline([this._latlng, newPos], legOptions); + map.addLayer(leg); + m._spiderLeg = leg; + + // Now add the marker. + m._preSpiderfyLatlng = m._latlng; + m.setLatLng(newPos); + if (m.setZIndexOffset) { + m.setZIndexOffset(1000000); //Make these appear on top of EVERYTHING + } + + fg.addLayer(m); + } + this.setOpacity(0.3); + + group._ignoreMove = false; + group.fire('spiderfied', { + cluster: this, + markers: childMarkers + }); + }, + + _animationUnspiderfy: function () { + this._noanimationUnspiderfy(); + } +}); + +//Animated versions here +L.MarkerCluster.include({ + + _animationSpiderfy: function (childMarkers, positions) { + var me = this, + group = this._group, + map = group._map, + fg = group._featureGroup, + thisLayerLatLng = this._latlng, + thisLayerPos = map.latLngToLayerPoint(thisLayerLatLng), + svg = L.Path.SVG, + legOptions = L.extend({}, this._group.options.spiderLegPolylineOptions), // Copy the options so that we can modify them for animation. + finalLegOpacity = legOptions.opacity, + i, m, leg, legPath, legLength, newPos; + + if (finalLegOpacity === undefined) { + finalLegOpacity = L.MarkerClusterGroup.prototype.options.spiderLegPolylineOptions.opacity; + } + + if (svg) { + // If the initial opacity of the spider leg is not 0 then it appears before the animation starts. + legOptions.opacity = 0; + + // Add the class for CSS transitions. + legOptions.className = (legOptions.className || '') + ' leaflet-cluster-spider-leg'; + } else { + // Make sure we have a defined opacity. + legOptions.opacity = finalLegOpacity; + } + + group._ignoreMove = true; + + // Add markers and spider legs to map, hidden at our center point. + // Traverse in ascending order to make sure that inner circleMarkers are on top of further legs. Normal markers are re-ordered by newPosition. + // The reverse order trick no longer improves performance on modern browsers. + for (i = 0; i < childMarkers.length; i++) { + m = childMarkers[i]; + + newPos = map.layerPointToLatLng(positions[i]); + + // Add the leg before the marker, so that in case the latter is a circleMarker, the leg is behind it. + leg = new L.Polyline([thisLayerLatLng, newPos], legOptions); + map.addLayer(leg); + m._spiderLeg = leg; + + // Explanations: https://jakearchibald.com/2013/animated-line-drawing-svg/ + // In our case the transition property is declared in the CSS file. + if (svg) { + legPath = leg._path; + legLength = legPath.getTotalLength() + 0.1; // Need a small extra length to avoid remaining dot in Firefox. + legPath.style.strokeDasharray = legLength; // Just 1 length is enough, it will be duplicated. + legPath.style.strokeDashoffset = legLength; + } + + // If it is a marker, add it now and we'll animate it out + if (m.setZIndexOffset) { + m.setZIndexOffset(1000000); // Make normal markers appear on top of EVERYTHING + } + if (m.clusterHide) { + m.clusterHide(); + } + + // Vectors just get immediately added + fg.addLayer(m); + + if (m._setPos) { + m._setPos(thisLayerPos); + } + } + + group._forceLayout(); + group._animationStart(); + + // Reveal markers and spider legs. + for (i = childMarkers.length - 1; i >= 0; i--) { + newPos = map.layerPointToLatLng(positions[i]); + m = childMarkers[i]; + + //Move marker to new position + m._preSpiderfyLatlng = m._latlng; + m.setLatLng(newPos); + + if (m.clusterShow) { + m.clusterShow(); + } + + // Animate leg (animation is actually delegated to CSS transition). + if (svg) { + leg = m._spiderLeg; + legPath = leg._path; + legPath.style.strokeDashoffset = 0; + //legPath.style.strokeOpacity = finalLegOpacity; + leg.setStyle({opacity: finalLegOpacity}); + } + } + this.setOpacity(0.3); + + group._ignoreMove = false; + + setTimeout(function () { + group._animationEnd(); + group.fire('spiderfied', { + cluster: me, + markers: childMarkers + }); + }, 200); + }, + + _animationUnspiderfy: function (zoomDetails) { + var me = this, + group = this._group, + map = group._map, + fg = group._featureGroup, + thisLayerPos = zoomDetails ? map._latLngToNewLayerPoint(this._latlng, zoomDetails.zoom, zoomDetails.center) : map.latLngToLayerPoint(this._latlng), + childMarkers = this.getAllChildMarkers(), + svg = L.Path.SVG, + m, i, leg, legPath, legLength, nonAnimatable; + + group._ignoreMove = true; + group._animationStart(); + + //Make us visible and bring the child markers back in + this.setOpacity(1); + for (i = childMarkers.length - 1; i >= 0; i--) { + m = childMarkers[i]; + + //Marker was added to us after we were spiderfied + if (!m._preSpiderfyLatlng) { + continue; + } + + //Close any popup on the marker first, otherwise setting the location of the marker will make the map scroll + m.closePopup(); + + //Fix up the location to the real one + m.setLatLng(m._preSpiderfyLatlng); + delete m._preSpiderfyLatlng; + + //Hack override the location to be our center + nonAnimatable = true; + if (m._setPos) { + m._setPos(thisLayerPos); + nonAnimatable = false; + } + if (m.clusterHide) { + m.clusterHide(); + nonAnimatable = false; + } + if (nonAnimatable) { + fg.removeLayer(m); + } + + // Animate the spider leg back in (animation is actually delegated to CSS transition). + if (svg) { + leg = m._spiderLeg; + legPath = leg._path; + legLength = legPath.getTotalLength() + 0.1; + legPath.style.strokeDashoffset = legLength; + leg.setStyle({opacity: 0}); + } + } + + group._ignoreMove = false; + + setTimeout(function () { + //If we have only <= one child left then that marker will be shown on the map so don't remove it! + var stillThereChildCount = 0; + for (i = childMarkers.length - 1; i >= 0; i--) { + m = childMarkers[i]; + if (m._spiderLeg) { + stillThereChildCount++; + } + } + + + for (i = childMarkers.length - 1; i >= 0; i--) { + m = childMarkers[i]; + + if (!m._spiderLeg) { //Has already been unspiderfied + continue; + } + + if (m.clusterShow) { + m.clusterShow(); + } + if (m.setZIndexOffset) { + m.setZIndexOffset(0); + } + + if (stillThereChildCount > 1) { + fg.removeLayer(m); + } + + map.removeLayer(m._spiderLeg); + delete m._spiderLeg; + } + group._animationEnd(); + group.fire('unspiderfied', { + cluster: me, + markers: childMarkers + }); + }, 200); + } +}); + + +L.MarkerClusterGroup.include({ + //The MarkerCluster currently spiderfied (if any) + _spiderfied: null, + + unspiderfy: function () { + this._unspiderfy.apply(this, arguments); + }, + + _spiderfierOnAdd: function () { + this._map.on('click', this._unspiderfyWrapper, this); + + if (this._map.options.zoomAnimation) { + this._map.on('zoomstart', this._unspiderfyZoomStart, this); + } + //Browsers without zoomAnimation or a big zoom don't fire zoomstart + this._map.on('zoomend', this._noanimationUnspiderfy, this); + + if (!L.Browser.touch) { + this._map.getRenderer(this); + //Needs to happen in the pageload, not after, or animations don't work in webkit + // http://stackoverflow.com/questions/8455200/svg-animate-with-dynamically-added-elements + //Disable on touch browsers as the animation messes up on a touch zoom and isn't very noticable + } + }, + + _spiderfierOnRemove: function () { + this._map.off('click', this._unspiderfyWrapper, this); + this._map.off('zoomstart', this._unspiderfyZoomStart, this); + this._map.off('zoomanim', this._unspiderfyZoomAnim, this); + this._map.off('zoomend', this._noanimationUnspiderfy, this); + + //Ensure that markers are back where they should be + // Use no animation to avoid a sticky leaflet-cluster-anim class on mapPane + this._noanimationUnspiderfy(); + }, + + //On zoom start we add a zoomanim handler so that we are guaranteed to be last (after markers are animated) + //This means we can define the animation they do rather than Markers doing an animation to their actual location + _unspiderfyZoomStart: function () { + if (!this._map) { //May have been removed from the map by a zoomEnd handler + return; + } + + this._map.on('zoomanim', this._unspiderfyZoomAnim, this); + }, + + _unspiderfyZoomAnim: function (zoomDetails) { + //Wait until the first zoomanim after the user has finished touch-zooming before running the animation + if (L.DomUtil.hasClass(this._map._mapPane, 'leaflet-touching')) { + return; + } + + this._map.off('zoomanim', this._unspiderfyZoomAnim, this); + this._unspiderfy(zoomDetails); + }, + + _unspiderfyWrapper: function () { + /// _unspiderfy but passes no arguments + this._unspiderfy(); + }, + + _unspiderfy: function (zoomDetails) { + if (this._spiderfied) { + this._spiderfied.unspiderfy(zoomDetails); + } + }, + + _noanimationUnspiderfy: function () { + if (this._spiderfied) { + this._spiderfied._noanimationUnspiderfy(); + } + }, + + //If the given layer is currently being spiderfied then we unspiderfy it so it isn't on the map anymore etc + _unspiderfyLayer: function (layer) { + if (layer._spiderLeg) { + this._featureGroup.removeLayer(layer); + + if (layer.clusterShow) { + layer.clusterShow(); + } + //Position will be fixed up immediately in _animationUnspiderfy + if (layer.setZIndexOffset) { + layer.setZIndexOffset(0); + } + + this._map.removeLayer(layer._spiderLeg); + delete layer._spiderLeg; + } + } +}); + + +/** + * Adds 1 public method to MCG and 1 to L.Marker to facilitate changing + * markers' icon options and refreshing their icon and their parent clusters + * accordingly (case where their iconCreateFunction uses data of childMarkers + * to make up the cluster icon). + */ + + +L.MarkerClusterGroup.include({ + /** + * Updates the icon of all clusters which are parents of the given marker(s). + * In singleMarkerMode, also updates the given marker(s) icon. + * @param layers L.MarkerClusterGroup|L.LayerGroup|Array(L.Marker)|Map(L.Marker)| + * L.MarkerCluster|L.Marker (optional) list of markers (or single marker) whose parent + * clusters need to be updated. If not provided, retrieves all child markers of this. + * @returns {L.MarkerClusterGroup} + */ + refreshClusters: function (layers) { + if (!layers) { + layers = this._topClusterLevel.getAllChildMarkers(); + } else if (layers instanceof L.MarkerClusterGroup) { + layers = layers._topClusterLevel.getAllChildMarkers(); + } else if (layers instanceof L.LayerGroup) { + layers = layers._layers; + } else if (layers instanceof L.MarkerCluster) { + layers = layers.getAllChildMarkers(); + } else if (layers instanceof L.Marker) { + layers = [layers]; + } // else: must be an Array(L.Marker)|Map(L.Marker) + this._flagParentsIconsNeedUpdate(layers); + this._refreshClustersIcons(); + + // In case of singleMarkerMode, also re-draw the markers. + if (this.options.singleMarkerMode) { + this._refreshSingleMarkerModeMarkers(layers); + } + + return this; + }, + + /** + * Simply flags all parent clusters of the given markers as having a "dirty" icon. + * @param layers Array(L.Marker)|Map(L.Marker) list of markers. + * @private + */ + _flagParentsIconsNeedUpdate: function (layers) { + var id, parent; + + // Assumes layers is an Array or an Object whose prototype is non-enumerable. + for (id in layers) { + // Flag parent clusters' icon as "dirty", all the way up. + // Dumb process that flags multiple times upper parents, but still + // much more efficient than trying to be smart and make short lists, + // at least in the case of a hierarchy following a power law: + // http://jsperf.com/flag-nodes-in-power-hierarchy/2 + parent = layers[id].__parent; + while (parent) { + parent._iconNeedsUpdate = true; + parent = parent.__parent; + } + } + }, + + /** + * Re-draws the icon of the supplied markers. + * To be used in singleMarkerMode only. + * @param layers Array(L.Marker)|Map(L.Marker) list of markers. + * @private + */ + _refreshSingleMarkerModeMarkers: function (layers) { + var id, layer; + + for (id in layers) { + layer = layers[id]; + + // Make sure we do not override markers that do not belong to THIS group. + if (this.hasLayer(layer)) { + // Need to re-create the icon first, then re-draw the marker. + layer.setIcon(this._overrideMarkerIcon(layer)); + } + } + } +}); + +L.Marker.include({ + /** + * Updates the given options in the marker's icon and refreshes the marker. + * @param options map object of icon options. + * @param directlyRefreshClusters boolean (optional) true to trigger + * MCG.refreshClustersOf() right away with this single marker. + * @returns {L.Marker} + */ + refreshIconOptions: function (options, directlyRefreshClusters) { + var icon = this.options.icon; + + L.setOptions(icon, options); + + this.setIcon(icon); + + // Shortcut to refresh the associated MCG clusters right away. + // To be used when refreshing a single marker. + // Otherwise, better use MCG.refreshClusters() once at the end with + // the list of modified markers. + if (directlyRefreshClusters && this.__parent) { + this.__parent._group.refreshClusters(this); + } + + return this; + } +}); + + +}(window, document)); \ No newline at end of file diff --git a/www/javascript/leaflet.markercluster.min.js b/www/javascript/leaflet.markercluster.min.js new file mode 100644 index 0000000..1eebf55 --- /dev/null +++ b/www/javascript/leaflet.markercluster.min.js @@ -0,0 +1,7 @@ +/* + Leaflet.markercluster, Provides Beautiful Animated Marker Clustering functionality for Leaflet, a JS library for interactive maps. + https://github.com/Leaflet/Leaflet.markercluster + (c) 2012-2013, Dave Leaver, smartrak +*/ +!function(e,t,i){L.MarkerClusterGroup=L.FeatureGroup.extend({options:{maxClusterRadius:80,iconCreateFunction:null,spiderfyOnMaxZoom:!0,showCoverageOnHover:!0,zoomToBoundsOnClick:!0,singleMarkerMode:!1,disableClusteringAtZoom:null,removeOutsideVisibleBounds:!0,animate:!0,animateAddingMarkers:!1,spiderfyDistanceMultiplier:1,spiderLegPolylineOptions:{weight:1.5,color:"#222",opacity:.5},chunkedLoading:!1,chunkInterval:200,chunkDelay:50,chunkProgress:null,polygonOptions:{}},initialize:function(e){L.Util.setOptions(this,e),this.options.iconCreateFunction||(this.options.iconCreateFunction=this._defaultIconCreateFunction),this.options.clusterPane||(this.options.clusterPane=L.Marker.prototype.options.pane),this._featureGroup=L.featureGroup(),this._featureGroup.addEventParent(this),this._nonPointGroup=L.featureGroup(),this._nonPointGroup.addEventParent(this),this._inZoomAnimation=0,this._needsClustering=[],this._needsRemoving=[],this._currentShownBounds=null,this._queue=[],this._childMarkerEventHandlers={dragstart:this._childMarkerDragStart,move:this._childMarkerMoved,dragend:this._childMarkerDragEnd};var t=L.DomUtil.TRANSITION&&this.options.animate;L.extend(this,t?this._withAnimation:this._noAnimation),this._markerCluster=t?L.MarkerCluster:L.MarkerClusterNonAnimated},addLayer:function(e){if(e instanceof L.LayerGroup)return this.addLayers([e]);if(!e.getLatLng)return this._nonPointGroup.addLayer(e),this.fire("layeradd",{layer:e}),this;if(!this._map)return this._needsClustering.push(e),this.fire("layeradd",{layer:e}),this;if(this.hasLayer(e))return this;this._unspiderfy&&this._unspiderfy(),this._addLayer(e,this._maxZoom),this.fire("layeradd",{layer:e}),this._topClusterLevel._recalculateBounds(),this._refreshClustersIcons();var t=e,i=this._zoom;if(e.__parent)for(;t.__parent._zoom>=i;)t=t.__parent;return this._currentShownBounds.contains(t.getLatLng())&&(this.options.animateAddingMarkers?this._animationAddLayer(e,t):this._animationAddLayerNonAnimated(e,t)),this},removeLayer:function(e){return e instanceof L.LayerGroup?this.removeLayers([e]):e.getLatLng?this._map?e.__parent?(this._unspiderfy&&(this._unspiderfy(),this._unspiderfyLayer(e)),this._removeLayer(e,!0),this.fire("layerremove",{layer:e}),this._topClusterLevel._recalculateBounds(),this._refreshClustersIcons(),e.off(this._childMarkerEventHandlers,this),this._featureGroup.hasLayer(e)&&(this._featureGroup.removeLayer(e),e.clusterShow&&e.clusterShow()),this):this:(!this._arraySplice(this._needsClustering,e)&&this.hasLayer(e)&&this._needsRemoving.push({layer:e,latlng:e._latlng}),this.fire("layerremove",{layer:e}),this):(this._nonPointGroup.removeLayer(e),this.fire("layerremove",{layer:e}),this)},addLayers:function(e,t){if(!L.Util.isArray(e))return this.addLayer(e);var i,n=this._featureGroup,r=this._nonPointGroup,s=this.options.chunkedLoading,o=this.options.chunkInterval,a=this.options.chunkProgress,h=e.length,l=0,u=!0;if(this._map){var _=(new Date).getTime(),d=L.bind(function(){for(var c=(new Date).getTime();h>l;l++){if(s&&0===l%200){var p=(new Date).getTime()-c;if(p>o)break}if(i=e[l],i instanceof L.LayerGroup)u&&(e=e.slice(),u=!1),this._extractNonGroupLayers(i,e),h=e.length;else if(i.getLatLng){if(!this.hasLayer(i)&&(this._addLayer(i,this._maxZoom),t||this.fire("layeradd",{layer:i}),i.__parent&&2===i.__parent.getChildCount())){var f=i.__parent.getAllChildMarkers(),m=f[0]===i?f[1]:f[0];n.removeLayer(m)}}else r.addLayer(i),t||this.fire("layeradd",{layer:i})}a&&a(l,h,(new Date).getTime()-_),l===h?(this._topClusterLevel._recalculateBounds(),this._refreshClustersIcons(),this._topClusterLevel._recursivelyAddChildrenToMap(null,this._zoom,this._currentShownBounds)):setTimeout(d,this.options.chunkDelay)},this);d()}else for(var c=this._needsClustering;h>l;l++)i=e[l],i instanceof L.LayerGroup?(u&&(e=e.slice(),u=!1),this._extractNonGroupLayers(i,e),h=e.length):i.getLatLng?this.hasLayer(i)||c.push(i):r.addLayer(i);return this},removeLayers:function(e){var t,i,n=e.length,r=this._featureGroup,s=this._nonPointGroup,o=!0;if(!this._map){for(t=0;n>t;t++)i=e[t],i instanceof L.LayerGroup?(o&&(e=e.slice(),o=!1),this._extractNonGroupLayers(i,e),n=e.length):(this._arraySplice(this._needsClustering,i),s.removeLayer(i),this.hasLayer(i)&&this._needsRemoving.push({layer:i,latlng:i._latlng}),this.fire("layerremove",{layer:i}));return this}if(this._unspiderfy){this._unspiderfy();var a=e.slice(),h=n;for(t=0;h>t;t++)i=a[t],i instanceof L.LayerGroup?(this._extractNonGroupLayers(i,a),h=a.length):this._unspiderfyLayer(i)}for(t=0;n>t;t++)i=e[t],i instanceof L.LayerGroup?(o&&(e=e.slice(),o=!1),this._extractNonGroupLayers(i,e),n=e.length):i.__parent?(this._removeLayer(i,!0,!0),this.fire("layerremove",{layer:i}),r.hasLayer(i)&&(r.removeLayer(i),i.clusterShow&&i.clusterShow())):(s.removeLayer(i),this.fire("layerremove",{layer:i}));return this._topClusterLevel._recalculateBounds(),this._refreshClustersIcons(),this._topClusterLevel._recursivelyAddChildrenToMap(null,this._zoom,this._currentShownBounds),this},clearLayers:function(){return this._map||(this._needsClustering=[],delete this._gridClusters,delete this._gridUnclustered),this._noanimationUnspiderfy&&this._noanimationUnspiderfy(),this._featureGroup.clearLayers(),this._nonPointGroup.clearLayers(),this.eachLayer(function(e){e.off(this._childMarkerEventHandlers,this),delete e.__parent},this),this._map&&this._generateInitialClusters(),this},getBounds:function(){var e=new L.LatLngBounds;this._topClusterLevel&&e.extend(this._topClusterLevel._bounds);for(var t=this._needsClustering.length-1;t>=0;t--)e.extend(this._needsClustering[t].getLatLng());return e.extend(this._nonPointGroup.getBounds()),e},eachLayer:function(e,t){var i,n,r,s=this._needsClustering.slice(),o=this._needsRemoving;for(this._topClusterLevel&&this._topClusterLevel.getAllChildMarkers(s),n=s.length-1;n>=0;n--){for(i=!0,r=o.length-1;r>=0;r--)if(o[r].layer===s[n]){i=!1;break}i&&e.call(t,s[n])}this._nonPointGroup.eachLayer(e,t)},getLayers:function(){var e=[];return this.eachLayer(function(t){e.push(t)}),e},getLayer:function(e){var t=null;return e=parseInt(e,10),this.eachLayer(function(i){L.stamp(i)===e&&(t=i)}),t},hasLayer:function(e){if(!e)return!1;var t,i=this._needsClustering;for(t=i.length-1;t>=0;t--)if(i[t]===e)return!0;for(i=this._needsRemoving,t=i.length-1;t>=0;t--)if(i[t].layer===e)return!1;return!(!e.__parent||e.__parent._group!==this)||this._nonPointGroup.hasLayer(e)},zoomToShowLayer:function(e,t){"function"!=typeof t&&(t=function(){});var i=function(){!e._icon&&!e.__parent._icon||this._inZoomAnimation||(this._map.off("moveend",i,this),this.off("animationend",i,this),e._icon?t():e.__parent._icon&&(this.once("spiderfied",t,this),e.__parent.spiderfy()))};e._icon&&this._map.getBounds().contains(e.getLatLng())?t():e.__parent._zoomt;t++)n=this._needsRemoving[t],n.newlatlng=n.layer._latlng,n.layer._latlng=n.latlng;for(t=0,i=this._needsRemoving.length;i>t;t++)n=this._needsRemoving[t],this._removeLayer(n.layer,!0),n.layer._latlng=n.newlatlng;this._needsRemoving=[],this._zoom=Math.round(this._map._zoom),this._currentShownBounds=this._getExpandedVisibleBounds(),this._map.on("zoomend",this._zoomEnd,this),this._map.on("moveend",this._moveEnd,this),this._spiderfierOnAdd&&this._spiderfierOnAdd(),this._bindEvents(),i=this._needsClustering,this._needsClustering=[],this.addLayers(i,!0)},onRemove:function(e){e.off("zoomend",this._zoomEnd,this),e.off("moveend",this._moveEnd,this),this._unbindEvents(),this._map._mapPane.className=this._map._mapPane.className.replace(" leaflet-cluster-anim",""),this._spiderfierOnRemove&&this._spiderfierOnRemove(),delete this._maxLat,this._hideCoverage(),this._featureGroup.remove(),this._nonPointGroup.remove(),this._featureGroup.clearLayers(),this._map=null},getVisibleParent:function(e){for(var t=e;t&&!t._icon;)t=t.__parent;return t||null},_arraySplice:function(e,t){for(var i=e.length-1;i>=0;i--)if(e[i]===t)return e.splice(i,1),!0},_removeFromGridUnclustered:function(e,t){for(var i=this._map,n=this._gridUnclustered,r=Math.floor(this._map.getMinZoom());t>=r&&n[t].removeObject(e,i.project(e.getLatLng(),t));t--);},_childMarkerDragStart:function(e){e.target.__dragStart=e.target._latlng},_childMarkerMoved:function(e){if(!this._ignoreMove&&!e.target.__dragStart){var t=e.target._popup&&e.target._popup.isOpen();this._moveChild(e.target,e.oldLatLng,e.latlng),t&&e.target.openPopup()}},_moveChild:function(e,t,i){e._latlng=t,this.removeLayer(e),e._latlng=i,this.addLayer(e)},_childMarkerDragEnd:function(e){e.target.__dragStart&&this._moveChild(e.target,e.target.__dragStart,e.target._latlng),delete e.target.__dragStart},_removeLayer:function(e,t,i){var n=this._gridClusters,r=this._gridUnclustered,s=this._featureGroup,o=this._map,a=Math.floor(this._map.getMinZoom());t&&this._removeFromGridUnclustered(e,this._maxZoom);var h,l=e.__parent,u=l._markers;for(this._arraySplice(u,e);l&&(l._childCount--,l._boundsNeedUpdate=!0,!(l._zoomt?"small":100>t?"medium":"large",new L.DivIcon({html:"
"+t+"
",className:"marker-cluster"+i,iconSize:new L.Point(40,40)})},_bindEvents:function(){var e=this._map,t=this.options.spiderfyOnMaxZoom,i=this.options.showCoverageOnHover,n=this.options.zoomToBoundsOnClick;(t||n)&&this.on("clusterclick",this._zoomOrSpiderfy,this),i&&(this.on("clustermouseover",this._showCoverage,this),this.on("clustermouseout",this._hideCoverage,this),e.on("zoomend",this._hideCoverage,this))},_zoomOrSpiderfy:function(e){for(var t=e.layer,i=t;1===i._childClusters.length;)i=i._childClusters[0];i._zoom===this._maxZoom&&i._childCount===t._childCount&&this.options.spiderfyOnMaxZoom?t.spiderfy():this.options.zoomToBoundsOnClick&&t.zoomToBounds(),e.originalEvent&&13===e.originalEvent.keyCode&&this._map._container.focus()},_showCoverage:function(e){var t=this._map;this._inZoomAnimation||(this._shownPolygon&&t.removeLayer(this._shownPolygon),e.layer.getChildCount()>2&&e.layer!==this._spiderfied&&(this._shownPolygon=new L.Polygon(e.layer.getConvexHull(),this.options.polygonOptions),t.addLayer(this._shownPolygon)))},_hideCoverage:function(){this._shownPolygon&&(this._map.removeLayer(this._shownPolygon),this._shownPolygon=null)},_unbindEvents:function(){var e=this.options.spiderfyOnMaxZoom,t=this.options.showCoverageOnHover,i=this.options.zoomToBoundsOnClick,n=this._map;(e||i)&&this.off("clusterclick",this._zoomOrSpiderfy,this),t&&(this.off("clustermouseover",this._showCoverage,this),this.off("clustermouseout",this._hideCoverage,this),n.off("zoomend",this._hideCoverage,this))},_zoomEnd:function(){this._map&&(this._mergeSplitClusters(),this._zoom=Math.round(this._map._zoom),this._currentShownBounds=this._getExpandedVisibleBounds())},_moveEnd:function(){if(!this._inZoomAnimation){var e=this._getExpandedVisibleBounds();this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds,Math.floor(this._map.getMinZoom()),this._zoom,e),this._topClusterLevel._recursivelyAddChildrenToMap(null,Math.round(this._map._zoom),e),this._currentShownBounds=e}},_generateInitialClusters:function(){var e=Math.ceil(this._map.getMaxZoom()),t=Math.floor(this._map.getMinZoom()),i=this.options.maxClusterRadius,n=i;"function"!=typeof i&&(n=function(){return i}),null!==this.options.disableClusteringAtZoom&&(e=this.options.disableClusteringAtZoom-1),this._maxZoom=e,this._gridClusters={},this._gridUnclustered={};for(var r=e;r>=t;r--)this._gridClusters[r]=new L.DistanceGrid(n(r)),this._gridUnclustered[r]=new L.DistanceGrid(n(r));this._topClusterLevel=new this._markerCluster(this,t-1)},_addLayer:function(e,t){var i,n,r=this._gridClusters,s=this._gridUnclustered,o=Math.floor(this._map.getMinZoom());for(this.options.singleMarkerMode&&this._overrideMarkerIcon(e),e.on(this._childMarkerEventHandlers,this);t>=o;t--){i=this._map.project(e.getLatLng(),t);var a=r[t].getNearObject(i);if(a)return a._addChild(e),e.__parent=a,void 0;if(a=s[t].getNearObject(i)){var h=a.__parent;h&&this._removeLayer(a,!1);var l=new this._markerCluster(this,t,a,e);r[t].addObject(l,this._map.project(l._cLatLng,t)),a.__parent=l,e.__parent=l;var u=l;for(n=t-1;n>h._zoom;n--)u=new this._markerCluster(this,n,u),r[n].addObject(u,this._map.project(a.getLatLng(),n));return h._addChild(u),this._removeFromGridUnclustered(a,t),void 0}s[t].addObject(e,i)}this._topClusterLevel._addChild(e),e.__parent=this._topClusterLevel},_refreshClustersIcons:function(){this._featureGroup.eachLayer(function(e){e instanceof L.MarkerCluster&&e._iconNeedsUpdate&&e._updateIcon()})},_enqueue:function(e){this._queue.push(e),this._queueTimeout||(this._queueTimeout=setTimeout(L.bind(this._processQueue,this),300))},_processQueue:function(){for(var e=0;ee?(this._animationStart(),this._animationZoomOut(this._zoom,e)):this._moveEnd()},_getExpandedVisibleBounds:function(){return this.options.removeOutsideVisibleBounds?L.Browser.mobile?this._checkBoundsMaxLat(this._map.getBounds()):this._checkBoundsMaxLat(this._map.getBounds().pad(1)):this._mapBoundsInfinite},_checkBoundsMaxLat:function(e){var t=this._maxLat;return t!==i&&(e.getNorth()>=t&&(e._northEast.lat=1/0),e.getSouth()<=-t&&(e._southWest.lat=-1/0)),e},_animationAddLayerNonAnimated:function(e,t){if(t===e)this._featureGroup.addLayer(e);else if(2===t._childCount){t._addToMap();var i=t.getAllChildMarkers();this._featureGroup.removeLayer(i[0]),this._featureGroup.removeLayer(i[1])}else t._updateIcon()},_extractNonGroupLayers:function(e,t){var i,n=e.getLayers(),r=0;for(t=t||[];r=0;i--)o=h[i],n.contains(o._latlng)||r.removeLayer(o)}),this._forceLayout(),this._topClusterLevel._recursivelyBecomeVisible(n,t),r.eachLayer(function(e){e instanceof L.MarkerCluster||!e._icon||e.clusterShow()}),this._topClusterLevel._recursively(n,e,t,function(e){e._recursivelyRestoreChildPositions(t)}),this._ignoreMove=!1,this._enqueue(function(){this._topClusterLevel._recursively(n,e,s,function(e){r.removeLayer(e),e.clusterShow()}),this._animationEnd()})},_animationZoomOut:function(e,t){this._animationZoomOutSingle(this._topClusterLevel,e-1,t),this._topClusterLevel._recursivelyAddChildrenToMap(null,t,this._getExpandedVisibleBounds()),this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds,Math.floor(this._map.getMinZoom()),e,this._getExpandedVisibleBounds())},_animationAddLayer:function(e,t){var i=this,n=this._featureGroup;n.addLayer(e),t!==e&&(t._childCount>2?(t._updateIcon(),this._forceLayout(),this._animationStart(),e._setPos(this._map.latLngToLayerPoint(t.getLatLng())),e.clusterHide(),this._enqueue(function(){n.removeLayer(e),e.clusterShow(),i._animationEnd()})):(this._forceLayout(),i._animationStart(),i._animationZoomOutSingle(t,this._map.getMaxZoom(),this._zoom)))}},_animationZoomOutSingle:function(e,t,i){var n=this._getExpandedVisibleBounds(),r=Math.floor(this._map.getMinZoom());e._recursivelyAnimateChildrenInAndAddSelfToMap(n,r,t+1,i);var s=this;this._forceLayout(),e._recursivelyBecomeVisible(n,i),this._enqueue(function(){if(1===e._childCount){var o=e._markers[0];this._ignoreMove=!0,o.setLatLng(o.getLatLng()),this._ignoreMove=!1,o.clusterShow&&o.clusterShow()}else e._recursively(n,i,r,function(e){e._recursivelyRemoveChildrenFromMap(n,r,t+1)});s._animationEnd()})},_animationEnd:function(){this._map&&(this._map._mapPane.className=this._map._mapPane.className.replace(" leaflet-cluster-anim","")),this._inZoomAnimation--,this.fire("animationend")},_forceLayout:function(){L.Util.falseFn(t.body.offsetWidth)}}),L.markerClusterGroup=function(e){return new L.MarkerClusterGroup(e)},L.MarkerCluster=L.Marker.extend({initialize:function(e,t,i,n){L.Marker.prototype.initialize.call(this,i?i._cLatLng||i.getLatLng():new L.LatLng(0,0),{icon:this,pane:e.options.clusterPane}),this._group=e,this._zoom=t,this._markers=[],this._childClusters=[],this._childCount=0,this._iconNeedsUpdate=!0,this._boundsNeedUpdate=!0,this._bounds=new L.LatLngBounds,i&&this._addChild(i),n&&this._addChild(n)},getAllChildMarkers:function(e){e=e||[];for(var t=this._childClusters.length-1;t>=0;t--)this._childClusters[t].getAllChildMarkers(e);for(var i=this._markers.length-1;i>=0;i--)e.push(this._markers[i]);return e},getChildCount:function(){return this._childCount},zoomToBounds:function(e){for(var t,i=this._childClusters.slice(),n=this._group._map,r=n.getBoundsZoom(this._bounds),s=this._zoom+1,o=n.getZoom();i.length>0&&r>s;){s++;var a=[];for(t=0;ts?this._group._map.setView(this._latlng,s):o>=r?this._group._map.setView(this._latlng,o+1):this._group._map.fitBounds(this._bounds,e)},getBounds:function(){var e=new L.LatLngBounds;return e.extend(this._bounds),e},_updateIcon:function(){this._iconNeedsUpdate=!0,this._icon&&this.setIcon(this)},createIcon:function(){return this._iconNeedsUpdate&&(this._iconObj=this._group.options.iconCreateFunction(this),this._iconNeedsUpdate=!1),this._iconObj.createIcon()},createShadow:function(){return this._iconObj.createShadow()},_addChild:function(e,t){this._iconNeedsUpdate=!0,this._boundsNeedUpdate=!0,this._setClusterCenter(e),e instanceof L.MarkerCluster?(t||(this._childClusters.push(e),e.__parent=this),this._childCount+=e._childCount):(t||this._markers.push(e),this._childCount++),this.__parent&&this.__parent._addChild(e,!0)},_setClusterCenter:function(e){this._cLatLng||(this._cLatLng=e._cLatLng||e._latlng)},_resetBounds:function(){var e=this._bounds;e._southWest&&(e._southWest.lat=1/0,e._southWest.lng=1/0),e._northEast&&(e._northEast.lat=-1/0,e._northEast.lng=-1/0)},_recalculateBounds:function(){var e,t,i,n,r=this._markers,s=this._childClusters,o=0,a=0,h=this._childCount;if(0!==h){for(this._resetBounds(),e=0;e=0;i--)n=r[i],n._icon&&(n._setPos(t),n.clusterHide())},function(e){var i,n,r=e._childClusters;for(i=r.length-1;i>=0;i--)n=r[i],n._icon&&(n._setPos(t),n.clusterHide())})},_recursivelyAnimateChildrenInAndAddSelfToMap:function(e,t,i,n){this._recursively(e,n,t,function(r){r._recursivelyAnimateChildrenIn(e,r._group._map.latLngToLayerPoint(r.getLatLng()).round(),i),r._isSingleParent()&&i-1===n?(r.clusterShow(),r._recursivelyRemoveChildrenFromMap(e,t,i)):r.clusterHide(),r._addToMap()})},_recursivelyBecomeVisible:function(e,t){this._recursively(e,this._group._map.getMinZoom(),t,null,function(e){e.clusterShow()})},_recursivelyAddChildrenToMap:function(e,t,i){this._recursively(i,this._group._map.getMinZoom()-1,t,function(n){if(t!==n._zoom)for(var r=n._markers.length-1;r>=0;r--){var s=n._markers[r];i.contains(s._latlng)&&(e&&(s._backupLatlng=s.getLatLng(),s.setLatLng(e),s.clusterHide&&s.clusterHide()),n._group._featureGroup.addLayer(s))}},function(t){t._addToMap(e)})},_recursivelyRestoreChildPositions:function(e){for(var t=this._markers.length-1;t>=0;t--){var i=this._markers[t];i._backupLatlng&&(i.setLatLng(i._backupLatlng),delete i._backupLatlng)}if(e-1===this._zoom)for(var n=this._childClusters.length-1;n>=0;n--)this._childClusters[n]._restorePosition();else for(var r=this._childClusters.length-1;r>=0;r--)this._childClusters[r]._recursivelyRestoreChildPositions(e)},_restorePosition:function(){this._backupLatlng&&(this.setLatLng(this._backupLatlng),delete this._backupLatlng)},_recursivelyRemoveChildrenFromMap:function(e,t,i,n){var r,s;this._recursively(e,t-1,i-1,function(e){for(s=e._markers.length-1;s>=0;s--)r=e._markers[s],n&&n.contains(r._latlng)||(e._group._featureGroup.removeLayer(r),r.clusterShow&&r.clusterShow())},function(e){for(s=e._childClusters.length-1;s>=0;s--)r=e._childClusters[s],n&&n.contains(r._latlng)||(e._group._featureGroup.removeLayer(r),r.clusterShow&&r.clusterShow())})},_recursively:function(e,t,i,n,r){var s,o,a=this._childClusters,h=this._zoom;if(h>=t&&(n&&n(this),r&&h===i&&r(this)),t>h||i>h)for(s=a.length-1;s>=0;s--)o=a[s],e.intersects(o._bounds)&&o._recursively(e,t,i,n,r)},_isSingleParent:function(){return this._childClusters.length>0&&this._childClusters[0]._childCount===this._childCount}}),L.Marker.include({clusterHide:function(){return this.options.opacityWhenUnclustered=this.options.opacity||1,this.setOpacity(0)},clusterShow:function(){var e=this.setOpacity(this.options.opacity||this.options.opacityWhenUnclustered);return delete this.options.opacityWhenUnclustered,e}}),L.DistanceGrid=function(e){this._cellSize=e,this._sqCellSize=e*e,this._grid={},this._objectPoint={}},L.DistanceGrid.prototype={addObject:function(e,t){var i=this._getCoord(t.x),n=this._getCoord(t.y),r=this._grid,s=r[n]=r[n]||{},o=s[i]=s[i]||[],a=L.Util.stamp(e);this._objectPoint[a]=t,o.push(e)},updateObject:function(e,t){this.removeObject(e),this.addObject(e,t)},removeObject:function(e,t){var i,n,r=this._getCoord(t.x),s=this._getCoord(t.y),o=this._grid,a=o[s]=o[s]||{},h=a[r]=a[r]||[];for(delete this._objectPoint[L.Util.stamp(e)],i=0,n=h.length;n>i;i++)if(h[i]===e)return h.splice(i,1),1===n&&delete a[r],!0},eachObject:function(e,t){var i,n,r,s,o,a,h,l=this._grid;for(i in l){o=l[i];for(n in o)for(a=o[n],r=0,s=a.length;s>r;r++)h=e.call(t,a[r]),h&&(r--,s--)}},getNearObject:function(e){var t,i,n,r,s,o,a,h,l=this._getCoord(e.x),u=this._getCoord(e.y),_=this._objectPoint,d=this._sqCellSize,c=null;for(t=u-1;u+1>=t;t++)if(r=this._grid[t])for(i=l-1;l+1>=i;i++)if(s=r[i])for(n=0,o=s.length;o>n;n++)a=s[n],h=this._sqDist(_[L.Util.stamp(a)],e),d>h&&(d=h,c=a);return c},_getCoord:function(e){return Math.floor(e/this._cellSize)},_sqDist:function(e,t){var i=t.x-e.x,n=t.y-e.y;return i*i+n*n}},function(){L.QuickHull={getDistant:function(e,t){var i=t[1].lat-t[0].lat,n=t[0].lng-t[1].lng;return n*(e.lat-t[0].lat)+i*(e.lng-t[0].lng)},findMostDistantPointFromBaseLine:function(e,t){var i,n,r,s=0,o=null,a=[];for(i=t.length-1;i>=0;i--)n=t[i],r=this.getDistant(n,e),r>0&&(a.push(n),r>s&&(s=r,o=n));return{maxPoint:o,newPoints:a}},buildConvexHull:function(e,t){var i=[],n=this.findMostDistantPointFromBaseLine(e,t);return n.maxPoint?(i=i.concat(this.buildConvexHull([e[0],n.maxPoint],n.newPoints)),i=i.concat(this.buildConvexHull([n.maxPoint,e[1]],n.newPoints))):[e[0]]},getConvexHull:function(e){var t,i=!1,n=!1,r=!1,s=!1,o=null,a=null,h=null,l=null,u=null,_=null;for(t=e.length-1;t>=0;t--){var d=e[t];(i===!1||d.lat>i)&&(o=d,i=d.lat),(n===!1||d.latr)&&(h=d,r=d.lng),(s===!1||d.lng=0;t--)e=i[t].getLatLng(),n.push(e);return L.QuickHull.getConvexHull(n)}}),L.MarkerCluster.include({_2PI:2*Math.PI,_circleFootSeparation:25,_circleStartAngle:Math.PI/6,_spiralFootSeparation:28,_spiralLengthStart:11,_spiralLengthFactor:5,_circleSpiralSwitchover:9,spiderfy:function(){if(this._group._spiderfied!==this&&!this._group._inZoomAnimation){var e,t=this.getAllChildMarkers(),i=this._group,n=i._map,r=n.latLngToLayerPoint(this._latlng);this._group._unspiderfy(),this._group._spiderfied=this,t.length>=this._circleSpiralSwitchover?e=this._generatePointsSpiral(t.length,r):(r.y+=10,e=this._generatePointsCircle(t.length,r)),this._animationSpiderfy(t,e)}},unspiderfy:function(e){this._group._inZoomAnimation||(this._animationUnspiderfy(e),this._group._spiderfied=null)},_generatePointsCircle:function(e,t){var i,n,r=this._group.options.spiderfyDistanceMultiplier*this._circleFootSeparation*(2+e),s=r/this._2PI,o=this._2PI/e,a=[];for(a.length=e,i=e-1;i>=0;i--)n=this._circleStartAngle+i*o,a[i]=new L.Point(t.x+s*Math.cos(n),t.y+s*Math.sin(n))._round();return a},_generatePointsSpiral:function(e,t){var i,n=this._group.options.spiderfyDistanceMultiplier,r=n*this._spiralLengthStart,s=n*this._spiralFootSeparation,o=n*this._spiralLengthFactor*this._2PI,a=0,h=[];for(h.length=e,i=e-1;i>=0;i--)a+=s/r+5e-4*i,h[i]=new L.Point(t.x+r*Math.cos(a),t.y+r*Math.sin(a))._round(),r+=o/a;return h},_noanimationUnspiderfy:function(){var e,t,i=this._group,n=i._map,r=i._featureGroup,s=this.getAllChildMarkers();for(i._ignoreMove=!0,this.setOpacity(1),t=s.length-1;t>=0;t--)e=s[t],r.removeLayer(e),e._preSpiderfyLatlng&&(e.setLatLng(e._preSpiderfyLatlng),delete e._preSpiderfyLatlng),e.setZIndexOffset&&e.setZIndexOffset(0),e._spiderLeg&&(n.removeLayer(e._spiderLeg),delete e._spiderLeg);i.fire("unspiderfied",{cluster:this,markers:s}),i._ignoreMove=!1,i._spiderfied=null}}),L.MarkerClusterNonAnimated=L.MarkerCluster.extend({_animationSpiderfy:function(e,t){var i,n,r,s,o=this._group,a=o._map,h=o._featureGroup,l=this._group.options.spiderLegPolylineOptions;for(o._ignoreMove=!0,i=0;i=0;n--)h=_.layerPointToLatLng(t[n]),r=e[n],r._preSpiderfyLatlng=r._latlng,r.setLatLng(h),r.clusterShow&&r.clusterShow(),f&&(s=r._spiderLeg,o=s._path,o.style.strokeDashoffset=0,s.setStyle({opacity:g}));this.setOpacity(.3),u._ignoreMove=!1,setTimeout(function(){u._animationEnd(),u.fire("spiderfied",{cluster:l,markers:e})},200)},_animationUnspiderfy:function(e){var t,i,n,r,s,o,a=this,h=this._group,l=h._map,u=h._featureGroup,_=e?l._latLngToNewLayerPoint(this._latlng,e.zoom,e.center):l.latLngToLayerPoint(this._latlng),d=this.getAllChildMarkers(),c=L.Path.SVG;for(h._ignoreMove=!0,h._animationStart(),this.setOpacity(1),i=d.length-1;i>=0;i--)t=d[i],t._preSpiderfyLatlng&&(t.closePopup(),t.setLatLng(t._preSpiderfyLatlng),delete t._preSpiderfyLatlng,o=!0,t._setPos&&(t._setPos(_),o=!1),t.clusterHide&&(t.clusterHide(),o=!1),o&&u.removeLayer(t),c&&(n=t._spiderLeg,r=n._path,s=r.getTotalLength()+.1,r.style.strokeDashoffset=s,n.setStyle({opacity:0})));h._ignoreMove=!1,setTimeout(function(){var e=0;for(i=d.length-1;i>=0;i--)t=d[i],t._spiderLeg&&e++;for(i=d.length-1;i>=0;i--)t=d[i],t._spiderLeg&&(t.clusterShow&&t.clusterShow(),t.setZIndexOffset&&t.setZIndexOffset(0),e>1&&u.removeLayer(t),l.removeLayer(t._spiderLeg),delete t._spiderLeg);h._animationEnd(),h.fire("unspiderfied",{cluster:a,markers:d})},200)}}),L.MarkerClusterGroup.include({_spiderfied:null,unspiderfy:function(){this._unspiderfy.apply(this,arguments)},_spiderfierOnAdd:function(){this._map.on("click",this._unspiderfyWrapper,this),this._map.options.zoomAnimation&&this._map.on("zoomstart",this._unspiderfyZoomStart,this),this._map.on("zoomend",this._noanimationUnspiderfy,this),L.Browser.touch||this._map.getRenderer(this)},_spiderfierOnRemove:function(){this._map.off("click",this._unspiderfyWrapper,this),this._map.off("zoomstart",this._unspiderfyZoomStart,this),this._map.off("zoomanim",this._unspiderfyZoomAnim,this),this._map.off("zoomend",this._noanimationUnspiderfy,this),this._noanimationUnspiderfy()},_unspiderfyZoomStart:function(){this._map&&this._map.on("zoomanim",this._unspiderfyZoomAnim,this)},_unspiderfyZoomAnim:function(e){L.DomUtil.hasClass(this._map._mapPane,"leaflet-touching")||(this._map.off("zoomanim",this._unspiderfyZoomAnim,this),this._unspiderfy(e))},_unspiderfyWrapper:function(){this._unspiderfy() +},_unspiderfy:function(e){this._spiderfied&&this._spiderfied.unspiderfy(e)},_noanimationUnspiderfy:function(){this._spiderfied&&this._spiderfied._noanimationUnspiderfy()},_unspiderfyLayer:function(e){e._spiderLeg&&(this._featureGroup.removeLayer(e),e.clusterShow&&e.clusterShow(),e.setZIndexOffset&&e.setZIndexOffset(0),this._map.removeLayer(e._spiderLeg),delete e._spiderLeg)}}),L.MarkerClusterGroup.include({refreshClusters:function(e){return e?e instanceof L.MarkerClusterGroup?e=e._topClusterLevel.getAllChildMarkers():e instanceof L.LayerGroup?e=e._layers:e instanceof L.MarkerCluster?e=e.getAllChildMarkers():e instanceof L.Marker&&(e=[e]):e=this._topClusterLevel.getAllChildMarkers(),this._flagParentsIconsNeedUpdate(e),this._refreshClustersIcons(),this.options.singleMarkerMode&&this._refreshSingleMarkerModeMarkers(e),this},_flagParentsIconsNeedUpdate:function(e){var t,i;for(t in e)for(i=e[t].__parent;i;)i._iconNeedsUpdate=!0,i=i.__parent},_refreshSingleMarkerModeMarkers:function(e){var t,i;for(t in e)i=e[t],this.hasLayer(i)&&i.setIcon(this._overrideMarkerIcon(i))}}),L.Marker.include({refreshIconOptions:function(e,t){var i=this.options.icon;return L.setOptions(i,e),this.setIcon(i),t&&this.__parent&&this.__parent._group.refreshClusters(this),this}})}(window,document); \ No newline at end of file diff --git a/www/javascript/mapzen.js b/www/javascript/mapzen.js index 92392eb..2425113 100644 --- a/www/javascript/mapzen.js +++ b/www/javascript/mapzen.js @@ -4716,7 +4716,7 @@ module.exports={ 'use strict'; var L = require('leaflet'); - + module.exports = L.LayerGroup.extend({ includes: L.Mixin.Events, @@ -4750,7 +4750,7 @@ module.exports={ this.options.styles, this.options.addWaypoints); }, - + getBounds: function() { return L.latLngBounds(this._route.coordinates); }, @@ -5128,7 +5128,7 @@ module.exports={ 'es': spanish, 'sp': spanish, - + 'nl': { directions: { N: 'noordelijke', @@ -20601,12 +20601,30 @@ if (typeof module === 'object' && module.exports) { wps.push(new Waypoint(L.latLng(wp.latLng), wp.name || "", wp.options || {})) } + // Before we hit the Valhalla API, let's make sure we don't have the + // route cached already. (20171006/dphiffer) + if ('cacheCheck' in routingOptions) { + var data = routingOptions.cacheCheck(url); + if (data) { + var cb = L.bind(this._routeDone, this); + setTimeout(function(){ + cb(data, wps, routingOptions, callback, context); + }, 0); + return this; + } + } + corslite(url, L.bind(function(err, resp) { var data; clearTimeout(timer); if (!timedOut) { if (!err) { data = JSON.parse(resp.responseText); + + if ('cacheStore' in routingOptions) { + routingOptions.cacheStore(url, data); + } + this._routeDone(data, wps, routingOptions, callback, context); } else { console.log("Error : " + err.response); @@ -21099,7 +21117,7 @@ var MapzenScarab = (function () { function _buildDescription(id, container) { var infoBox = document.createElement('div') infoBox.className = "mz-bug-" + id - infoBox.textContent = opts.description + infoBox.textContent = opts.description infoBox.style.width = container.offsetWidth + 'px' infoBox.style.marginLeft = container.style.marginLeft @@ -21108,7 +21126,7 @@ var MapzenScarab = (function () { } function resizeDescription(container) { - var containerWidth = container.offsetWidth + var containerWidth = container.offsetWidth infoDescriptionEl.style.width = containerWidth + 'px' infoDescriptionEl.style.marginLeft = container.style.marginLeft } diff --git a/www/javascript/mapzen.places.api.init.js b/www/javascript/mapzen.places.api.init.js new file mode 100644 index 0000000..784bbac --- /dev/null +++ b/www/javascript/mapzen.places.api.init.js @@ -0,0 +1,16 @@ +window.addEventListener('load', function(e){ + + var endpoint_handler = function() { + var endpoint = document.body.getAttribute("data-api-endpoint"); + return endpoint; + } + + var authentication_handler = function(form_data) { + var api_key = document.body.getAttribute("data-mapzen-api-key"); + form_data.append('api_key', api_key); + return form_data; + } + + mapzen.places.api.set_handler('endpoint', endpoint_handler); + mapzen.places.api.set_handler('authentication', authentication_handler); +}); diff --git a/www/javascript/mapzen.places.api.js b/www/javascript/mapzen.places.api.js new file mode 100644 index 0000000..d7a3abd --- /dev/null +++ b/www/javascript/mapzen.places.api.js @@ -0,0 +1,320 @@ +(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.mapzen = g.mapzen || {}; + g.mapzen.places = g.mapzen.places || {}; + g.mapzen.places.api = g.mapzen.places.api = f(); + } + +}(function(){ + + var null_handler = function(){ + return undefined; + }; + + var mapzen_endpoint = function(){ + return "https://places.mapzen.com/v1" + }; + + var mapzen_authentication = function(form_data){ + var api_key = "mapzen-xxxxxxx"; + if (typeof L !== "undefined" && + typeof L.Mapzen !== "undefined" && + typeof L.Mapzen.apiKey !== "undefined"){ + api_key = L.Mapzen.apiKey; + } + form_data.append("api_key", api_key); + }; + + var self = { + + '_handlers': { + 'endpoint': mapzen_endpoint, + 'authentication': mapzen_authentication + }, + + 'set_apikey': function(key){ + + return self.set_handler("authentication", function(form_data){ + form_data.append("api_key", key); + }); + }, + + 'set_handler': function(target, handler){ + + if (! self._handlers[target]){ + console.log("MISSING " + target); + return false; + } + + if (typeof(handler) != "function"){ + console.log(target + " IS NOT A FUNCTION"); + return false; + } + + self._handlers[target] = handler; + }, + + 'get_handler': function(target){ + + if (! self._handlers[target]){ + return false; + } + + return self._handlers[target]; + }, + + 'method': function(name, args){ + + if (! args){ + args = {"verb": "GET"}; + } + + var m = function(n, v){ + + var self = { + 'name': function(){ return n; }, + 'verb': function(){ return v; }, + }; + + return self; + }; + + return m(name, args["verb"]); + }, + + 'call': function(method, data, on_success, on_error){ + + if (typeof(method) == "string"){ + method = self.method(method); + } + + var dothis_onsuccess = function(rsp){ + + if (on_success){ + on_success(rsp); + } + }; + + var dothis_onerror = function(rsp){ + + console.log("ERROR", rsp); + + if (on_error){ + on_error(rsp); + } + }; + + var form_data = data; + + if ((! form_data) || (! form_data.append)){ + + form_data = new FormData(); + + for (key in data){ + form_data.append(key, data[key]); + } + } + + form_data.append('method', method.name()); + + var get_endpoint = self.get_handler('endpoint'); + + if (! get_endpoint){ + dothis_onerror(self.destruct("Missing endpoint handler")); + return false + } + + var endpoint = get_endpoint(); + + if (! endpoint){ + dothis_onerror(self.destruct("Endpoint handler returns no endpoint!")); + return false + } + + if (! form_data.get("api_key")){ + + var set_authentication = self.get_handler('authentication'); + + if (! set_authentication){ + dothis_onerror(self.destruct("there is no authentication handler")); + return false; + } + + set_authentication(form_data); + } + + var onload = function(rsp){ + + var target = rsp.target; + + if (target.readyState != 4){ + return; + } + + var status_code = target['status']; + var status_text = target['statusText']; + + var raw = target['responseText']; + var data = undefined; + + var fmt = form_data.get("format"); + + if ((fmt == "json") || (fmt == "geojson") || (fmt == null)){ + + try { + data = JSON.parse(raw); + } + + catch (e){ + dothis_onerror(self.destruct("failed to parse JSON " + e)); + return false; + } + + if (data['stat'] != 'ok'){ + dothis_onerror(data); + return false; + } + } + + else { + data = raw; + } + + dothis_onsuccess(data); + return true; + }; + + var onprogress = function(rsp){ + // console.log("progress"); + }; + + var onfailed = function(rsp){ + dothis_onerror(self.destruct("connection failed " + rsp)); + }; + + var onabort = function(rsp){ + dothis_onerror(self.destruct("connection aborted " + rsp)); + }; + + // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data + + try { + var req = new XMLHttpRequest(); + + req.addEventListener("load", onload); + req.addEventListener("progress", onprogress); + req.addEventListener("error", onfailed); + req.addEventListener("abort", onabort); + + if (method.verb() == "GET"){ + + if (form_data.keys()){ + + var query = []; + + for (var pair of form_data.entries()) { + query.push(pair[0] + "=" + encodeURIComponent(pair[1])); + } + + var query_string = query.join("&"); + var sep = (endpoint.indexOf('?') == -1) ? '?' : '&'; + + endpoint = endpoint + sep + query.join("&"); + } + + req.open("GET", endpoint, true); + req.send(); + + return; + } + + req.open("POST", endpoint, true); + req.send(form_data); + + } catch (e) { + + dothis_onerror(self.destruct("failed to send request, because " + e)); + return false; + } + + return false; + }, + + 'call_paginated': function(method, data, on_page, on_error, on_complete){ + + var results = []; + + var dothis_oncomplete = function(rsp) { + + results.push(rsp); + + if (on_page) { + on_page(rsp); + } + + if (rsp.next_query) { + + var args = rsp.next_query.split('&'); + + for (var i = 0; i < args.length; i++) { + var arg = args[i].split('='); + var key = decodeURIComponent(arg[0]); + var value = decodeURIComponent(arg[1]); + data[key] = value; + } + + self.call(method, data, dothis_oncomplete, on_error); + + } else if (on_complete) { + on_complete(results); + } + }; + + self.call(method, data, dothis_oncomplete, on_error); + }, + + 'execute_method': function(method, data, on_success, on_error){ + self.call(method, data, on_success, on_error); + }, + + 'execute_method_paginated': function(method, data, on_page, on_error, on_complete){ + self.call_paginated(method, data, on_page, on_error, on_complete); + }, + + 'destruct': function(msg){ + + return { + 'stat': 'error', + 'error': { + 'code': 999, + 'message': msg + } + }; + + } + } + + return self; + +})); diff --git a/www/javascript/mapzen.places.id.init.js b/www/javascript/mapzen.places.id.init.js index 641d1dd..0994381 100644 --- a/www/javascript/mapzen.places.id.init.js +++ b/www/javascript/mapzen.places.id.init.js @@ -1,54 +1,93 @@ window.addEventListener("load", function load(event){ - var fetch = function(url, onsuccess, onerror){ - - var req = new XMLHttpRequest(); - - req.onload = function(){ - - var feature; - - try { - feature = JSON.parse(this.responseText); - } - - catch (e){ - onerror(e); - return false; - } - - onsuccess(feature); - }; - - req.open("get", url, true); - req.send(); - }; - - var cb = function(map){ - - var map_el = document.getElementById("map"); - var wof_id = map_el.getAttribute("data-wof-id"); - var wof_parent_id = map_el.getAttribute("data-wof-parent-id"); - var wof_placetype = map_el.getAttribute("data-wof-placetype"); - - var abs_path = mapzen.whosonfirst.uri.id2abspath(wof_id); - - var onsuccess = function(feature){ - var layer = mapzen.places.map.add_geojson_to_map(map, feature); + var fetch = function(url, onsuccess, onerror){ + + var req = new XMLHttpRequest(); + + req.onload = function(){ + + var feature; + + try { + feature = JSON.parse(this.responseText); + } + + catch (e){ + onerror(e); + return false; + } + + onsuccess(feature); + }; + + req.open("get", url, true); + req.send(); }; - - var onerror = function(rsp){ - console.log("ERROR", rsp); + + var cb = function(map){ + + var map_el = document.getElementById("map"); + var wof_id = map_el.getAttribute("data-wof-id"); + var wof_parent_id = map_el.getAttribute("data-wof-parent-id"); + var wof_placetype = map_el.getAttribute("data-wof-placetype"); + + var abs_path = mapzen.whosonfirst.uri.id2abspath(wof_id); + + var onsuccess = function(feature){ + var layer = mapzen.places.map.add_geojson_to_map(map, feature); + }; + + var onerror = function(rsp){ + console.log("ERROR", rsp); + }; + + fetch(abs_path, onsuccess, onerror); + + if (wof_parent_id){ + var abs_path = mapzen.whosonfirst.uri.id2abspath(wof_parent_id); + fetch(abs_path, onsuccess, onerror); + } + + if (mapzen && mapzen.places && mapzen.places.routing){ + mapzen.places.routing.init(map); + } }; - - fetch(abs_path, onsuccess, onerror); - if (wof_placetype == "venue"){ + mapzen.places.map.draw_place_map("map", cb); - var abs_path = mapzen.whosonfirst.uri.id2abspath(wof_parent_id); - fetch(abs_path, onsuccess, onerror); + var summary = document.getElementById('wikipedia-summary'); + if (summary) { + var wk_page = summary.getAttribute('data-page'); + if (wk_page) { + var title = wk_page.replace(/_/g, ' '); + var url_title = encodeURIComponent(title); + var origin = encodeURIComponent('*'); + var url = 'https://en.wikipedia.org/w/api.php?format=json&action=query&redirects=1&prop=extracts&exintro=&explaintext=&titles=' + url_title + '&origin=' + origin; + var onerror = function() { + console.error('Could not load ' + url); + }; + var req = new XMLHttpRequest(); + req.onload = function(){ + try { + var rsp = JSON.parse(req.responseText); + } + catch(e) { + console.error('Could not parse result'); + return; + } + for (var id in rsp.query.pages) { + var page = rsp.query.pages[id]; + var summary_text = page.extract; + var sentences = page.extract.split('. '); + if (sentences.length > 1) { + // Let's keep it to two sentences. + summary_text = sentences[0] + '. ' + sentences[1] + '.'; + } + summary.innerHTML = '
Wikipedia

' + htmlspecialchars(summary_text) + '

' + htmlspecialchars(page.title) + ' on Wikipedia'; + } + }; + req.open("get", url, true); + req.send(); + } } - }; - - mapzen.places.map.draw_place_map("map", cb); }); diff --git a/www/javascript/mapzen.places.map.js b/www/javascript/mapzen.places.map.js index 807f563..d2e6455 100644 --- a/www/javascript/mapzen.places.map.js +++ b/www/javascript/mapzen.places.map.js @@ -3,135 +3,221 @@ mapzen.places = mapzen.places || {}; mapzen.places.map = (function(){ - var maps = {}; - - var self = { + var maps = {}; - 'get_map': function(map_id){ + var self = { - if (! maps[map_id]){ + 'get_map': function(map_id){ - var api_key = document.body.getAttribute("data-mapzen-api-key"); - var abs_root_url = document.body.getAttribute("data-abs-root-url"); + if (! maps[map_id]){ - L.Mapzen.apiKey = api_key; + var api_key = document.body.getAttribute("data-mapzen-api-key"); + var abs_root_url = document.body.getAttribute("data-abs-root-url"); - var map = L.Mapzen.map(map_id, { - - // https://github.com/mapzen/mapzen.js/blob/master/src/js/components/tangram.js - - tangramOptions: { - //scene: L.Mapzen.BasemapStyles.Refill, - scene: abs_root_url + "tangram/refill-style.zip", - tangramURL: abs_root_url + "javascript/tangram.min.js" - } - }); + L.Mapzen.apiKey = api_key; - maps[map_id] = map; - } + var map = L.Mapzen.map(map_id, { + zoomControl: false, + maxZoom: 20, + // https://github.com/mapzen/mapzen.js/blob/master/src/js/components/tangram.js + tangramOptions: { + //scene: L.Mapzen.BasemapStyles.Refill, + scene: abs_root_url + "tangram/refill-style.zip", + tangramURL: abs_root_url + "javascript/tangram.min.js" + } + }); - return maps[map_id]; - }, - - 'draw_place_map': function(map_id, cb){ - - var map_el = document.getElementById(map_id); - var map = self.get_map(map_id); + L.control.zoom({ + position: 'topleft' + }).addTo(map); - var placetype = map_el.getAttribute("data-wof-placetype"); + maps[map_id] = map; + } - var lat = map_el.getAttribute("data-geom-latitude"); - var lon = map_el.getAttribute("data-geom-longitude"); + return maps[map_id]; + }, - lat = parseFloat(lat); - lon = parseFloat(lon); + 'get_marker': function(feature, latlon){ - var bbox = map_el.getAttribute("data-geom-bbox"); - bbox = bbox.split(","); + var props = feature['properties']; + var label = props['wof:name']; - var min_lon = parseFloat(bbox[0]); - var min_lat = parseFloat(bbox[1]); - var max_lon = parseFloat(bbox[2]); - var max_lat = parseFloat(bbox[3]); + if (! latlon) { + var lat = props['geom:latitude']; + var lon = props['geom:longitude']; + latlon = [lat, lon]; + } - if (placetype == "venue"){ + var abs_root_url = document.body.getAttribute("data-abs-root-url"); + var icon = L.icon({ + iconUrl: abs_root_url + 'images/pin.png', + iconSize: [32, 47], + iconAnchor: [16, 46], + }); + var m = L.marker(latlon, { + icon: icon + }); + m.bindTooltip(label); - var parent_bbox = map_el.getAttribute("data-parent-geom-bbox"); - parent_bbox = parent_bbox.split(","); + return m; + }, - if (parent_bbox.length == 4){ - min_lon = parseFloat(parent_bbox[0]); - min_lat = parseFloat(parent_bbox[1]); - max_lon = parseFloat(parent_bbox[2]); - max_lat = parseFloat(parent_bbox[3]); - } - } + 'feature_handler': function(feature, layer){ + + var props = feature['properties']; + var wofid = props["wof:id"]; + + layer.on('click', function (e){ + + var enc_id = encodeURIComponent(wofid); + + var abs_root_url = document.body.getAttribute("data-abs-root-url"); + var url = abs_root_url + "id/" + enc_id + "/"; + + location.href = url; + }); + }, + + 'draw_nearby_map': function(map_id, cb){ + + var map_el = document.getElementById(map_id); + var map = self.get_map(map_id); + + if (map_el.getAttribute("data-wof-id")){ + return self.draw_place_map(map_id, cb); + } + + map.setView([37.7749, -122.4194], 12); + + cb(map); + }, + + 'draw_place_map': function(map_id, cb){ + + var map_el = document.getElementById(map_id); + var map = self.get_map(map_id); + + var placetype = map_el.getAttribute("data-wof-placetype"); + + var lat = map_el.getAttribute("data-geom-latitude"); + var lon = map_el.getAttribute("data-geom-longitude"); + + lat = parseFloat(lat); + lon = parseFloat(lon); + + var bbox = map_el.getAttribute("data-geom-bbox"); + if (bbox) { + bbox = bbox.split(","); + + var min_lon = parseFloat(bbox[0]); + var min_lat = parseFloat(bbox[1]); + var max_lon = parseFloat(bbox[2]); + var max_lat = parseFloat(bbox[3]); + } + + if ((min_lat == max_lat) && (min_lon == max_lon)){ + + var zoom = 12; + + if (placetype == "venue"){ + zoom = 17; + } + + map.setView([lat, lon], zoom); + } + + else { + var sw = L.latLng(min_lat, min_lon); + var ne = L.latLng(max_lat, max_lon); + + var bounds = L.latLngBounds(sw, ne); + var opts = { "padding": [100, 100] }; + + map.fitBounds(bounds, opts); + } + + // this doesn't work well enough to use yet... + + /* + var abs_root_url = document.body.getAttribute("data-abs-root-url"); + + var opts = { + "url": abs_root_url + "pelias/v1", + "focus": false, + "panToPoint": false, + }; + + var geocoder = L.Mapzen.geocoder(opts); + geocoder.addTo(map); + */ + + cb(map); + }, + + 'add_geojson_to_map': function(map, geojson, more){ + + if (! more){ + more = {}; + } + + var args = { + "pointToLayer": self.get_marker, + "onEachFeature": self.feature_handler + }; + + // console.log("[map][geojson] ADD", geojson, args); + + var layer = L.geoJSON(geojson, args); + + // http://leafletjs.com/reference-1.1.0.html#layergroup-setzindex + // https://github.com/Leaflet/Leaflet/issues/3427 (sigh...) + + if (more["z-index"]){ + var z = layer.setZIndex(more["z-index"]); + } + + return layer.addTo(map); + }, + + 'add_geojson_clusters_to_map': function(map, geojson, more){ + + var cluster = L.markerClusterGroup({ + maxClusterRadius: 120, + showCoverageOnHover: false + }); + var feature, layer; + + for (var i = 0; i < geojson.features.length; i++) { + feature = geojson.features[i]; + marker = self.get_marker(feature); + self.feature_handler(feature, marker); + cluster.addLayer(marker); + } + + map.addLayer(cluster); + }, + + 'get_place_coords': function(place){ + + var lat = null; + var lon = null; - if ((min_lat == max_lat) && (min_lon == max_lon)){ + if ('lbl:latitude' in place){ + lat = place['lbl:latitude']; + } else if ('geom:latitude' in place){ + lat = place['geom:latitude']; + } - var zoom = 12; + if ('lbl:longitude' in place){ + lon = place['lbl:longitude']; + } else if ('geom:longitude' in place){ + lon = place['geom:longitude']; + } - if (placetype == "venue"){ - zoom = 16; + return [lon, lat]; } + }; - map.setView([lat, lon], zoom); - } - - else { - var sw = L.latLng(min_lat, min_lon); - var ne = L.latLng(max_lat, max_lon); - - var bounds = L.latLngBounds(sw, ne); - var opts = { "padding": [100, 100] }; - - map.fitBounds(bounds, opts); - } - - // this doesn't work well enough to use yet... - - /* - var abs_root_url = document.body.getAttribute("data-abs-root-url"); - - var opts = { - "url": abs_root_url + "pelias/v1", - "focus": false, - "panToPoint": false, - }; - - var geocoder = L.Mapzen.geocoder(opts); - geocoder.addTo(map); - */ - - cb(map); - }, - - 'add_geojson_to_map': function(map, geojson, more){ - - if (! more){ - more = {}; - } - - var args = { - // "style": style, - // "pointToLayer": handler - } - - // console.log("[map][geojson] ADD", geojson, args); - - var layer = L.geoJSON(geojson, args); - - // http://leafletjs.com/reference-1.1.0.html#layergroup-setzindex - // https://github.com/Leaflet/Leaflet/issues/3427 (sigh...) - - if (more["z-index"]){ - var z = layer.setZIndex(more["z-index"]); - } - - return layer.addTo(map); - } - }; - - return self; + return self; })(); diff --git a/www/javascript/mapzen.places.nearby.init.js b/www/javascript/mapzen.places.nearby.init.js new file mode 100644 index 0000000..c84077c --- /dev/null +++ b/www/javascript/mapzen.places.nearby.init.js @@ -0,0 +1,195 @@ +window.addEventListener("load", function load(event){ + + var no_results = document.querySelector('#no-results'); + var loading_results = document.querySelector('#loading-results'); + var num_results = document.querySelector('#num-results'); + var results_table = document.querySelector('#search-results'); + var results_tbody = results_table.querySelector('tbody'); + var result_template = document.querySelector('#result-template'); + var abs_root_url = document.body.getAttribute("data-abs-root-url"); + + function add_geojson_to_results_table(geojson){ + + for (var i = 0; i < geojson.features.length; i++){ + + var feature = geojson.features[i]; + var props = feature.properties; + var tr = result_template.cloneNode(true); + + results_tbody.appendChild(tr); + tr.className = 'results-item'; + + var esc_id = htmlspecialchars(props['wof:id']); + tr.querySelector('.id').innerHTML = esc_id; + + var esc_name = htmlspecialchars(props['wof:name']); + var esc_href = htmlspecialchars(abs_root_url + 'id/' + props['wof:id'] + '/'); + tr.querySelector('.name').innerHTML = esc_name; + tr.querySelector('.name').setAttribute('href', esc_href); + + var esc_pt = htmlspecialchars(props['wof:placetype']); + tr.querySelector('.placetype').innerHTML = esc_pt; + + var currentness = 'unknown'; + if (mapzen.whosonfirst.existential.is_current(props)){ + currentness = 'current'; + } + else if (mapzen.whosonfirst.existential.is_deprecated(props)){ + currentness = 'deprecated'; + } + else if (mapzen.whosonfirst.existential.is_ceased(props)){ + currentness = 'ceased'; + } + else if (mapzen.whosonfirst.existential.is_superseded(props)){ + currentness = 'superseded'; + } + tr.querySelector('.currentness').innerHTML = currentness; + + var country_code = props['iso:country']; + if (typeof whosonfirst_countries[country_code] != 'undefined'){ + var country = whosonfirst_countries[country_code]; + var country_id = htmlspecialchars(country['wof:id']); + var country_name = htmlspecialchars(country['wof:name']); + var country_link = '' + country_name + ''; + tr.querySelector('.country').innerHTML = country_link; + } + } + results_table.className = 'table'; + loading_results.className = 'hidden'; + no_results.className = 'hidden'; + + var num = results_tbody.querySelectorAll('tr').length; + num_results.innerHTML = num.toLocaleString() + ' results'; + num_results.className = ''; + } + + var cb = function(map){ + + L.Mapzen.hash({ + map: map + }); + + var nearby_layer; + + var nearby_clear = function(){ + if (nearby_layer){ + nearby_layer.remove(map); + } + no_results.className = ''; + results_table.className = 'hidden'; + results_tbody.innerHTML = ''; + num_results.className = 'hidden'; + }; + + var nearby = function(){ + + var center = map.getCenter(); + + var lat = center.lat; + var lon = center.lng; + + var method = "whosonfirst.places.getNearby"; + + var args = { + "latitude": lat, + "longitude": lon, + "per_page": 500, + "extras": "geom:,iso:country,lbl:,mz:is_current,edtf:,wof:superseded_by", + }; + + var on_page = function(rsp){ + + var features = []; + + var places = rsp["places"]; + var count_places = places.length; + + for (var i=0; i < count_places; i++){ + + var place = places[i]; + + var name = place["wof:name"]; + + var coords = mapzen.places.map.get_place_coords(place); + var geom = { + "type": "Point", + "coordinates": coords, + }; + + var props = place; + + var feature = { + "type": "Feature", + "geometry": geom, + "properties": props, + }; + + features.push(feature); + } + + var feature_collection = { + "type": "FeatureCollection", + "features": features, + }; + + nearby_layer = mapzen.places.map.add_geojson_clusters_to_map(map, feature_collection); + add_geojson_to_results_table(feature_collection); + }; + + var on_error = function(rsp) { + console.error(rsp); + }; + + nearby_clear(); + + loading_results.className = ''; + no_results.className = 'hidden'; + + mapzen.places.api.call_paginated(method, args, on_page, on_error); + }; + + //map.on("dragend", nearby); + //map.on("zoomend", nearby); + + nearby(); + + var locate = L.control.locate({ + setView: 'once', + drawCircle: false, + drawMarker: false, + locateOptions: { + maxZoom: 16 + } + }).addTo(map); + + var btn = document.getElementById('nearby-find'); + btn.addEventListener('click', function(e) { + + e.preventDefault(); + var css = btn.className + ''; + if (css.indexOf('disabled') != -1) { + return; + } + + btn.className = css + ' disabled'; + locate.start(); + + }, false); + + map.on({ + locationfound: function(location) { + locate.stop(); + var css = btn.className + ''; + btn.className = css.replace('disabled', ''); + map.setView([location.latitude, location.longitude], 16); + nearby(); + }, + locationerror: function() { + var css = btn.className + ''; + btn.className = css.replace('disabled', ''); + } + }); + }; + + mapzen.places.map.draw_nearby_map("map", cb); +}); diff --git a/www/javascript/mapzen.places.results.init.js b/www/javascript/mapzen.places.results.init.js new file mode 100644 index 0000000..97e988a --- /dev/null +++ b/www/javascript/mapzen.places.results.init.js @@ -0,0 +1,51 @@ +window.addEventListener("load", function load(event){ + + if (! document.getElementById('map')) { + return; + } + var map = mapzen.places.map.get_map("map"); + + // We use a mock GeoJSON FeatureCollection to derive the bbox + var geojson = { + type: "FeatureCollection", + features: [] + }; + + var results = document.querySelectorAll('.results-item'); + for (var i = 0; i < results.length; i++) { + var item = results[i]; + var lat = parseFloat(item.getAttribute('data-latitude')); + var lng = parseFloat(item.getAttribute('data-longitude')); + var name = item.querySelector('a[itemprop="name"]').innerHTML; + var feature = { + type: "Feature", + bbox: [lng, lat, lng, lat], + properties: { + "wof:id": item.getAttribute('data-wof-id'), + "wof:name": name + }, + geometry: { + type: "Point", + coordinates: [lng, lat] + } + }; + geojson.features.push(feature); + mapzen.places.map.add_geojson_to_map(map, feature); + } + + var bbox = mapzen.whosonfirst.geojson.derive_bbox(geojson); + if (bbox[0] == bbox[2] && bbox[1] == bbox[3]) { + map.setView([bbox[1], bbox[0]], 16); + } + + else { + var sw = L.latLng(bbox[1], bbox[0]); + var ne = L.latLng(bbox[3], bbox[2]); + + var bounds = L.latLngBounds(sw, ne); + var opts = { "padding": [100, 100] }; + + map.fitBounds(bounds, opts); + } + +}, false); diff --git a/www/javascript/mapzen.places.routing.js b/www/javascript/mapzen.places.routing.js new file mode 100644 index 0000000..865e742 --- /dev/null +++ b/www/javascript/mapzen.places.routing.js @@ -0,0 +1,417 @@ +var mapzen = mapzen || {}; +mapzen.places = mapzen.places || {}; + +mapzen.places.routing = (function(){ + + var cache_key = 'routing_cache'; + + // Cache until end of today. + var eod = new Date(); + eod.setHours(23, 59, 59, 999); + var cache_ttl = eod.getTime() - new Date().getTime(); + + var self = { + + 'init': function(map){ + self.map = map; + self.setup_units(); + self.setup_controls(); + self.setup_hash_events(); + self.check_query(location.search); + self.check_query(location.hash); + self.cache_gc(); + }, + + 'setup_units': function(){ + var units = 'metric'; + if ("localStorage" in window && + localStorage.units){ + units = localStorage.units; + } + else { + self.fetch('https://ip.dev.mapzen.com/?raw=1', function(rsp) { + self.units = self.get_default_units(rsp.country_id); + if ("localStorage" in window){ + localStorage.units = self.units; + } + }); + } + self.units = units; + }, + + 'setup_controls': function(){ + document.getElementById('go-geolocate').addEventListener('click', self.geolocate_click, false); + document.getElementById('go-show-inputs').addEventListener('click', self.show_inputs_click, false); + document.getElementById('go-form').addEventListener('submit', self.form_submit, false); + }, + + 'setup_hash_events': function(){ + window.addEventListener('hashchange', function(){ + self.check_query(location.hash); + }, false); + }, + + 'check_query': function(query){ + var dir_match = query.match(/directions=([^&]+)/); + var from_match = query.match(/from=([^&]+)/); + if (dir_match && from_match){ + var from = decodeURIComponent(from_match[1].replace(/\+/g, ' ')); + var type = decodeURIComponent(dir_match[1].replace(/\+/g, ' ')); + self.start_loading(); + var result = self.get_directions(from, type); + if (typeof result == "string"){ + var alert = document.getElementById('go-feedback'); + alert.innerHTML = htmlspecialchars(result); + alert.className = 'alert alert-danger headroom'; + } + } + }, + + 'start_loading': function(){ + var btn = document.getElementById('go-btn'); + var classes = btn.className + ''; + btn.className = classes + ' disabled'; + btn.value = 'Loading...'; + }, + + 'is_loading': function(){ + var btn = document.getElementById('go-btn'); + var classes = btn.className + ''; + return classes.indexOf('disabled') != -1; + }, + + 'done_loading': function(){ + var btn = document.getElementById('go-btn'); + var classes = btn.className + ''; + btn.className = classes.replace('disabled', ''); + btn.value = 'Get Directions'; + }, + + 'geolocate_click': function(e){ + e.preventDefault(); + if (self.is_loading()) { + return; + } + self.start_loading(); + if ("geolocation" in navigator){ + navigator.geolocation.getCurrentPosition(function(position) { + var lat = position.coords.latitude.toFixed(6); + var lon = position.coords.longitude.toFixed(6); + var from = lat + ', ' + lon; + var type = self.get_default_type(); + self.show_inputs(from); + var query = 'from=' + encodeURIComponent(from) + '&' + + 'directions=' + encodeURIComponent(type); + location.hash = '#' + query; + }); + } + else { + alert('Your browser does not support geolocation.'); + self.done_loading(); + } + }, + + 'show_inputs': function(from, type){ + if (! type){ + type = self.get_default_type(); + } + var select = document.getElementById('go-costing'); + for (var i = 0; i < select.options.length; i++){ + if (select.options[i].value == type){ + select.selectedIndex = i; + break; + } + } + + if (from){ + document.getElementById('go-from').value = from; + } + document.getElementById('go-inputs').className = 'row'; + document.getElementById('go-feedback').className = 'hidden'; + }, + + 'form_submit': function(e){ + e.preventDefault(); + var from = document.getElementById('go-from').value; + var select = document.getElementById('go-costing'); + var type = select.options[select.selectedIndex].value; + var query = 'from=' + encodeURIComponent(from.replace(/ /g, '+')) + '&' + + 'directions=' + encodeURIComponent(type.replace(/ /g, '+')); + location.hash = '#' + query; + }, + + 'adjust_bounds': function(){ + + // Adapted from https://mapzen.com/resources/projects/turn-by-turn/demo/demo.js + + // Adjust padding for fitBounds() + // ============================== + // + // See this discussion: https://github.com/perliedman/leaflet-routing-machine/issues/60 + // We override Leaflet's default fitBounds method to use our padding options by + // default. Thus, LRM calls fitBounds() as is. Additionally, any other scripts + // that call for fitBounds() can take advantage of the same padding behaviour. + + var map = self.map; + + var is_mobile = (window.innerWidth < 472); + var bounds_tl = is_mobile ? [15, 200] : [30, 30]; + var bounds_br = is_mobile ? [15, 15] : [328, 30]; + + map.origFitBounds = map.fitBounds; + map.fitBounds = function (bounds, options) { + map.origFitBounds(bounds, { + // Left padding accounts for the narrative window. + // Top padding accounts for the floating section navigation bar. + // These conditions apply only when the viewport breakpoint is at + // desktop screens or higher. Otherwise, assume that the narrative + // window is not present, and that the section navigation is + // condensed, so less padding is required on mobile viewports. + paddingTopLeft: bounds_tl, + // Bottom and right padding accounts only for slight + // breathing room, in order to prevent markers from appearing + // at the very edge of maps. + paddingBottomRight: bounds_br, + }); + }; + + // Adjust offset for panTo() + // ============================== + map.origPanTo = map.panTo; + // In LRM, coordinate is array format [lat, lng] + map.panTo = function (coordinate) { + var offset_x = Math.round((bounds_tl[0] - bounds_br[0]) / 2); + var offset_y = Math.round((bounds_tl[1] - bounds_br[1]) / 2); + var x = map.latLngToContainerPoint(coordinate).x - offset_x; + var y = map.latLngToContainerPoint(coordinate).y - offset_y; + var point = map.containerPointToLatLng([x, y]); + map.origPanTo(point); + }; + }, + + 'routing_error': function(e){ + if (e.error && + e.error.message){ + // yeah, we get a JSON blob passed back, which is weird + try { + var msg = JSON.parse(e.error.message); + } + catch (e){ + console.error(e); + } + var feedback = document.getElementById('go-feedback'); + feedback.innerHTML = htmlspecialchars(msg.error); + feedback.className = 'alert alert-danger headroom'; + + // Hide directions pane, since we don't have any + var lrm = document.body.querySelector('.leaflet-routing-container'); + if (lrm){ + var classes = lrm.className + ''; + lrm.className = classes + ' hidden'; + } + } + }, + + 'get_directions': function(from, type){ + + if (! type){ + type = self.get_default_type(); + } + else { + self.set_default_type(type); + } + + var latlon = from.split(','); + if (latlon.length == 2){ + var lat = parseFloat(latlon[0].trim()); + var lon = parseFloat(latlon[1].trim()); + } + + if (isNaN(lat) || isNaN(lon)){ + self.show_inputs('', type); + return "Invalid latitude/longitude starting point."; + } + self.show_inputs(from, type); + var from = L.latLng(lat, lon); + + var costings = { + walking: 'pedestrian', + biking: 'bicycle', + transit: 'multimodal', + driving: 'auto' + }; + if (! costings[type]){ + return "Unknown directions method '" + htmlspecialchars(type) + "'"; + } + + var lat = document.querySelector('*[itemprop="latitude"').innerHTML; + var lon = document.querySelector('*[itemprop="longitude"').innerHTML; + var lat = parseFloat(lat); + var lon = parseFloat(lon); + if (isNaN(lat) || isNaN(lon)){ + return "Invalid latitude/longitude destination."; + } + var to = L.latLng(lat, lon); + + // Show directions pane, in case we hid it before + var lrm = document.body.querySelector('.leaflet-routing-container'); + if (lrm){ + var classes = lrm.className + ''; + lrm.className = classes.replace('hidden', ''); + } + + self.adjust_bounds(); + var routingControl = L.Mapzen.routing.control({ + waypoints: [from, to], + fitSelectedRoutes: true, + router: L.Mapzen.routing.router({ + costing: costings[type], + cacheCheck: self.cache_check, + cacheStore: self.cache_set_value + }), + formatter: new L.Mapzen.routing.formatter({ + units: self.units + }), + defaultErrorHandler: self.routing_error + }).addTo(self.map); + routingControl.on('routesfound', function(){ + self.done_loading(); + }); + + return true; + }, + + 'show_inputs_click': function(e){ + e.preventDefault(); + setTimeout(function(){ + var from = document.getElementById('go-from'); + if (from.value == ''){ + from.focus(); + } + else { + from.select(); + } + }, 0); + self.show_inputs(); + }, + + 'fetch': function(url, onsuccess, onerror){ + + var req = new XMLHttpRequest(); + + req.onload = function(){ + + var feature; + + try { + feature = JSON.parse(this.responseText); + } + + catch (e){ + onerror(e); + return false; + } + + onsuccess(feature); + }; + + req.open("get", url, true); + req.send(); + }, + + 'get_default_units': function(country_id){ + var units = 'metric'; + if (country_id == 85633793 || // USA + country_id == 85632181 || // Myanmar + country_id == 85632249){ // Liberia + units = 'imperial'; + } + return units; + }, + + 'get_default_type': function(){ + var type = 'driving'; + if ("localStorage" in window && + localStorage.directions){ + type = localStorage.directions; + } + return type; + }, + + 'set_default_type': function(type){ + if ("localStorage" in window){ + localStorage.directions = type; + } + return type; + }, + + 'cache_check': function(url) { + + var cache = self.cache_load(); + + if (cache && url in cache){ + console.log('CHECKING CACHE', cache[url]); + var cached = cache[url]; + var data = cached.data; + console.log('CACHE HIT', data); + return data; + } + console.log('CACHE MISS: ' + url); + return null; + }, + + 'cache_set_value': function(url, data){ + var cache = self.cache_load() || {}; + cache[url] = { + 'data': data, + 'cached_at': (new Date().getTime()) + }; + console.log('CACHE STORE: ' + url); + return self.cache_save(cache); + }, + + 'cache_load': function(){ + var cache = null; + if ("localStorage" in window && localStorage[cache_key]){ + try { + cache = JSON.parse(localStorage[cache_key]); + } + catch (e){ + console.log('ERROR decoding route cache'); + cache = {}; + } + } + return cache; + }, + + 'cache_save': function(cache){ + if ("localStorage" in window){ + localStorage[cache_key] = JSON.stringify(cache); + return cache; + } + return false; + }, + + 'cache_gc': function(){ + var cache = self.cache_load() || {}; + console.log('checking cache', cache); + var now = new Date().getTime(); + var found_expired = false; + for (var url in cache){ + if (now - cache[url].cached_at > cache_ttl){ + // expire expired cache + delete cache[url]; + console.log('EXPIRED cache ' + url); + found_expired = true; + } + } + if (found_expired){ + self.cache_save(cache); + } + } + + }; + + return self; + +})(); diff --git a/www/javascript/mapzen.styleguide.min.js b/www/javascript/mapzen.styleguide.min.js index 1bf76aa..df14ae2 100644 --- a/www/javascript/mapzen.styleguide.min.js +++ b/www/javascript/mapzen.styleguide.min.js @@ -1,4 +1,5 @@ -!function e(t,n,i){function o(s,a){if(!n[s]){if(!t[s]){var l="function"==typeof require&&require;if(!a&&l)return l(s,!0);if(r)return r(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=n[s]={exports:{}};t[s][0].call(c.exports,function(e){var n=t[s][1][e];return o(n?n:e)},c,c.exports,e,t,n,i)}return n[s].exports}for(var r="function"==typeof require&&require,s=0;s=e-i&&"bottom"},n.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(n.RESET).addClass("affix");var e=this.$target.scrollTop(),t=this.$element.offset();return this.pinnedOffset=t.top-e},n.prototype.checkPositionWithEventLoop=function(){setTimeout(e.proxy(this.checkPosition,this),1)},n.prototype.checkPosition=function(){if(this.$element.is(":visible")){var t=this.$element.height(),i=this.options.offset,o=i.top,r=i.bottom,s=Math.max(e(document).height(),e(document.body).height());"object"!=typeof i&&(r=o=i),"function"==typeof o&&(o=i.top(this.$element)),"function"==typeof r&&(r=i.bottom(this.$element));var a=this.getState(s,t,o,r);if(this.affixed!=a){null!=this.unpin&&this.$element.css("top","");var l="affix"+(a?"-"+a:""),u=e.Event(l+".bs.affix");if(this.$element.trigger(u),u.isDefaultPrevented())return;this.affixed=a,this.unpin="bottom"==a?this.getPinnedOffset():null,this.$element.removeClass(n.RESET).addClass(l).trigger(l.replace("affix","affixed")+".bs.affix")}"bottom"==a&&this.$element.offset({top:s-t-r})}};var i=e.fn.affix;e.fn.affix=t,e.fn.affix.Constructor=n,e.fn.affix.noConflict=function(){return e.fn.affix=i,this},e(window).on("load",function(){e('[data-spy="affix"]').each(function(){var n=e(this),i=n.data();i.offset=i.offset||{},null!=i.offsetBottom&&(i.offset.bottom=i.offsetBottom),null!=i.offsetTop&&(i.offset.top=i.offsetTop),t.call(n,i)})})}(jQuery)}).call(n,t,void 0,void 0)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"/home/ubuntu/styleguide/node_modules/jquery/dist/jquery.js":7}],2:[function(e,t,n){+function(e){"use strict";function t(t){var n,i=t.attr("data-target")||(n=t.attr("href"))&&n.replace(/.*(?=#[^\s]+$)/,"");return e(i)}function n(t){return this.each(function(){var n=e(this),o=n.data("bs.collapse"),r=e.extend({},i.DEFAULTS,n.data(),"object"==typeof t&&t);!o&&r.toggle&&/show|hide/.test(t)&&(r.toggle=!1),o||n.data("bs.collapse",o=new i(this,r)),"string"==typeof t&&o[t]()})}var i=function(t,n){this.$element=e(t),this.options=e.extend({},i.DEFAULTS,n),this.$trigger=e('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};i.VERSION="3.3.7",i.TRANSITION_DURATION=350,i.DEFAULTS={toggle:!0},i.prototype.dimension=function(){var e=this.$element.hasClass("width");return e?"width":"height"},i.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var t,o=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(o&&o.length&&(t=o.data("bs.collapse"),t&&t.transitioning))){var r=e.Event("show.bs.collapse");if(this.$element.trigger(r),!r.isDefaultPrevented()){o&&o.length&&(n.call(o,"hide"),t||o.data("bs.collapse",null));var s=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[s](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var a=function(){this.$element.removeClass("collapsing").addClass("collapse in")[s](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!e.support.transition)return a.call(this);var l=e.camelCase(["scroll",s].join("-"));this.$element.one("bsTransitionEnd",e.proxy(a,this)).emulateTransitionEnd(i.TRANSITION_DURATION)[s](this.$element[0][l])}}}},i.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var t=e.Event("hide.bs.collapse");if(this.$element.trigger(t),!t.isDefaultPrevented()){var n=this.dimension();this.$element[n](this.$element[n]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var o=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return e.support.transition?void this.$element[n](0).one("bsTransitionEnd",e.proxy(o,this)).emulateTransitionEnd(i.TRANSITION_DURATION):o.call(this)}}},i.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},i.prototype.getParent=function(){return e(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(e.proxy(function(n,i){var o=e(i);this.addAriaAndCollapsedClass(t(o),o)},this)).end()},i.prototype.addAriaAndCollapsedClass=function(e,t){var n=e.hasClass("in");e.attr("aria-expanded",n),t.toggleClass("collapsed",!n).attr("aria-expanded",n)};var o=e.fn.collapse;e.fn.collapse=n,e.fn.collapse.Constructor=i,e.fn.collapse.noConflict=function(){return e.fn.collapse=o,this},e(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(i){var o=e(this);o.attr("data-target")||i.preventDefault();var r=t(o),s=r.data("bs.collapse"),a=s?"toggle":o.data();n.call(r,a)})}(jQuery)},{}],3:[function(e,t,n){(function(n){e("/home/ubuntu/styleguide/node_modules/jquery/dist/jquery.js");(function(e,t,n){+function(e){"use strict";function t(t){var n=t.attr("data-target");n||(n=t.attr("href"),n=n&&/#[A-Za-z]/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,""));var i=n&&e(n);return i&&i.length?i:t.parent()}function n(n){n&&3===n.which||(e(o).remove(),e(r).each(function(){var i=e(this),o=t(i),r={relatedTarget:this};o.hasClass("open")&&(n&&"click"==n.type&&/input|textarea/i.test(n.target.tagName)&&e.contains(o[0],n.target)||(o.trigger(n=e.Event("hide.bs.dropdown",r)),n.isDefaultPrevented()||(i.attr("aria-expanded","false"),o.removeClass("open").trigger(e.Event("hidden.bs.dropdown",r)))))}))}function i(t){return this.each(function(){var n=e(this),i=n.data("bs.dropdown");i||n.data("bs.dropdown",i=new s(this)),"string"==typeof t&&i[t].call(n)})}var o=".dropdown-backdrop",r='[data-toggle="dropdown"]',s=function(t){e(t).on("click.bs.dropdown",this.toggle)};s.VERSION="3.3.7",s.prototype.toggle=function(i){var o=e(this);if(!o.is(".disabled, :disabled")){var r=t(o),s=r.hasClass("open");if(n(),!s){"ontouchstart"in document.documentElement&&!r.closest(".navbar-nav").length&&e(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(e(this)).on("click",n);var a={relatedTarget:this};if(r.trigger(i=e.Event("show.bs.dropdown",a)),i.isDefaultPrevented())return;o.trigger("focus").attr("aria-expanded","true"),r.toggleClass("open").trigger(e.Event("shown.bs.dropdown",a))}return!1}},s.prototype.keydown=function(n){if(/(38|40|27|32)/.test(n.which)&&!/input|textarea/i.test(n.target.tagName)){var i=e(this);if(n.preventDefault(),n.stopPropagation(),!i.is(".disabled, :disabled")){var o=t(i),s=o.hasClass("open");if(!s&&27!=n.which||s&&27==n.which)return 27==n.which&&o.find(r).trigger("focus"),i.trigger("click");var a=" li:not(.disabled):visible a",l=o.find(".dropdown-menu"+a);if(l.length){var u=l.index(n.target);38==n.which&&u>0&&u--,40==n.which&&udocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&e?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!e?this.scrollbarWidth:""})},n.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},n.prototype.checkScrollbar=function(){var e=window.innerWidth;if(!e){var t=document.documentElement.getBoundingClientRect();e=t.right-Math.abs(t.left)}this.bodyIsOverflowing=document.body.clientWidth a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",e.proxy(this.process,this)),this.refresh(),this.process()}function n(n){return this.each(function(){var i=e(this),o=i.data("bs.scrollspy"),r="object"==typeof n&&n;o||i.data("bs.scrollspy",o=new t(this,r)),"string"==typeof n&&o[n]()})}t.VERSION="3.3.7",t.DEFAULTS={offset:10},t.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},t.prototype.refresh=function(){var t=this,n="offset",i=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),e.isWindow(this.$scrollElement[0])||(n="position",i=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var t=e(this),o=t.data("target")||t.attr("href"),r=/^#./.test(o)&&e(o);return r&&r.length&&r.is(":visible")&&[[r[n]().top+i,o]]||null}).sort(function(e,t){return e[0]-t[0]}).each(function(){t.offsets.push(this[0]),t.targets.push(this[1])})},t.prototype.process=function(){var e,t=this.$scrollElement.scrollTop()+this.options.offset,n=this.getScrollHeight(),i=this.options.offset+n-this.$scrollElement.height(),o=this.offsets,r=this.targets,s=this.activeTarget;if(this.scrollHeight!=n&&this.refresh(),t>=i)return s!=(e=r[r.length-1])&&this.activate(e);if(s&&t=o[e]&&(void 0===o[e+1]||t0&&t-1 in e)}function o(e,t,n){if(se.isFunction(t))return se.grep(e,function(e,i){return!!t.call(e,i,e)!==n});if(t.nodeType)return se.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(me.test(t))return se.filter(t,e,n);t=se.filter(t,e)}return se.grep(e,function(e){return ee.call(t,e)>-1!==n})}function r(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function s(e){var t={};return se.each(e.match(Te)||[],function(e,n){t[n]=!0}),t}function a(){G.removeEventListener("DOMContentLoaded",a),e.removeEventListener("load",a),se.ready()}function l(){this.expando=se.expando+l.uid++}function u(e,t,n){var i;if(void 0===n&&1===e.nodeType)if(i="data-"+t.replace(Ae,"-$&").toLowerCase(),n=e.getAttribute(i),"string"==typeof n){try{n="true"===n||"false"!==n&&("null"===n?null:+n+""===n?+n:je.test(n)?se.parseJSON(n):n)}catch(o){}Ne.set(e,t,n)}else n=void 0;return n}function c(e,t,n,i){var o,r=1,s=20,a=i?function(){return i.cur()}:function(){return se.css(e,t,"")},l=a(),u=n&&n[3]||(se.cssNumber[t]?"":"px"),c=(se.cssNumber[t]||"px"!==u&&+l)&&$e.exec(se.css(e,t));if(c&&c[3]!==u){u=u||c[3],n=n||[],c=+l||1;do r=r||".5",c/=r,se.style(e,t,c+u);while(r!==(r=a()/l)&&1!==r&&--s)}return n&&(c=+c||+l||0,o=n[1]?c+(n[1]+1)*n[2]:+n[2],i&&(i.unit=u,i.start=c,i.end=o)),o}function f(e,t){var n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[];return void 0===t||t&&se.nodeName(e,t)?se.merge([e],n):n}function d(e,t){for(var n=0,i=e.length;n-1)o&&o.push(r);else if(u=se.contains(r.ownerDocument,r),s=f(p.appendChild(r),"script"),u&&d(s),n)for(c=0;r=s[c++];)Re.test(r.type||"")&&n.push(r);return p}function h(){return!0}function g(){return!1}function m(){try{return G.activeElement}catch(e){}}function v(e,t,n,i,o,r){var s,a;if("object"==typeof t){"string"!=typeof n&&(i=i||n,n=void 0);for(a in t)v(e,a,n,i,t[a],r);return e}if(null==i&&null==o?(o=n,i=n=void 0):null==o&&("string"==typeof n?(o=i,i=void 0):(o=i,i=n,n=void 0)),o===!1)o=g;else if(!o)return e;return 1===r&&(s=o,o=function(e){return se().off(e),s.apply(this,arguments)},o.guid=s.guid||(s.guid=se.guid++)),e.each(function(){se.event.add(this,t,o,i,n)})}function y(e,t){return se.nodeName(e,"table")&&se.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function b(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function x(e){var t=ze.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function w(e,t){var n,i,o,r,s,a,l,u;if(1===t.nodeType){if(Se.hasData(e)&&(r=Se.access(e),s=Se.set(t,r),u=r.events)){delete s.handle,s.events={};for(o in u)for(n=0,i=u[o].length;n1&&"string"==typeof g&&!oe.checkClone&&Ue.test(g))return e.each(function(o){var r=e.eq(o);m&&(t[0]=g.call(this,o,r.html())),C(r,t,n,i)});if(d&&(o=p(t,e[0].ownerDocument,!1,e,i),r=o.firstChild,1===o.childNodes.length&&(o=r),r||i)){for(s=se.map(f(o,"script"),b),a=s.length;c")).appendTo(t.documentElement),t=Ve[0].contentDocument,t.write(),t.close(),n=k(e,t),Ve.detach()),Qe[e]=n),n}function N(e,t,n){var i,o,r,s,a=e.style;return n=n||Je(e),s=n?n.getPropertyValue(t)||n[t]:void 0,""!==s&&void 0!==s||se.contains(e.ownerDocument,e)||(s=se.style(e,t)),n&&!oe.pixelMarginRight()&&Ge.test(s)&&Ye.test(t)&&(i=a.width,o=a.minWidth,r=a.maxWidth,a.minWidth=a.maxWidth=a.width=s,s=n.width,a.width=i,a.minWidth=o,a.maxWidth=r),void 0!==s?s+"":s}function j(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function A(e){if(e in ot)return e;for(var t=e[0].toUpperCase()+e.slice(1),n=it.length;n--;)if(e=it[n]+t,e in ot)return e}function D(e,t,n){var i=$e.exec(t);return i?Math.max(0,i[2]-(n||0))+(i[3]||"px"):t}function $(e,t,n,i,o){for(var r=n===(i?"border":"content")?4:"width"===t?1:0,s=0;r<4;r+=2)"margin"===n&&(s+=se.css(e,n+qe[r],!0,o)),i?("content"===n&&(s-=se.css(e,"padding"+qe[r],!0,o)),"margin"!==n&&(s-=se.css(e,"border"+qe[r]+"Width",!0,o))):(s+=se.css(e,"padding"+qe[r],!0,o),"padding"!==n&&(s+=se.css(e,"border"+qe[r]+"Width",!0,o)));return s}function q(e,t,n){var i=!0,o="width"===t?e.offsetWidth:e.offsetHeight,r=Je(e),s="border-box"===se.css(e,"boxSizing",!1,r);if(o<=0||null==o){if(o=N(e,t,r),(o<0||null==o)&&(o=e.style[t]),Ge.test(o))return o;i=s&&(oe.boxSizingReliable()||o===e.style[t]),o=parseFloat(o)||0}return o+$(e,t,n||(s?"border":"content"),i,r)+"px"}function L(e,t){for(var n,i,o,r=[],s=0,a=e.length;s=0&&n=0},isPlainObject:function(e){var t;if("object"!==se.type(e)||e.nodeType||se.isWindow(e))return!1;if(e.constructor&&!ie.call(e,"constructor")&&!ie.call(e.constructor.prototype||{},"isPrototypeOf"))return!1;for(t in e);return void 0===t||ie.call(e,t)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?te[ne.call(e)]||"object":typeof e},globalEval:function(e){var t,n=eval;e=se.trim(e),e&&(1===e.indexOf("use strict")?(t=G.createElement("script"),t.text=e,G.head.appendChild(t).parentNode.removeChild(t)):n(e))},camelCase:function(e){return e.replace(le,"ms-").replace(ue,ce)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t){var i,o=0;if(n(e))for(i=e.length;oT.cacheLength&&delete e[t.shift()],e[n+" "]=i}var t=[];return e}function i(e){return e[F]=!0,e}function o(e){var t=q.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function r(e,t){for(var n=e.split("|"),i=n.length;i--;)T.attrHandle[n[i]]=t}function s(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||V)-(~e.sourceIndex||V);if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function a(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function l(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function u(e){return i(function(t){return t=+t,i(function(n,i){for(var o,r=e([],n.length,t),s=r.length;s--;)n[o=r[s]]&&(n[o]=!(i[o]=n[o]))})})}function c(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function f(){}function d(e){for(var t=0,n=e.length,i="";t1?function(t,n,i){for(var o=e.length;o--;)if(!e[o](t,n,i))return!1;return!0}:e[0]}function g(e,n,i){for(var o=0,r=n.length;o-1&&(i[u]=!(s[u]=f))}}else b=m(b===s?b.splice(h,b.length):b),r?r(null,s,b,l):K.apply(s,b)})}function y(e){for(var t,n,i,o=e.length,r=T.relative[e[0].type],s=r||T.relative[" "],a=r?1:0,l=p(function(e){return e===t},s,!0),u=p(function(e){return ee(t,e)>-1},s,!0),c=[function(e,n,i){var o=!r&&(i||n!==j)||((t=n).nodeType?l(e,n,i):u(e,n,i));return t=null,o}];a1&&h(c),a>1&&d(e.slice(0,a-1).concat({value:" "===e[a-2].type?"*":""})).replace(ae,"$1"),n,a0,r=e.length>0,s=function(i,s,a,l,u){var c,f,d,p=0,h="0",g=i&&[],v=[],y=j,b=i||r&&T.find.TAG("*",u),x=W+=null==y?1:Math.random()||.1,w=b.length;for(u&&(j=s===q||s||u);h!==w&&null!=(c=b[h]);h++){if(r&&c){for(f=0,s||c.ownerDocument===q||($(c),a=!O);d=e[f++];)if(d(c,s||q,a)){l.push(c);break}u&&(W=x)}o&&((c=!d&&c)&&p--,i&&g.push(c))}if(p+=h,o&&h!==p){for(f=0;d=n[f++];)d(g,v,s,a);if(i){if(p>0)for(;h--;)g[h]||v[h]||(v[h]=G.call(l));v=m(v)}K.apply(l,v),u&&!i&&v.length>0&&p+n.length>1&&t.uniqueSort(l)}return u&&(W=x,j=y),g};return o?i(s):s}var x,w,T,C,E,k,S,N,j,A,D,$,q,L,O,H,R,P,I,F="sizzle"+1*new Date,M=e.document,W=0,B=0,_=n(),U=n(),z=n(),X=function(e,t){return e===t&&(D=!0),0},V=1<<31,Q={}.hasOwnProperty,Y=[],G=Y.pop,J=Y.push,K=Y.push,Z=Y.slice,ee=function(e,t){for(var n=0,i=e.length;n+~]|"+ne+")"+ne+"*"),ce=new RegExp("="+ne+"*([^\\]'\"]*?)"+ne+"*\\]","g"),fe=new RegExp(re),de=new RegExp("^"+ie+"$"),pe={ID:new RegExp("^#("+ie+")"),CLASS:new RegExp("^\\.("+ie+")"),TAG:new RegExp("^("+ie+"|[*])"),ATTR:new RegExp("^"+oe),PSEUDO:new RegExp("^"+re),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ne+"*(even|odd|(([+-]|)(\\d*)n|)"+ne+"*(?:([+-]|)"+ne+"*(\\d+)|))"+ne+"*\\)|)","i"),bool:new RegExp("^(?:"+te+")$","i"),needsContext:new RegExp("^"+ne+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ne+"*((?:-\\d)?\\d*)"+ne+"*\\)|)(?=[^-]|$)","i")},he=/^(?:input|select|textarea|button)$/i,ge=/^h\d$/i,me=/^[^{]+\{\s*\[native \w/,ve=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ye=/[+~]/,be=/'|\\/g,xe=new RegExp("\\\\([\\da-f]{1,6}"+ne+"?|("+ne+")|.)","ig"),we=function(e,t,n){var i="0x"+t-65536;return i!==i||n?t:i<0?String.fromCharCode(i+65536):String.fromCharCode(i>>10|55296,1023&i|56320)},Te=function(){$()};try{K.apply(Y=Z.call(M.childNodes),M.childNodes),Y[M.childNodes.length].nodeType}catch(Ce){K={apply:Y.length?function(e,t){J.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}w=t.support={},E=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},$=t.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:M;return i!==q&&9===i.nodeType&&i.documentElement?(q=i,L=q.documentElement,O=!E(q),(n=q.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",Te,!1):n.attachEvent&&n.attachEvent("onunload",Te)),w.attributes=o(function(e){return e.className="i",!e.getAttribute("className")}),w.getElementsByTagName=o(function(e){return e.appendChild(q.createComment("")),!e.getElementsByTagName("*").length}),w.getElementsByClassName=me.test(q.getElementsByClassName),w.getById=o(function(e){return L.appendChild(e).id=F,!q.getElementsByName||!q.getElementsByName(F).length}),w.getById?(T.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&O){var n=t.getElementById(e);return n?[n]:[]}},T.filter.ID=function(e){var t=e.replace(xe,we);return function(e){return e.getAttribute("id")===t}}):(delete T.find.ID,T.filter.ID=function(e){var t=e.replace(xe,we);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}}),T.find.TAG=w.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):w.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],o=0,r=t.getElementsByTagName(e);if("*"===e){for(;n=r[o++];)1===n.nodeType&&i.push(n);return i}return r},T.find.CLASS=w.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&O)return t.getElementsByClassName(e)},R=[],H=[],(w.qsa=me.test(q.querySelectorAll))&&(o(function(e){L.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&H.push("[*^$]="+ne+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||H.push("\\["+ne+"*(?:value|"+te+")"),e.querySelectorAll("[id~="+F+"-]").length||H.push("~="),e.querySelectorAll(":checked").length||H.push(":checked"),e.querySelectorAll("a#"+F+"+*").length||H.push(".#.+[+~]")}),o(function(e){var t=q.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&H.push("name"+ne+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||H.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),H.push(",.*:")})),(w.matchesSelector=me.test(P=L.matches||L.webkitMatchesSelector||L.mozMatchesSelector||L.oMatchesSelector||L.msMatchesSelector))&&o(function(e){w.disconnectedMatch=P.call(e,"div"),P.call(e,"[s!='']:x"),R.push("!=",re)}),H=H.length&&new RegExp(H.join("|")),R=R.length&&new RegExp(R.join("|")),t=me.test(L.compareDocumentPosition),I=t||me.test(L.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},X=t?function(e,t){if(e===t)return D=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!w.sortDetached&&t.compareDocumentPosition(e)===n?e===q||e.ownerDocument===M&&I(M,e)?-1:t===q||t.ownerDocument===M&&I(M,t)?1:A?ee(A,e)-ee(A,t):0:4&n?-1:1)}:function(e,t){if(e===t)return D=!0,0;var n,i=0,o=e.parentNode,r=t.parentNode,a=[e],l=[t];if(!o||!r)return e===q?-1:t===q?1:o?-1:r?1:A?ee(A,e)-ee(A,t):0;if(o===r)return s(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)l.unshift(n);for(;a[i]===l[i];)i++;return i?s(a[i],l[i]):a[i]===M?-1:l[i]===M?1:0},q):q},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==q&&$(e),n=n.replace(ce,"='$1']"),w.matchesSelector&&O&&!z[n+" "]&&(!R||!R.test(n))&&(!H||!H.test(n)))try{var i=P.call(e,n);if(i||w.disconnectedMatch||e.document&&11!==e.document.nodeType)return i}catch(o){}return t(n,q,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==q&&$(e),I(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==q&&$(e);var n=T.attrHandle[t.toLowerCase()],i=n&&Q.call(T.attrHandle,t.toLowerCase())?n(e,t,!O):void 0;return void 0!==i?i:w.attributes||!O?e.getAttribute(t):(i=e.getAttributeNode(t))&&i.specified?i.value:null},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],i=0,o=0;if(D=!w.detectDuplicates,A=!w.sortStable&&e.slice(0),e.sort(X),D){for(;t=e[o++];)t===e[o]&&(i=n.push(o));for(;i--;)e.splice(n[i],1)}return A=null,e},C=t.getText=function(e){var t,n="",i=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=C(e)}else if(3===o||4===o)return e.nodeValue}else for(;t=e[i++];)n+=C(t);return n},T=t.selectors={cacheLength:50,createPseudo:i,match:pe,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(xe,we),e[3]=(e[3]||e[4]||e[5]||"").replace(xe,we),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return pe.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&fe.test(n)&&(t=k(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(xe,we).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=_[e+" "];return t||(t=new RegExp("(^|"+ne+")"+e+"("+ne+"|$)"))&&_(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,n,i){return function(o){var r=t.attr(o,e);return null==r?"!="===n:!n||(r+="","="===n?r===i:"!="===n?r!==i:"^="===n?i&&0===r.indexOf(i):"*="===n?i&&r.indexOf(i)>-1:"$="===n?i&&r.slice(-i.length)===i:"~="===n?(" "+r.replace(se," ")+" ").indexOf(i)>-1:"|="===n&&(r===i||r.slice(0,i.length+1)===i+"-"))}},CHILD:function(e,t,n,i,o){var r="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===i&&0===o?function(e){return!!e.parentNode}:function(t,n,l){var u,c,f,d,p,h,g=r!==s?"nextSibling":"previousSibling",m=t.parentNode,v=a&&t.nodeName.toLowerCase(),y=!l&&!a,b=!1;if(m){if(r){for(;g;){for(d=t;d=d[g];)if(a?d.nodeName.toLowerCase()===v:1===d.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[s?m.firstChild:m.lastChild],s&&y){for(d=m,f=d[F]||(d[F]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),u=c[e]||[],p=u[0]===W&&u[1],b=p&&u[2],d=p&&m.childNodes[p];d=++p&&d&&d[g]||(b=p=0)||h.pop();)if(1===d.nodeType&&++b&&d===t){c[e]=[W,p,b];break}}else if(y&&(d=t,f=d[F]||(d[F]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),u=c[e]||[],p=u[0]===W&&u[1],b=p),b===!1)for(;(d=++p&&d&&d[g]||(b=p=0)||h.pop())&&((a?d.nodeName.toLowerCase()!==v:1!==d.nodeType)||!++b||(y&&(f=d[F]||(d[F]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),c[e]=[W,b]),d!==t)););return b-=o,b===i||b%i===0&&b/i>=0}}},PSEUDO:function(e,n){var o,r=T.pseudos[e]||T.setFilters[e.toLowerCase()]||t.error("unsupported pseudo: "+e);return r[F]?r(n):r.length>1?(o=[e,e,"",n],T.setFilters.hasOwnProperty(e.toLowerCase())?i(function(e,t){for(var i,o=r(e,n),s=o.length;s--;)i=ee(e,o[s]),e[i]=!(t[i]=o[s])}):function(e){return r(e,0,o)}):r}},pseudos:{not:i(function(e){var t=[],n=[],o=S(e.replace(ae,"$1"));return o[F]?i(function(e,t,n,i){for(var r,s=o(e,null,i,[]),a=e.length;a--;)(r=s[a])&&(e[a]=!(t[a]=r))}):function(e,i,r){return t[0]=e,o(t,null,r,n),t[0]=null,!n.pop()}}),has:i(function(e){return function(n){return t(e,n).length>0}}),contains:i(function(e){return e=e.replace(xe,we),function(t){return(t.textContent||t.innerText||C(t)).indexOf(e)>-1}}),lang:i(function(e){return de.test(e||"")||t.error("unsupported lang: "+e),e=e.replace(xe,we).toLowerCase(),function(t){var n;do if(n=O?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===L},focus:function(e){return e===q.activeElement&&(!q.hasFocus||q.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!T.pseudos.empty(e)},header:function(e){return ge.test(e.nodeName)},input:function(e){return he.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:u(function(){return[0]}),last:u(function(e,t){return[t-1]}),eq:u(function(e,t,n){return[n<0?n+t:n]}),even:u(function(e,t){for(var n=0;n=0;)e.push(i);return e}),gt:u(function(e,t,n){for(var i=n<0?n+t:n;++i2&&"ID"===(s=r[0]).type&&w.getById&&9===t.nodeType&&O&&T.relative[r[1].type]){if(t=(T.find.ID(s.matches[0].replace(xe,we),t)||[])[0],!t)return n;u&&(t=t.parentNode),e=e.slice(r.shift().value.length)}for(o=pe.needsContext.test(e)?0:r.length;o--&&(s=r[o],!T.relative[a=s.type]);)if((l=T.find[a])&&(i=l(s.matches[0].replace(xe,we),ye.test(r[0].type)&&c(t.parentNode)||t))){if(r.splice(o,1),e=i.length&&d(r),!e)return K.apply(n,i),n;break}}return(u||S(e,f))(i,t,!O,n,!t||ye.test(e)&&c(t.parentNode)||t),n},w.sortStable=F.split("").sort(X).join("")===F,w.detectDuplicates=!!D,$(),w.sortDetached=o(function(e){return 1&e.compareDocumentPosition(q.createElement("div"))}),o(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||r("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),w.attributes&&o(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||r("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),o(function(e){return null==e.getAttribute("disabled")})||r(te,function(e,t,n){var i;if(!n)return e[t]===!0?t.toLowerCase():(i=e.getAttributeNode(t))&&i.specified?i.value:null}),t}(e);se.find=fe,se.expr=fe.selectors,se.expr[":"]=se.expr.pseudos,se.uniqueSort=se.unique=fe.uniqueSort,se.text=fe.getText,se.isXMLDoc=fe.isXML,se.contains=fe.contains;var de=function(e,t,n){for(var i=[],o=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(o&&se(e).is(n))break;i.push(e)}return i},pe=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},he=se.expr.match.needsContext,ge=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,me=/^.[^:#\[\.,]*$/;se.filter=function(e,t,n){var i=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===i.nodeType?se.find.matchesSelector(i,e)?[i]:[]:se.find.matches(e,se.grep(t,function(e){return 1===e.nodeType}))},se.fn.extend({find:function(e){var t,n=this.length,i=[],o=this;if("string"!=typeof e)return this.pushStack(se(e).filter(function(){for(t=0;t1?se.unique(i):i),i.selector=this.selector?this.selector+" "+e:e,i},filter:function(e){return this.pushStack(o(this,e||[],!1))},not:function(e){return this.pushStack(o(this,e||[],!0))},is:function(e){return!!o(this,"string"==typeof e&&he.test(e)?se(e):e||[],!1).length}});var ve,ye=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,be=se.fn.init=function(e,t,n){var i,o;if(!e)return this;if(n=n||ve,"string"==typeof e){if(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:ye.exec(e),!i||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof se?t[0]:t,se.merge(this,se.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:G,!0)),ge.test(i[1])&&se.isPlainObject(t))for(i in t)se.isFunction(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return o=G.getElementById(i[2]),o&&o.parentNode&&(this.length=1,this[0]=o),this.context=G,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):se.isFunction(e)?void 0!==n.ready?n.ready(e):e(se):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),se.makeArray(e,this))};be.prototype=se.fn,ve=se(G);var xe=/^(?:parents|prev(?:Until|All))/,we={children:!0,contents:!0,next:!0,prev:!0};se.fn.extend({has:function(e){var t=se(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&se.find.matchesSelector(n,e))){r.push(n);break}return this.pushStack(r.length>1?se.uniqueSort(r):r)},index:function(e){return e?"string"==typeof e?ee.call(se(e),this[0]):ee.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(se.uniqueSort(se.merge(this.get(),se(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),se.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return de(e,"parentNode")},parentsUntil:function(e,t,n){return de(e,"parentNode",n)},next:function(e){return r(e,"nextSibling")},prev:function(e){return r(e,"previousSibling")},nextAll:function(e){return de(e,"nextSibling")},prevAll:function(e){return de(e,"previousSibling")},nextUntil:function(e,t,n){return de(e,"nextSibling",n)},prevUntil:function(e,t,n){return de(e,"previousSibling",n)},siblings:function(e){return pe((e.parentNode||{}).firstChild,e)},children:function(e){return pe(e.firstChild)},contents:function(e){return e.contentDocument||se.merge([],e.childNodes)}},function(e,t){se.fn[e]=function(n,i){var o=se.map(this,t,n);return"Until"!==e.slice(-5)&&(i=n),i&&"string"==typeof i&&(o=se.filter(i,o)),this.length>1&&(we[e]||se.uniqueSort(o),xe.test(e)&&o.reverse()),this.pushStack(o)}});var Te=/\S+/g;se.Callbacks=function(e){e="string"==typeof e?s(e):se.extend({},e);var t,n,i,o,r=[],a=[],l=-1,u=function(){for(o=e.once,i=t=!0;a.length;l=-1)for(n=a.shift();++l-1;)r.splice(n,1),n<=l&&l--}),this},has:function(e){return e?se.inArray(e,r)>-1:r.length>0},empty:function(){return r&&(r=[]),this},disable:function(){return o=a=[],r=n="",this},disabled:function(){return!r},lock:function(){return o=a=[],n||(r=n=""),this},locked:function(){return!!o},fireWith:function(e,n){return o||(n=n||[],n=[e,n.slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!i}};return c},se.extend({Deferred:function(e){var t=[["resolve","done",se.Callbacks("once memory"),"resolved"],["reject","fail",se.Callbacks("once memory"),"rejected"],["notify","progress",se.Callbacks("memory")]],n="pending",i={state:function(){return n},always:function(){return o.done(arguments).fail(arguments),this},then:function(){var e=arguments;return se.Deferred(function(n){se.each(t,function(t,r){var s=se.isFunction(e[t])&&e[t];o[r[1]](function(){var e=s&&s.apply(this,arguments);e&&se.isFunction(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[r[0]+"With"](this===i?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?se.extend(e,i):i}},o={};return i.pipe=i.then,se.each(t,function(e,r){var s=r[2],a=r[3];i[r[1]]=s.add,a&&s.add(function(){n=a},t[1^e][2].disable,t[2][2].lock),o[r[0]]=function(){return o[r[0]+"With"](this===o?i:this,arguments),this},o[r[0]+"With"]=s.fireWith}),i.promise(o),e&&e.call(o,o),o},when:function(e){var t,n,i,o=0,r=J.call(arguments),s=r.length,a=1!==s||e&&se.isFunction(e.promise)?s:0,l=1===a?e:se.Deferred(),u=function(e,n,i){return function(o){n[e]=this,i[e]=arguments.length>1?J.call(arguments):o,i===t?l.notifyWith(n,i):--a||l.resolveWith(n,i)}};if(s>1)for(t=new Array(s),n=new Array(s),i=new Array(s);o0||(Ce.resolveWith(G,[se]),se.fn.triggerHandler&&(se(G).triggerHandler("ready"),se(G).off("ready"))))}}),se.ready.promise=function(t){return Ce||(Ce=se.Deferred(),"complete"===G.readyState||"loading"!==G.readyState&&!G.documentElement.doScroll?e.setTimeout(se.ready):(G.addEventListener("DOMContentLoaded",a),e.addEventListener("load",a))),Ce.promise(t)},se.ready.promise();var Ee=function(e,t,n,i,o,r,s){var a=0,l=e.length,u=null==n;if("object"===se.type(n)){o=!0;for(a in n)Ee(e,t,a,n[a],!0,r,s)}else if(void 0!==i&&(o=!0,se.isFunction(i)||(s=!0),u&&(s?(t.call(e,i),t=null):(u=t,t=function(e,t,n){return u.call(se(e),n)})),t))for(;a-1&&void 0!==n&&Ne.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){Ne.remove(this,e)})}}),se.extend({queue:function(e,t,n){var i;if(e)return t=(t||"fx")+"queue",i=Se.get(e,t),n&&(!i||se.isArray(n)?i=Se.access(e,t,se.makeArray(n)):i.push(n)),i||[]},dequeue:function(e,t){t=t||"fx";var n=se.queue(e,t),i=n.length,o=n.shift(),r=se._queueHooks(e,t),s=function(){se.dequeue(e,t)};"inprogress"===o&&(o=n.shift(),i--),o&&("fx"===t&&n.unshift("inprogress"),delete r.stop,o.call(e,s,r)),!i&&r&&r.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Se.get(e,n)||Se.access(e,n,{empty:se.Callbacks("once memory").add(function(){Se.remove(e,[t+"queue",n])})})}}),se.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length",""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};Pe.optgroup=Pe.option,Pe.tbody=Pe.tfoot=Pe.colgroup=Pe.caption=Pe.thead,Pe.th=Pe.td;var Ie=/<|&#?\w+;/;!function(){var e=G.createDocumentFragment(),t=e.appendChild(G.createElement("div")),n=G.createElement("input");n.setAttribute("type","radio"),n.setAttribute("checked","checked"),n.setAttribute("name","t"),t.appendChild(n),oe.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,t.innerHTML="",oe.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();var Fe=/^key/,Me=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,We=/^([^.]*)(?:\.(.+)|)/;se.event={global:{},add:function(e,t,n,i,o){var r,s,a,l,u,c,f,d,p,h,g,m=Se.get(e);if(m)for(n.handler&&(r=n,n=r.handler,o=r.selector),n.guid||(n.guid=se.guid++),(l=m.events)||(l=m.events={}),(s=m.handle)||(s=m.handle=function(t){return"undefined"!=typeof se&&se.event.triggered!==t.type?se.event.dispatch.apply(e,arguments):void 0}),t=(t||"").match(Te)||[""],u=t.length;u--;)a=We.exec(t[u])||[],p=g=a[1],h=(a[2]||"").split(".").sort(),p&&(f=se.event.special[p]||{},p=(o?f.delegateType:f.bindType)||p,f=se.event.special[p]||{},c=se.extend({type:p,origType:g,data:i,handler:n,guid:n.guid,selector:o,needsContext:o&&se.expr.match.needsContext.test(o),namespace:h.join(".")},r),(d=l[p])||(d=l[p]=[],d.delegateCount=0,f.setup&&f.setup.call(e,i,h,s)!==!1||e.addEventListener&&e.addEventListener(p,s)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),o?d.splice(d.delegateCount++,0,c):d.push(c),se.event.global[p]=!0)},remove:function(e,t,n,i,o){var r,s,a,l,u,c,f,d,p,h,g,m=Se.hasData(e)&&Se.get(e);if(m&&(l=m.events)){for(t=(t||"").match(Te)||[""],u=t.length;u--;)if(a=We.exec(t[u])||[],p=g=a[1],h=(a[2]||"").split(".").sort(),p){for(f=se.event.special[p]||{},p=(i?f.delegateType:f.bindType)||p,d=l[p]||[],a=a[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=r=d.length;r--;)c=d[r],!o&&g!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(d.splice(r,1),c.selector&&d.delegateCount--,f.remove&&f.remove.call(e,c));s&&!d.length&&(f.teardown&&f.teardown.call(e,h,m.handle)!==!1||se.removeEvent(e,p,m.handle),delete l[p])}else for(p in l)se.event.remove(e,p+t[u],n,i,!0);se.isEmptyObject(l)&&Se.remove(e,"handle events")}},dispatch:function(e){e=se.event.fix(e);var t,n,i,o,r,s=[],a=J.call(arguments),l=(Se.get(this,"events")||{})[e.type]||[],u=se.event.special[e.type]||{};if(a[0]=e,e.delegateTarget=this,!u.preDispatch||u.preDispatch.call(this,e)!==!1){for(s=se.event.handlers.call(this,e,l),t=0;(o=s[t++])&&!e.isPropagationStopped();)for(e.currentTarget=o.elem,n=0;(r=o.handlers[n++])&&!e.isImmediatePropagationStopped();)e.rnamespace&&!e.rnamespace.test(r.namespace)||(e.handleObj=r,e.data=r.data,i=((se.event.special[r.origType]||{}).handle||r.handler).apply(o.elem,a),void 0!==i&&(e.result=i)===!1&&(e.preventDefault(),e.stopPropagation()));return u.postDispatch&&u.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,i,o,r,s=[],a=t.delegateCount,l=e.target;if(a&&l.nodeType&&("click"!==e.type||isNaN(e.button)||e.button<1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&(l.disabled!==!0||"click"!==e.type)){for(i=[],n=0;n-1:se.find(o,this,null,[l]).length),i[o]&&i.push(r);i.length&&s.push({elem:l,handlers:i})}return a]*)\/>/gi,_e=/\s*$/g;se.extend({htmlPrefilter:function(e){return e.replace(Be,"<$1>")},clone:function(e,t,n){var i,o,r,s,a=e.cloneNode(!0),l=se.contains(e.ownerDocument,e);if(!(oe.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||se.isXMLDoc(e)))for(s=f(a),r=f(e),i=0,o=r.length;i0&&d(s,!l&&f(e,"script")),a},cleanData:function(e){for(var t,n,i,o=se.event.special,r=0;void 0!==(n=e[r]);r++)if(ke(n)){if(t=n[Se.expando]){if(t.events)for(i in t.events)o[i]?se.event.remove(n,i):se.removeEvent(n,i,t.handle);n[Se.expando]=void 0}n[Ne.expando]&&(n[Ne.expando]=void 0)}}}),se.fn.extend({domManip:C,detach:function(e){return E(this,e,!0)},remove:function(e){return E(this,e)},text:function(e){return Ee(this,function(e){return void 0===e?se.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return C(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=y(this,e);t.appendChild(e)}})},prepend:function(){return C(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=y(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return C(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return C(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(se.cleanData(f(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return se.clone(this,e,t)})},html:function(e){return Ee(this,function(e){var t=this[0]||{},n=0,i=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!_e.test(e)&&!Pe[(He.exec(e)||["",""])[1].toLowerCase()]){e=se.htmlPrefilter(e);try{for(;n1)},show:function(){return L(this,!0)},hide:function(){return L(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){Le(this)?se(this).show():se(this).hide()})}}),se.Tween=O,O.prototype={constructor:O,init:function(e,t,n,i,o,r){this.elem=e,this.prop=n,this.easing=o||se.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=i,this.unit=r||(se.cssNumber[n]?"":"px")},cur:function(){var e=O.propHooks[this.prop];return e&&e.get?e.get(this):O.propHooks._default.get(this)},run:function(e){var t,n=O.propHooks[this.prop];return this.options.duration?this.pos=t=se.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):O.propHooks._default.set(this),this}},O.prototype.init.prototype=O.prototype,O.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=se.css(e.elem,e.prop,""),t&&"auto"!==t?t:0)},set:function(e){se.fx.step[e.prop]?se.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[se.cssProps[e.prop]]&&!se.cssHooks[e.prop]?e.elem[e.prop]=e.now:se.style(e.elem,e.prop,e.now+e.unit)}}},O.propHooks.scrollTop=O.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},se.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},se.fx=O.prototype.init,se.fx.step={};var rt,st,at=/^(?:toggle|show|hide)$/,lt=/queueHooks$/;se.Animation=se.extend(M,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return c(n.elem,e,$e.exec(t),n),n}]},tweener:function(e,t){se.isFunction(e)?(t=e,e=["*"]):e=e.match(Te);for(var n,i=0,o=e.length;i1)},removeAttr:function(e){return this.each(function(){se.removeAttr(this,e)})}}),se.extend({attr:function(e,t,n){var i,o,r=e.nodeType;if(3!==r&&8!==r&&2!==r)return"undefined"==typeof e.getAttribute?se.prop(e,t,n):(1===r&&se.isXMLDoc(e)||(t=t.toLowerCase(),o=se.attrHooks[t]||(se.expr.match.bool.test(t)?ut:void 0)),void 0!==n?null===n?void se.removeAttr(e,t):o&&"set"in o&&void 0!==(i=o.set(e,n,t))?i:(e.setAttribute(t,n+""),n):o&&"get"in o&&null!==(i=o.get(e,t))?i:(i=se.find.attr(e,t),null==i?void 0:i))},attrHooks:{type:{set:function(e,t){if(!oe.radioValue&&"radio"===t&&se.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,i,o=0,r=t&&t.match(Te);if(r&&1===e.nodeType)for(;n=r[o++];)i=se.propFix[n]||n,se.expr.match.bool.test(n)&&(e[i]=!1),e.removeAttribute(n)}}),ut={set:function(e,t,n){return t===!1?se.removeAttr(e,n):e.setAttribute(n,n),n}},se.each(se.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ct[t]||se.find.attr;ct[t]=function(e,t,i){var o,r;return i||(r=ct[t],ct[t]=o,o=null!=n(e,t,i)?t.toLowerCase():null,ct[t]=r),o}});var ft=/^(?:input|select|textarea|button)$/i,dt=/^(?:a|area)$/i;se.fn.extend({prop:function(e,t){return Ee(this,se.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[se.propFix[e]||e]})}}),se.extend({prop:function(e,t,n){var i,o,r=e.nodeType;if(3!==r&&8!==r&&2!==r)return 1===r&&se.isXMLDoc(e)||(t=se.propFix[t]||t,o=se.propHooks[t]),void 0!==n?o&&"set"in o&&void 0!==(i=o.set(e,n,t))?i:e[t]=n:o&&"get"in o&&null!==(i=o.get(e,t))?i:e[t]},propHooks:{tabIndex:{get:function(e){var t=se.find.attr(e,"tabindex");return t?parseInt(t,10):ft.test(e.nodeName)||dt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),oe.optSelected||(se.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),se.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){se.propFix[this.toLowerCase()]=this});var pt=/[\t\r\n\f]/g;se.fn.extend({addClass:function(e){var t,n,i,o,r,s,a,l=0;if(se.isFunction(e))return this.each(function(t){se(this).addClass(e.call(this,t,W(this)))});if("string"==typeof e&&e)for(t=e.match(Te)||[];n=this[l++];)if(o=W(n),i=1===n.nodeType&&(" "+o+" ").replace(pt," ")){for(s=0;r=t[s++];)i.indexOf(" "+r+" ")<0&&(i+=r+" ");a=se.trim(i),o!==a&&n.setAttribute("class",a)}return this},removeClass:function(e){var t,n,i,o,r,s,a,l=0;if(se.isFunction(e))return this.each(function(t){se(this).removeClass(e.call(this,t,W(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof e&&e)for(t=e.match(Te)||[];n=this[l++];)if(o=W(n),i=1===n.nodeType&&(" "+o+" ").replace(pt," ")){for(s=0;r=t[s++];)for(;i.indexOf(" "+r+" ")>-1;)i=i.replace(" "+r+" "," ");a=se.trim(i),o!==a&&n.setAttribute("class",a)}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):se.isFunction(e)?this.each(function(n){se(this).toggleClass(e.call(this,n,W(this),t),t)}):this.each(function(){var t,i,o,r;if("string"===n)for(i=0,o=se(this),r=e.match(Te)||[];t=r[i++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&"boolean"!==n||(t=W(this),t&&Se.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||e===!1?"":Se.get(this,"__className__")||""))})},hasClass:function(e){var t,n,i=0;for(t=" "+e+" ";n=this[i++];)if(1===n.nodeType&&(" "+W(n)+" ").replace(pt," ").indexOf(t)>-1)return!0;return!1}});var ht=/\r/g,gt=/[\x20\t\r\n\f]+/g;se.fn.extend({val:function(e){var t,n,i,o=this[0];{if(arguments.length)return i=se.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=i?e.call(this,n,se(this).val()):e,null==o?o="":"number"==typeof o?o+="":se.isArray(o)&&(o=se.map(o,function(e){return null==e?"":e+""})),t=se.valHooks[this.type]||se.valHooks[this.nodeName.toLowerCase()],t&&"set"in t&&void 0!==t.set(this,o,"value")||(this.value=o))});if(o)return t=se.valHooks[o.type]||se.valHooks[o.nodeName.toLowerCase()],t&&"get"in t&&void 0!==(n=t.get(o,"value"))?n:(n=o.value,"string"==typeof n?n.replace(ht,""):null==n?"":n)}}}),se.extend({valHooks:{option:{get:function(e){var t=se.find.attr(e,"value");return null!=t?t:se.trim(se.text(e)).replace(gt," ")}},select:{get:function(e){for(var t,n,i=e.options,o=e.selectedIndex,r="select-one"===e.type||o<0,s=r?null:[],a=r?o+1:i.length,l=o<0?a:r?o:0;l-1)&&(n=!0);return n||(e.selectedIndex=-1),r}}}}),se.each(["radio","checkbox"],function(){se.valHooks[this]={set:function(e,t){if(se.isArray(t))return e.checked=se.inArray(se(e).val(),t)>-1}},oe.checkOn||(se.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var mt=/^(?:focusinfocus|focusoutblur)$/;se.extend(se.event,{trigger:function(t,n,i,o){var r,s,a,l,u,c,f,d=[i||G],p=ie.call(t,"type")?t.type:t,h=ie.call(t,"namespace")?t.namespace.split("."):[];if(s=a=i=i||G,3!==i.nodeType&&8!==i.nodeType&&!mt.test(p+se.event.triggered)&&(p.indexOf(".")>-1&&(h=p.split("."),p=h.shift(),h.sort()),u=p.indexOf(":")<0&&"on"+p,t=t[se.expando]?t:new se.Event(p,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=h.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:se.makeArray(n,[t]),f=se.event.special[p]||{},o||!f.trigger||f.trigger.apply(i,n)!==!1)){if(!o&&!f.noBubble&&!se.isWindow(i)){for(l=f.delegateType||p,mt.test(l+p)||(s=s.parentNode);s;s=s.parentNode)d.push(s),a=s;a===(i.ownerDocument||G)&&d.push(a.defaultView||a.parentWindow||e)}for(r=0;(s=d[r++])&&!t.isPropagationStopped();)t.type=r>1?l:f.bindType||p,c=(Se.get(s,"events")||{})[t.type]&&Se.get(s,"handle"),c&&c.apply(s,n),c=u&&s[u],c&&c.apply&&ke(s)&&(t.result=c.apply(s,n),t.result===!1&&t.preventDefault());return t.type=p,o||t.isDefaultPrevented()||f._default&&f._default.apply(d.pop(),n)!==!1||!ke(i)||u&&se.isFunction(i[p])&&!se.isWindow(i)&&(a=i[u],a&&(i[u]=null),se.event.triggered=p,i[p](),se.event.triggered=void 0,a&&(i[u]=a)),t.result}},simulate:function(e,t,n){var i=se.extend(new se.Event,n,{type:e,isSimulated:!0});se.event.trigger(i,null,t)}}),se.fn.extend({trigger:function(e,t){return this.each(function(){se.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return se.event.trigger(e,t,n,!0)}}),se.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){se.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),se.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),oe.focusin="onfocusin"in e,oe.focusin||se.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){se.event.simulate(t,e.target,se.event.fix(e))};se.event.special[t]={setup:function(){var i=this.ownerDocument||this,o=Se.access(i,t);o||i.addEventListener(e,n,!0),Se.access(i,t,(o||0)+1)},teardown:function(){var i=this.ownerDocument||this,o=Se.access(i,t)-1;o?Se.access(i,t,o):(i.removeEventListener(e,n,!0),Se.remove(i,t))}}});var vt=e.location,yt=se.now(),bt=/\?/;se.parseJSON=function(e){return JSON.parse(e+"")},se.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(i){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||se.error("Invalid XML: "+t),n};var xt=/#.*$/,wt=/([?&])_=[^&]*/,Tt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ct=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Et=/^(?:GET|HEAD)$/,kt=/^\/\//,St={},Nt={},jt="*/".concat("*"),At=G.createElement("a");At.href=vt.href,se.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:vt.href,type:"GET",isLocal:Ct.test(vt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":jt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":se.parseJSON,"text xml":se.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?U(U(e,se.ajaxSettings),t):U(se.ajaxSettings,e)},ajaxPrefilter:B(St),ajaxTransport:B(Nt),ajax:function(t,n){function i(t,n,i,a){var u,f,y,b,w,C=n;2!==x&&(x=2,l&&e.clearTimeout(l),o=void 0,s=a||"",T.readyState=t>0?4:0,u=t>=200&&t<300||304===t,i&&(b=z(d,T,i)),b=X(d,b,T,u),u?(d.ifModified&&(w=T.getResponseHeader("Last-Modified"),w&&(se.lastModified[r]=w),w=T.getResponseHeader("etag"),w&&(se.etag[r]=w)),204===t||"HEAD"===d.type?C="nocontent":304===t?C="notmodified":(C=b.state,f=b.data,y=b.error,u=!y)):(y=C,!t&&C||(C="error",t<0&&(t=0))),T.status=t,T.statusText=(n||C)+"",u?g.resolveWith(p,[f,C,T]):g.rejectWith(p,[T,C,y]),T.statusCode(v),v=void 0,c&&h.trigger(u?"ajaxSuccess":"ajaxError",[T,d,u?f:y]),m.fireWith(p,[T,C]),c&&(h.trigger("ajaxComplete",[T,d]),--se.active||se.event.trigger("ajaxStop")))}"object"==typeof t&&(n=t,t=void 0),n=n||{};var o,r,s,a,l,u,c,f,d=se.ajaxSetup({},n),p=d.context||d,h=d.context&&(p.nodeType||p.jquery)?se(p):se.event,g=se.Deferred(),m=se.Callbacks("once memory"),v=d.statusCode||{},y={},b={},x=0,w="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(2===x){if(!a)for(a={};t=Tt.exec(s);)a[t[1].toLowerCase()]=t[2];t=a[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===x?s:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return x||(e=b[n]=b[n]||e,y[e]=t),this},overrideMimeType:function(e){return x||(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(x<2)for(t in e)v[t]=[v[t],e[t]];else T.always(e[T.status]);return this},abort:function(e){var t=e||w;return o&&o.abort(t),i(0,t),this}};if(g.promise(T).complete=m.add,T.success=T.done,T.error=T.fail,d.url=((t||d.url||vt.href)+"").replace(xt,"").replace(kt,vt.protocol+"//"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=se.trim(d.dataType||"*").toLowerCase().match(Te)||[""],null==d.crossDomain){u=G.createElement("a");try{u.href=d.url,u.href=u.href,d.crossDomain=At.protocol+"//"+At.host!=u.protocol+"//"+u.host}catch(C){d.crossDomain=!0}}if(d.data&&d.processData&&"string"!=typeof d.data&&(d.data=se.param(d.data,d.traditional)),_(St,d,n,T),2===x)return T;c=se.event&&d.global,c&&0===se.active++&&se.event.trigger("ajaxStart"),d.type=d.type.toUpperCase(),d.hasContent=!Et.test(d.type),r=d.url,d.hasContent||(d.data&&(r=d.url+=(bt.test(r)?"&":"?")+d.data,delete d.data),d.cache===!1&&(d.url=wt.test(r)?r.replace(wt,"$1_="+yt++):r+(bt.test(r)?"&":"?")+"_="+yt++)),d.ifModified&&(se.lastModified[r]&&T.setRequestHeader("If-Modified-Since",se.lastModified[r]),se.etag[r]&&T.setRequestHeader("If-None-Match",se.etag[r])),(d.data&&d.hasContent&&d.contentType!==!1||n.contentType)&&T.setRequestHeader("Content-Type",d.contentType),T.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+("*"!==d.dataTypes[0]?", "+jt+"; q=0.01":""):d.accepts["*"]);for(f in d.headers)T.setRequestHeader(f,d.headers[f]);if(d.beforeSend&&(d.beforeSend.call(p,T,d)===!1||2===x))return T.abort();w="abort";for(f in{success:1,error:1,complete:1})T[f](d[f]);if(o=_(Nt,d,n,T)){if(T.readyState=1,c&&h.trigger("ajaxSend",[T,d]),2===x)return T;d.async&&d.timeout>0&&(l=e.setTimeout(function(){T.abort("timeout")},d.timeout));try{x=1,o.send(y,i)}catch(C){if(!(x<2))throw C;i(-1,C)}}else i(-1,"No Transport");return T},getJSON:function(e,t,n){return se.get(e,t,n,"json")},getScript:function(e,t){return se.get(e,void 0,t,"script")}}),se.each(["get","post"],function(e,t){se[t]=function(e,n,i,o){return se.isFunction(n)&&(o=o||i, -i=n,n=void 0),se.ajax(se.extend({url:e,type:t,dataType:o,data:n,success:i},se.isPlainObject(e)&&e))}}),se._evalUrl=function(e){return se.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},se.fn.extend({wrapAll:function(e){var t;return se.isFunction(e)?this.each(function(t){se(this).wrapAll(e.call(this,t))}):(this[0]&&(t=se(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this)},wrapInner:function(e){return se.isFunction(e)?this.each(function(t){se(this).wrapInner(e.call(this,t))}):this.each(function(){var t=se(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=se.isFunction(e);return this.each(function(n){se(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){se.nodeName(this,"body")||se(this).replaceWith(this.childNodes)}).end()}}),se.expr.filters.hidden=function(e){return!se.expr.filters.visible(e)},se.expr.filters.visible=function(e){return e.offsetWidth>0||e.offsetHeight>0||e.getClientRects().length>0};var Dt=/%20/g,$t=/\[\]$/,qt=/\r?\n/g,Lt=/^(?:submit|button|image|reset|file)$/i,Ot=/^(?:input|select|textarea|keygen)/i;se.param=function(e,t){var n,i=[],o=function(e,t){t=se.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(void 0===t&&(t=se.ajaxSettings&&se.ajaxSettings.traditional),se.isArray(e)||e.jquery&&!se.isPlainObject(e))se.each(e,function(){o(this.name,this.value)});else for(n in e)V(n,e[n],t,o);return i.join("&").replace(Dt,"+")},se.fn.extend({serialize:function(){return se.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=se.prop(this,"elements");return e?se.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!se(this).is(":disabled")&&Ot.test(this.nodeName)&&!Lt.test(e)&&(this.checked||!Oe.test(e))}).map(function(e,t){var n=se(this).val();return null==n?null:se.isArray(n)?se.map(n,function(e){return{name:t.name,value:e.replace(qt,"\r\n")}}):{name:t.name,value:n.replace(qt,"\r\n")}}).get()}}),se.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(t){}};var Ht={0:200,1223:204},Rt=se.ajaxSettings.xhr();oe.cors=!!Rt&&"withCredentials"in Rt,oe.ajax=Rt=!!Rt,se.ajaxTransport(function(t){var n,i;if(oe.cors||Rt&&!t.crossDomain)return{send:function(o,r){var s,a=t.xhr();if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(s in t.xhrFields)a[s]=t.xhrFields[s];t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||o["X-Requested-With"]||(o["X-Requested-With"]="XMLHttpRequest");for(s in o)a.setRequestHeader(s,o[s]);n=function(e){return function(){n&&(n=i=a.onload=a.onerror=a.onabort=a.onreadystatechange=null,"abort"===e?a.abort():"error"===e?"number"!=typeof a.status?r(0,"error"):r(a.status,a.statusText):r(Ht[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=n(),i=a.onerror=n("error"),void 0!==a.onabort?a.onabort=i:a.onreadystatechange=function(){4===a.readyState&&e.setTimeout(function(){n&&i()})},n=n("abort");try{a.send(t.hasContent&&t.data||null)}catch(l){if(n)throw l}},abort:function(){n&&n()}}}),se.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return se.globalEval(e),e}}}),se.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),se.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,o){t=se(" + {if "places"|@features_is_enabled} + + + {else} + {/if} + + + + - + + {if "routing"|@features_is_enabled} + + {/if} + + + + + + + @@ -35,8 +61,30 @@ + {if "places"|@features_is_enabled} + + {/if} + + {if "places"|@features_is_enabled} + + + + + + {/if} + - + {if "places"|@features_is_enabled} + {assign var="api_endpoint" value="https://places.mapzen.com/v1/"} + {else} + {assign var="api_endpoint" value=$cfg.api_abs_root_url|cat:$cfg.api_endpoint} + {/if} + + - {include file="inc_head_navi.txt"} + {if "places"|@features_is_enabled} + {include file="inc_head_navi_mapzen.txt"} + {else} + {include file="inc_head_navi.txt"} + {/if} diff --git a/www/templates/inc_head_navi_mapzen.txt b/www/templates/inc_head_navi_mapzen.txt new file mode 100644 index 0000000..ff38338 --- /dev/null +++ b/www/templates/inc_head_navi_mapzen.txt @@ -0,0 +1,29 @@ + diff --git a/www/templates/inc_pagination.txt b/www/templates/inc_pagination.txt index 83a5c73..adf2d79 100644 --- a/www/templates/inc_pagination.txt +++ b/www/templates/inc_pagination.txt @@ -4,95 +4,111 @@
    - {* previous button *} - {if $pagination.page > 1} -
  • {if $pagination_page_as_queryarg}
  • -
  • previous page
  • + {* previous button *} + {if $pagination.page > 1} + {if $pagination_page_as_queryarg} + {if $pagination_url|strpos:"?" === false} +
  • previous page
  • + {else} +
  • previous page
  • + {/if} {else}
  • previous page
  • {/if} {else} -
  • you are here
  • +
  • you are here
  • {/if} {* middle *} {if $pagination.page_count > 10} - {assign var=range_mid value=7} - {assign var=rfloor value=$range_mid/2|@floor} - - {assign var=range_min value=$pagination.page-$rfloor} - {assign var=range_max value=$pagination.page+$rfloor} - - {if $range_min <= 0} - {assign var=adjmin value=$range_min|@abs} - {assign var=range_max value=$range_max+$adjmin+1} - {assign var=range_min value=1} - {/if} - - {if $range_max > $pagination.page_count} - {assign var=adjmax value=$range_max-$pagination.page_count} - {assign var=range_min value=$range_min-$adjmax} - {assign var=range_max value=$pagination.page_count} - {/if} - - {assign var=range value=$range_min|range:$range_max} - {assign var=rlen value=$range|@count} - {assign var=rlen value=$rlen-1} - - {section name=paglp start=1 loop=$pagination.page_count+1} - {assign var=i value=$smarty.section.paglp.index} - - {if $range.0 > 2 && $i == $range.0} -
  • ...
  • - {/if} - - {if $i == 1 || $i == $pagination.page_count || $i|in_array:$range} - {if $i == $pagination.page} -
  • {$i}
  • - {elseif $pagination_page_as_queryarg} -
  • {$i}
  • - {else} -
  • {$i}
  • - {/if} - {/if} - - {if $range.$rlen < $pagination.page_count-1 && $i == $range.$rlen} -
  • ...
  • - {/if} - - {/section} + {assign var=range_mid value=7} + {assign var=rfloor value=$range_mid/2|@floor} + + {assign var=range_min value=$pagination.page-$rfloor} + {assign var=range_max value=$pagination.page+$rfloor} + + {if $range_min <= 0} + {assign var=adjmin value=$range_min|@abs} + {assign var=range_max value=$range_max+$adjmin+1} + {assign var=range_min value=1} + {/if} + + {if $range_max > $pagination.page_count} + {assign var=adjmax value=$range_max-$pagination.page_count} + {assign var=range_min value=$range_min-$adjmax} + {assign var=range_max value=$pagination.page_count} + {/if} + + {assign var=range value=$range_min|range:$range_max} + {assign var=rlen value=$range|@count} + {assign var=rlen value=$rlen-1} + + {section name=paglp start=1 loop=$pagination.page_count+1} + {assign var=i value=$smarty.section.paglp.index} + + {if $range.0 > 2 && $i == $range.0} +
  • ...
  • + {/if} + + {if $i == 1 || $i == $pagination.page_count || $i|in_array:$range} + {if $i == $pagination.page} +
  • {$i}
  • + {elseif $pagination_page_as_queryarg} + {if $pagination_url|strpos:"?" === false} +
  • {$i}
  • + {else} +
  • {$i}
  • + {/if} + {else} +
  • {$i}
  • + {/if} + {/if} + + {if $range.$rlen < $pagination.page_count-1 && $i == $range.$rlen} +
  • ...
  • + {/if} + + {/section} {else} - - {section name=paglp start=1 loop=$pagination.page_count+1} - {assign var=i value=$smarty.section.paglp.index} - - {if $i == $pagination.page} -
  • {$i}
  • - {else} - {if $pagination_page_as_queryarg} -
  • {$i}
  • - {else} -
  • {$i}
  • - {/if} - {/if} - - {/section} - + + {section name=paglp start=1 loop=$pagination.page_count+1} + {assign var=i value=$smarty.section.paglp.index} + + {if $i == $pagination.page} +
  • {$i}
  • + {else} + {if $pagination_page_as_queryarg} + {if $pagination_url|strpos:"?" === false} +
  • {$i}
  • + {else} +
  • {$i}
  • + {/if} + {else} +
  • {$i}
  • + {/if} + {/if} + + {/section} + {/if} - {* next button *} - {if $pagination.page < $pagination.page_count} + {* next button *} + {if $pagination.page < $pagination.page_count} {if $pagination_page_as_queryarg} -
  • next page
  • + {if $pagination_url|strpos:"?" === false} +
  • next page
  • + {else} +
  • next page
  • + {/if} {else} -
  • next page
  • +
  • next page
  • {/if} {else} -
  • you are here
  • +
  • you are here
  • {/if} - +
{if 0}

Page {$pagination.page|number_format|escape} of {$pagination.page_count|number_format|escape}

{/if} @@ -102,4 +118,3 @@ {/if} - diff --git a/www/templates/inc_results.txt b/www/templates/inc_results.txt new file mode 100644 index 0000000..23c3bff --- /dev/null +++ b/www/templates/inc_results.txt @@ -0,0 +1,39 @@ +
+
+ {if $pagination.total_count > 0} +
+

+ {$pagination.total_count|number_format} result{if $pagination.total_count > 1}s{/if} + {if $pagination.total_count > 0} + page {$pagination.page|escape} of {$pagination.page_count|number_format|escape} + {/if} +

+
+ + + + + + + + + + + + {foreach from=$results item=result} + {include file="inc_results_item.txt"} + {/foreach} + +
IDNamePlacetypeCurrentnessCountry
+
+ {else} +

No results found.

+ {/if} +
+
+ +{if $pagination.total_count > $pagination.results_start + $pagination.per_page} + {include file="inc_pagination.txt"} +{/if} + + diff --git a/www/templates/inc_results_item.txt b/www/templates/inc_results_item.txt new file mode 100644 index 0000000..157e74a --- /dev/null +++ b/www/templates/inc_results_item.txt @@ -0,0 +1,7 @@ + + {$result|@whosonfirst_places_property:"wof:id"|@escape} + {$result|@whosonfirst_places_property:"wof:name"|@escape} + {$result|@whosonfirst_places_property:"wof:placetype"|@escape} + {$result|@whosonfirst_places_currentness|@escape} + {$result|@whosonfirst_places_country_link} + diff --git a/www/templates/inc_search_form.txt b/www/templates/inc_search_form.txt new file mode 100644 index 0000000..552b18a --- /dev/null +++ b/www/templates/inc_search_form.txt @@ -0,0 +1,14 @@ +
+
+ + +
+
+ +
+
diff --git a/www/templates/inc_venue_hours.txt b/www/templates/inc_venue_hours.txt new file mode 100644 index 0000000..c6d5a69 --- /dev/null +++ b/www/templates/inc_venue_hours.txt @@ -0,0 +1,26 @@ +{if !$mz_hours} +
Hours
We don’t know the hours for this place +{else} +
Hours
+ {if $mz_hours.sun && $mz_hours.sun.open && $mz_hours.sun.close} +
Sunday: {$mz_hours.sun.open|whosonfirst_places_format_time}–{$mz_hours.sun.close|whosonfirst_places_format_time}
+ {/if} + {if $mz_hours.mon && $mz_hours.mon.open && $mz_hours.mon.close} +
Monday: {$mz_hours.mon.open|whosonfirst_places_format_time}–{$mz_hours.mon.close|whosonfirst_places_format_time}
+ {/if} + {if $mz_hours.tue && $mz_hours.tue.open && $mz_hours.tue.close} +
Tuesday: {$mz_hours.tue.open|whosonfirst_places_format_time}–{$mz_hours.tue.close|whosonfirst_places_format_time}
+ {/if} + {if $mz_hours.wed && $mz_hours.wed.open && $mz_hours.wed.close} +
Wednesday: {$mz_hours.wed.open|whosonfirst_places_format_time}–{$mz_hours.wed.close|whosonfirst_places_format_time}
+ {/if} + {if $mz_hours.thu && $mz_hours.thu.open && $mz_hours.thu.close} +
Thursday: {$mz_hours.thu.open|whosonfirst_places_format_time}–{$mz_hours.thu.close|whosonfirst_places_format_time}
+ {/if} + {if $mz_hours.fri && $mz_hours.fri.open && $mz_hours.fri.close} +
Friday: {$mz_hours.fri.open|whosonfirst_places_format_time}–{$mz_hours.fri.close|whosonfirst_places_format_time}
+ {/if} + {if $mz_hours.sat && $mz_hours.sat.open && $mz_hours.sat.close} +
Saturday: {$mz_hours.sat.open|whosonfirst_places_format_time}–{$mz_hours.sat.close|whosonfirst_places_format_time}
+ {/if} +{/if} diff --git a/www/templates/inc_venue_links.txt b/www/templates/inc_venue_links.txt new file mode 100644 index 0000000..d3a0b49 --- /dev/null +++ b/www/templates/inc_venue_links.txt @@ -0,0 +1,8 @@ +{if !$links} +
Links
We don’t have any links for this place +{else} +
Links
+ {foreach from=$links item='text' key='url'} + + {/foreach} +{/if} diff --git a/www/templates/markdown_api_format_description_chicken.txt b/www/templates/markdown_api_format_description_chicken.txt index 9f206df..340f4a9 100644 --- a/www/templates/markdown_api_format_description_chicken.txt +++ b/www/templates/markdown_api_format_description_chicken.txt @@ -3,7 +3,7 @@ #### Example request ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.getInfoMulti&api_key=your-mapzen-api-key&ids=101712565,101712563&format=chicken' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.getInfoMulti&api_key=your-mapzen-api-key&ids=101712565,101712563&format=chicken' ``` #### Example response diff --git a/www/templates/markdown_api_format_description_csv.txt b/www/templates/markdown_api_format_description_csv.txt index 65c8e2f..3b0a5d9 100644 --- a/www/templates/markdown_api_format_description_csv.txt +++ b/www/templates/markdown_api_format_description_csv.txt @@ -3,7 +3,7 @@ CSV (Comma Separated Value) #### Example request ``` -curl -X GET 'https://whosonfirst-api.mapzen.com?method=whosonfirst.places.search&api_key=your-mapzen-api-key&q=poutine&page=1&per_page=1&format=csv' +curl -X GET 'https://places.mapzen.com/v1?method=mapzen.places.search&api_key=your-mapzen-api-key&q=poutine&page=1&per_page=1&format=csv' ``` #### Example response @@ -15,7 +15,7 @@ curl -X GET 'https://whosonfirst-api.mapzen.com?method=whosonfirst.places.search < Date: Tue, 28 Feb 2017 21:13:37 GMT < Status: 200 OK < X-api-pagination-cursor: -< X-api-pagination-next-query: method=whosonfirst.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2&format=csv +< X-api-pagination-next-query: method=mapzen.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2&format=csv < X-api-pagination-page: 1 < X-api-pagination-pages: 13 < X-api-pagination-per-page: 1 diff --git a/www/templates/markdown_api_format_description_geojson.txt b/www/templates/markdown_api_format_description_geojson.txt index 5d3b06c..180931d 100644 --- a/www/templates/markdown_api_format_description_geojson.txt +++ b/www/templates/markdown_api_format_description_geojson.txt @@ -3,7 +3,7 @@ GeoJSON is a data-interchange format based on JavaScript. For more details, cons #### Example request ``` -curl -X GET 'https://whosonfirst-api.mapzen.com?method=whosonfirst.places.getInfoMulti&api_key=your-mapzen-api-key&&ids=101712565,101712563&format=geojson' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.getInfoMulti&api_key=your-mapzen-api-key&&ids=101712565,101712563&format=geojson' ``` #### Example response diff --git a/www/templates/markdown_api_format_description_json.txt b/www/templates/markdown_api_format_description_json.txt index abb1d62..f3e8343 100644 --- a/www/templates/markdown_api_format_description_json.txt +++ b/www/templates/markdown_api_format_description_json.txt @@ -3,7 +3,7 @@ JSON (JavaScript Object Notation) is a data-interchange format based on JavaScri #### Example request ``` -curl -X GET 'https://whosonfirst-api.mapzen.com?method=whosonfirst.places.search&api_key=your-mapzen-api-key&q=poutine&page=1&per_page=1&format=json' +curl -X GET 'https://places.mapzen.com/v1/?method=whosonfirst.places.search&api_key=your-mapzen-api-key&q=poutine&page=1&per_page=1&format=json' ``` #### Example response @@ -15,7 +15,7 @@ curl -X GET 'https://whosonfirst-api.mapzen.com?method=whosonfirst.places.search < Date: Tue, 28 Feb 2017 22:29:49 GMT < Status: 200 OK < X-api-pagination-cursor: -< X-api-pagination-next-query: method=whosonfirst.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2 +< X-api-pagination-next-query: method=mapzen.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2 < X-api-pagination-page: 1 < X-api-pagination-pages: 13 < X-api-pagination-per-page: 1 @@ -25,7 +25,7 @@ curl -X GET 'https://whosonfirst-api.mapzen.com?method=whosonfirst.places.search < { "cursor": null, - "next_query": "method=whosonfirst.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2", + "next_query": "method=mapzen.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2", "page": 1, "pages": 13, "per_page": 1, diff --git a/www/templates/markdown_api_format_description_meta.txt b/www/templates/markdown_api_format_description_meta.txt index 89a04cd..913d667 100644 --- a/www/templates/markdown_api_format_description_meta.txt +++ b/www/templates/markdown_api_format_description_meta.txt @@ -3,7 +3,7 @@ As in a Who's On First "meta" file. A meta file is really just a CSV file with a #### Example request ``` -curl -X GET 'https://whosonfirst-api.mapzen.com?method=whosonfirst.places.search&api_key=your-mapzen-api-key&q=poutine&page=1&per_page=1&format=meta' +curl -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.search&api_key=your-mapzen-api-key&q=poutine&page=1&per_page=1&format=meta' ``` #### Example response @@ -15,7 +15,7 @@ curl -X GET 'https://whosonfirst-api.mapzen.com?method=whosonfirst.places.search < Date: Tue, 28 Feb 2017 22:25:13 GMT < Status: 200 OK < X-api-pagination-cursor: -< X-api-pagination-next-query: method=whosonfirst.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2&format=meta +< X-api-pagination-next-query: method=mapzen.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2&format=meta < X-api-pagination-page: 1 < X-api-pagination-pages: 13 < X-api-pagination-per-page: 1 diff --git a/www/templates/markdown_mapzen_api_docs.txt b/www/templates/markdown_mapzen_api_docs.txt index e510cc6..d4ccf17 100644 --- a/www/templates/markdown_mapzen_api_docs.txt +++ b/www/templates/markdown_mapzen_api_docs.txt @@ -1,9 +1,11 @@ -The Who's On First API allows developers (and robots) programmatic access to query and retrieve Who's On First data via a [REST-ish](#cgi) interface. +The Mapzen Places API allows developers (and robots) programmatic access to query and retrieve Who's On First data via a [REST-ish](#cgi) interface. API methods are dispatched over `HTTP` with one or more query parameters and data is returned in response as [JSON](formats.md#json) by default but you may also specify [CSV](formats.md#csv) or Who's On First's own [meta](formats.md#meta) formatted responses for certain [API methods](methods.md). -The endpoint for the Who's On First API is: **[https://whosonfirst-api.mapzen.com/](https://whosonfirst-api.mapzen.com/)** +The endpoint for the Mapzen Places API is: **[https://places.mapzen.com/v1/](https://places.mapzen.com/v1/)** + +_If you're wondering the chances that there will ever be a `/v2` are slim-to-never._ All errors are returned using [HTTP status codes](errors.md) in the `400-599` range. @@ -12,27 +14,16 @@ All errors are returned using [HTTP status codes](errors.md) in the `400-599` ra ### Caveats -You should treat this API as though it were in "beta". - -Which is to say: The point is for _the thing to work_ but there are probably still some rough edges and lingering gotchas so you should adjust your expectations and your code accordingly. In the meantime have at it and [please let us know](https://twitter.co/alloftheplaces) if something is busted or just doesn't feel right. - -Also some methods are "more beta" than others. These methods are flagged as being `experimental` which means that both either their inputs or their outputs _may_ change without warning. We'll try not to introduce any backwards incompatible changes but you should approach these API methods defensively. +The API is not feature complete yet, which is to say it will keep growing as time goes by. The easiest way to think about the Mapzen Places API is to look at the Who's On First [Spelunker](https://whosonfirst.mapzen.com/spelunker/) website and imagine that anything you can do there to search and navigate all those places should also be possible via the API. As of this writing it is not but we'll get there. If there is anything currently missing that you'd like or need to do sooner than later [send up a flare](https://twitter.co/alloftheplaces) and we'll see about adding it to the list. -Finally the API is not feature complete yet. The easiest way to think about the Who's On First API is to look at the Who's On First [Spelunker]() website and imagine that anything you can do there to search and navigate all those places should also be possible via the API. As of this writing it is not but we'll get there. If there is anything currently missing that you'd like or need to do sooner than later [send up a flare](https://twitter.co/alloftheplaces) and we'll see about adding it to the list. +Some API methods are flagged as being `experimental` which means that both either their inputs or their outputs _may_ change without warning. We'll try not to introduce any backwards incompatible changes but you should approach these API methods defensively. ### API Keys -To use the Who's On First API, you should [first obtain a free developer API key](https://mapzen.com/documentation/overview/). +To use the Mapzen Places API, you should [first obtain a free developer API key](https://mapzen.com/documentation/overview/). ### Rate limits See the [Mapzen developer overview](https://mapzen.com/documentation/overview/) for more on API keys and rate limits. - -### Shout outs - - -![CGI has a posse](prism.gif) - -High fives and finger guns to the [Common Gateway Interface](https://en.wikipedia.org/wiki/Common_Gateway_Interface). diff --git a/www/templates/markdown_mapzen_api_errors.txt b/www/templates/markdown_mapzen_api_errors.txt index 9cd5c4c..f725fcc 100644 --- a/www/templates/markdown_mapzen_api_errors.txt +++ b/www/templates/markdown_mapzen_api_errors.txt @@ -1,4 +1,4 @@ -In addition to any already [assigned HTTP status codes](https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml) The Who's On First API assigns specific meaning to certain codes and defines the following additional status codes for representing errors or a failure scenario, across all API methods: +In addition to any already [assigned HTTP status codes](https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml) The Mapzen Places API assigns specific meaning to certain codes and defines the following additional status codes for representing errors or a failure scenario, across all API methods: ### Mapzen errors @@ -11,7 +11,7 @@ In addition to any already [assigned HTTP status codes](https://www.iana.org/ass | `401` | KeyDisabled | | `403` | KeyError | | `404` | ApiUnknown | -| `429` | Queries per minute/hour/day exceeded | +| `429` | Free rate limits or monthly spending limits exceeded | {if 0}| `502` | EndpointMissingError | | `504` | EndpointTimeoutError |{/if} diff --git a/www/templates/markdown_mapzen_api_formats.txt b/www/templates/markdown_mapzen_api_formats.txt index 279483f..2c99a91 100644 --- a/www/templates/markdown_mapzen_api_formats.txt +++ b/www/templates/markdown_mapzen_api_formats.txt @@ -1,9 +1,10 @@ ## Response formats -The default response format is [{$default_format|@strtoupper|@escape}](formats.md#{$default_format|@escape}). +Response formats are listed alphabetically. The **default** response format is **[{$default_format|@strtoupper|@escape}](formats.md#{$default_format|@escape})**. {foreach from=$response_formats item="format"} +{if $format != "chicken"} ### {if $format=="meta"}Meta file{else}{$format|@strtoupper|escape}{/if} @@ -11,4 +12,12 @@ The default response format is [{$default_format|@strtoupper|@escape}](formats.m {capture assign="template"}markdown_api_format_description_{$format|escape}.txt{/capture} {include file=$template} +{/if} {/foreach} + +{if 0} + +### 🐔 (or "chicken") + +{include file="markdown_api_format_description_chicken.txt"} +{/if} diff --git a/www/templates/markdown_mapzen_api_method.txt b/www/templates/markdown_mapzen_api_method.txt index faf3b3c..a19788b 100644 --- a/www/templates/markdown_mapzen_api_method.txt +++ b/www/templates/markdown_mapzen_api_method.txt @@ -84,7 +84,7 @@ This API method does not define any custom error codes. For the list of error co {if $example_calls and $example_calls.$method} ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method={$method|escape}&api_key=your-mapzen-api-key{foreach from=$example_calls.$method.parameters item="v" key="k"}&{$k|@escape}={$v|@escape}{/foreach}' +curl -X GET 'https://places.mapzen.com/v1/?method={$method|escape}&api_key=your-mapzen-api-key{foreach from=$example_calls.$method.parameters item="v" key="k"}&{$k|@escape}={$v|@escape}{/foreach}' {$example_calls.$method.response} ``` @@ -93,7 +93,7 @@ _This example response has been truncated for the sake of brevity._ {/if} {else} ``` -curl -X GET 'https://whosonfirst-api.mapzen.com/?method={$method|escape}&api_key=your-mapzen-api-key{if $details.parameters|@count}{foreach from=$details.parameters item="param" name="params"}{if $param.documented}&{$param.name|escape}={$param.name|strtoupper|escape}{if !$smarty.foreach.params.last}{/if}{/if}{/foreach}{/if}' +curl -X GET 'https://places.mapzen.com/v1/?method={$method|escape}&api_key=your-mapzen-api-key{if $details.parameters|@count}{foreach from=$details.parameters item="param" name="params"}{if $param.documented}&{$param.name|escape}={$param.name|strtoupper|escape}{if !$smarty.foreach.params.last}{/if}{/if}{/foreach}{/if}' ``` {/if} diff --git a/www/templates/markdown_mapzen_api_pagination.txt b/www/templates/markdown_mapzen_api_pagination.txt index 5307e8b..55c26f5 100644 --- a/www/templates/markdown_mapzen_api_pagination.txt +++ b/www/templates/markdown_mapzen_api_pagination.txt @@ -19,7 +19,7 @@ For example, let's say you wanted to use the API to fetch all the places with a ```{literal} { "places": [ ... ], - "next_query": "method=whosonfirst.places.search&alt=Paris&per_page=5&page=2", + "next_query": "method=mapzen.places.search&alt=Paris&per_page=5&page=2", "total": 7, "page": 1, "per_page": 5, @@ -41,7 +41,7 @@ For example, let's say you wanted to use the API to fetch all of the venues near ```{literal} { "places": [ ... ], - "next_query": "method=whosonfirst.places.getNearby&latitude=40.784165&longitude=-73.958110&placetype=venue&per_page=10&cursor={CURSOR}", + "next_query": "method=mapzen.places.getNearby&latitude=40.784165&longitude=-73.958110&placetype=venue&per_page=10&cursor={CURSOR}", "per_page": 10, "cursor": {CURSOR}, "stat": "ok" @@ -62,7 +62,7 @@ For example, let's say you wanted to use the API to fetch all the microhoo ```{literal} { "places": [ ... ], - "next_query": "method=whosonfirst.places.search&placetype=microhood&page=2&per_page=5", + "next_query": "method=mapzen.places.search&placetype=microhood&page=2&per_page=5", "total": 186, "page": 1, "per_page": 5, @@ -77,7 +77,7 @@ But if you then asked the API to fetch all of the neighbourhoods, a ```{literal} { "places": [ ... ], - "next_query": "method=whosonfirst.places.search&placetype=neighbourhood&per_page=5&cursor={CURSOR}", + "next_query": "method=mapzen.places.search&placetype=neighbourhood&per_page=5&cursor={CURSOR}", "total": 81065, "page": null, "pages": 16213, @@ -101,7 +101,7 @@ For example, let's say you wanted to use the API to fetch all the localities (th ```{literal} { "places": [ ... ], - "next_query": "method=whosonfirst.places.search&placetype=locality&per_page=5&cursor={CURSOR}", + "next_query": "method=mapzen.places.search&placetype=locality&per_page=5&cursor={CURSOR}", "total": 208214, "page": null, "pages": 41643, @@ -129,7 +129,7 @@ Pagination properties are also returned as HTTP response headers. This is useful For example: ``` -$> curl -s -v -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.places.search&api_key=API_KEY&q=poutine&extras=geom:bbox&page=1&format=csv&per_page=1' +$> curl -s -v -X GET 'https://places.mapzen.com/v1/?method=mapzen.places.search&api_key=API_KEY&q=poutine&extras=geom:bbox&page=1&format=csv&per_page=1' < HTTP/1.1 200 OK < Access-Control-Allow-Origin: * @@ -137,7 +137,7 @@ $> curl -s -v -X GET 'https://whosonfirst-api.mapzen.com/?method=whosonfirst.pla < Date: Tue, 28 Feb 2017 21:13:37 GMT < Status: 200 OK < X-api-pagination-cursor: -< X-api-pagination-next-query: method=whosonfirst.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2&format=csv +< X-api-pagination-next-query: method=mapzen.places.search&q=poutine&extras=geom%3Abbox&per_page=1&page=2&format=csv < X-api-pagination-page: 1 < X-api-pagination-pages: 13 < X-api-pagination-per-page: 1 diff --git a/www/templates/page_api_method_explore.txt b/www/templates/page_api_method_explore.txt index d1ea4bf..a19039d 100644 --- a/www/templates/page_api_method_explore.txt +++ b/www/templates/page_api_method_explore.txt @@ -148,6 +148,7 @@ $(document).ready(function(){ _api = new flamework.api(); _api.set_handler('endpoint', window.api_explorer.endpoint); _api.set_handler('accesstoken', window.api_explorer.accesstoken); + _api.set_handler('authentication', window.api_explorer.authentication); }, 'call': function(method, data, on_success, on_error){ @@ -160,7 +161,19 @@ $(document).ready(function(){ 'accesstoken': function(){ return document.body.getAttribute("data-api-access-token"); - } + }, + + 'authentication': function(form_data){ + + var access_token = document.body.getAttribute("data-api-access-token"); + + if (! form_data.has("access_token")){ + form_data.append("access_token", access_token); + } + + return form_data; + } + } return self; diff --git a/www/templates/page_brand.txt b/www/templates/page_brand.txt new file mode 100644 index 0000000..19d3958 --- /dev/null +++ b/www/templates/page_brand.txt @@ -0,0 +1,63 @@ +{capture assign="brand_id"}{$brand|@whosonfirst_brands_property:"wof:brand_id"}{/capture} +{capture assign="brand_name"}{$brand|@whosonfirst_brands_property:"wof:brand_name"}{/capture} +{capture assign="page_title"}{$brand_name} | #brands{/capture} +{capture assign="extra_meta"} +{if $places|@count>0} + + + + + + + + + + + + +{/if} +{/capture} +{include file="inc_head.txt"} + +
+ + +
+
+

Places that are a #{$brand_name|@escape}

+ + {if $superseded_by|@count and $supersedes|@count} + {elseif $superseded_by|@count} + + {if $superseded_by|@count == 1} +

This #brand has been superseded by {$superseded_by.0|@whosonfirst_brands_property:"wof:brand_name"|@escape}.

+ {else} +

This #brand has been superseded a number of times by {foreach from=$superseded_by item="row" name="superseded"}{$row.0|@whosonfirst_brands_property:"wof:brand_name"|@escape}{if $smarty.foreach.superseded.last}{else} and {/if}{/foreach}.

+ {/if} + + {elseif $supersedes|@count} + + {if $supersedes|@count == 1} +

{$brand_name|@escape} supersedes the #brand formerly known as {$supersedes.0|@whosonfirst_brands_property:"wof:brand_name"|@escape}.

+ {else} +

{$brand_name|@escape} supersedes the #brands formerly known as {foreach from=$supersedes item="row" name="superseded"}{$row|@whosonfirst_brands_property:"wof:brand_name"|@escape}{if $smarty.foreach.superseded.last}{else} and {/if}{/foreach}.

+ {/if} + + {else}{/if} + +
+
+ + + {if $places|@count==0} + {if $superseded_by|@count == 0}

Hrm, we can't find any places associated with that #brand

{/if} + {else} + + {include file="inc_results.txt" results=$places pagination=$pagination} + + {/if} + + {include file="inc_brands_caveats.txt"} +
+ +{include file="inc_foot.txt"} diff --git a/www/templates/page_brands.txt b/www/templates/page_brands.txt new file mode 100644 index 0000000..60b83d2 --- /dev/null +++ b/www/templates/page_brands.txt @@ -0,0 +1,16 @@ +{capture assign="page_title"}Brands{/capture} +{include file="inc_head.txt} + +
+ +
+
+

Brands

+
+
+ + {include file="inc_brands_list.txt"} + {include file="inc_brands_caveats.txt"} +
+ +{include file="inc_foot.txt} diff --git a/www/templates/page_brands_search.txt b/www/templates/page_brands_search.txt new file mode 100644 index 0000000..0509778 --- /dev/null +++ b/www/templates/page_brands_search.txt @@ -0,0 +1,38 @@ +{capture assign="page_title"}Brands{/capture} +{include file="inc_head.txt} + +
+ +
+
+

+ {if $query} + Brands matching {$query|@escape}

+ {else} + Search by brand + {/if} + +
+
+ + {if $query} + {if $brands|@count} + {include file="inc_brands_list.txt"} + {else} +

Nothing matched your query.

+ {/if} + {else} +
+
+
+ + +
+ +
+
+ {/if} + +
+ +{include file="inc_foot.txt} diff --git a/www/templates/page_id.txt b/www/templates/page_id.txt index 2389aa9..f17882c 100644 --- a/www/templates/page_id.txt +++ b/www/templates/page_id.txt @@ -3,11 +3,13 @@ {capture assign="wof_placetype"}{$place|@whosonfirst_places_property:"wof:placetype"}{/capture} {capture assign="wof_country"}{$place|@whosonfirst_places_property:"wof:country"}{/capture} {capture assign="wof_parent_id"}{$place|@whosonfirst_places_property:"wof:parent_id"}{/capture} +{capture assign="wof_brand_id"}{$place|@whosonfirst_places_property:"wof:brand_id"}{/capture} {capture assign="wof_parent_name"}{$place|@whosonfirst_places_property:"wof:parent.wof:name"}{/capture} {capture assign="wof_parent_placetype"}{$place|@whosonfirst_places_property:"wof:parent.wof:placetype"}{/capture} {capture assign="wof_blurb_escaped"}{$wof_name|@escape} is a {$wof_placetype|@escape} and its Who's On First ID is {$wof_id|@escape}.{if $wof_country != ""} :flag-{$wof_country|@strtolower|@escape}:{/if}{/capture} {capture assign="page_title"}{$wof_name} ({$wof_id}){/capture} {capture assign="extra_meta"} +{capture assign="lat_lon_link"}{$place|@whosonfirst_places_property:"geom:latitude"|@escape}, {$place|@whosonfirst_places_property:"geom:longitude"|@escape}{/capture} @@ -23,44 +25,130 @@ {/capture} {include file="inc_head.txt"} -
+{assign var="wof_parents" value=$place|@whosonfirst_places_property:"wof:parents"} -
-

{$wof_name|@escape}

+
+
+
+ +
+
+
+
+

{$wof_name|@escape}

+ {if $wof_placetype == "venue"} +
+ {if $wof_parent_id < 0} + {if $wof_parents|@count} + {foreach from=$wof_parents item="row" name="parents"}{$row|@whosonfirst_places_property:"wof:name"}{if !$smarty.foreach.parents.last}, {/if}{/foreach} + {/if} + {else} + in {$wof_parent_name|@escape}. + {/if} -
+ {if $wof_brand_id}See all the {$wof_name|@escape} in {$cfg.site_name|@escape}.{/if} +
+ {/if} +
+
+
+ {if $wof_placetype == "venue"} +
+ {capture assign="addr_full"}{$place|@whosonfirst_places_property:"addr:full"}{/capture} + {capture assign="addr_phone"}{$place|@whosonfirst_places_property:"addr:phone"}{/capture} + {if $addr_full != ""}

{$addr_full|@escape}

{/if} + {if $addr_phone != ""}

{$addr_phone|@escape}

{/if} + {include file="inc_venue_hours.txt"} + {include file="inc_venue_links.txt"} +
+
+
+
+ {else} +
+
+
+ {/if} +
-
+
+
    +
  • {$wof_name|@escape} is a {$wof_placetype|@escape} and its Who's On First ID is {$wof_id|@escape}.
  • +
  • + {if $wof_parent_id == -1} + We aren't entirely certain who this {$wof_placetype|@escape} is parented by. + {elseif $wof_parent_id < 0} + + This {$wof_placetype|@escape}'s parentage is complicated. + + {$wof_parent_name|@escape} + {if $wof_parents|@count} + It is parented by {foreach from=$wof_parents item="row" name="parents"}{$row|@whosonfirst_places_property:"wof:name"}{if !$smarty.foreach.parents.last} and {/if}{/foreach} {if $wof_parents|@count==2}both of which{else}all of which{/if} are a {$wof_parents.0|@whosonfirst_places_property:"wof:placetype"}. + {/if} + + {else} + It is parented by {$wof_parent_name|@escape} which is a {$place|@whosonfirst_places_property:"wof:parent.wof:placetype"|@escape}. + {/if} +
  • + {if "routing"|@features_is_enabled} +
  • + Get directions from + where I am now (use geolocation) + or from a specific location. +
  • + {/if} +
+
-
- + {if "routing"|@features_is_enabled} + + {/if} - {if $wof_placetype == "venue"} -
    - {capture assign="addr_full"}{$place|@whosonfirst_places_property:"addr:full"}{/capture} - {capture assign="addr_phone"}{$place|@whosonfirst_places_property:"addr:phone"}{/capture} - {assign var="wof_tags" value=$place|@whosonfirst_places_property:"wof:tags"} - {if $addr_full != ""}
  • Its address is {$addr_full|@escape} and its exact latitude and longitude is {$place|@whosonfirst_places_property:"geom:latitude"|@escape}, {$place|@whosonfirst_places_property:"geom:longitude"|@escape}.
  • {/if} - {if $addr_phone != ""}
  • Its phone number is {$addr_phone|@escape}.
  • {/if} - {if $wof_tags|@count}
  • It is tagged {foreach from=$wof_tags item="tag" name="tags"}{$tag|@escape}{if $smarty.foreach.tags.last}.{else} and {/if}{/foreach}{/if}
  • -
- {/if} +
+
    + {if $wof_placetype == "venue"} + {assign var="wof_tags" value=$place|@whosonfirst_places_property:"wof:tags"} +
  • Its exact latitude and longitude is {$lat_lon_link}.
  • + {if $wof_tags|@count}
  • It is tagged {foreach from=$wof_tags item="tag" name="tags"}{$tag|@escape}{if $smarty.foreach.tags.last}.{else} and {/if}{/foreach}{/if}
  • + {else} +
  • Its exact latitude and longitude is {$lat_lon_link}.
  • + {/if} +
+ +
- + {if $wikipedia_page} +
+
+
+ {/if}
diff --git a/www/templates/page_id_old.txt b/www/templates/page_id_old.txt new file mode 100644 index 0000000..2e6f2e6 --- /dev/null +++ b/www/templates/page_id_old.txt @@ -0,0 +1,137 @@ +{capture assign="wof_id"}{$place|@whosonfirst_places_property:"wof:id"}{/capture} +{capture assign="wof_name"}{$place|@whosonfirst_places_property:"wof:name"}{/capture} +{capture assign="wof_placetype"}{$place|@whosonfirst_places_property:"wof:placetype"}{/capture} +{capture assign="wof_country"}{$place|@whosonfirst_places_property:"wof:country"}{/capture} +{capture assign="wof_parent_id"}{$place|@whosonfirst_places_property:"wof:parent_id"}{/capture} +{capture assign="wof_parent_name"}{$place|@whosonfirst_places_property:"wof:parent.wof:name"}{/capture} +{capture assign="wof_parent_placetype"}{$place|@whosonfirst_places_property:"wof:parent.wof:placetype"}{/capture} +{capture assign="wof_blurb_escaped"}{$wof_name|@escape} is a {$wof_placetype|@escape} and its Who's On First ID is {$wof_id|@escape}.{if $wof_country != ""} :flag-{$wof_country|@strtolower|@escape}:{/if}{/capture} +{capture assign="page_title"}{$wof_name} ({$wof_id}){/capture} +{capture assign="extra_meta"} +{capture assign="lat_lon_link"}{$place|@whosonfirst_places_property:"geom:latitude"|@escape}, {$place|@whosonfirst_places_property:"geom:longitude"|@escape}{/capture} + + + + + + + + + + + + +{/capture} +{include file="inc_head.txt"} + +
+
+
+ +
+
+
+
+

{$wof_name|@escape}

+
+
+
+
+
+
+
+ +
+
    +
  • {$wof_name|@escape} is a {$wof_placetype|@escape} and its Who's On First ID is {$wof_id|@escape}.
  • +
  • + {if $wof_parent_id == -1} + We aren't entirely certain who this {$wof_placetype|@escape} is parented by. + {elseif $wof_parent_id < 0} + + This {$wof_placetype|@escape}'s parentage is complicated. + + {assign var="wof_parents" value=$place|@whosonfirst_places_property:"wof:parents"} + + {if $wof_parents|@count} + It is parented by {foreach from=$wof_parents item="row" name="parents"}{$row|@whosonfirst_places_property:"wof:name"}{if !$smarty.foreach.parents.last} and {/if}{/foreach} {if $wof_parents|@count==2}both of which{else}all of which{/if} are a {$wof_parents.0|@whosonfirst_places_property:"wof:placetype"}. + {/if} + + {else} + It is parented by {$wof_parent_name|@escape} which is a {$place|@whosonfirst_places_property:"wof:parent.wof:placetype"|@escape}. + {/if} +
  • + {if "routing"|@features_is_enabled} +
  • + Get directions from + where I am now (use geolocation) + or from a specific location. +
  • + {/if} +
+
+ + {if "routing"|@features_is_enabled} + + {/if} + +
+
    + {if $wof_placetype == "venue"} + {capture assign="addr_full"}{$place|@whosonfirst_places_property:"addr:full"}{/capture} + {capture assign="addr_phone"}{$place|@whosonfirst_places_property:"addr:phone"}{/capture} + {assign var="wof_tags" value=$place|@whosonfirst_places_property:"wof:tags"} + {if $addr_full != ""} +
  • Its address is {$addr_full|@escape} and its exact latitude and longitude is {$lat_lon_link}.
  • + {else} +
  • Its exact latitude and longitude is {$lat_lon_link}.
  • + {/if} + {if $addr_phone != ""}
  • Its phone number is {$addr_phone|@escape}.
  • {/if} + {if $wof_tags|@count}
  • It is tagged {foreach from=$wof_tags item="tag" name="tags"}{$tag|@escape}{if $smarty.foreach.tags.last}.{else} and {/if}{/foreach}{/if}
  • +
  • {include file="inc_venue_links.txt"}
  • +
  • {include file="inc_venue_hours.txt"}
  • + {else} +
  • Its exact latitude and longitude is {$lat_lon_link}.
  • + {/if} +
+ +
+ + {if $wikipedia_page} +
+
+
+ {/if} + +
+ + + +{include file="inc_foot.txt"} diff --git a/www/templates/page_index.txt b/www/templates/page_index.txt index 4d7e820..1b719ff 100644 --- a/www/templates/page_index.txt +++ b/www/templates/page_index.txt @@ -1,7 +1,31 @@ {include file='inc_head.txt' nav_tab='home'} -
-

{$cfg.site_name|@escape} is a gazetteer. Gazetteer is a fancy word for a big list of places where each place has a stable, unique identifier and pointers to all the other places that it has a relationship with.

+
+
+
+

{$cfg.site_name|@escape}

+

{$cfg.site_name|@escape} is a gazetteer. Gazetteer is a fancy word for a big list of places where each place has a stable, unique identifier and pointers to all the other places that it has a relationship with. Browse nearby places »

+
+
+ +
+ {include file="inc_search_form.txt"} +
+ + {if "places"|@features_is_enabled} + + + {/if}
+ {include file='inc_foot.txt'} diff --git a/www/templates/page_nearby.txt b/www/templates/page_nearby.txt new file mode 100644 index 0000000..83674cd --- /dev/null +++ b/www/templates/page_nearby.txt @@ -0,0 +1,66 @@ +{capture assign="page_title"}Nearby{/capture} +{include file="inc_head.txt"} +{if $place} + {capture assign="wof_id"}{$place|@whosonfirst_places_property:"wof:id"}{/capture} + {capture assign="wof_name"}{$place|@whosonfirst_places_property:"wof:name"}{/capture} +{/if} +
+
+
+ +
+
+
+
+

nearby places

+
+ +
+ {if $place} +
+ {else} +
+ {/if} +

No results found.

+ + +
+ + + + + + + + + + + + + + + + + + + + +
+
+ + + + +{include file="inc_foot.txt"} diff --git a/www/templates/page_placetype.txt b/www/templates/page_placetype.txt new file mode 100644 index 0000000..f310cc6 --- /dev/null +++ b/www/templates/page_placetype.txt @@ -0,0 +1,11 @@ +{include file="inc_head.txt"} + +
+
+ +
+ +
+
+ +{include file="inc_foot.txt"} diff --git a/www/templates/page_search.txt b/www/templates/page_search.txt new file mode 100644 index 0000000..8545fc0 --- /dev/null +++ b/www/templates/page_search.txt @@ -0,0 +1,30 @@ +{include file='inc_head.txt' nav_tab='home'} + +
+
+
+ +
+
+
+
+

search results

+
+
+ {include file="inc_search_form.txt"} + {if $debug} +
+
+
{$debug|escape}
+
+
+ {/if} + {include file="inc_results.txt"} +
+ +{include file='inc_foot.txt'} diff --git a/www/templates/page_tag.txt b/www/templates/page_tag.txt index d9b2395..c4f7d8a 100644 --- a/www/templates/page_tag.txt +++ b/www/templates/page_tag.txt @@ -1,22 +1,30 @@ {capture assign="page_title"}Places tagged {$tag}{if $place} (in {$place|@whosonfirst_places_property:"wof:name"|@escape}){/if}{/capture} {include file="inc_head.txt"} -
- -
- -

Places tagged {$tag|@escape}{if $place} in {$place|@whosonfirst_places_property:"wof:name"|@escape}{/if}

- - - -
- -{include file="inc_pagination.txt"} - +
+
+
+ +
+
+
+
+

places tagged {$tag|@escape}{if $place} in {$place|@whosonfirst_places_property:"wof:name"|@escape}{/if}

+
+
+ {if $debug} +
+
+
{$debug|escape}
+
+
+ {/if} + {include file="inc_results.txt"}
{include file="inc_foot.txt"}