forked from security_vision/semantic_graph
Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
|
d457c8eea0 |
16 changed files with 965 additions and 2659 deletions
49
README.md
49
README.md
|
@ -4,21 +4,54 @@ This repository contains a script to pull semantic data out of Semantic Mediawik
|
||||||
|
|
||||||
Built for [Security Vision](https://securityvision.io).
|
Built for [Security Vision](https://securityvision.io).
|
||||||
|
|
||||||
## Document
|
|
||||||
|
|
||||||
```
|
|
||||||
pandoc EU\ Greens\ Report\ -\ Biometric\ Mass\ Surveillance\ v.3.docx --extract-media=images --template=template.html --section-divs -s -o output.html --metadata title="Biometric and Behavioural Mass Surveillance in EU Member States" -c mvp.css --toc --toc-depth=2
|
|
||||||
```
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
wget https://d3js.org/d3.v6.min.js
|
wget https://d3js.org/d3.v6.min.js
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Update:
|
||||||
|
|
||||||
|
```
|
||||||
|
python wiki_relations.py
|
||||||
|
```
|
||||||
|
|
||||||
## Data
|
## Data
|
||||||
|
|
||||||
|
_Ask_ SMW with the following query:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
({{#ask: [[Category:Deployments||Institution]]
|
||||||
|
OR [[Category:Technologies]] [[Developed by (institutions)::+]] // TODO: + should give a subquery <q></q> with all institutions in EU
|
||||||
|
OR [[Category:Technologies]] [[-Software Deployed::+]] // TODO: + should give a subquery <q></q> with all deployments in EU
|
||||||
|
|?Category
|
||||||
|
|?Geolocation
|
||||||
|
|?City
|
||||||
|
|?City.Has Coordinates=Has Coordinates
|
||||||
|
|?City.Is in Country=City Country
|
||||||
|
|?City Country.Has Coordinates=Country Coordinates
|
||||||
|
|?Clients
|
||||||
|
|?Managed by
|
||||||
|
|?Used by
|
||||||
|
|?Funded by
|
||||||
|
|?Provided by // TODO: technology/product provided by
|
||||||
|
|?Software Deployed
|
||||||
|
|?Developped by (institutions)
|
||||||
|
|format=broadtable
|
||||||
|
|limit=500
|
||||||
|
|offset=0
|
||||||
|
|link=all
|
||||||
|
|sort=
|
||||||
|
|order=asc
|
||||||
|
|headers=show
|
||||||
|
|searchlabel=... further results
|
||||||
|
|class=sortable wikitable smwtable
|
||||||
|
}}
|
||||||
|
|
||||||
|
TODO: see: https://www.semantic-mediawiki.org/wiki/Help:Querying_for_the_absence_of_a_property
|
||||||
|
|
||||||
{{#ask: [[Category:Deployments||Institution]] [[Is in Greens Report 2021::True]]
|
{{#ask: [[Category:Deployments||Institution]] [[Is in Greens Report 2021::True]]
|
||||||
|?Category
|
|?Category
|
||||||
|?Geolocation
|
|?Geolocation
|
||||||
|
@ -49,3 +82,9 @@ wget https://d3js.org/d3.v6.min.js
|
||||||
|class=sortable wikitable smwtable
|
|class=sortable wikitable smwtable
|
||||||
}}
|
}}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Fetch using CURL:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl 'https://www.securityvision.io/wiki/index.php?title=Special:Ask&#search' -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Content-Type: application/x-www-form-urlencoded' -H 'Origin: https://www.securityvision.io' -H 'Connection: keep-alive' -H 'Referer: https://www.securityvision.io/wiki/index.php/Special:Ask' -H 'Upgrade-Insecure-Requests: 1' --data-raw 'title=Special%3AAsk&_action=submit&q=%5B%5BCategory%3ADeployments%7C%7CInstitution%5D%5D++&po=%0D%0A+%7C%3FCategory%0D%0A+%7C%3FGeolocation%0D%0A+%7C%3FCity%0D%0A+%7C%3FCity.Has+Coordinates%3DCity+Coordinates%0D%0A+%7C%3FCity.Is+in+Country%3DCity+Country%0D%0A+%7C%3FCity+Country.Has+Coordinates%3DCountry+Coordinates%0D%0A+%7C%3FClients%0D%0A+%7C%3FManaged+by%0D%0A+%7C%3FUsed+by%0D%0A+%7C%3FFunded+by%0D%0A+%7C%3FProvided+by%0D%0A+%7C%3FSoftware+Deployed%0D%0A+%7C%3FSoftware+Deployed.Developped+by+%28institutions%29%3DSoftware+Developer%0D%0A+%7C%3FDatasets+Used%0D%0A+%7C%3FDatasets+Used.Developed+by+Institution%3DDataset+Developer&eq=yes&p%5Bformat%5D=json&p%5Blimit%5D=500&p%5Boffset%5D=0&p%5Blink%5D=all&p%5Bheaders%5D=show&p%5Bmainlabel%5D=&p%5Bintro%5D=&p%5Boutro%5D=&p%5Bsearchlabel%5D=JSON&p%5Bdefault%5D=&p%5Btype%5D=full&p%5Bfilename%5D=result2.json&sort_num%5B%5D=&order_num%5B%5D=asc&sort_num%5B%5D=&order_num%5B%5D=asc&eq=yes'
|
||||||
|
```
|
|
@ -4,6 +4,7 @@ import requests
|
||||||
import argparse
|
import argparse
|
||||||
import datetime
|
import datetime
|
||||||
import tqdm
|
import tqdm
|
||||||
|
import csv
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,11 +13,12 @@ logger = logging.getLogger('wiki')
|
||||||
default_categories = [
|
default_categories = [
|
||||||
# 'Person',
|
# 'Person',
|
||||||
'Institution',
|
'Institution',
|
||||||
'Technology',
|
'Products',
|
||||||
'Deployments',
|
'Deployments',
|
||||||
'Dataset',
|
'Dataset',
|
||||||
'City',
|
'City',
|
||||||
#'Country',# for deployments without city we should configure Geolocation
|
#'Country',# for deployments without city we should configure Geolocation
|
||||||
|
'Technology Type',
|
||||||
]
|
]
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description='Turn wiki into nodes & links, usable by d3-force.')
|
parser = argparse.ArgumentParser(description='Turn wiki into nodes & links, usable by d3-force.')
|
||||||
|
@ -28,6 +30,8 @@ parser.add_argument('--output', default="semantic_data.json",
|
||||||
help='Output JSON file')
|
help='Output JSON file')
|
||||||
parser.add_argument('--credentials', default="no_credentials.json",
|
parser.add_argument('--credentials', default="no_credentials.json",
|
||||||
help="JSON file containing the Bot's credentials")
|
help="JSON file containing the Bot's credentials")
|
||||||
|
parser.add_argument('--generate-csv', action='store_true',
|
||||||
|
help="generate edge.csv & nodes.csv")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
@ -257,3 +261,17 @@ if __name__ == "__main__":
|
||||||
with open(args.output, 'w') as fp:
|
with open(args.output, 'w') as fp:
|
||||||
json.dump(collection, fp)
|
json.dump(collection, fp)
|
||||||
|
|
||||||
|
if args.generate_csv:
|
||||||
|
with open('nodes.csv', 'w') as csvfile:
|
||||||
|
all_keys = set().union(*(d.keys() for d in collection['nodes']))
|
||||||
|
# all_keys = ['@id']
|
||||||
|
dict_writer = csv.DictWriter(csvfile, fieldnames=all_keys, extrasaction='ignore', restval='')
|
||||||
|
dict_writer.writeheader()
|
||||||
|
dict_writer.writerows(collection['nodes'])
|
||||||
|
|
||||||
|
with open('edges.csv', 'w') as csvfile:
|
||||||
|
all_keys = set().union(*(d.keys() for d in collection['links']))
|
||||||
|
dict_writer = csv.DictWriter(csvfile, fieldnames=all_keys, extrasaction='ignore', restval='')
|
||||||
|
dict_writer.writeheader()
|
||||||
|
dict_writer.writerows(collection['links'])
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Lexend Mega Regular';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
src: local('Lexend Mega Regular'), url('LexendMega-Regular.woff') format('woff');
|
||||||
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--color1: #9741f9;
|
--color1: #9741f9;
|
||||||
|
@ -33,13 +38,13 @@ body {
|
||||||
/* background: linear-gradient(to top, #040308, #AD4A28, #DD723C, #fc7001, #dcb697, #9ba5ae, #3e5879, #020b1a); */
|
/* background: linear-gradient(to top, #040308, #AD4A28, #DD723C, #fc7001, #dcb697, #9ba5ae, #3e5879, #020b1a); */
|
||||||
background: var(--body-back);
|
background: var(--body-back);
|
||||||
/* background: #9cb3c9; */
|
/* background: #9cb3c9; */
|
||||||
font-family: 'CelloSansRegular', sans-serif;
|
font-family: sans-serif;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
font-family: 'CelloSansRegular', sans-serif;
|
font-family: sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
svg.dragging {
|
svg.dragging {
|
||||||
|
@ -131,7 +136,7 @@ svg #header #titlePath, svg #header #title2Path, svg #header #subtitlePath {
|
||||||
|
|
||||||
svg #header text {
|
svg #header text {
|
||||||
font-size: 180px;
|
font-size: 180px;
|
||||||
font-family: "CelloSansRegular", sans-serif;
|
font-family: "Lexend Mega Regular";
|
||||||
/*Comfortaa*/
|
/*Comfortaa*/
|
||||||
opacity: .8;
|
opacity: .8;
|
||||||
fill: var(--title-color);
|
fill: var(--title-color);
|
||||||
|
@ -622,8 +627,5 @@ p.subtitle {
|
||||||
}
|
}
|
||||||
|
|
||||||
#sources a{
|
#sources a{
|
||||||
color: var(--link-hover-related-color);
|
color: lightblue;
|
||||||
}
|
|
||||||
#sources a:hover{
|
|
||||||
color: var(--link-hover-color);
|
|
||||||
}
|
}
|
182
www/graph.js
182
www/graph.js
|
@ -114,7 +114,6 @@ const CONFIG = {
|
||||||
"Software Developer",
|
"Software Developer",
|
||||||
"Dataset Developer",
|
"Dataset Developer",
|
||||||
"Related Institutions",
|
"Related Institutions",
|
||||||
"Is Department Of",
|
|
||||||
"Involved Entities",
|
"Involved Entities",
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -155,10 +154,6 @@ const CONFIG = {
|
||||||
"label": "is related to",
|
"label": "is related to",
|
||||||
"swap": true,
|
"swap": true,
|
||||||
},
|
},
|
||||||
"Is Department Of": {
|
|
||||||
"label": "is part of",
|
|
||||||
"swap": false,
|
|
||||||
},
|
|
||||||
"Involved Entities": {
|
"Involved Entities": {
|
||||||
"label": "is involved in",
|
"label": "is involved in",
|
||||||
"swap": true,
|
"swap": true,
|
||||||
|
@ -368,8 +363,6 @@ function getLinkId(link) {
|
||||||
|
|
||||||
class NodeMap {
|
class NodeMap {
|
||||||
constructor(parent) {
|
constructor(parent) {
|
||||||
this.ready = false;
|
|
||||||
this.readyCallback = false;
|
|
||||||
this.root = d3.select(parent);
|
this.root = d3.select(parent);
|
||||||
this.resizeEvent = window.addEventListener('resize', this.resize.bind(this));
|
this.resizeEvent = window.addEventListener('resize', this.resize.bind(this));
|
||||||
this.tooltipEl = document.getElementById('tooltip');
|
this.tooltipEl = document.getElementById('tooltip');
|
||||||
|
@ -549,46 +542,57 @@ class NodeMap {
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// this.title = this.container.append('g').attr('id', 'header');
|
this.title = this.container.append('g').attr('id', 'header');
|
||||||
|
|
||||||
// const titleFeature = {
|
const titleFeature = {
|
||||||
// "type": "LineString",
|
"type": "LineString",
|
||||||
// "coordinates": []
|
"coordinates": []
|
||||||
// };
|
};
|
||||||
// const title2Feature = {
|
const title2Feature = {
|
||||||
// "type": "LineString",
|
"type": "LineString",
|
||||||
// "coordinates": []
|
"coordinates": []
|
||||||
// };
|
};
|
||||||
// const subtitleFeature = {
|
const subtitleFeature = {
|
||||||
// "type": "LineString",
|
"type": "LineString",
|
||||||
// "coordinates": []
|
"coordinates": []
|
||||||
// };
|
};
|
||||||
// for (let index = 26; index < 70; index++) {
|
for (let index = 26; index < 70; index++) {
|
||||||
// // projection apparently tries to find the shortest path between two points
|
// projection apparently tries to find the shortest path between two points
|
||||||
// // which is NOT following a lat/lon line on the globe
|
// which is NOT following a lat/lon line on the globe
|
||||||
// titleFeature.coordinates.push([index, 52]);
|
titleFeature.coordinates.push([index, 52]);
|
||||||
// title2Feature.coordinates.push([index, 50.5]);
|
title2Feature.coordinates.push([index, 50.5]);
|
||||||
// subtitleFeature.coordinates.push([index, 49]);
|
subtitleFeature.coordinates.push([index, 49]);
|
||||||
// }
|
}
|
||||||
// this.title.append("path")
|
this.title.append("path")
|
||||||
// .attr("id", "titlePath")
|
.attr("id", "titlePath")
|
||||||
// .attr("d", this.proj(titleFeature))
|
.attr("d", this.proj(titleFeature))
|
||||||
// ;
|
;
|
||||||
// this.title.append("path")
|
this.title.append("path")
|
||||||
// .attr("id", "title2Path")
|
.attr("id", "title2Path")
|
||||||
// .attr("d", this.proj(title2Feature))
|
.attr("d", this.proj(title2Feature))
|
||||||
// ;
|
;
|
||||||
// this.title.append("path")
|
this.title.append("path")
|
||||||
// .attr("id", "subtitlePath")
|
.attr("id", "subtitlePath")
|
||||||
// .attr("d", this.proj(subtitleFeature))
|
.attr("d", this.proj(subtitleFeature))
|
||||||
// ;
|
;
|
||||||
// this.title.append("text")
|
this.title.append("text")
|
||||||
// .html('<textPath xlink:href="#titlePath">Remote Biometric</textPath>')
|
.html('<textPath xlink:href="#titlePath">Remote Biometric</textPath>')
|
||||||
// this.title.append("text")
|
this.title.append("text")
|
||||||
// .html('<textPath xlink:href="#title2Path">Identification</textPath>')
|
.html('<textPath xlink:href="#title2Path">Identification</textPath>')
|
||||||
// this.title.append("text")
|
this.title.append("text")
|
||||||
// .attr("id", "subtitle")
|
.attr("id", "subtitle")
|
||||||
// .html('<textPath xlink:href="#subtitlePath">' + CONFIG.subtitle + '</textPath>')
|
.html('<textPath xlink:href="#subtitlePath">' + CONFIG.subtitle + '</textPath>')
|
||||||
|
|
||||||
|
// this.title.append('text')
|
||||||
|
// .attr('class', 'title')
|
||||||
|
// .attr('x', 1000)
|
||||||
|
// .attr('y', 1000)
|
||||||
|
// .text(CONFIG.title);
|
||||||
|
// this.title.append('text')
|
||||||
|
// .attr('class', 'subtitle')
|
||||||
|
// .attr('x', 1000)
|
||||||
|
// .attr('y', 1200)
|
||||||
|
// .text(CONFIG.subtitle);
|
||||||
|
|
||||||
this.link = this.container.append("g")
|
this.link = this.container.append("g")
|
||||||
.attr('class', 'links')
|
.attr('class', 'links')
|
||||||
|
@ -664,34 +668,6 @@ class NodeMap {
|
||||||
this.update();
|
this.update();
|
||||||
|
|
||||||
setTimeout(() => this.calculateLabels(), 1000);
|
setTimeout(() => this.calculateLabels(), 1000);
|
||||||
|
|
||||||
this.ready = true;
|
|
||||||
if(this.readyCallback)
|
|
||||||
this.readyCallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
triggerReset(){
|
|
||||||
const cb = () => {
|
|
||||||
this.deselectNode();
|
|
||||||
this.resetZoom();
|
|
||||||
}
|
|
||||||
if(this.ready){
|
|
||||||
cb();
|
|
||||||
} else {
|
|
||||||
this.readyCallback = cb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
triggerSelect(toSelect){
|
|
||||||
const cb = () => {
|
|
||||||
const node = this.graph.nodes.filter(n => n.id == toSelect)[0]
|
|
||||||
this.selectNode(node);
|
|
||||||
}
|
|
||||||
if(this.ready){
|
|
||||||
cb();
|
|
||||||
} else {
|
|
||||||
this.readyCallback = cb;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resetZoom() {
|
resetZoom() {
|
||||||
|
@ -932,39 +908,6 @@ class NodeMap {
|
||||||
this.sourcesEl.classList.remove('visible');
|
this.sourcesEl.classList.remove('visible');
|
||||||
}
|
}
|
||||||
|
|
||||||
hoverNode(evt, n){
|
|
||||||
console.log('hover!', n)
|
|
||||||
// d3.select(this).classed('hover', true);
|
|
||||||
const links = document.getElementsByClassName('link');
|
|
||||||
const linkedLinks = [];
|
|
||||||
for (let link of links) {
|
|
||||||
const l = d3.select(link).datum();
|
|
||||||
if (n == l.target || n == l.source) {
|
|
||||||
link.classList.add('linkedHover');
|
|
||||||
// make sure it's the last element, so it's drawn on top
|
|
||||||
// link.parentNode.appendChild(link); .. causes gliches
|
|
||||||
// find related related node:
|
|
||||||
const otherNode = n == l.target ? l.source : l.target;
|
|
||||||
const otherNodeEl = document.getElementById(otherNode.id);
|
|
||||||
otherNodeEl.classList.add('linkedHover');
|
|
||||||
linkedLinks.push(l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(evt){
|
|
||||||
this.showTooltip(evt.target, n, linkedLinks);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
endHoverNode(n){
|
|
||||||
this.hideTooltip();
|
|
||||||
const links = document.getElementsByClassName('linkedHover');
|
|
||||||
while (links.length) {
|
|
||||||
links[0].classList.remove('linkedHover');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
// console.log(this.graph)
|
// console.log(this.graph)
|
||||||
|
|
||||||
|
@ -982,10 +925,31 @@ class NodeMap {
|
||||||
evt.stopPropagation(); this.selectNode(n);
|
evt.stopPropagation(); this.selectNode(n);
|
||||||
});
|
});
|
||||||
group.on("mouseover", (evt, n) => {
|
group.on("mouseover", (evt, n) => {
|
||||||
this.hoverNode(evt, n);
|
// d3.select(this).classed('hover', true);
|
||||||
|
const links = document.getElementsByClassName('link');
|
||||||
|
const linkedLinks = [];
|
||||||
|
for (let link of links) {
|
||||||
|
const l = d3.select(link).datum();
|
||||||
|
if (n == l.target || n == l.source) {
|
||||||
|
link.classList.add('linkedHover');
|
||||||
|
// make sure it's the last element, so it's drawn on top
|
||||||
|
// link.parentNode.appendChild(link); .. causes gliches
|
||||||
|
// find related related node:
|
||||||
|
const otherNode = n == l.target ? l.source : l.target;
|
||||||
|
const otherNodeEl = document.getElementById(otherNode.id);
|
||||||
|
otherNodeEl.classList.add('linkedHover');
|
||||||
|
linkedLinks.push(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.showTooltip(evt.target, n, linkedLinks);
|
||||||
|
|
||||||
});
|
});
|
||||||
group.on("mouseout", (evt, n) => {
|
group.on("mouseout", (evt, n) => {
|
||||||
this.endHoverNode(n);
|
this.hideTooltip();
|
||||||
|
const links = document.getElementsByClassName('linkedHover');
|
||||||
|
while (links.length) {
|
||||||
|
links[0].classList.remove('linkedHover');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// group.append('circle').attr("r", 5 /*this.nodeSize*/);
|
// group.append('circle').attr("r", 5 /*this.nodeSize*/);
|
||||||
group.append('path')
|
group.append('path')
|
||||||
|
|
|
@ -2,9 +2,8 @@
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link rel="stylesheet" media="screen" href="https://fontlibrary.org//face/cello-sans" type="text/css"/>
|
|
||||||
<link rel="stylesheet" href="graph.css">
|
<link rel="stylesheet" href="graph.css">
|
||||||
<title>Biometric and Behavioural Mass Surveillance in EU Member States</title>
|
<title>Remote Biometric Identification | A survey of the European Union</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@ -15,8 +14,8 @@
|
||||||
<div id='map'></div>
|
<div id='map'></div>
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<h1>Biometric and Behavioural Mass Surveillance</h1>
|
<h1>Remote Biometric Identification</h1>
|
||||||
<p class='subtitle'>in EU Member States</p>
|
<p class='subtitle'>A survey of the European Union</p>
|
||||||
|
|
||||||
<aside id="filters">
|
<aside id="filters">
|
||||||
<h3 onclick="this.parentNode.classList.toggle('hide');">Filter</h3>
|
<h3 onclick="this.parentNode.classList.toggle('hide');">Filter</h3>
|
||||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 207 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.1 MiB |
Binary file not shown.
Before Width: | Height: | Size: 4 MiB |
Binary file not shown.
Before Width: | Height: | Size: 70 KiB |
Binary file not shown.
Before Width: | Height: | Size: 20 KiB |
Binary file not shown.
Before Width: | Height: | Size: 16 KiB |
|
@ -1,610 +0,0 @@
|
||||||
/* adapted from MVP.css v1.7.3 - https://github.com/andybrewer/mvp */
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--border-radius: 5px;
|
|
||||||
--box-shadow: 2px 2px 10px;
|
|
||||||
--color: #d1bce9;
|
|
||||||
--hover-color: #9741f9;
|
|
||||||
--color-accent: #118bee15;
|
|
||||||
--color-bg: #fff;
|
|
||||||
--color-bg-secondary: #e9e9e9;
|
|
||||||
--color-secondary: darkblue; /*#920de9;*/
|
|
||||||
--color-secondary-accent: #920de90b;
|
|
||||||
--color-shadow: #f4f4f4;
|
|
||||||
--color-text: #000;
|
|
||||||
--color-text-secondary: #999;
|
|
||||||
--font-family: 'CelloSansRegular', sans-serif;
|
|
||||||
--hover-brightness: 1.2;
|
|
||||||
--justify-important: center;
|
|
||||||
--justify-normal: left;
|
|
||||||
--line-height: 1.5;
|
|
||||||
--width-card: 285px;
|
|
||||||
--width-card-medium: 460px;
|
|
||||||
--width-card-wide: 800px;
|
|
||||||
--width-content: 720px;
|
|
||||||
}
|
|
||||||
|
|
||||||
iframe {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: calc(100% - var(--width-content) - 4rem);
|
|
||||||
height: 100vh;
|
|
||||||
border-style: none none none none;
|
|
||||||
/* border-width: 3px;
|
|
||||||
border-color: black; */
|
|
||||||
}
|
|
||||||
|
|
||||||
content {
|
|
||||||
margin-left: 55vw;
|
|
||||||
max-width: var(--width-content);
|
|
||||||
margin-right: 5vw;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 1350px) {
|
|
||||||
iframe#map{
|
|
||||||
display: none;;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
:root {
|
|
||||||
--color: #0097fc;
|
|
||||||
--color-accent: #0097fc4f;
|
|
||||||
--color-bg: #333;
|
|
||||||
--color-bg-secondary: #555;
|
|
||||||
--color-secondary: #e20de9;
|
|
||||||
--color-secondary-accent: #e20de94f;
|
|
||||||
--color-shadow: #bbbbbb20;
|
|
||||||
--color-text: #f7f7f7;
|
|
||||||
--color-text-secondary: #aaa;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Layout */
|
|
||||||
article aside {
|
|
||||||
background: var(--color-secondary-accent);
|
|
||||||
border-left: 4px solid var(--color-secondary);
|
|
||||||
padding: 0.01rem 0.8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background: var(--color-bg);
|
|
||||||
color: var(--color-text);
|
|
||||||
font-family: var(--font-family);
|
|
||||||
line-height: var(--line-height);
|
|
||||||
margin: 0;
|
|
||||||
overflow-x: hidden;
|
|
||||||
padding: 1rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer,
|
|
||||||
header,
|
|
||||||
main {
|
|
||||||
margin: 0 0 0 auto;
|
|
||||||
max-width: var(--width-content);
|
|
||||||
width: calc(100% - 4rem);
|
|
||||||
padding: .5rem 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
header{
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
padding-left: 0;
|
|
||||||
padding-right: 0;
|
|
||||||
background-color: white;
|
|
||||||
border-bottom: solid 1px var(--color-bg-secondary);
|
|
||||||
z-index: 999;
|
|
||||||
max-width: calc(var(--width-content) + 4rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 740px) {
|
|
||||||
header{
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
|
||||||
background-color: var(--color-bg-secondary);
|
|
||||||
border: none;
|
|
||||||
height: 1px;
|
|
||||||
margin: 4rem 0;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
section {
|
|
||||||
justify-content: var(--justify-important);
|
|
||||||
}
|
|
||||||
|
|
||||||
section img,
|
|
||||||
article img {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
section pre {
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
section aside {
|
|
||||||
border: 1px solid var(--color-bg-secondary);
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
box-shadow: var(--box-shadow) var(--color-shadow);
|
|
||||||
margin: 1rem;
|
|
||||||
padding: 1.25rem;
|
|
||||||
width: var(--width-card);
|
|
||||||
}
|
|
||||||
|
|
||||||
section aside:hover {
|
|
||||||
box-shadow: var(--box-shadow) var(--color-bg-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
[hidden] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Headers */
|
|
||||||
article header,
|
|
||||||
div header,
|
|
||||||
main header {
|
|
||||||
padding-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
/* text-align: var(--justify-important); */
|
|
||||||
}
|
|
||||||
|
|
||||||
header a b,
|
|
||||||
header a em,
|
|
||||||
header a i,
|
|
||||||
header a strong {
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
margin-right: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
header nav > a{
|
|
||||||
color: var(--color-text);
|
|
||||||
/* padding-left: .5rem */
|
|
||||||
}
|
|
||||||
header nav img {
|
|
||||||
margin: 1rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
section header {
|
|
||||||
padding-top: 0;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nav */
|
|
||||||
nav {
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
/* font-weight: bold; */
|
|
||||||
justify-content: space-between;
|
|
||||||
padding:0 2rem;
|
|
||||||
/* margin-bottom: 7rem; */
|
|
||||||
}
|
|
||||||
|
|
||||||
nav > a{ font-weight: bold;}
|
|
||||||
|
|
||||||
nav ul {
|
|
||||||
list-style: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav ul li {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 0.5rem;
|
|
||||||
position: relative;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nav Dropdown */
|
|
||||||
nav ul li:hover ul {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav ul li ul {
|
|
||||||
background: var(--color-bg);
|
|
||||||
border: 1px solid var(--color-bg-secondary);
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
box-shadow: var(--box-shadow) var(--color-shadow);
|
|
||||||
display: none;
|
|
||||||
height: auto;
|
|
||||||
right: -2px;
|
|
||||||
padding: .5rem 1rem;
|
|
||||||
position: absolute;
|
|
||||||
top: 1.7rem;
|
|
||||||
white-space: nowrap;
|
|
||||||
width: auto;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav ul li ul li.space{
|
|
||||||
margin-top:1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav ul li ul::before {
|
|
||||||
/* fill gap above to make mousing over them easier */
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
top: -0.5rem;
|
|
||||||
height: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav ul li ul li,
|
|
||||||
nav ul li ul li a {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Typography */
|
|
||||||
code,
|
|
||||||
samp {
|
|
||||||
background-color: var(--color-accent);
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
color: var(--color-text);
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 0.1rem;
|
|
||||||
padding: 0 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
details {
|
|
||||||
margin: 1.3rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
details summary {
|
|
||||||
font-weight: bold;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1,
|
|
||||||
h2,
|
|
||||||
h3,
|
|
||||||
h4,
|
|
||||||
h5,
|
|
||||||
h6 {
|
|
||||||
text-align: left;
|
|
||||||
line-height: var(--line-height);
|
|
||||||
padding-top: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1{
|
|
||||||
padding-top: 100px;
|
|
||||||
margin-bottom: 4rem;
|
|
||||||
font-size: 150%;
|
|
||||||
}
|
|
||||||
h2{
|
|
||||||
padding-top:5rem;
|
|
||||||
font-size: 125%;
|
|
||||||
}
|
|
||||||
/* h1::before{
|
|
||||||
content: "CHAPTER " counter(h1counter) ".\0000a0\0000a0";
|
|
||||||
counter-increment: h1counter;
|
|
||||||
counter-reset: h2counter;
|
|
||||||
}
|
|
||||||
h2:before {
|
|
||||||
content: counter(h1counter) "." counter(h2counter) ".\0000a0\0000a0";
|
|
||||||
counter-increment: h2counter;
|
|
||||||
counter-reset: h3counter;
|
|
||||||
}
|
|
||||||
h3:before {
|
|
||||||
content: counter(h1counter) "." counter(h2counter) "." counter(h3counter) ".\0000a0\0000a0";
|
|
||||||
counter-increment: h3counter;
|
|
||||||
} */
|
|
||||||
|
|
||||||
/* thanks: http://philarcher.org/diary/2013/headingnumbers/ */
|
|
||||||
body {counter-reset: h1}
|
|
||||||
h1 {counter-reset: h2}
|
|
||||||
h2 {counter-reset: h3}
|
|
||||||
h3 {counter-reset: h4}
|
|
||||||
h4 {counter-reset: h5}
|
|
||||||
h5 {counter-reset: h6}
|
|
||||||
|
|
||||||
h1:before {counter-increment: h1; content: "CHAPTER "counter(h1) ". " }
|
|
||||||
h2:before {counter-increment: h2; content: counter(h1) "." counter(h2) ". "}
|
|
||||||
h3:before {counter-increment: h3; content: counter(h1) "." counter(h2) "." counter(h3) ". "}
|
|
||||||
|
|
||||||
h1.nocount:before, h1.title:before, h1.Title:before, h2.nocount:before, h3.nocount:before, h4.nocount:before, h5.nocount:before, h6.nocount:before { content: ""; counter-increment: none }
|
|
||||||
|
|
||||||
|
|
||||||
mark {
|
|
||||||
padding: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol li,
|
|
||||||
ul li {
|
|
||||||
padding: 0.2rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 0.75rem 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
margin: 1rem 0;
|
|
||||||
max-width: var(--width-card-wide);
|
|
||||||
padding: 1rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre code,
|
|
||||||
pre samp {
|
|
||||||
display: block;
|
|
||||||
max-width: var(--width-card-wide);
|
|
||||||
padding: 0.5rem 2rem;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
small {
|
|
||||||
color: var(--color-text-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
sup {
|
|
||||||
/* background-color: var(--color-secondary); */
|
|
||||||
/* border-radius: var(--border-radius); */
|
|
||||||
/* color: var(--color-secondary); */
|
|
||||||
/* font-size: xx-small; */
|
|
||||||
font-weight: bold;
|
|
||||||
/* margin: 0.2rem;
|
|
||||||
padding: 0.2rem 0.3rem; */
|
|
||||||
position: relative;
|
|
||||||
top: -2px;
|
|
||||||
}
|
|
||||||
/* sup::before{
|
|
||||||
content: '[';
|
|
||||||
}
|
|
||||||
sup::after{
|
|
||||||
content: ']';
|
|
||||||
} */
|
|
||||||
|
|
||||||
/* Links */
|
|
||||||
a, a sup {
|
|
||||||
color: inherit;
|
|
||||||
border-bottom: solid 2px var(--color);
|
|
||||||
display: inline;
|
|
||||||
/* font-weight: bold; */
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover, a:hover sup {
|
|
||||||
color: var(--hover-color);
|
|
||||||
border-color: var(--hover-color);
|
|
||||||
/* text-decoration: underline; */
|
|
||||||
}
|
|
||||||
a.footnote-ref{
|
|
||||||
border:none;
|
|
||||||
/* background-color: var(--hover-color); */
|
|
||||||
}
|
|
||||||
|
|
||||||
nav a{
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a b,
|
|
||||||
a em,
|
|
||||||
a i,
|
|
||||||
a strong,
|
|
||||||
button {
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
display: inline-block;
|
|
||||||
font-size: medium;
|
|
||||||
font-weight: bold;
|
|
||||||
line-height: var(--line-height);
|
|
||||||
margin: 0.5rem 0;
|
|
||||||
padding: 1rem 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
font-family: var(--font-family);
|
|
||||||
}
|
|
||||||
|
|
||||||
button:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
color: var(--hover-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
a b,
|
|
||||||
a strong,
|
|
||||||
button {
|
|
||||||
background-color: var(--color);
|
|
||||||
border: 2px solid var(--color);
|
|
||||||
color: var(--color-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
a em,
|
|
||||||
a i {
|
|
||||||
border: 2px solid var(--color);
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
color: var(--color);
|
|
||||||
display: inline-block;
|
|
||||||
padding: 1rem 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
article aside a {
|
|
||||||
color: var(--color-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Images */
|
|
||||||
figure {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
figure img {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
figure figcaption {
|
|
||||||
color: var(--color-text-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Forms */
|
|
||||||
|
|
||||||
button:disabled,
|
|
||||||
input:disabled {
|
|
||||||
background: var(--color-bg-secondary);
|
|
||||||
border-color: var(--color-bg-secondary);
|
|
||||||
color: var(--color-text-secondary);
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
button[disabled]:hover {
|
|
||||||
filter: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
form {
|
|
||||||
border: 1px solid var(--color-bg-secondary);
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
box-shadow: var(--box-shadow) var(--color-shadow);
|
|
||||||
display: block;
|
|
||||||
max-width: var(--width-card-wide);
|
|
||||||
min-width: var(--width-card);
|
|
||||||
padding: 1.5rem;
|
|
||||||
text-align: var(--justify-normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
form header {
|
|
||||||
margin: 1.5rem 0;
|
|
||||||
padding: 1.5rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
input,
|
|
||||||
label,
|
|
||||||
select,
|
|
||||||
textarea {
|
|
||||||
display: block;
|
|
||||||
font-size: inherit;
|
|
||||||
max-width: var(--width-card-wide);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="checkbox"],
|
|
||||||
input[type="radio"] {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="checkbox"]+label,
|
|
||||||
input[type="radio"]+label {
|
|
||||||
display: inline-block;
|
|
||||||
font-weight: normal;
|
|
||||||
position: relative;
|
|
||||||
top: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input,
|
|
||||||
select,
|
|
||||||
textarea {
|
|
||||||
border: 1px solid var(--color-bg-secondary);
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
padding: 0.4rem 0.8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[readonly],
|
|
||||||
textarea[readonly] {
|
|
||||||
background-color: var(--color-bg-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 0.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Tables */
|
|
||||||
table {
|
|
||||||
border: 1px solid var(--color-bg-secondary);
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
border-spacing: 0;
|
|
||||||
display: inline-block;
|
|
||||||
max-width: 100%;
|
|
||||||
overflow-x: auto;
|
|
||||||
padding: 0;
|
|
||||||
/* white-space: nowrap; */
|
|
||||||
}
|
|
||||||
|
|
||||||
table td,
|
|
||||||
table th,
|
|
||||||
table tr {
|
|
||||||
padding: 0.4rem 0.8rem;
|
|
||||||
text-align: var(--justify-important);
|
|
||||||
}
|
|
||||||
|
|
||||||
table thead {
|
|
||||||
background-color: var(--color);
|
|
||||||
border-collapse: collapse;
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
color: var(--color-bg);
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
table thead th:first-child {
|
|
||||||
border-top-left-radius: var(--border-radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
table thead th:last-child {
|
|
||||||
border-top-right-radius: var(--border-radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
table thead th:first-child,
|
|
||||||
table tr td:first-child {
|
|
||||||
text-align: var(--justify-normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
table tr:nth-child(even) {
|
|
||||||
background-color: var(--color-accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Quotes */
|
|
||||||
blockquote {
|
|
||||||
display: block;
|
|
||||||
font-size: 100%;
|
|
||||||
line-height: var(--line-height);
|
|
||||||
margin: 1rem auto;
|
|
||||||
max-width: var(--width-card-medium);
|
|
||||||
padding: 1.5rem 1rem;
|
|
||||||
text-align: var(--justify-important);
|
|
||||||
}
|
|
||||||
|
|
||||||
blockquote footer {
|
|
||||||
color: var(--color-text-secondary);
|
|
||||||
display: block;
|
|
||||||
font-size: small;
|
|
||||||
line-height: var(--line-height);
|
|
||||||
padding: 1.5rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
h1.title{
|
|
||||||
font-size: 50px;
|
|
||||||
padding: 20vh 0;
|
|
||||||
}
|
|
||||||
h1.Title{
|
|
||||||
font-size: xx-large;
|
|
||||||
padding: 20vh 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.keypoints{
|
|
||||||
background-color: black;
|
|
||||||
color: var(--color-bg-secondary);
|
|
||||||
padding: 2rem;
|
|
||||||
margin: 0 -2rem;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.keypoints > p > strong{
|
|
||||||
margin-left:2.5rem;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.maplink{
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
506
www/story.html
Normal file
506
www/story.html
Normal file
|
@ -0,0 +1,506 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Biometric Mass Surveillance</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
iframe {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 50vw;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
content {
|
||||||
|
margin-left: 55vw;
|
||||||
|
max-width: 800px;
|
||||||
|
margin-right: 5vw;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<iframe id='frame' src="index.html"></iframe>
|
||||||
|
|
||||||
|
<content>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<p>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi risus augue, pellentesque quis iaculis
|
||||||
|
vitae, condimentum a leo. Nunc scelerisque, odio a tristique molestie, massa mi sollicitudin odio, ac
|
||||||
|
fermentum orci nisi a ipsum. Curabitur pellentesque eleifend risus, eget porta tellus malesuada ut. Nunc
|
||||||
|
dignissim, ipsum pellentesque accumsan faucibus, mi leo mattis ante, a rhoncus massa leo vel augue.
|
||||||
|
Mauris eros nunc, vehicula et faucibus at, convallis non odio. Ut gravida, lorem non sodales maximus,
|
||||||
|
purus justo blandit felis, at sollicitudin dolor erat eget est. Ut euismod auctor lorem, iaculis
|
||||||
|
pulvinar odio tempus et. Proin ullamcorper cursus posuere. Donec venenatis diam nulla, sed egestas ipsum
|
||||||
|
vestibulum ultrices. Proin lobortis elementum semper. Morbi sollicitudin aliquam tortor, ac maximus urna
|
||||||
|
finibus vel. Vivamus ultricies, nibh non hendrerit rutrum, sapien neque eleifend leo, nec lobortis
|
||||||
|
libero orci ut sapien.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Nulla porttitor dolor laoreet elit ornare, eu pellentesque nulla tempus. Duis et suscipit massa. Etiam
|
||||||
|
velit lorem, ornare at odio vel, malesuada imperdiet massa. Pellentesque mauris justo, sollicitudin quis
|
||||||
|
varius vel, dignissim ut turpis. Maecenas vel odio mauris. Aliquam maximus maximus erat vel fermentum.
|
||||||
|
Aenean vel venenatis diam. Interdum et malesuada fames ac ante ipsum primis in faucibus. Curabitur risus
|
||||||
|
risus, facilisis sed velit a, feugiat eleifend quam. Donec rutrum molestie sem.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Ut metus elit, porta et turpis in, sodales imperdiet ligula. Nam vulputate ultricies urna non facilisis.
|
||||||
|
Vivamus sit amet pulvinar risus. Nullam id odio tempus, malesuada metus et, lobortis nibh. Suspendisse
|
||||||
|
viverra nulla magna, id tincidunt turpis pretium rhoncus. Pellentesque vel aliquet dui. Mauris eleifend
|
||||||
|
efficitur libero eu porttitor. Aenean congue interdum dui eget aliquam. Maecenas volutpat porta quam,
|
||||||
|
vitae congue justo cursus in. Fusce ac congue lorem. Nulla pretium odio ac quam aliquam convallis.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Fusce a urna ac lorem eleifend eleifend. Etiam mollis quam nisl, et scelerisque felis lacinia quis.
|
||||||
|
Mauris ullamcorper mi et feugiat auctor. Sed placerat tincidunt tincidunt. Vestibulum dictum vestibulum
|
||||||
|
orci dignissim ornare. Nullam sed congue sapien. Donec rhoncus nibh quis malesuada egestas. Cras non est
|
||||||
|
quam. Curabitur vulputate, metus non faucibus rutrum, ex lorem viverra ligula, sodales vehicula sapien
|
||||||
|
diam quis justo. Quisque tempor maximus mauris sit amet eleifend. Cras auctor feugiat ullamcorper.
|
||||||
|
Mauris ultricies elit vel euismod volutpat. Praesent in elit dignissim, dignissim urna varius,
|
||||||
|
consectetur lacus. Sed ligula tellus, consectetur a ligula a, tempus hendrerit urna. Maecenas volutpat
|
||||||
|
sapien risus, ac egestas ex porta et.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Nullam velit quam, efficitur vitae sem nec, sodales porttitor orci. Sed egestas lacus sit amet ex
|
||||||
|
dictum, sit amet tincidunt ex hendrerit. Morbi pharetra, ipsum sed gravida fermentum, felis quam rhoncus
|
||||||
|
lacus, vitae auctor enim ligula pulvinar tellus. Cras sapien augue, ultricies pulvinar arcu et,
|
||||||
|
convallis porttitor augue. Vestibulum accumsan lorem eros, id volutpat orci tincidunt at. Vivamus porta
|
||||||
|
magna id finibus tristique. Quisque sodales augue in lacus tristique ornare. Curabitur cursus hendrerit
|
||||||
|
neque rutrum blandit. Maecenas posuere ex eget eleifend fringilla.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Integer est dui, elementum in nisl nec, blandit auctor libero. Cras in nulla nunc. Curabitur fringilla
|
||||||
|
dolor sagittis felis fringilla, non euismod felis tempus. Aenean scelerisque euismod nisl vitae
|
||||||
|
tincidunt. Nam nec purus eleifend, fringilla diam quis, faucibus ex. Maecenas nunc felis, rhoncus sed
|
||||||
|
sollicitudin non, luctus sed dolor. Phasellus elit neque, rutrum a est venenatis, convallis imperdiet
|
||||||
|
dui. Vestibulum at ultrices eros, at vulputate sem. Ut vestibulum libero sed sapien sagittis, id laoreet
|
||||||
|
velit eleifend. Phasellus eleifend nec odio non bibendum. Suspendisse nec lectus nec ex blandit rutrum
|
||||||
|
nec et felis. Cras libero justo, sagittis sed lacinia quis, pharetra quis nibh. Maecenas vitae lacus ac
|
||||||
|
augue condimentum suscipit.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Pellentesque eu tempor orci. Aenean pulvinar, justo ac maximus molestie, nibh nunc rutrum ex, varius
|
||||||
|
finibus mi nulla lobortis tellus. Nam dictum leo maximus ultrices maximus. Aliquam bibendum libero sem,
|
||||||
|
mattis pulvinar erat vulputate quis. Duis venenatis nisi ac sem iaculis, nec feugiat orci elementum.
|
||||||
|
Curabitur accumsan lacinia justo id suscipit. In lacinia ornare justo quis egestas. Nullam nec lacus a
|
||||||
|
ligula pulvinar tempus eget id nunc. Morbi tincidunt placerat placerat.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" data-title="Dragonfly Project">
|
||||||
|
<h2>Project Dragonfly</h2>
|
||||||
|
<p>
|
||||||
|
Morbi vitae nulla erat. Etiam eros ipsum, tristique in maximus sed, rutrum a mi. Integer molestie
|
||||||
|
imperdiet mauris sit amet lacinia. Aenean dignissim posuere lacus, ut vulputate tellus venenatis
|
||||||
|
posuere. Nullam suscipit tempor massa at viverra. Sed volutpat justo ut lacinia luctus. Sed egestas
|
||||||
|
hendrerit tellus, non bibendum quam gravida non. Aenean suscipit ligula tristique venenatis molestie.
|
||||||
|
Nunc aliquet orci mi.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Nunc vel dolor lorem. Sed venenatis lacinia sapien ut aliquam. Nulla vitae tincidunt sem. Aliquam eu
|
||||||
|
nisl pharetra, ornare justo nec, egestas nisi. Nam et metus vitae enim tempus vestibulum. Fusce ipsum
|
||||||
|
quam, maximus et mattis nec, consectetur vitae urna. Vivamus rhoncus augue sed justo bibendum, in
|
||||||
|
imperdiet metus vestibulum. Nam egestas eleifend enim ultricies lobortis. Pellentesque sed nibh eros.
|
||||||
|
Nulla mattis facilisis felis, eu lacinia neque condimentum ut. Suspendisse fermentum ultrices faucibus.
|
||||||
|
Aliquam ac ultrices lectus, in pharetra lectus. Curabitur in molestie felis. Proin ac ante eget sem
|
||||||
|
fringilla hendrerit sit amet a leo. Sed at nunc vitae dolor vestibulum luctus quis ac nunc. Suspendisse
|
||||||
|
nunc justo, gravida id pharetra et, convallis nec velit.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Nunc dui leo, varius ac venenatis nec, vehicula et dui. Pellentesque quis enim dolor. Vestibulum
|
||||||
|
tincidunt egestas porta. Suspendisse ac nisl nisl. Pellentesque auctor convallis euismod. In pharetra
|
||||||
|
iaculis accumsan. Maecenas scelerisque molestie dui eu gravida. Aliquam hendrerit ipsum vitae laoreet
|
||||||
|
laoreet. Phasellus nec mattis leo, at rhoncus sem. Nam maximus, dolor eget consequat mattis, tortor leo
|
||||||
|
blandit mi, in lacinia est ligula et erat. Fusce at nisi eleifend, dapibus leo eget, porttitor ipsum.
|
||||||
|
Duis tristique velit vitae dui fermentum, quis gravida lorem tempor. Phasellus sed risus diam. Aenean
|
||||||
|
fringilla justo ac felis lacinia, quis placerat tellus pretium.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Vestibulum ante nisl, porta vitae ultrices in, fermentum eget tellus. Quisque ornare, leo aliquet tempor
|
||||||
|
aliquet, ligula diam vehicula nisi, nec faucibus mauris ex at dui. Phasellus vel ligula suscipit lacus
|
||||||
|
eleifend egestas. Suspendisse ut lacus suscipit, gravida dui at, volutpat dolor. Nunc suscipit erat ac
|
||||||
|
risus tempus tempor. Nulla quis mi blandit, hendrerit mauris eget, commodo nisl. Aliquam ultricies purus
|
||||||
|
metus, quis gravida ante condimentum quis. Mauris porta vestibulum ornare. Vivamus elementum pharetra
|
||||||
|
nisl, a vehicula nibh. Etiam ac turpis tortor.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Nunc non elit ac diam interdum pretium ac sed velit. Etiam non metus elementum, consectetur ante vel,
|
||||||
|
iaculis lorem. Pellentesque convallis finibus ipsum ut fermentum. Morbi at eros vel felis pharetra
|
||||||
|
dapibus faucibus et nisl. Nunc sit amet felis nec leo malesuada aliquam quis in risus. Sed quis leo
|
||||||
|
felis. Curabitur in porta urna. Nulla dignissim, tortor et sodales auctor, ante odio porttitor nunc, ut
|
||||||
|
tincidunt ligula dolor non sapien. Suspendisse vitae iaculis urna, id commodo sem.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Nulla facilisi. Sed at augue sit amet erat posuere consectetur. Aliquam pretium lectus ipsum, nec ornare
|
||||||
|
enim tincidunt sit amet. Praesent sit amet iaculis odio. Etiam nibh risus, pulvinar vel arcu quis,
|
||||||
|
elementum faucibus mauris. Curabitur posuere leo a consectetur hendrerit. Proin finibus lobortis turpis,
|
||||||
|
ac feugiat est elementum at. Suspendisse vitae neque id nisi ultricies viverra. Curabitur ut libero sed
|
||||||
|
arcu accumsan accumsan a sed ex. Sed suscipit non sapien non eleifend. Vivamus condimentum scelerisque
|
||||||
|
est, sit amet sollicitudin nisi lacinia nec. Nunc in lacus consectetur neque ultrices laoreet ut et est.
|
||||||
|
Quisque vulputate odio neque, eget laoreet felis molestie sit amet.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class='section' data-title="Burglary-Free Neighbourhood">
|
||||||
|
<h2>Burglary-free Neighbourhood</h2>
|
||||||
|
<p>
|
||||||
|
Aenean fringilla nisl sed ante congue, in commodo tellus ullamcorper. Nullam sollicitudin, lacus id
|
||||||
|
interdum facilisis, erat augue feugiat justo, ac finibus nunc tellus ac odio. Cras a tempor nulla.
|
||||||
|
Nullam consequat convallis eros, sed interdum orci. Etiam justo lectus, ornare nec risus ut,
|
||||||
|
pellentesque mattis ante. Integer tristique sapien quis lacus cursus luctus. Pellentesque risus lacus,
|
||||||
|
auctor eget lacus eu, dapibus pretium ligula. Sed eget tortor ut lacus elementum facilisis. Pellentesque
|
||||||
|
velit ante, sagittis vel odio nec, rhoncus sagittis sem. Duis sodales lectus eget suscipit scelerisque.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Donec suscipit, nulla at congue scelerisque, eros odio consectetur quam, a ornare ex leo a sapien.
|
||||||
|
Curabitur gravida massa at posuere aliquet. Maecenas consequat, dui quis posuere hendrerit, nunc ipsum
|
||||||
|
interdum erat, sit amet ultricies justo nibh vel nulla. Integer venenatis semper ipsum quis congue.
|
||||||
|
Nulla facilisi. Proin dapibus diam nec erat viverra imperdiet. Proin quis rhoncus sem. Maecenas
|
||||||
|
ultricies elementum mauris, sit amet rutrum libero laoreet cursus. Maecenas quam velit, consectetur sit
|
||||||
|
amet sapien vitae, tempor egestas nisi. Suspendisse pulvinar ultricies erat sit amet pretium. In luctus,
|
||||||
|
diam vitae ornare feugiat, risus eros tincidunt orci, at convallis lacus lacus quis felis.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Praesent et facilisis elit, id ultricies magna. Donec interdum sed dolor vitae blandit. Vestibulum
|
||||||
|
hendrerit eros et magna finibus, nec pharetra est aliquam. Suspendisse tempor sagittis maximus. Ut
|
||||||
|
porttitor tellus ipsum, non malesuada lectus vulputate a. Fusce vitae bibendum justo, non aliquam elit.
|
||||||
|
Mauris fringilla purus sit amet aliquet laoreet. Nulla tempus ac metus luctus porta. Donec quis tellus
|
||||||
|
luctus, dignissim nisl vitae, iaculis eros. Duis nisl nulla, rhoncus eu iaculis non, faucibus vitae
|
||||||
|
risus. Pellentesque consectetur faucibus metus. Nulla facilisi.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Mauris maximus ullamcorper mattis. Morbi consectetur mollis sapien, sed ultricies ipsum interdum vitae.
|
||||||
|
Proin feugiat vitae elit eget pharetra. Sed in maximus nisl, non ultrices massa. In nec ipsum placerat,
|
||||||
|
tempor neque vitae, consequat neque. Nam in tempor libero. Sed feugiat massa pellentesque malesuada
|
||||||
|
volutpat. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec
|
||||||
|
vel odio vel orci auctor aliquam convallis id lacus. Sed euismod ultricies ullamcorper. Morbi lobortis
|
||||||
|
luctus interdum. Quisque ac nisl lobortis, elementum tortor et, euismod erat.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Etiam at dolor mauris. Morbi in mauris scelerisque, suscipit lacus id, condimentum est. Vestibulum ante
|
||||||
|
ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Sed rutrum lobortis ullamcorper.
|
||||||
|
Vivamus ac mi non libero rutrum tempus. Donec ante ipsum, gravida eu magna auctor, efficitur molestie
|
||||||
|
augue. Aenean a justo eros. Vivamus aliquet pretium eros, tempus feugiat odio molestie vitae. Aenean
|
||||||
|
mattis gravida erat, eget venenatis dolor faucibus nec. Nullam in risus feugiat, aliquam nisi vel,
|
||||||
|
tincidunt tortor. Donec quis imperdiet felis. Curabitur suscipit auctor purus quis faucibus. Cras nec
|
||||||
|
diam rutrum, pharetra erat ut, pellentesque augue. Morbi mattis massa ut ante congue blandit. Orci
|
||||||
|
varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Integer tincidunt odio non mauris egestas viverra. Nulla blandit vulputate enim vel vestibulum. Donec
|
||||||
|
suscipit dignissim nisi a scelerisque. Class aptent taciti sociosqu ad litora torquent per conubia
|
||||||
|
nostra, per inceptos himenaeos. Donec egestas mauris posuere diam tempor, vel consectetur enim rhoncus.
|
||||||
|
Phasellus accumsan feugiat dui, sit amet viverra neque facilisis in. Pellentesque fermentum ipsum
|
||||||
|
porttitor, luctus felis eu, ornare quam. Integer ut pharetra nisi. Phasellus sed facilisis quam, nec
|
||||||
|
porta metus. Sed consequat ac nisl eget faucibus. Proin blandit nisi id pharetra vestibulum. Vestibulum
|
||||||
|
posuere nibh vitae elit pharetra rhoncus at a ligula. Duis at tincidunt dolor. Quisque a diam varius,
|
||||||
|
facilisis libero a, volutpat dolor. Nulla vel accumsan diam. Praesent eu neque nibh.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Suspendisse ac libero mi. In hac habitasse platea dictumst. Ut bibendum a dui eu congue. Sed et lacus
|
||||||
|
congue, faucibus nulla cursus, sagittis odio. In ac risus vehicula, interdum mauris quis, porttitor
|
||||||
|
massa. Vivamus non iaculis tortor. Mauris ac pharetra urna. Integer ac mattis enim. Integer egestas
|
||||||
|
velit purus. In hac habitasse platea dictumst. Ut interdum felis ut libero pellentesque, ac vulputate
|
||||||
|
felis faucibus. Sed facilisis fringilla leo, et condimentum quam fermentum ac. Maecenas blandit
|
||||||
|
sollicitudin libero in pretium.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Donec sodales convallis sapien eget rutrum. Nullam fermentum nisi nec auctor convallis. Phasellus
|
||||||
|
euismod ante erat, ut vulputate sem rhoncus et. Quisque ac eros sit amet metus aliquet blandit. Integer
|
||||||
|
sagittis ligula vitae orci gravida rhoncus. Vestibulum eu ante id ipsum ultricies tempor. Proin viverra,
|
||||||
|
felis vel suscipit laoreet, lorem nisl condimentum ipsum, id convallis ipsum ante ac sem. Maecenas vitae
|
||||||
|
ultricies augue. Morbi lectus dolor, tempus ac scelerisque sit amet, condimentum eget tortor. Fusce id
|
||||||
|
rutrum ligula.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
In suscipit purus at leo convallis sodales. Sed a placerat arcu. Fusce id mi quis nisl ullamcorper
|
||||||
|
imperdiet. Donec eu leo sit amet lacus euismod accumsan. Fusce facilisis congue leo eu commodo. Sed vel
|
||||||
|
libero sem. Nulla nec volutpat eros. Pellentesque habitant morbi tristique senectus et netus et
|
||||||
|
malesuada fames ac turpis egestas. In lacinia massa sed justo tincidunt, sed aliquam erat tristique. Nam
|
||||||
|
porta pharetra nisi eu aliquet.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
In in neque vel ligula dictum suscipit. Cras cursus a felis nec mattis. Praesent rhoncus orci nec nulla
|
||||||
|
rutrum, sit amet iaculis massa varius. Mauris sit amet finibus ipsum. Nam sit amet augue sed ipsum
|
||||||
|
laoreet venenatis. Praesent feugiat faucibus congue. Nunc vulputate ante at neque suscipit auctor. In
|
||||||
|
nec sagittis lacus. Suspendisse ornare ut eros a lobortis. Donec et pharetra urna, sit amet dictum enim.
|
||||||
|
Morbi fringilla ligula tristique nibh tempus, quis pharetra sem imperdiet. Suspendisse auctor fringilla
|
||||||
|
purus, ultricies feugiat augue consectetur et. Integer neque mauris, elementum imperdiet finibus vel,
|
||||||
|
suscipit ac metus. In hac habitasse platea dictumst. Mauris eu nibh porttitor, tempor enim vel,
|
||||||
|
tristique libero.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Suspendisse commodo in justo a hendrerit. Nunc nec laoreet ante. Nam ac tincidunt libero, sed rhoncus
|
||||||
|
libero. Nunc et arcu a ex consequat malesuada eget vel nunc. Mauris felis lectus, sodales sed lacus id,
|
||||||
|
congue blandit diam. Curabitur eu quam accumsan augue accumsan lacinia. Nulla id justo elementum,
|
||||||
|
placerat lectus et, varius purus. Nam congue, erat at congue posuere, diam felis consequat mi, a tempor
|
||||||
|
erat odio id dolor. Nunc pulvinar libero sit amet neque posuere, sit amet placerat metus facilisis. In
|
||||||
|
justo libero, facilisis condimentum molestie eu, tristique in sapien. Interdum et malesuada fames ac
|
||||||
|
ante ipsum primis in faucibus. In mattis, nisl eu mollis ultricies, justo lacus commodo nisl, ut
|
||||||
|
pulvinar augue odio nec leo. Pellentesque ornare tellus nec massa pellentesque, id euismod odio mattis.
|
||||||
|
Aliquam at massa a nisi maximus varius. Donec interdum odio id nibh commodo, in ultricies lacus lacinia.
|
||||||
|
Ut et ultricies libero.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Nunc pretium vehicula leo, ut vehicula dolor ultricies quis. Nunc ultricies elit lobortis lorem tempus
|
||||||
|
placerat. Vestibulum vitae velit ut libero pretium dignissim sed vitae sapien. Ut ornare nunc nec tortor
|
||||||
|
sodales, nec volutpat risus ornare. Morbi ac iaculis arcu. Fusce viverra feugiat porta. Nam aliquam
|
||||||
|
aliquet urna quis consequat. Sed suscipit arcu ut eros imperdiet posuere non at nunc. Quisque ac
|
||||||
|
convallis lacus, non efficitur nulla. Interdum et malesuada fames ac ante ipsum primis in faucibus.
|
||||||
|
Fusce suscipit tincidunt pharetra. Sed eget egestas enim.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Quisque tellus nulla, facilisis eget ante ac, pharetra pretium mauris. Nam arcu urna, condimentum sed
|
||||||
|
urna sed, mattis dictum nisi. Maecenas eget ante facilisis, dignissim nisl non, venenatis odio. Integer
|
||||||
|
turpis enim, sagittis eu commodo nec, mollis at ex. In non dui dictum, porttitor mauris in, rutrum
|
||||||
|
dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Proin vel
|
||||||
|
nisi eros. Aliquam vel turpis est. Class aptent taciti sociosqu ad litora torquent per conubia nostra,
|
||||||
|
per inceptos himenaeos. In libero risus, feugiat non tristique quis, egestas vel tortor. Praesent cursus
|
||||||
|
lorem nec euismod placerat. Fusce tincidunt non risus at luctus. Nullam hendrerit mi diam, ut rhoncus
|
||||||
|
neque accumsan vel. Sed cursus dolor id velit ullamcorper rhoncus. Duis volutpat sodales aliquam.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Curabitur dignissim posuere ex sit amet porta. Sed viverra arcu et sapien tristique, ullamcorper
|
||||||
|
eleifend elit posuere. Aenean nec augue dui. Proin semper efficitur vehicula. Praesent vestibulum tortor
|
||||||
|
fringilla dolor congue maximus. Morbi sagittis mollis blandit. Lorem ipsum dolor sit amet, consectetur
|
||||||
|
adipiscing elit. Cras pulvinar laoreet tincidunt. Mauris hendrerit mollis neque nec vehicula. Mauris
|
||||||
|
auctor pharetra nisl, at ornare ante accumsan feugiat. Maecenas felis risus, posuere vel nunc et,
|
||||||
|
fringilla viverra dolor. Cras consectetur rutrum ipsum vel tempus. Etiam mattis ante in lacus mollis,
|
||||||
|
non porta quam pulvinar. Sed rutrum tempor placerat. Sed id dui eleifend, interdum tellus ut, sagittis
|
||||||
|
odio. Ut iaculis at enim a dignissim.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Proin tempor mi sed mattis mollis. Quisque nulla odio, rutrum vitae ligula eget, interdum faucibus
|
||||||
|
tellus. Aliquam et augue vel justo molestie vestibulum eu nec risus. Maecenas aliquet, risus eget
|
||||||
|
feugiat consequat, diam magna bibendum diam, sed pharetra tellus purus ut est. Aenean dictum pulvinar
|
||||||
|
vestibulum. Sed non neque eros. Etiam vitae aliquam nisl, quis congue velit. Ut gravida libero vel
|
||||||
|
vestibulum tincidunt. Sed vel nibh ac velit aliquam porttitor eget et nulla.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Suspendisse ut odio molestie odio auctor sollicitudin. Vestibulum viverra ornare nibh, vel lobortis odio
|
||||||
|
dapibus ac. Cras dapibus porta libero, nec congue nisi sagittis sit amet. Class aptent taciti sociosqu
|
||||||
|
ad litora torquent per conubia nostra, per inceptos himenaeos. Donec ullamcorper leo vitae urna
|
||||||
|
sollicitudin sodales. Suspendisse quis nulla vitae quam ornare lobortis sodales sit amet lectus.
|
||||||
|
Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut eleifend gravida laoreet. Cras id purus
|
||||||
|
vehicula, egestas velit sit amet, pretium magna. In in pulvinar quam.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Aliquam fermentum a tellus a sodales. Pellentesque habitant morbi tristique senectus et netus et
|
||||||
|
malesuada fames ac turpis egestas. Etiam facilisis molestie ipsum ac viverra. Vestibulum lacus nunc,
|
||||||
|
egestas at lorem vel, pulvinar consequat lacus. Sed feugiat nisl vel risus vehicula, sed imperdiet elit
|
||||||
|
ornare. Maecenas non magna vitae erat feugiat scelerisque. Nam vulputate lacus porta porttitor
|
||||||
|
sollicitudin.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Quisque auctor tellus lorem, et ornare tellus efficitur id. Cras dictum tortor quis lorem facilisis, in
|
||||||
|
molestie erat porta. Sed vel porttitor libero. Etiam pulvinar augue a semper finibus. Mauris tellus
|
||||||
|
metus, lobortis non viverra eu, commodo quis nunc. Maecenas vitae pellentesque lectus. Nunc ut felis
|
||||||
|
tellus. Phasellus a mi in neque placerat egestas eget vitae tellus. Vivamus ut metus tellus.
|
||||||
|
Pellentesque mollis tempus tempus.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Ut at pretium lacus, non sollicitudin velit. Vivamus sagittis fermentum purus, nec suscipit lectus
|
||||||
|
imperdiet eu. Cras velit risus, porttitor vitae lectus id, condimentum pulvinar sem. Ut lacinia metus eu
|
||||||
|
rhoncus finibus. Vivamus accumsan, ex suscipit porttitor dictum, tellus lectus luctus lorem, sed lacinia
|
||||||
|
lectus sem et ligula. Duis vitae turpis nunc. Curabitur non sapien felis. Maecenas a egestas nunc, eget
|
||||||
|
luctus quam. Duis vestibulum metus eu turpis vulputate, et lacinia ante maximus. Vivamus molestie leo
|
||||||
|
eget sem dictum, nec posuere sapien euismod.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Cras et risus venenatis nisi dapibus feugiat non at dui. Pellentesque faucibus nulla aliquam nunc
|
||||||
|
congue, ut fringilla est viverra. Mauris nulla elit, ornare non augue a, cursus elementum diam. Proin
|
||||||
|
pulvinar justo nulla, et semper tortor dapibus ac. Maecenas ac libero ut eros hendrerit auctor at nec
|
||||||
|
augue. Aliquam dictum, ligula fermentum lobortis egestas, risus neque pulvinar felis, id lobortis tellus
|
||||||
|
nunc eget massa. Fusce vel mollis arcu. Suspendisse dapibus, tortor in blandit pulvinar, nulla dolor
|
||||||
|
euismod justo, vel ullamcorper dui ante ac dolor. Duis congue urna et purus posuere semper. Phasellus ut
|
||||||
|
feugiat justo, in commodo turpis. Donec venenatis et urna ut vestibulum.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Nam tristique odio a ultricies suscipit. Cras sollicitudin vulputate euismod. Sed elementum congue
|
||||||
|
tortor, ut pretium lacus dapibus accumsan. Sed eget aliquam tortor. Donec blandit tempor tellus, sit
|
||||||
|
amet pharetra mauris iaculis vel. Quisque pharetra nisi eget orci egestas dignissim. Mauris sed laoreet
|
||||||
|
ligula, vel placerat ante. Curabitur vel libero ornare, suscipit ante sed, feugiat orci. Sed malesuada
|
||||||
|
mattis augue. Sed auctor mattis diam, bibendum pretium arcu tempus quis.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Praesent id finibus purus, sed congue turpis. Maecenas fringilla, nisi non elementum congue, diam nunc
|
||||||
|
vestibulum urna, non elementum quam risus ut tellus. Donec imperdiet, turpis vel elementum sollicitudin,
|
||||||
|
ipsum odio faucibus lectus, quis facilisis urna nibh non ipsum. Sed sed massa sed orci cursus viverra eu
|
||||||
|
quis velit. Donec volutpat pretium erat vitae sodales. Suspendisse posuere nisi at orci rhoncus,
|
||||||
|
fermentum sodales lacus scelerisque. Suspendisse consectetur enim eget faucibus eleifend. Nullam magna
|
||||||
|
eros, elementum id aliquam non, egestas eu nunc. Sed tincidunt scelerisque nibh, id venenatis dolor
|
||||||
|
ultricies vitae. Morbi sapien nisi, tempor ut odio non, varius varius ipsum.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Pellentesque sit amet maximus nibh, et placerat orci. Duis accumsan libero a dolor dignissim viverra.
|
||||||
|
Sed purus nibh, egestas eu nisi at, commodo elementum sem. Nunc id dui a ex condimentum venenatis.
|
||||||
|
Maecenas id mattis nunc. Fusce accumsan nibh nec lacus congue consequat. Donec cursus laoreet leo in
|
||||||
|
egestas. Proin sit amet dui tristique, rhoncus tortor eget, aliquet tellus. Aenean vitae pellentesque
|
||||||
|
ex, in congue odio. Etiam lectus velit, fermentum ultricies consequat eget, pellentesque quis tellus.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Aenean id libero et turpis fringilla elementum. Orci varius natoque penatibus et magnis dis parturient
|
||||||
|
montes, nascetur ridiculus mus. Sed vel ex euismod, dignissim nunc ac, consequat ipsum. Donec et tortor
|
||||||
|
nisi. Nulla tempor turpis nec elit aliquam, id rutrum nulla blandit. Maecenas ullamcorper turpis
|
||||||
|
placerat lectus imperdiet tincidunt. Vestibulum tempor posuere risus tincidunt porttitor. Mauris sit
|
||||||
|
amet hendrerit diam, non porta sem. Proin finibus quam eu metus vulputate, quis vehicula lectus
|
||||||
|
lobortis. Aenean libero felis, ullamcorper sit amet sagittis et, scelerisque et leo. Sed vehicula sem
|
||||||
|
justo, eget pulvinar leo laoreet nec. In hac habitasse platea dictumst.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Donec ac felis sem. Morbi lorem felis, mollis ac elit ut, luctus congue augue. Donec leo purus, accumsan
|
||||||
|
non pulvinar vel, hendrerit vitae diam. Etiam bibendum ut quam vehicula cursus. Mauris tristique
|
||||||
|
volutpat ligula. Ut quis augue sollicitudin, tincidunt nisl ac, egestas turpis. Morbi gravida in nisi
|
||||||
|
non interdum. Nullam pharetra accumsan tellus in laoreet. Mauris auctor auctor odio. Nunc cursus at
|
||||||
|
metus a fermentum. Interdum et malesuada fames ac ante ipsum primis in faucibus.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Mauris hendrerit vel mi non mollis. Morbi nibh felis, convallis non lacinia sed, accumsan in nulla.
|
||||||
|
Fusce non erat in massa venenatis euismod. Fusce justo felis, varius nec dolor vel, lobortis fringilla
|
||||||
|
enim. Pellentesque ac fringilla mi. Aliquam ultrices interdum pellentesque. Vivamus purus mi, porta ut
|
||||||
|
dui malesuada, interdum lobortis leo. Sed in sem in dolor hendrerit posuere ut eget tortor. Duis id
|
||||||
|
dolor vitae risus accumsan tincidunt.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Sed consectetur ornare risus porta rutrum. Sed vel leo at neque rutrum lobortis eu at lorem. Curabitur
|
||||||
|
ultrices congue lacinia. Proin non bibendum augue. Maecenas et volutpat leo, in rutrum neque. In
|
||||||
|
efficitur, purus quis pharetra pretium, nibh metus pharetra metus, vitae euismod mi metus a nibh.
|
||||||
|
Praesent condimentum velit felis, sollicitudin pretium elit lacinia nec. Integer non arcu dignissim,
|
||||||
|
suscipit nunc nec, rutrum tellus. Mauris lobortis, lorem lacinia sagittis tincidunt, mi lacus viverra
|
||||||
|
orci, id ultricies ipsum dui at quam.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Maecenas ornare sagittis vestibulum. Phasellus egestas a tellus sit amet ullamcorper. Sed eu vestibulum
|
||||||
|
sapien. Ut et ipsum augue. Sed tincidunt nibh magna, non accumsan dolor aliquet eu. Cras vitae pharetra
|
||||||
|
elit. Donec pretium dui nec pellentesque vehicula. Cras eu sem elementum mi posuere fringilla. Duis
|
||||||
|
porta, purus a sodales rhoncus, eros eros iaculis turpis, nec ornare magna nisl a ex. Pellentesque
|
||||||
|
dictum eu mi non pretium. Donec pharetra elementum dui. Curabitur et nunc ut nunc euismod aliquet eu
|
||||||
|
quis libero. Quisque sollicitudin metus maximus elit lacinia bibendum a a velit. Sed commodo est at nisl
|
||||||
|
varius, et egestas libero mattis. Vivamus sit amet rutrum turpis, nec vulputate purus. Morbi in feugiat
|
||||||
|
massa.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Pellentesque vel justo congue, scelerisque ex at, vehicula diam. Donec elementum tincidunt nulla, et
|
||||||
|
pharetra ex varius et. Suspendisse iaculis ligula a dolor bibendum, quis eleifend velit tristique. Fusce
|
||||||
|
vitae leo vitae dolor porta lobortis. Pellentesque consectetur sem quis dolor rhoncus volutpat.
|
||||||
|
Pellentesque ullamcorper volutpat condimentum. Cras venenatis elit a vehicula feugiat. Maecenas interdum
|
||||||
|
enim justo, eu tincidunt nibh pharetra at. Cras porta dui ut accumsan aliquam. Nam ut ultricies dolor.
|
||||||
|
Ut in libero vitae nibh accumsan maximus. Duis hendrerit ligula ligula, vehicula ullamcorper purus
|
||||||
|
cursus vel. Mauris efficitur vulputate elit id fermentum. Nam turpis lorem, fermentum et ullamcorper ut,
|
||||||
|
ultrices aliquam felis. Morbi et faucibus justo.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Morbi a nisi nibh. Aenean ut ex ut justo cursus venenatis. Aliquam erat volutpat. Phasellus posuere
|
||||||
|
libero sed enim pretium maximus. Curabitur risus nunc, feugiat nec libero sed, fermentum semper turpis.
|
||||||
|
Pellentesque vestibulum scelerisque ipsum quis porttitor. Proin dapibus tortor sed odio dignissim, a
|
||||||
|
maximus turpis fringilla.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Aenean blandit nulla lorem, sodales rutrum leo dignissim ac. Aliquam ornare nulla mi, eget mollis enim
|
||||||
|
rhoncus eu. Donec quis erat sem. Sed in orci quis lectus interdum efficitur. Fusce non fringilla orci.
|
||||||
|
Pellentesque elementum ut leo at aliquet. Mauris fringilla, nisi in imperdiet consectetur, lorem tellus
|
||||||
|
iaculis eros, quis ullamcorper justo est sit amet felis. In felis justo, mattis nec elit vel, convallis
|
||||||
|
accumsan libero. Nulla facilisi. Suspendisse faucibus, magna a hendrerit tempor, elit elit posuere nibh,
|
||||||
|
non maximus mi enim ac justo. Mauris ut tempor leo. Etiam finibus imperdiet pellentesque. Vestibulum
|
||||||
|
massa arcu, iaculis vitae leo eu, fringilla semper metus. Etiam nunc dolor, consectetur eu justo non,
|
||||||
|
feugiat viverra est. Aliquam tristique molestie purus, quis ultrices est ullamcorper eu. Etiam cursus
|
||||||
|
elit et rhoncus viverra.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Donec et porttitor lacus. Suspendisse venenatis sapien ut ultrices ornare. Quisque dignissim, tortor ut
|
||||||
|
fringilla dignissim, est orci lobortis odio, ac egestas sem odio dapibus lorem. Vestibulum in magna
|
||||||
|
fermentum, laoreet metus sit amet, molestie lacus. Ut quam felis, dignissim non gravida non, vulputate
|
||||||
|
quis sapien. Sed sit amet tellus sem. Fusce eget ligula et enim feugiat vulputate. Duis nec orci id
|
||||||
|
lectus accumsan fermentum vel ac dolor. Aliquam vel accumsan augue, at consequat nibh. Ut vulputate
|
||||||
|
sapien augue, ullamcorper accumsan magna luctus id. In congue et dui sed tempus. Sed et venenatis dui,
|
||||||
|
et viverra sem. Nam elementum, libero sed lobortis pellentesque, nulla dolor tincidunt odio, in
|
||||||
|
ullamcorper orci magna eu nulla.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Etiam vitae pharetra erat. Pellentesque ullamcorper a urna vel gravida. Maecenas dapibus erat sed metus
|
||||||
|
ultrices, venenatis pulvinar felis bibendum. Morbi sollicitudin pretium rhoncus. Proin tempor pretium
|
||||||
|
feugiat. Ut sed ornare eros. Etiam sed ullamcorper justo. Integer tristique ornare lobortis. Aenean et
|
||||||
|
vestibulum sapien. Aliquam non interdum diam. Pellentesque egestas sagittis nibh, eu feugiat leo
|
||||||
|
vestibulum eget. Proin bibendum ligula sapien, ut dapibus turpis sodales sed. Sed vitae nunc feugiat,
|
||||||
|
porta diam non, fringilla arcu. Suspendisse eleifend arcu vitae mi auctor suscipit. Lorem ipsum dolor
|
||||||
|
sit amet, consectetur adipiscing elit. Integer ut odio vel ipsum luctus maximus.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Nunc rhoncus dui nibh, ac pulvinar risus vulputate in. Quisque gravida convallis ultricies. In vitae
|
||||||
|
felis dolor. Aenean congue vitae libero ac mattis. Quisque tincidunt arcu id mi bibendum, non viverra mi
|
||||||
|
vulputate. Sed mollis commodo elementum. Vivamus iaculis urna at ante tempor, eu aliquet elit bibendum.
|
||||||
|
Praesent feugiat lacinia dolor, sit amet semper enim auctor nec.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Vivamus tincidunt turpis id nulla maximus commodo. Nullam a ligula ut risus congue tempus in et ipsum.
|
||||||
|
Fusce dapibus a elit vitae sagittis. Nam metus quam, pretium a tortor eu, molestie hendrerit lacus. Cras
|
||||||
|
volutpat lacinia sem, non volutpat tellus pretium sagittis. Morbi a viverra diam, vel feugiat nisi. Orci
|
||||||
|
varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras varius nibh ut
|
||||||
|
tempor ullamcorper. Cras convallis, massa sit amet mollis laoreet, elit erat scelerisque arcu, ac
|
||||||
|
bibendum augue dolor vel nunc. Aliquam sit amet orci nec dui venenatis imperdiet.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Nulla facilisi. Aliquam vehicula velit in aliquam auctor. Cras ut nibh diam. Donec vitae vulputate
|
||||||
|
lacus. Suspendisse potenti. Morbi quis leo quis sapien sagittis finibus in id purus. Sed congue
|
||||||
|
fringilla purus, vel finibus leo aliquet eu. Cras volutpat sapien imperdiet erat consectetur interdum.
|
||||||
|
Nam eu pretium diam, quis mattis lacus.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Donec sed ligula nunc. Donec fermentum tempor diam, malesuada cursus ante iaculis at. Aliquam sodales
|
||||||
|
lectus in lorem molestie commodo. Ut aliquet faucibus commodo. Curabitur ut nisi sit amet orci molestie
|
||||||
|
ultrices at ac diam. Morbi nec tellus nec enim lobortis faucibus quis non tellus. Nulla varius ligula in
|
||||||
|
dolor fringilla vulputate. Phasellus sed finibus justo, nec faucibus ipsum. Cras at tempor mi. Donec
|
||||||
|
ipsum ligula, ultrices in suscipit non, cursus vel est. In vitae neque condimentum, euismod nunc at,
|
||||||
|
pulvinar est. Donec rhoncus luctus ornare.
|
||||||
|
</p>
|
||||||
|
</content>
|
||||||
|
<script>
|
||||||
|
const frameEl = document.getElementById('frame');
|
||||||
|
frameEl.addEventListener('load', function () {
|
||||||
|
|
||||||
|
const caseEls = document.getElementsByClassName('section');
|
||||||
|
for (let caseEl of caseEls) {
|
||||||
|
console.log(caseEl.dataset.title);
|
||||||
|
const toSelect = typeof caseEl.dataset.title == 'undefined' ? null : frameEl.contentWindow.getIdForTitle(caseEl.dataset.title);
|
||||||
|
// navItemEl.hash url-encodes
|
||||||
|
// let targetEl = document.getElementById(navItemEl.attributes.href.value.substr(1));
|
||||||
|
// let wrapperEl = targetEl.parentNode;
|
||||||
|
let intersectionObserver = new IntersectionObserver(function (entries) {
|
||||||
|
console.log(entries);
|
||||||
|
// If intersectionRatio is 0, the target is out of view
|
||||||
|
// and we do not need to do anything.
|
||||||
|
if (entries[0].intersectionRatio <= 0) {
|
||||||
|
// navItemEl.classList.remove('active');
|
||||||
|
} else {
|
||||||
|
if(toSelect === null) {
|
||||||
|
frameEl.contentWindow.mapGraph.deselectNode();
|
||||||
|
frameEl.contentWindow.mapGraph.resetZoom();
|
||||||
|
} else {
|
||||||
|
const node = frameEl.contentWindow.mapGraph.graph.nodes.filter(n => n.id == toSelect)[0]
|
||||||
|
frameEl.contentWindow.mapGraph.selectNode(node);
|
||||||
|
}
|
||||||
|
// navItemEl.classList.add('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
// start observing
|
||||||
|
intersectionObserver.observe(caseEl);
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
// frame.contentWindow;
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
309
www/world_test.html
Normal file
309
www/world_test.html
Normal file
|
@ -0,0 +1,309 @@
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body{
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<script src="https://d3js.org/d3.v6.min.js"></script>
|
||||||
|
<script src="https://d3js.org/topojson.v3.min.js"></script>
|
||||||
|
<script src="//unpkg.com/d3-geo-zoom"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
// see also: http://bl.ocks.org/dwtkns/4973620
|
||||||
|
var width = window.innerWidth;
|
||||||
|
var height = window.innerHeight;
|
||||||
|
|
||||||
|
const eu_countries = ['Austria', 'Italy', 'Belgium', 'Latvia', 'Bulgaria', 'Lithuania', 'Croatia', 'Luxembourg', 'Cyprus', 'Malta', 'Czechia', 'Netherlands', 'Denmark', 'Poland', 'Estonia ', 'Portugal', 'Finland ', 'Romania', 'France', 'Slovakia', 'Germany', 'Slovenia', 'Greece', 'Spain', 'Hungary', 'Sweden', 'Ireland'];
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
'max_y_rotation' : 55,
|
||||||
|
}
|
||||||
|
|
||||||
|
var graph = {
|
||||||
|
nodes: [
|
||||||
|
{ id: "New York", lat: 40.706109, lon: -74.01194 },
|
||||||
|
{ id: "London", lat: 51.508070, lon: -0.126432 },
|
||||||
|
{ id: "Montevideo", lat: -34.901776, lon: -56.163983 },
|
||||||
|
{ id: "London-NewYork1" },
|
||||||
|
{ id: "London-NewYork2" },
|
||||||
|
{ id: "London-NewYork3" },
|
||||||
|
{ id: "Montevideo-London" }
|
||||||
|
],
|
||||||
|
links: [
|
||||||
|
{ source: "New York", target: "London-NewYork1" },
|
||||||
|
{ source: "New York", target: "London-NewYork2" },
|
||||||
|
{ source: "New York", target: "London-NewYork3" },
|
||||||
|
{ source: "London-NewYork1", target: "London" },
|
||||||
|
{ source: "London-NewYork2", target: "London" },
|
||||||
|
{ source: "London-NewYork3", target: "London" },
|
||||||
|
{ source: "London", target: "Montevideo-London" },
|
||||||
|
{ source: "Montevideo-London", target: "Montevideo" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const force = d3.forceSimulation()
|
||||||
|
.force("link", d3.forceLink()
|
||||||
|
.id(function (d) {
|
||||||
|
return d.id;
|
||||||
|
})
|
||||||
|
.distance(10))
|
||||||
|
.force("charge", d3.forceManyBody().strength(-200));
|
||||||
|
|
||||||
|
|
||||||
|
const svg = d3.select("body")
|
||||||
|
.append("svg")
|
||||||
|
.attr("width", width)
|
||||||
|
.attr("height", height);
|
||||||
|
|
||||||
|
const container = svg.append("g").attr("id", "container");
|
||||||
|
|
||||||
|
const projection = d3.geoOrthographic()
|
||||||
|
.center([0, 0])
|
||||||
|
.translate([width / 2, height / 2])
|
||||||
|
.rotate([ -12, -52, 0])
|
||||||
|
.clipAngle(90)
|
||||||
|
.scale(height*1.5);
|
||||||
|
|
||||||
|
const proj = d3.geoPath().projection(projection);
|
||||||
|
const graticule = d3.geoGraticule10();
|
||||||
|
|
||||||
|
const g_countries = container.append("g").attr("id", "countries");
|
||||||
|
const g_borders = container.append("g").attr("id", "borders");
|
||||||
|
container.append("g")
|
||||||
|
.append('path')
|
||||||
|
.attr("class", "graticule")
|
||||||
|
.attr('d', proj(graticule))
|
||||||
|
.attr("fill", "none")
|
||||||
|
.attr("stroke-width", "!px")
|
||||||
|
.attr("stroke", (n) => {
|
||||||
|
return "lightgray";
|
||||||
|
});
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
d3.json("https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json").then(function (world) {
|
||||||
|
// land = topojson.feature(world, world.objects.land)
|
||||||
|
const borders = topojson.mesh(world, world.objects.countries, (a, b) => a !== b)
|
||||||
|
console.log(borders);
|
||||||
|
const countries = topojson.feature(world, world.objects.countries).features;
|
||||||
|
// console.log(topojson.feature(world, world.objects.countries).features);
|
||||||
|
g_countries.selectAll("path")
|
||||||
|
.data(countries)
|
||||||
|
.enter()
|
||||||
|
.append("path")
|
||||||
|
.attr("class", "countries")
|
||||||
|
.attr("d", proj)
|
||||||
|
.attr("fill", (n) => {
|
||||||
|
if(eu_countries.indexOf(n.properties.name) !== -1) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return "lightgray";
|
||||||
|
});
|
||||||
|
|
||||||
|
g_borders//.selectAll("path")
|
||||||
|
// .data(borders)
|
||||||
|
// .enter()
|
||||||
|
.append("path")
|
||||||
|
.attr("class", "borders")
|
||||||
|
.attr("d", proj(borders))
|
||||||
|
.attr("fill", "none")
|
||||||
|
.attr("stroke-width", "2px")
|
||||||
|
.attr("stroke", (n) => {
|
||||||
|
return "white";
|
||||||
|
});
|
||||||
|
|
||||||
|
const links = container.append('g')
|
||||||
|
.attr("id", "links")
|
||||||
|
.selectAll("line")
|
||||||
|
.data(graph.links)
|
||||||
|
.enter()
|
||||||
|
.append("line")
|
||||||
|
.attr("stroke-width", 2)
|
||||||
|
.attr("stroke", "black");
|
||||||
|
|
||||||
|
|
||||||
|
const nodes = container.append('g')
|
||||||
|
.attr("id", "nodes")
|
||||||
|
.selectAll("circle")
|
||||||
|
.data(graph.nodes)
|
||||||
|
.enter()
|
||||||
|
.append("circle")
|
||||||
|
.attr('r', 5)
|
||||||
|
.call(d3.drag()
|
||||||
|
.on("start", dragInicia)
|
||||||
|
.on("drag", dragging)
|
||||||
|
.on("end", dragTermina));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
force.nodes(graph.nodes);
|
||||||
|
force.force("link").links(graph.links);
|
||||||
|
|
||||||
|
graph.nodes.forEach(function (d) {
|
||||||
|
if (d.lon && d.lat) {
|
||||||
|
var p = projection([d.lon, d.lat]);
|
||||||
|
d.fx = p[0];
|
||||||
|
d.fy = p[1];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//simulación y actualizacion de la posicion de los nodos en cada "tick"
|
||||||
|
force.on("tick", function () {
|
||||||
|
links
|
||||||
|
.attr('x1', function (d) {
|
||||||
|
return d.source.x;
|
||||||
|
})
|
||||||
|
.attr('y1', function (d) {
|
||||||
|
return d.source.y;
|
||||||
|
})
|
||||||
|
.attr('x2', function (d) {
|
||||||
|
return d.target.x;
|
||||||
|
})
|
||||||
|
.attr('y2', function (d) {
|
||||||
|
return d.target.y;
|
||||||
|
})
|
||||||
|
;
|
||||||
|
|
||||||
|
nodes
|
||||||
|
.attr('cx', function (d) {
|
||||||
|
return d.x;
|
||||||
|
})
|
||||||
|
.attr('cy', function (d) {
|
||||||
|
return d.y;
|
||||||
|
})
|
||||||
|
;
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
function dragInicia(d) {
|
||||||
|
if (!d.lon || !d.lat) {
|
||||||
|
if (!d3.event.active) force.alphaTarget(0.3).restart();
|
||||||
|
d.fx = d.x;
|
||||||
|
d.fy = d.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragging(d) {
|
||||||
|
if (!d.lon || !d.lat) {
|
||||||
|
d.fx = d3.event.x;
|
||||||
|
d.fy = d3.event.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragTermina(d) {
|
||||||
|
if (!d.lon || !d.lat) {
|
||||||
|
if (!d3.event.active) force.alphaTarget(0);
|
||||||
|
d.fx = null;
|
||||||
|
d.fy = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function refresh() {
|
||||||
|
container.selectAll(".countries").attr("d", proj);
|
||||||
|
container.selectAll(".graticule").attr("d", proj(graticule));
|
||||||
|
container.selectAll(".borders").attr("d", proj(borders));
|
||||||
|
|
||||||
|
// console.log(graph.nodes);
|
||||||
|
force.alpha = 0;
|
||||||
|
force.restart();
|
||||||
|
graph.nodes.forEach(function (d) {
|
||||||
|
if (d.lon && d.lat) {
|
||||||
|
var p = projection([d.lon, d.lat]);
|
||||||
|
d.fx = p[0];
|
||||||
|
d.fy = p[1];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// svg.call(d3.zoom().extent([[0,0],[1,1]]).scaleExtent([0.3, 6]).on("start", function () {
|
||||||
|
// // svg.node().classList.add("dragging");
|
||||||
|
// }).on("end", function () {
|
||||||
|
// // svg.node().classList.remove("dragging");
|
||||||
|
// }).on("zoom", function ({ transform }) {
|
||||||
|
// // container.attr("transform", transform);
|
||||||
|
// o = [transform.x/6, -transform.y/6];
|
||||||
|
// o[1] = o[1] > config.max_y_rotation ? config.max_y_rotation :
|
||||||
|
// o[1] < -config.max_y_rotation ? -config.max_y_rotation :
|
||||||
|
// o[1];
|
||||||
|
// projection .rotate(o).scale(window.innerHeight*1.5*transform.k)
|
||||||
|
|
||||||
|
// refresh();
|
||||||
|
// // container.attr("transform", "scale(" + transform.k + ")");
|
||||||
|
// }));
|
||||||
|
|
||||||
|
|
||||||
|
// svg.on("wheel.zoom", (e) => {
|
||||||
|
|
||||||
|
// }, {passive: false})
|
||||||
|
|
||||||
|
d3.geoZoom()
|
||||||
|
.northUp(true)
|
||||||
|
.projection(projection)
|
||||||
|
.scaleExtent([.3, 6])
|
||||||
|
.onMove(refresh)(svg.node());
|
||||||
|
// (<mapDomNode>);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// d3.select('svg').call(d3.drag()
|
||||||
|
// .on("start", mousedown)
|
||||||
|
// .on("drag", mousemove)
|
||||||
|
// .on("end", mouseup));
|
||||||
|
// var m0, o0;
|
||||||
|
// function mousedown(e) {
|
||||||
|
// m0 = [d3.event.x, d3.event.y];
|
||||||
|
// o0 = projection.rotate();
|
||||||
|
// console.log(e, d3.event, m0,o0);
|
||||||
|
// // d3.event.preventDefault();
|
||||||
|
// }
|
||||||
|
// function mousemove() {
|
||||||
|
// if (m0) {
|
||||||
|
// var m1 = [d3.event.x, d3.event.y]
|
||||||
|
// , o1 = [o0[0] + (m1[0] - m0[0]) / 6, o0[1] + (m0[1] - m1[1]) / 6];
|
||||||
|
// o1[1] = o1[1] > config.max_y_rotation ? config.max_y_rotation :
|
||||||
|
// o1[1] < -config.max_y_rotation ? -config.max_y_rotation :
|
||||||
|
// o1[1];
|
||||||
|
// projection.rotate(o1);
|
||||||
|
// // sky.rotate(o1);
|
||||||
|
// refresh();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// function mouseup() {
|
||||||
|
// if (m0) {
|
||||||
|
// mousemove();
|
||||||
|
// m0 = null;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
function resize(){
|
||||||
|
width = window.innerWidth;
|
||||||
|
height = window.innerHeight;
|
||||||
|
|
||||||
|
d3.selectAll('svg')
|
||||||
|
.attr("width", width)
|
||||||
|
.attr("height", height);
|
||||||
|
projection.translate([width / 2, height / 2]);
|
||||||
|
projection.scale(height*1.5);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
window.addEventListener('resize', resize);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in a new issue