Compare commits

...

4 Commits

Author SHA1 Message Date
fcefe8a9ad
Update main config and content files 2022-01-31 23:45:28 -05:00
5ed61b06fa
Add web resource minification 2022-01-31 23:45:08 -05:00
5ab9ad02de
Reorganize http resources and build logic 2022-01-31 23:01:07 -05:00
691f92d90d
Cleanup project meta
Add makefile clean target
Update gitignore
Remove unused site static resources
2022-01-31 22:57:49 -05:00
29 changed files with 1396 additions and 805 deletions

3
.gitignore vendored
View File

@ -1,3 +1,4 @@
export/
publish/
.venv/
*.conf
__pycache__

View File

@ -1,3 +1,3 @@
clean:
rm --recursive --force export
rm --recursive --force publish
rm --force nginx.conf

490
build.py
View File

@ -1,98 +1,132 @@
import argparse
import datetime
import hashlib
import shutil
import sys
import uuid
from dataclasses import dataclass
from pathlib import Path
from typing import Any
from typing import Dict
from typing import List
from typing import NamedTuple
from typing import Optional
from typing import Sequence
from typing import Tuple
from typing import Union
import jinja2
import jsmin
import marshmallow as msh
import minify_html
import ruamel.yaml
yaml = ruamel.yaml.YAML(typ="safe")
@dataclass
class MediaContainer:
title: str
source: str
preview: Optional[str] = None
anchor: Optional[Union[str, int]] = None
content: Optional[str] = None
hide_source: bool = False
def multi_replace(source: str, replacements: Sequence[Tuple[str, str]]) -> str:
for old, new in replacements:
replaced = source.replace(old, new)
return replaced
class MediaSerializer(msh.Schema):
title = msh.fields.String(required=True)
source = msh.fields.String(required=True)
preview = msh.fields.String(required=False)
anchor = msh.fields.String(required=False)
content = msh.fields.String(required=False)
hide_source = msh.fields.Boolean(required=False)
class PathField(msh.fields.String):
def _deserialize(self, value, *args, **kwargs):
return Path(value).expanduser().resolve()
class BaseSchema(msh.Schema):
@msh.post_load
def _make_dataclass(self, data: Dict[str, Any], *args, **kwargs):
return self.Container(**data)
class MediaSerializer(BaseSchema):
@dataclass
class Container:
title: str
link: str
anchor: str
content: Optional[str]
def preload_url(self, config) -> str:
if config.build.kodak:
return f"{config.build.kodak.baseurl}image/{self.link}/{config.build.kodak.preload}.jpeg"
return self.link
def asset_url(self, config) -> str:
if config.build.kodak:
return f"{config.build.kodak.baseurl}image/{self.link}/{config.build.kodak.asset}.jpeg"
return self.link
def source_url(self, config) -> str:
if config.build.kodak:
return f"{config.build.kodak.baseurl}image/{self.link}/original"
return self.link
title = msh.fields.String()
link = msh.fields.String()
anchor = msh.fields.String(allow_none=True, missing=None)
content = msh.fields.String(allow_none=True, missing=None)
@msh.post_load
def _make_dataclass(self, data: Dict[str, Any], *args, **kwargs) -> MediaContainer:
return MediaContainer(**data)
def _make_default_anchor(self, data, **kwargs):
if not data.anchor:
data.anchor = multi_replace(
data.title, [(" ", "-"), ("?", ""), ("!", ""), (".", ""), (":", "")]
)
return data
@dataclass
class LinkContainer:
link: str
title: Optional[str] = None
icon: Optional[str] = None
class LinkSerializer(BaseSchema):
@dataclass
class Container:
title: Optional[str]
url: str
icon: str
url = msh.fields.URL()
title = msh.fields.String(allow_none=True, missing=None)
icon = msh.fields.String(missing="fas fa-external-link-square-alt")
class LinkSerializer(msh.Schema):
link = msh.fields.URL(required=True)
title = msh.fields.String(required=False)
icon = msh.fields.String(required=False)
class LocationSeralizer(BaseSchema):
class Container(NamedTuple):
title: str
link: str
@msh.post_load
def _make_dataclass(self, data: Dict[str, Any], *args, **kwargs) -> LinkContainer:
return LinkContainer(**data)
title = msh.fields.String()
link = msh.fields.URL()
class Location(NamedTuple):
title: str
link: str
class PostSerializer(BaseSchema):
@dataclass
class Container:
title: str
description: Optional[str]
location: LocationSeralizer.Container
date: datetime.date
banner: Optional[str]
slug: str
links: Sequence[LinkSerializer.Container]
media: Sequence[MediaSerializer.Container]
def banner_url(self, config) -> str:
if config.build.kodak:
return f"{config.build.kodak.baseurl}image/{self.banner}/{config.build.kodak.banner}.jpeg"
return self.banner
class LocationSeralizer(msh.Schema):
title = msh.fields.String(required=True)
link = msh.fields.URL(required=True)
@msh.post_load
def _make_dataclass(self, data: Dict[str, Any], *args, **kwargs) -> Location:
return Location(**data)
@dataclass
class PostContainer:
title: str
location: Location
date: datetime.date
banner: str
media: Sequence[MediaContainer]
links: Sequence[LinkContainer] = ()
slug: Optional[str] = None
class PostSerializer(msh.Schema):
title = msh.fields.String(required=True)
location = msh.fields.Nested(LocationSeralizer, required=True)
date = msh.fields.Date("%Y-%m-%d", required=True)
banner = msh.fields.URL(required=True)
slug = msh.fields.String(required=False)
links = msh.fields.List(msh.fields.Nested(LinkSerializer), required=False)
media = msh.fields.List(msh.fields.Nested(MediaSerializer), required=True)
title = msh.fields.String()
description = msh.fields.String(missing=None, allow_none=True)
location = msh.fields.Nested(LocationSeralizer)
date = msh.fields.Raw()
banner = msh.fields.String(missing=None, allow_none=True)
slug = msh.fields.String(
validate=msh.validate.Regexp(r"^[a-z0-9][a-z0-9\-]+[a-z0-9]$")
)
links = msh.fields.List(msh.fields.Nested(LinkSerializer), missing=list())
media = msh.fields.List(msh.fields.Nested(MediaSerializer), missing=list())
@msh.validates_schema
def _unique_anchors(self, data: Dict[str, Any], **kwargs):
@ -102,87 +136,313 @@ class PostSerializer(msh.Schema):
f"Media anchors used multiple times: {set([item for item in anchors if anchors.count(item) > 1])}"
)
@msh.post_load
def _make_dataclass(self, data: Dict[str, Any], *args, **kwargs) -> PostContainer:
for index, item in enumerate(data["media"]):
item.anchor = item.anchor or index
data["media"][index] = item
return PostContainer(**data)
class ConfigBuildKodakSerializer(BaseSchema):
@dataclass
class Container:
baseurl: str
link_original: bool
asset: str
banner: str
preload: str
baseurl = msh.fields.URL()
link_original = msh.fields.Boolean(missing=False)
asset = msh.fields.String()
banner = msh.fields.String()
preload = msh.fields.String()
class ConfigSerializer(msh.Schema):
static = msh.fields.List(msh.fields.String(), required=False)
posts = msh.fields.List(msh.fields.Nested(PostSerializer), required=True)
class ConfigBuildSerializer(BaseSchema):
@dataclass
class Container:
generated: Path
posts: Path
static: Path
bundle: Path
templates: Path
post_base: str
kodak: ConfigBuildKodakSerializer.Container
@msh.validates_schema
def _unique_slugs(self, data: Dict[str, Any], **kwargs):
slugs = [item.slug for item in data["posts"] if item.slug is not None]
if len(slugs) != len(set(slugs)):
raise msh.ValidationError(
f"Post slugs used multiple times: {set([item for item in slugs if slugs.count(item) > 1])}"
generated = PathField(missing=Path("publish"))
posts = PathField(missing=Path("posts"))
static = PathField(missing=Path("static"))
bundle = PathField(missing=Path("bundle"))
templates = PathField(missing=Path("templates"))
post_base = msh.fields.String(
missing="explore", validate=msh.validate.Regexp(r"[a-z0-9\-]+")
)
kodak = msh.fields.Nested(ConfigBuildKodakSerializer, missing=None)
class ConfigSerializer(BaseSchema):
@dataclass
class Container:
domain: str
https: bool
baseurl: str
title: str
email: str
description: str
keywords: Sequence[str]
social: Dict[str, str]
build: ConfigBuildSerializer.Container
@property
def url(self) -> str:
return f"http{'s' if self.https else ''}://{self.domain}{self.baseurl}"
domain = msh.fields.String()
https = msh.fields.Boolean(missing=True)
baseurl = msh.fields.String()
title = msh.fields.String()
email = msh.fields.Email()
description = msh.fields.String()
keywords = msh.fields.List(
msh.fields.String(validate=msh.validate.Regexp(r"^[a-z0-9]+$"))
)
social = msh.fields.Dict(
keys=msh.fields.String(
validate=msh.validate.OneOf(
["instagram", "facebook", "twitter", "mastodon", "patreon"]
)
@msh.post_load
def _remove_future(self, data: Dict[str, Any], *args, **kwargs) -> PostContainer:
posts = [item for item in data["posts"] if item.date <= datetime.date.today()]
data["posts"] = posts
return data
),
values=msh.fields.Url(),
missing=dict(),
)
build = msh.fields.Nested(ConfigBuildSerializer)
def get_args() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument(
"--config", help="Path to the config file", default=(Path.cwd() / "config.yaml")
"-c",
"--config",
help="Path to the config file",
default=(Path.cwd() / "config.yaml"),
)
parser.add_argument(
"-c", "--check", action="store_true", help="Check the config without building"
"--check", action="store_true", help="Check the config without building"
)
parser.add_argument(
"--dev",
action="store_true",
help="Run local development server",
)
return parser.parse_args()
def _hash_from_file(path: Union[str, Path]):
"""Construct from a file path, generating the hash of the file
.. note:: This method attempts to _efficiently_ compute a hash of large image files. The
hashing code was adapted from here:
https://stackoverflow.com/a/44873382/5361209
"""
hasher = hashlib.sha256()
view = memoryview(bytearray(1024 * 1024))
with Path(path).open("rb", buffering=0) as infile:
for chunk in iter(lambda: infile.readinto(view), 0): # type: ignore
hasher.update(view[:chunk])
return hasher
def _copy_resource(path: Path, dest_dir: Path):
if path.is_file():
dest_dir.mkdir(parents=True, exist_ok=True)
shutil.copyfile(path, dest_dir / path.name, follow_symlinks=True)
elif path.is_dir():
for item in path.iterdir():
_copy_resource(item, dest_dir / path.name)
def _write_template(env: jinja2.Environment, name: str, dest: Path, **kwargs):
dest.parent.mkdir(exist_ok=True)
template = env.get_template(name).render(**kwargs)
minified = minify_html.minify(template, keep_comments=False)
with dest.open("w") as outfile:
outfile.write(minified)
def _build_bundle(
config: ConfigSerializer.Container, ftype: str, dest: str, sources: List[str]
) -> str:
(config.build.generated / ftype.lower()).mkdir(exist_ok=True, parents=True)
working_path = (
config.build.generated / ftype.lower() / f"{uuid.uuid4().hex}.{ftype.lower()}"
)
content: List[str] = []
for source in sources:
try:
with (
config.build.bundle / ftype.lower() / f"{source}.{ftype.lower()}"
).open("r") as infile:
content.append(infile.read())
except FileNotFoundError as err:
raise ValueError(
f"No {ftype.upper()} source file to bundle named '{source}'"
) from err
if ftype.lower() == "js":
minified = jsmin.jsmin("\n\n".join(content))
else:
minified = minify_html.minify("\n\n".join(content), keep_comments=False)
hasher = hashlib.sha256()
hasher.update(minified.encode("utf-8"))
slug = f"{dest}-{hasher.hexdigest()[:8]}"
final_path = config.build.generated / ftype.lower() / f"{slug}.{ftype.lower()}"
with final_path.open("w") as outfile:
outfile.write(minified)
return slug
def _dev(
cwd: Path,
config: ConfigSerializer.Container,
posts: Sequence[PostSerializer.Container],
):
config.https = False
config.domain = "localhost:5000"
config.base_url = "/"
# server = http.server.HTTPServer(
# ("127.0.0.1", 5000),
# functools.partial(
# http.server.SimpleHTTPRequestHandler, directory=str(cwd / config.build.generated)
# ),
# )
_build(cwd, config, posts)
# print(f"Serving dev site at {config.url}, press Ctrl+C to exit", file=sys.stderr)
# try:
# server.serve_forever()
# except KeyboardInterrupt:
# print("Stopping...", file=sys.stderr)
# server.shutdown()
def _build(
cwd: Path,
config: ConfigSerializer.Container,
posts: Sequence[PostSerializer.Container],
):
print(
f"Rebuilding static assets into {cwd / config.build.generated}", file=sys.stderr
)
env = jinja2.Environment(
loader=jinja2.FileSystemLoader(str(cwd / config.build.templates)),
autoescape=jinja2.select_autoescape(["html", "xml"]),
)
output = cwd / config.build.generated
static = cwd / config.build.static
today = datetime.datetime.utcnow()
bundle_slug = uuid.uuid4().hex[:8]
index_css_bundle = _build_bundle(config, "css", "index", ["common", "home"])
index_js_bundle = _build_bundle(
config, "js", "index", ["random-background", "preloader"]
)
_write_template(
env,
"index.html.j2",
output / "index.html",
config=config,
today=today,
css_bundle=index_css_bundle,
js_bundle=index_js_bundle,
)
_write_template(
env, "sitemap.xml.j2", output / "sitemap.xml", config=config, today=today
)
_write_template(
env,
"robots.txt.j2",
output / "robots.txt",
config=config,
today=today,
disallowed=[item.name for item in static.iterdir() if item.is_dir()],
)
static = cwd / config.build.static
if static.exists():
for item in static.iterdir():
_copy_resource(item, output)
explore_css_bundle = _build_bundle(config, "css", "explore", ["common", "explore"])
explore_js_bundle = _build_bundle(
config,
"js",
"explore",
["random-background", "preloader", "toggle-article-text-button"],
)
_write_template(
env,
"explore.html.j2",
output / config.build.post_base / "index.html",
config=config,
today=today,
posts=posts,
css_bundle=explore_css_bundle,
js_bundle=explore_js_bundle,
)
post_css_bundle = _build_bundle(config, "css", "post", ["common"])
post_js_bundle = _build_bundle(config, "js", "post", ["preloader"])
for post in posts:
_write_template(
env,
"post.html.j2",
output / config.build.post_base / post.slug / "index.html",
config=config,
today=today,
post=post,
css_bundle=post_css_bundle,
js_bundle=post_js_bundle,
)
def main():
args = get_args()
cwd = Path.cwd().resolve()
output = cwd / "export"
explore = output / "explore"
with Path(args.config).resolve().open() as infile:
with Path(args.config).resolve().open(encoding="utf-8") as infile:
config = ConfigSerializer().load(yaml.load(infile))
posts = []
post_serializer = PostSerializer()
for item in (cwd / config.build.posts).iterdir():
if item.suffix.lower() == ".yaml":
with item.open() as infile:
raw = yaml.load(infile)
raw["slug"] = raw.get("slug", item.stem)
posts.append(post_serializer.load(raw))
slugs = [post.slug for post in posts]
if len(set(slugs)) != len(slugs):
raise msh.ValidationError("Duplicate post slugs found in config")
if args.check:
print("Config check successful!", file=sys.stderr)
return 0
env = jinja2.Environment(
loader=jinja2.FileSystemLoader(str(cwd / "templates")),
autoescape=jinja2.select_autoescape(["html", "xml"]),
)
posts = sorted(posts, key=lambda item: item.date, reverse=True)
output.mkdir(exist_ok=True)
explore.mkdir(exist_ok=True)
if args.dev:
_dev(cwd, config, posts)
else:
_build(cwd, config, posts)
index = env.get_template("index.html.j2").render(config=config)
with (explore / "index.html").open("w") as outfile:
outfile.write(index)
sitemap = env.get_template("sitemap.xml.j2").render(config=config)
with (output / "sitemap.xml").open("w") as outfile:
outfile.write(sitemap)
for static in config["static"]:
dest = Path(output / static).resolve()
dest.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(static, str(output / static), follow_symlinks=True)
post_template = env.get_template("post.html.j2")
for post_data in config["posts"]:
post = post_template.render(post=post_data)
with (explore / f"{post_data.slug}.html").open("w") as outfile:
outfile.write(post)
nginx = env.get_template("nginx.conf.d.j2").render(config=config)
with (cwd / "nginx.conf").open("w") as outfile:
outfile.write(nginx)
return 0
if __name__ == "__main__":

View File

@ -5,19 +5,13 @@ html {
font-family: Verdana, Helvetica, sans-serif;
}
a {
color: inherit;
text-decoration: none;
transition: all 0.1s ease-in-out;
}
a:hover {
text-decoration: none;
text-shadow: 5px 5px 10px #fff, -5px -5px 10px #fff;
body {
color: white;
font-family: sans-serif;
}
#background-image {
background-image: url("https://cdn.enp.one/img/backgrounds/cl-photo-allis.jpg");
background-image: url("https://cdn.enp.one/img/backgrounds/cl-photo-rt112.jpg");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
@ -38,136 +32,13 @@ a:hover {
z-index: 0;
}
#content {
text-align: center;
text-shadow: 3px 3px 5px #000, -3px -3px 5px #000;
font-weight: bold;
color: white;
padding: 1em;
width: 40em;
max-width: 90%;
background-color: rgba(0, 0, 0, 0.4);
border-style: solid;
border-width: 2px;
border-color: rgba(0, 0, 0, 0);
border-radius: 128px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.6), 0 6px 20px 0 rgba(0, 0, 0, 0.6);
position: absolute;
top: 15%;
left: 50%;
transform: translate(-50%, 0);
z-index: 10;
}
#logo {
margin: auto;
margin-top: -5em;
max-width: 60%;
width: 50%;
display: block;
border-style: solid;
border-color: rgba(0, 0, 0, 0.2);
border-radius: 50%;
border-width: 5px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4), 0 6px 20px 0 rgba(0, 0, 0, 0.4);
}
h1 {
font-variant: small-caps;
font-size: 2.5em;
}
#content p {
margin: 2em;
line-height: 1.5;
}
ul.buttons {
list-style: none;
padding-left: 0;
margin-top: 1em;
margin-bottom: 1em;
font-size: 1.75em;
}
ul.buttons li {
line-height: 1;
padding: 0.5em;
margin-left: 0.5em;
margin-right: 0.5em;
text-transform: uppercase;
}
.button.nav {
padding-top: 0.75em;
padding-bottom: 0.55em;
padding-left: 1.5em;
padding-right: 1.5em;
border-radius: 30px;
transition: all 0.25s ease-in-out;
}
.button:hover {
text-shadow:
-3px -3px 5px #fff,
-3px 3px 5px #fff,
3px -3px 5px #fff,
3px 3px 5px #fff,
0px 0px 7px #ff0000;
}
.button.nav:hover {
text-shadow:
0px 0px 7px #000,
-5px -5px 10px #fff,
-5px 5px 10px #fff,
5px -5px 10px #fff,
5px 5px 10px #fff;
-webkit-animation-name: pulse;
-webkit-animation-duration: 5s;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
-webkit-animation-fill-mode: none;
animation-name: pulse;
animation-duration: 5s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-fill-mode: none;
}
.explore:hover { color: #5588e0; }
.youtube:hover { color: #ff0000; }
.instagram:hover { color: #c13584; }
.twitter:hover { color: #1da1f2; }
#background-info {
text-align: right;
font-size: 0.85em;
padding: 0.75em;
#background-image .overlay {
background-color: rgba(0, 0, 0, 0.8);
width: 100%;
height: 100%;
position: fixed;
bottom: 0;
right: 0;
z-index: 5;
}
footer { font-size: 0.9em; }
footer div { margin-bottom: 0.5em; }
footer a.button i {
padding: 0.5em;
font-size: 1.25em;
top: 0;
left: 0;
}
.fadeout {
@ -227,49 +98,6 @@ footer a.button i {
100% {opacity: 0;}
}
@keyframes pulse {
0% {
box-shadow:
0px 0px 15px 3px #fff,
0px 0px 15px 3px #88a9fc;
}
10% {
box-shadow:
-10px -10px 15px 3px #fff,
10px 10px 15px 3px #88a9fc;
}
30% {
box-shadow:
-10px 10px 15px 3px #b5f7fc,
10px -10px 15px 3px #fcaa99;
}
45% {
box-shadow:
10px 10px 15px 3px #ecf9a7,
-10px -10px 15px 3px #fcaa99;
}
60% {
box-shadow:
10px -10px 15px 3px #ecf9a7,
-10px 10px 15px 3px #abfcad;
}
75% {
box-shadow:
-10px -10px 15px 3px #b5f7fc,
10px 10px 15px 3px #abfcad;
}
90% {
box-shadow:
-10px 10px 15px 3px #fff,
10px -10px 15px 3px #88a9fc;
}
100% {
box-shadow:
0px 0px 15px 3px #b5f7fc,
0px 0px 15px 3px #88a9fc;
}
}
@-webkit-keyframes spinner {
0% { transform: translate(-50%,-50%) rotate(0deg); }
100% { transform: translate(-50%,-50%) rotate(360deg); }
@ -280,25 +108,67 @@ footer a.button i {
100% { transform: translate(-50%,-50%) rotate(360deg); }
}
@media only screen and (max-width: 600px) {
#content {
padding: 0;
padding-bottom: 1em;
border-radius: 32px;
top: 6em;
}
#content p {
margin: 1em;
}
ul.buttons {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
ul.buttons li {
display: block;
margin-top: 1em;
}
a {
color: inherit;
text-decoration: none;
transition: all 0.1s ease-in-out;
}
a:hover {
text-decoration: none;
text-shadow: 5px 5px 10px #fff, -5px -5px 10px #fff;
}
ul.buttons {
list-style: none;
padding-left: 0;
margin-top: 1em;
margin-bottom: 1em;
font-size: 1.75em;
}
ul.buttons li {
line-height: 1;
padding: 0.5em;
margin-left: 0.5em;
margin-right: 0.5em;
text-transform: uppercase;
}
.button:hover {
text-shadow:
-3px -3px 5px #fff,
-3px 3px 5px #fff,
3px -3px 5px #fff,
3px 3px 5px #fff,
0px 0px 7px #ff0000;
}
.button.nav:hover {
text-shadow:
0px 0px 7px #000,
-5px -5px 10px #fff,
-5px 5px 10px #fff,
5px -5px 10px #fff,
5px 5px 10px #fff;
-webkit-animation-name: pulse;
-webkit-animation-duration: 5s;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
-webkit-animation-fill-mode: none;
animation-name: pulse;
animation-duration: 5s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-fill-mode: none;
}
.explore:hover { color: #5588e0; }
.youtube:hover { color: #ff0000; }
.instagram:hover { color: #c13584; }
.twitter:hover { color: #1da1f2; }

View File

@ -1,53 +1,8 @@
html {
background-color: black;
}
body {
color: white;
font-family: sans-serif;
}
a {
color: inherit;
text-decoration: none;
}
ul {
list-style: none;
padding: 0;
}
#background-image {
background-image: url("https://cdn.enp.one/img/backgrounds/cl-photo-rt112.jpg");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
filter: blur(6px);
-webkit-filter: blur(6px);
position: fixed;
height: 100%;
width: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 0;
}
#background-image .overlay {
background-color: rgba(0, 0, 0, 0.8);
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
}
#toggle-description {
position: fixed;
right: 0;
@ -74,17 +29,26 @@ ul {
color: black;
}
#header h1 {
#header {
font-variant: small-caps;
border-bottom-style: solid;
margin-left: auto;
margin-right: auto;
margin-bottom: 2em;
margin-top: 1em;
padding-bottom: 1em;
width: 75%;
text-shadow: 3px 3px 5px #000;
text-align: left;
margin-bottom: 2em;
margin-top: 1em;
}
#header h1 {
border-bottom-style: solid;
padding-bottom: 1em;
margin-left: auto;
margin-right: auto;
width: 75%;
}
#header p {
margin-left: auto;
margin-right: auto;
width: 75%;
}
#header span {
@ -170,3 +134,27 @@ ul {
margin-left: 1em;
margin-right: 0.7em;
}
@media only screen and (max-width: 600px) {
h1 { font-size: 1.5rem; }
h2 { font-size: 1.25rem; }
p { font-size: 0.9rem; }
#toggle-description { font-size: 1.25rem; }
.article {
border-radius: 3em;
margin-bottom: 1em;
}
.article-banner {
border-radius: 3em;
}
.article-content {
padding-left: 2em;
padding-right: 2em;
}
}

143
bundle/css/home.css Normal file
View File

@ -0,0 +1,143 @@
#content {
text-align: center;
text-shadow: 3px 3px 5px #000, -3px -3px 5px #000;
font-weight: bold;
color: white;
padding: 1em;
width: 40em;
max-width: 90%;
background-color: rgba(0, 0, 0, 0.4);
border-style: solid;
border-width: 2px;
border-color: rgba(0, 0, 0, 0);
border-radius: 128px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.6), 0 6px 20px 0 rgba(0, 0, 0, 0.6);
position: absolute;
top: 15%;
left: 50%;
transform: translate(-50%, 0);
z-index: 10;
}
#logo {
margin: auto;
margin-top: -5em;
max-width: 60%;
width: 50%;
display: block;
border-style: solid;
border-color: rgba(0, 0, 0, 0.2);
border-radius: 50%;
border-width: 5px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4), 0 6px 20px 0 rgba(0, 0, 0, 0.4);
}
h1 {
font-variant: small-caps;
font-size: 2.5em;
}
#content p {
margin: 2em;
line-height: 1.5;
}
.button.nav {
padding-top: 0.75em;
padding-bottom: 0.55em;
padding-left: 1.5em;
padding-right: 1.5em;
border-radius: 30px;
transition: all 0.25s ease-in-out;
}
#background-info {
text-align: right;
font-size: 0.85em;
padding: 0.75em;
position: fixed;
bottom: 0;
right: 0;
z-index: 5;
}
footer { font-size: 0.9em; }
footer div { margin-bottom: 0.5em; }
footer a.button i {
padding: 0.5em;
font-size: 1.25em;
}
@keyframes pulse {
0% {
box-shadow:
0px 0px 15px 3px #fff,
0px 0px 15px 3px #88a9fc;
}
10% {
box-shadow:
-10px -10px 15px 3px #fff,
10px 10px 15px 3px #88a9fc;
}
30% {
box-shadow:
-10px 10px 15px 3px #b5f7fc,
10px -10px 15px 3px #fcaa99;
}
45% {
box-shadow:
10px 10px 15px 3px #ecf9a7,
-10px -10px 15px 3px #fcaa99;
}
60% {
box-shadow:
10px -10px 15px 3px #ecf9a7,
-10px 10px 15px 3px #abfcad;
}
75% {
box-shadow:
-10px -10px 15px 3px #b5f7fc,
10px 10px 15px 3px #abfcad;
}
90% {
box-shadow:
-10px 10px 15px 3px #fff,
10px -10px 15px 3px #88a9fc;
}
100% {
box-shadow:
0px 0px 15px 3px #b5f7fc,
0px 0px 15px 3px #88a9fc;
}
}
@media only screen and (max-width: 600px) {
#content {
padding: 0;
padding-bottom: 1em;
border-radius: 32px;
top: 6em;
}
#content p {
margin: 1em;
}
ul.buttons {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
ul.buttons li {
display: block;
margin-top: 1em;
}
}

8
bundle/js/preloader.js Normal file
View File

@ -0,0 +1,8 @@
window.addEventListener("load", async function() {
document.getElementById("preloader").classList.add("fadeout");
// I don't actually know how promises or async works
// ¯\_(ツ)_/¯
// https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep
await new Promise(r => setTimeout(r, 250))
document.getElementById("preloader").style.display = "none";
});

View File

@ -66,7 +66,6 @@ const BACKGROUND_IMAGES = [
}
];
function selectBackground() {
let max = BACKGROUND_IMAGES.length - 1
let min = 0;
@ -75,42 +74,10 @@ function selectBackground() {
return BACKGROUND_IMAGES[index];
}
function togglePrimaryText() {
let items = document.getElementsByClassName("article");
for (index = 0; index < items.length; index++) {
if (items[index].classList.contains("primary-text")) {
items[index].classList.remove("primary-text");
} else {
items[index].classList.add("primary-text");
}
}
let button = document.getElementById("toggle-description");
if (button.classList.contains("active")) {
button.classList.remove("active");
} else {
button.classList.add("active");
}
};
window.addEventListener("DOMContentLoaded", function () {
window.addEventListener("DOMContentLoaded", function() {
let selected = selectBackground()
document.getElementById(
"background-image"
).style.backgroundImage = "url(" + selected.url + ")";
});
window.addEventListener("load", async function () {
document.getElementById("toggle-description").addEventListener("click", togglePrimaryText);
document.getElementById("preloader").classList.add("fadeout");
// I don't actually know how promises or async works
// ¯\_(ツ)_/¯
// https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep
await new Promise(r => setTimeout(r, 250))
document.getElementById("preloader").style.display = "none";
});

View File

@ -0,0 +1,23 @@
function togglePrimaryText() {
let items = document.getElementsByClassName("article");
for (index = 0; index < items.length; index++) {
if (items[index].classList.contains("primary-text")) {
items[index].classList.remove("primary-text");
} else {
items[index].classList.add("primary-text");
}
}
let button = document.getElementById("toggle-description");
if (button.classList.contains("active")) {
button.classList.remove("active");
} else {
button.classList.add("active");
}
};
window.addEventListener("load", async function() {
document.getElementById("toggle-description").addEventListener("click", togglePrimaryText);
});

View File

@ -1,65 +1,20 @@
---
static:
- css/style.css
- css/explore.css
- js/custom.js
- error/404.html
- index.html
- robots.txt
posts:
- title: Talcott's "Castle on the Mountain" does not dissapoint
slug: heubline-tower
location:
title: Simsbury, CT
link: https://maps.google.com
date: "2020-01-01"
banner: https://cdn.enp.one/img/backgrounds/cl-photo-denver.jpg
media: []
domain: allaroundhere.org
baseurl: /
title: All Around Here
email: me@allaroundhere.org
description: Some of the best places are all around here
keywords: [travel, photography, explore, exploration, urbex, urban, nature, all, around, here, local, museum, history, historical, society]
social:
instagram: https://www.instagram.com/allaroundhere/
twitter: https://www.twitter.com/enpaul_/
- title: The three hundred year old fort with delusions of grandeur
slug: fort-revere
location:
title: Hull, MA
link: https://maps.google.com
date: "2020-01-01"
banner: https://cdn.enp.one/img/backgrounds/cl-photo-denver.jpg
media: []
- title: Supervillian lair or air traffic control station?
slug: jss-north-truro
location:
title: North Truro, MA
link: https://maps.google.com
date: "2020-01-01"
banner: https://cdn.enp.one/img/backgrounds/cl-photo-denver.jpg
media: []
- title: A 1:1 recreation of the set for Star Trek the Original Series
slug: star-trek-set-tours
location:
title: Ticonderoga, NY
link: https://maps.google.com
date: "2020-01-01"
banner: https://cdn.enp.one/img/backgrounds/cl-photo-denver.jpg
links:
- title: Star Trek Set Tours
link: https://www.startrektour.com/
media: []
- title: The most successful forest conservation project in the USA
slug: mount-greylock
location:
title: North Adams, MA
link: https://maps.google.com
date: "2020-01-01"
banner: https://cdn.enp.one/img/backgrounds/cl-photo-denver.jpg
media: []
- title: Ghosts of parties past are the last inhabitants of this magnificent forest castle
slug: castle-of-madame-sherri
location:
title: Chesterfield, NH
link: https://maps.google.com
date: "2020-01-01"
banner: https://cdn.enp.one/img/backgrounds/cl-photo-denver.jpg
media: []
build:
generated: publish/
post_base: explore/
kodak:
baseurl: http://localhost:8000/
link_original: true
asset: web
banner: banner
preload: lowres

View File

@ -1,115 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<!-- Web crawler and search indexing meta -->
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="author" content="admin@allaroundhere.org"/>
<meta name="description" content="Some of the best places are all around here"/>
<meta name="robots" content="index follow"/>
<meta
name="keywords"
content="travel photography explore exploration urbex urban nature all around here local museum history historical society"
/>
<!-- Facebook integration meta -->
<meta property="og:title" content="All Around Here"/>
<meta property="og:url" content="https://allaroundhere.org/explore/"/>
<meta property='og:site_name' content="All Around Here"/>
<meta property="og:type" content="website"/>
<meta property='og:locale' content="en_US"/>
<meta property="og:image" content="https://cdn.enp.one/img/backgrounds/cl-photo-boston.jpg"/>
<meta property='og:description' content="Some of the best places are all around here"/>
<!-- Twitter integration meta -->
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="https://allaroundhere.org/explore/">
<meta name="twitter:title" content="All Around Here">
<meta name="twitter:description" content="Some of the best places are all around here">
<meta name="twitter:image" content="https://cdn.enp.one/img/backgrounds/cl-photo-boston.jpg">
<meta name="twitter:image:alt" content="All Around Here">
<title>All Around Here</title>
<link rel="shortcut icon" href="https://cdn.enp.one/img/logos/aah-b-sm.png">
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.enp.one/img/logos/aah-b-sm.png">
<link rel="icon" type="image/png" sizes="32x32" href="https://cdn.enp.one/img/logos/aah-b-sm.png" >
<link rel="icon" type="image/png" sizes="16x16" href="https://cdn.enp.one/img/logos/aah-b-sm.png">
<link rel="stylesheet" href="css/style.css"/>
<link
rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.6.3/css/all.css"
integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/"
crossorigin="anonymous"
/>
<script type="text/javascript" src="js/custom.js"></script>
<noscript><style>.nojs { display: none; }</style></noscript>
</head>
<body>
<div id="background-image"></div>
<div id="preloader" class="nojs"><div class="spinner"><div></div></div></div>
<div id="content">
<img
id="logo"
alt="Road to the great wide nowhere"
src="https://cdn.enp.one/img/logos/aah-md.jpg"
/>
<h1>All Around Here</h1>
<p>
This is a project of mine where I turn my random travels, undirected wanderings, and
unexpected discoveries into something other people can enjoy along with me. There are a
lot of cool things in the world and I like to find them, wherever I happen to be. If you're
interested in seeing some of these arbitrary oddities then check out the links below.
</p>
<ul class="buttons">
<li>
<a class="button nav" title="Explore All Around Here" href="explore/">
<i class="fas fa-binoculars"></i>&nbsp;Explore
</a>
</li>
</ul>
<footer>
<div>
<!-- <a
class="button youtube"
title="Subscribe to All Around Here on YouTube"
href="https://www.instagram.com/allaroundhere/"
>
<i class="fab fa-youtube"></i>
</a> -->
<a
class="button instagram"
title="Follow All Around Here on instagram @allaroundhere"
href="https://www.instagram.com/allaroundhere/"
>
<i class="fab fa-instagram"></i>
</a>
<a
class="button twitter"
title="Follow me on twitter @enpaul_"
href="https://www.twitter.com/enpaul_/"
>
<i class="fab fa-twitter"></i>
</a>
</div>
<div>
<a title="Personal website" href="https://enpaul.net/">&copy;2021 enpaul</a>
</div>
</footer>
</div>
</body>
</html>

548
poetry.lock generated
View File

@ -6,6 +6,14 @@ category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "appnope"
version = "0.1.2"
description = "Disable App Nap on macOS >= 10.9"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "aspy.refactor-imports"
version = "2.2.0"
@ -17,27 +25,49 @@ python-versions = ">=3.6.1"
[package.dependencies]
cached-property = "*"
[[package]]
name = "attrs"
version = "21.2.0"
description = "Classes Without Boilerplate"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[package.extras]
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"]
docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"]
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"]
[[package]]
name = "backcall"
version = "0.2.0"
description = "Specifications for callback functions passed in to an API"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "black"
version = "20.8b1"
version = "22.1.0"
description = "The uncompromising code formatter."
category = "dev"
optional = false
python-versions = ">=3.6"
python-versions = ">=3.6.2"
[package.dependencies]
appdirs = "*"
click = ">=7.1.2"
click = ">=8.0.0"
mypy-extensions = ">=0.4.3"
pathspec = ">=0.6,<1"
regex = ">=2020.1.8"
toml = ">=0.10.1"
typed-ast = ">=1.4.0"
typing-extensions = ">=3.7.4"
pathspec = ">=0.9.0"
platformdirs = ">=2"
tomli = ">=1.1.0"
typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}
[package.extras]
colorama = ["colorama (>=0.4.3)"]
d = ["aiohttp (>=3.3.2)", "aiohttp-cors"]
d = ["aiohttp (>=3.7.4)"]
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "cached-property"
@ -57,12 +87,31 @@ python-versions = ">=3.6.1"
[[package]]
name = "click"
version = "7.1.2"
version = "8.0.3"
description = "Composable command line interface toolkit"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]]
name = "colorama"
version = "0.4.4"
description = "Cross-platform colored terminal text."
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "decorator"
version = "5.1.0"
description = "Decorators for Humans"
category = "dev"
optional = false
python-versions = ">=3.5"
[[package]]
name = "distlib"
version = "0.3.1"
@ -90,6 +139,69 @@ python-versions = ">=3.6.1"
[package.extras]
license = ["editdistance-s"]
[[package]]
name = "importlib-metadata"
version = "4.8.1"
description = "Read metadata from Python packages"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.dependencies]
zipp = ">=0.5"
[package.extras]
docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
perf = ["ipython"]
testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"]
[[package]]
name = "ipython"
version = "7.28.0"
description = "IPython: Productive Interactive Computing"
category = "dev"
optional = false
python-versions = ">=3.7"
[package.dependencies]
appnope = {version = "*", markers = "sys_platform == \"darwin\""}
backcall = "*"
colorama = {version = "*", markers = "sys_platform == \"win32\""}
decorator = "*"
jedi = ">=0.16"
matplotlib-inline = "*"
pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""}
pickleshare = "*"
prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0"
pygments = "*"
traitlets = ">=4.2"
[package.extras]
all = ["Sphinx (>=1.3)", "ipykernel", "ipyparallel", "ipywidgets", "nbconvert", "nbformat", "nose (>=0.10.1)", "notebook", "numpy (>=1.17)", "pygments", "qtconsole", "requests", "testpath"]
doc = ["Sphinx (>=1.3)"]
kernel = ["ipykernel"]
nbconvert = ["nbconvert"]
nbformat = ["nbformat"]
notebook = ["notebook", "ipywidgets"]
parallel = ["ipyparallel"]
qtconsole = ["qtconsole"]
test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.17)"]
[[package]]
name = "jedi"
version = "0.18.0"
description = "An autocompletion tool for Python that can be used for text editors."
category = "dev"
optional = false
python-versions = ">=3.6"
[package.dependencies]
parso = ">=0.8.0,<0.9.0"
[package.extras]
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<6.0.0)"]
[[package]]
name = "jinja2"
version = "2.11.3"
@ -104,6 +216,33 @@ MarkupSafe = ">=0.23"
[package.extras]
i18n = ["Babel (>=0.8)"]
[[package]]
name = "jsmin"
version = "3.0.0"
description = "JavaScript minifier."
category = "main"
optional = false
python-versions = "*"
[[package]]
name = "markdown-it-py"
version = "1.1.0"
description = "Python port of markdown-it. Markdown parsing, done right!"
category = "dev"
optional = false
python-versions = "~=3.6"
[package.dependencies]
attrs = ">=19,<22"
[package.extras]
code_style = ["pre-commit (==2.6)"]
compare = ["commonmark (>=0.9.1,<0.10.0)", "markdown (>=3.2.2,<3.3.0)", "mistletoe-ebp (>=0.10.0,<0.11.0)", "mistune (>=0.8.4,<0.9.0)", "panflute (>=1.12,<2.0)"]
linkify = ["linkify-it-py (>=1.0,<2.0)"]
plugins = ["mdit-py-plugins"]
rtd = ["myst-nb (==0.13.0a1)", "pyyaml", "sphinx (>=2,<4)", "sphinx-copybutton", "sphinx-panels (>=0.4.0,<0.5.0)", "sphinx-book-theme"]
testing = ["coverage", "psutil", "pytest (>=3.6,<4)", "pytest-benchmark (>=3.2,<4.0)", "pytest-cov", "pytest-regressions"]
[[package]]
name = "markupsafe"
version = "1.1.1"
@ -126,6 +265,38 @@ docs = ["sphinx (==3.4.3)", "sphinx-issues (==1.2.0)", "alabaster (==0.7.12)", "
lint = ["mypy (==0.812)", "flake8 (==3.9.0)", "flake8-bugbear (==21.3.2)", "pre-commit (>=2.4,<3.0)"]
tests = ["pytest", "pytz", "simplejson"]
[[package]]
name = "matplotlib-inline"
version = "0.1.3"
description = "Inline Matplotlib backend for Jupyter"
category = "dev"
optional = false
python-versions = ">=3.5"
[package.dependencies]
traitlets = "*"
[[package]]
name = "mdformat"
version = "0.7.10"
description = "CommonMark compliant Markdown formatter"
category = "dev"
optional = false
python-versions = ">=3.7,<4.0"
[package.dependencies]
importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""}
markdown-it-py = ">=1.0.0b2,<2.0.0"
tomli = ">=1.1.0"
[[package]]
name = "minify-html"
version = "0.8.0"
description = "Extremely fast and smart HTML + JS + CSS minifier"
category = "main"
optional = false
python-versions = "*"
[[package]]
name = "mypy-extensions"
version = "0.4.3"
@ -142,13 +313,56 @@ category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "parso"
version = "0.8.2"
description = "A Python Parser"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.extras]
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
testing = ["docopt", "pytest (<6.0.0)"]
[[package]]
name = "pathspec"
version = "0.8.1"
version = "0.9.0"
description = "Utility library for gitignore style pattern matching of file paths."
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
[[package]]
name = "pexpect"
version = "4.8.0"
description = "Pexpect allows easy control of interactive console applications."
category = "dev"
optional = false
python-versions = "*"
[package.dependencies]
ptyprocess = ">=0.5"
[[package]]
name = "pickleshare"
version = "0.7.5"
description = "Tiny 'shelve'-like database with concurrency support"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "platformdirs"
version = "2.4.1"
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "dev"
optional = false
python-versions = ">=3.7"
[package.extras]
docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"]
test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"]
[[package]]
name = "pre-commit"
@ -178,6 +392,33 @@ python-versions = ">=3.6.1"
"ruamel.yaml" = ">=0.15"
toml = "*"
[[package]]
name = "prompt-toolkit"
version = "3.0.20"
description = "Library for building powerful interactive command lines in Python"
category = "dev"
optional = false
python-versions = ">=3.6.2"
[package.dependencies]
wcwidth = "*"
[[package]]
name = "ptyprocess"
version = "0.7.0"
description = "Run a subprocess in a pseudo terminal"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "pygments"
version = "2.10.0"
description = "Pygments is a syntax highlighting package written in Python."
category = "dev"
optional = false
python-versions = ">=3.5"
[[package]]
name = "pyyaml"
version = "5.4.1"
@ -186,14 +427,6 @@ category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
[[package]]
name = "regex"
version = "2021.4.4"
description = "Alternative regular expression module, to replace re."
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "reorder-python-imports"
version = "2.4.0"
@ -245,20 +478,31 @@ optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
[[package]]
name = "typed-ast"
version = "1.4.3"
description = "a fork of Python 2 and 3 ast modules with type comment support"
name = "tomli"
version = "1.2.1"
description = "A lil' TOML parser"
category = "dev"
optional = false
python-versions = "*"
python-versions = ">=3.6"
[[package]]
name = "traitlets"
version = "5.1.0"
description = "Traitlets Python configuration system"
category = "dev"
optional = false
python-versions = ">=3.7"
[package.extras]
test = ["pytest"]
[[package]]
name = "typing-extensions"
version = "3.7.4.3"
description = "Backported and Experimental Type Hints for Python 3.5+"
version = "4.0.1"
description = "Backported and Experimental Type Hints for Python 3.6+"
category = "dev"
optional = false
python-versions = "*"
python-versions = ">=3.6"
[[package]]
name = "virtualenv"
@ -278,22 +522,76 @@ six = ">=1.9.0,<2"
docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)"]
testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "packaging (>=20.0)", "xonsh (>=0.9.16)"]
[[package]]
name = "wcwidth"
version = "0.2.5"
description = "Measures the displayed width of unicode strings in a terminal"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "zipp"
version = "3.6.0"
description = "Backport of pathlib-compatible object wrapper for zip files"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.extras]
docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"]
[metadata]
lock-version = "1.1"
python-versions = "^3.8"
content-hash = "51b47f6f5d03384e10f3f43974a6a936341408d03cac317460c76c4b51242f7f"
content-hash = "a1028b5917bdf0e31b39431da10311b8a331bbfa12909ab889c6321698c62694"
[metadata.files]
appdirs = [
{file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
{file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"},
]
appnope = [
{file = "appnope-0.1.2-py2.py3-none-any.whl", hash = "sha256:93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442"},
{file = "appnope-0.1.2.tar.gz", hash = "sha256:dd83cd4b5b460958838f6eb3000c660b1f9caf2a5b1de4264e941512f603258a"},
]
"aspy.refactor-imports" = [
{file = "aspy.refactor_imports-2.2.0-py2.py3-none-any.whl", hash = "sha256:7a18039d2e8be6b02b4791ce98891deb46b459b575c52ed35ab818c4eaa0c098"},
{file = "aspy.refactor_imports-2.2.0.tar.gz", hash = "sha256:78ca24122963fd258ebfc4a8dc708d23a18040ee39dca8767675821e84e9ea0a"},
]
attrs = [
{file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"},
{file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"},
]
backcall = [
{file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"},
{file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"},
]
black = [
{file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"},
{file = "black-22.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1297c63b9e1b96a3d0da2d85d11cd9bf8664251fd69ddac068b98dc4f34f73b6"},
{file = "black-22.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2ff96450d3ad9ea499fc4c60e425a1439c2120cbbc1ab959ff20f7c76ec7e866"},
{file = "black-22.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e21e1f1efa65a50e3960edd068b6ae6d64ad6235bd8bfea116a03b21836af71"},
{file = "black-22.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f69158a7d120fd641d1fa9a921d898e20d52e44a74a6fbbcc570a62a6bc8ab"},
{file = "black-22.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:228b5ae2c8e3d6227e4bde5920d2fc66cc3400fde7bcc74f480cb07ef0b570d5"},
{file = "black-22.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b1a5ed73ab4c482208d20434f700d514f66ffe2840f63a6252ecc43a9bc77e8a"},
{file = "black-22.1.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35944b7100af4a985abfcaa860b06af15590deb1f392f06c8683b4381e8eeaf0"},
{file = "black-22.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7835fee5238fc0a0baf6c9268fb816b5f5cd9b8793423a75e8cd663c48d073ba"},
{file = "black-22.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dae63f2dbf82882fa3b2a3c49c32bffe144970a573cd68d247af6560fc493ae1"},
{file = "black-22.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fa1db02410b1924b6749c245ab38d30621564e658297484952f3d8a39fce7e8"},
{file = "black-22.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c8226f50b8c34a14608b848dc23a46e5d08397d009446353dad45e04af0c8e28"},
{file = "black-22.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2d6f331c02f0f40aa51a22e479c8209d37fcd520c77721c034517d44eecf5912"},
{file = "black-22.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:742ce9af3086e5bd07e58c8feb09dbb2b047b7f566eb5f5bc63fd455814979f3"},
{file = "black-22.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fdb8754b453fb15fad3f72cd9cad3e16776f0964d67cf30ebcbf10327a3777a3"},
{file = "black-22.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5660feab44c2e3cb24b2419b998846cbb01c23c7fe645fee45087efa3da2d61"},
{file = "black-22.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:6f2f01381f91c1efb1451998bd65a129b3ed6f64f79663a55fe0e9b74a5f81fd"},
{file = "black-22.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:efbadd9b52c060a8fc3b9658744091cb33c31f830b3f074422ed27bad2b18e8f"},
{file = "black-22.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8871fcb4b447206904932b54b567923e5be802b9b19b744fdff092bd2f3118d0"},
{file = "black-22.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccad888050f5393f0d6029deea2a33e5ae371fd182a697313bdbd835d3edaf9c"},
{file = "black-22.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07e5c049442d7ca1a2fc273c79d1aecbbf1bc858f62e8184abe1ad175c4f7cc2"},
{file = "black-22.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:373922fc66676133ddc3e754e4509196a8c392fec3f5ca4486673e685a421321"},
{file = "black-22.1.0-py3-none-any.whl", hash = "sha256:3524739d76b6b3ed1132422bf9d82123cd1705086723bc3e235ca39fd21c667d"},
{file = "black-22.1.0.tar.gz", hash = "sha256:a7c0192d35635f6fc1174be575cb7915e92e5dd629ee79fdaf0dcfa41a80afb5"},
]
cached-property = [
{file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"},
@ -304,8 +602,16 @@ cfgv = [
{file = "cfgv-3.2.0.tar.gz", hash = "sha256:cf22deb93d4bcf92f345a5c3cd39d3d41d6340adc60c78bbbd6588c384fda6a1"},
]
click = [
{file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"},
{file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"},
{file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"},
{file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"},
]
colorama = [
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
]
decorator = [
{file = "decorator-5.1.0-py3-none-any.whl", hash = "sha256:7b12e7c3c6ab203a29e157335e9122cb03de9ab7264b137594103fd4a683b374"},
{file = "decorator-5.1.0.tar.gz", hash = "sha256:e59913af105b9860aa2c8d3272d9de5a56a4e608db9a2f167a8480b323d529a7"},
]
distlib = [
{file = "distlib-0.3.1-py2.py3-none-any.whl", hash = "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb"},
@ -319,10 +625,29 @@ identify = [
{file = "identify-2.2.4-py2.py3-none-any.whl", hash = "sha256:ad9f3fa0c2316618dc4d840f627d474ab6de106392a4f00221820200f490f5a8"},
{file = "identify-2.2.4.tar.gz", hash = "sha256:9bcc312d4e2fa96c7abebcdfb1119563b511b5e3985ac52f60d9116277865b2e"},
]
importlib-metadata = [
{file = "importlib_metadata-4.8.1-py3-none-any.whl", hash = "sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15"},
{file = "importlib_metadata-4.8.1.tar.gz", hash = "sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1"},
]
ipython = [
{file = "ipython-7.28.0-py3-none-any.whl", hash = "sha256:f16148f9163e1e526f1008d7c8d966d9c15600ca20d1a754287cf96d00ba6f1d"},
{file = "ipython-7.28.0.tar.gz", hash = "sha256:2097be5c814d1b974aea57673176a924c4c8c9583890e7a5f082f547b9975b11"},
]
jedi = [
{file = "jedi-0.18.0-py2.py3-none-any.whl", hash = "sha256:18456d83f65f400ab0c2d3319e48520420ef43b23a086fdc05dff34132f0fb93"},
{file = "jedi-0.18.0.tar.gz", hash = "sha256:92550a404bad8afed881a137ec9a461fed49eca661414be45059329614ed0707"},
]
jinja2 = [
{file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"},
{file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"},
]
jsmin = [
{file = "jsmin-3.0.0.tar.gz", hash = "sha256:88fc1bd6033a47c5911dbcada7d279c7a8b7ad0841909590f6a742c20c4d2e08"},
]
markdown-it-py = [
{file = "markdown-it-py-1.1.0.tar.gz", hash = "sha256:36be6bb3ad987bfdb839f5ba78ddf094552ca38ccbd784ae4f74a4e1419fc6e3"},
{file = "markdown_it_py-1.1.0-py3-none-any.whl", hash = "sha256:98080fc0bc34c4f2bcf0846a096a9429acbd9d5d8e67ed34026c03c61c464389"},
]
markupsafe = [
{file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"},
{file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"},
@ -381,6 +706,31 @@ marshmallow = [
{file = "marshmallow-3.11.1-py2.py3-none-any.whl", hash = "sha256:0dd42891a5ef288217ed6410917f3c6048f585f8692075a0052c24f9bfff9dfd"},
{file = "marshmallow-3.11.1.tar.gz", hash = "sha256:16e99cb7f630c0ef4d7d364ed0109ac194268dde123966076ab3dafb9ae3906b"},
]
matplotlib-inline = [
{file = "matplotlib-inline-0.1.3.tar.gz", hash = "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee"},
{file = "matplotlib_inline-0.1.3-py3-none-any.whl", hash = "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"},
]
mdformat = [
{file = "mdformat-0.7.10-py3-none-any.whl", hash = "sha256:27bd8ebecb3c02ac90ccef93702b16587e8dc6f302a90b8d7381cad6b72c69e1"},
{file = "mdformat-0.7.10.tar.gz", hash = "sha256:bb086c56445a56d2d256e3b47504ccb96d03628f091f4d687cd456944ca91158"},
]
minify-html = [
{file = "minify_html-0.8.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:18ad08813517757a3130532b221355ca0859b41b2fafac59db74782db67b92a8"},
{file = "minify_html-0.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ccaaefd5b81b99fe1a9c16158c5d79a5396959d03e017934f765b511c5e876c"},
{file = "minify_html-0.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7be4458bb1b0b58bb1bc95563c1b65d75ba5096683281fb280dfd6ec865d2ea"},
{file = "minify_html-0.8.0-cp310-cp310-manylinux_2_24_x86_64.whl", hash = "sha256:156c7387caa3196d3762f5dbf5c61d894889f04d49750a00fb9fb1259394ce89"},
{file = "minify_html-0.8.0-cp310-none-win_amd64.whl", hash = "sha256:1cfeb9802aacf68b9e888b6589c5b6b48bd56cc26a5e10c84058f9b42e52ec4e"},
{file = "minify_html-0.8.0-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:44c0cc36e1d3858cf8b21ba6b24fbd8a6e9baddc5d60f5cbef22f603c63b234b"},
{file = "minify_html-0.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2a13c30375e3942c785bbff14b1d46cb9ae83433f29cf27fe176863b9dd90f06"},
{file = "minify_html-0.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1656962670273ba4e0c3edf369afd07c3443e2684bed459f0c0927d62ab3064b"},
{file = "minify_html-0.8.0-cp38-cp38-manylinux_2_24_x86_64.whl", hash = "sha256:528372bfca7d1fbd11edeb5c76c415da50638480b2191682824f3de2a7a295ff"},
{file = "minify_html-0.8.0-cp38-none-win_amd64.whl", hash = "sha256:9f7697139ca7aa150e3706a1fa21094991c36503525bfa6482e9af973a8a7c13"},
{file = "minify_html-0.8.0-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:68fa4c1982f2058a9ff3db6adc4c0582ba2e4166e99e6b6e8fed5ac21416954e"},
{file = "minify_html-0.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:930dc7c8f26b96eb5685b9f8bd498d2bfe3c835437b1b41ff99e13ccb91ed06e"},
{file = "minify_html-0.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c312d700f52a69af18dbc95b95669f5dc298f433b3c3b0911fa7441c3c7cfeeb"},
{file = "minify_html-0.8.0-cp39-cp39-manylinux_2_24_x86_64.whl", hash = "sha256:5f75e7484ba09a8c313428bdce7e6aca1340231e5e6983d3246be7d7c964587e"},
{file = "minify_html-0.8.0-cp39-none-win_amd64.whl", hash = "sha256:bac93bb286751af2ad2db5d6e63f54e30fc1632a1fb3b6622cad180d67aa4cb5"},
]
mypy-extensions = [
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
@ -389,9 +739,25 @@ nodeenv = [
{file = "nodeenv-1.6.0-py2.py3-none-any.whl", hash = "sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7"},
{file = "nodeenv-1.6.0.tar.gz", hash = "sha256:3ef13ff90291ba2a4a7a4ff9a979b63ffdd00a464dbe04acf0ea6471517a4c2b"},
]
parso = [
{file = "parso-0.8.2-py2.py3-none-any.whl", hash = "sha256:a8c4922db71e4fdb90e0d0bc6e50f9b273d3397925e5e60a717e719201778d22"},
{file = "parso-0.8.2.tar.gz", hash = "sha256:12b83492c6239ce32ff5eed6d3639d6a536170723c6f3f1506869f1ace413398"},
]
pathspec = [
{file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"},
{file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"},
{file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"},
{file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
]
pexpect = [
{file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"},
{file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"},
]
pickleshare = [
{file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"},
{file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"},
]
platformdirs = [
{file = "platformdirs-2.4.1-py3-none-any.whl", hash = "sha256:1d7385c7db91728b83efd0ca99a5afb296cab9d0ed8313a45ed8ba17967ecfca"},
{file = "platformdirs-2.4.1.tar.gz", hash = "sha256:440633ddfebcc36264232365d7840a970e75e1018d15b4327d11f91909045fda"},
]
pre-commit = [
{file = "pre_commit-2.12.1-py2.py3-none-any.whl", hash = "sha256:70c5ec1f30406250b706eda35e868b87e3e4ba099af8787e3e8b4b01e84f4712"},
@ -401,6 +767,18 @@ pre-commit-hooks = [
{file = "pre_commit_hooks-3.4.0-py2.py3-none-any.whl", hash = "sha256:b1d329fc712f53f56af7c4a0ac08c414a7fcfd634dbd829c3a03f39cfb9c3574"},
{file = "pre_commit_hooks-3.4.0.tar.gz", hash = "sha256:57e377b931aceead550e4a7bdbe8065e79e371e80f593b5b6d1129e63a77154f"},
]
prompt-toolkit = [
{file = "prompt_toolkit-3.0.20-py3-none-any.whl", hash = "sha256:6076e46efae19b1e0ca1ec003ed37a933dc94b4d20f486235d436e64771dcd5c"},
{file = "prompt_toolkit-3.0.20.tar.gz", hash = "sha256:eb71d5a6b72ce6db177af4a7d4d7085b99756bf656d98ffcc4fecd36850eea6c"},
]
ptyprocess = [
{file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
{file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"},
]
pygments = [
{file = "Pygments-2.10.0-py3-none-any.whl", hash = "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380"},
{file = "Pygments-2.10.0.tar.gz", hash = "sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"},
]
pyyaml = [
{file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"},
{file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"},
@ -408,65 +786,30 @@ pyyaml = [
{file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"},
{file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"},
{file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"},
{file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"},
{file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"},
{file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"},
{file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"},
{file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"},
{file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"},
{file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"},
{file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"},
{file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"},
{file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"},
{file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"},
{file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"},
{file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"},
{file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"},
{file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"},
{file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"},
{file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"},
{file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"},
{file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"},
{file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"},
{file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"},
{file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"},
{file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"},
]
regex = [
{file = "regex-2021.4.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:619d71c59a78b84d7f18891fe914446d07edd48dc8328c8e149cbe0929b4e000"},
{file = "regex-2021.4.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:47bf5bf60cf04d72bf6055ae5927a0bd9016096bf3d742fa50d9bf9f45aa0711"},
{file = "regex-2021.4.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:281d2fd05555079448537fe108d79eb031b403dac622621c78944c235f3fcf11"},
{file = "regex-2021.4.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:bd28bc2e3a772acbb07787c6308e00d9626ff89e3bfcdebe87fa5afbfdedf968"},
{file = "regex-2021.4.4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:7c2a1af393fcc09e898beba5dd59196edaa3116191cc7257f9224beaed3e1aa0"},
{file = "regex-2021.4.4-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c38c71df845e2aabb7fb0b920d11a1b5ac8526005e533a8920aea97efb8ec6a4"},
{file = "regex-2021.4.4-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:96fcd1888ab4d03adfc9303a7b3c0bd78c5412b2bfbe76db5b56d9eae004907a"},
{file = "regex-2021.4.4-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:ade17eb5d643b7fead300a1641e9f45401c98eee23763e9ed66a43f92f20b4a7"},
{file = "regex-2021.4.4-cp36-cp36m-win32.whl", hash = "sha256:e8e5b509d5c2ff12f8418006d5a90e9436766133b564db0abaec92fd27fcee29"},
{file = "regex-2021.4.4-cp36-cp36m-win_amd64.whl", hash = "sha256:11d773d75fa650cd36f68d7ca936e3c7afaae41b863b8c387a22aaa78d3c5c79"},
{file = "regex-2021.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d3029c340cfbb3ac0a71798100ccc13b97dddf373a4ae56b6a72cf70dfd53bc8"},
{file = "regex-2021.4.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:18c071c3eb09c30a264879f0d310d37fe5d3a3111662438889ae2eb6fc570c31"},
{file = "regex-2021.4.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:4c557a7b470908b1712fe27fb1ef20772b78079808c87d20a90d051660b1d69a"},
{file = "regex-2021.4.4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:01afaf2ec48e196ba91b37451aa353cb7eda77efe518e481707e0515025f0cd5"},
{file = "regex-2021.4.4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:3a9cd17e6e5c7eb328517969e0cb0c3d31fd329298dd0c04af99ebf42e904f82"},
{file = "regex-2021.4.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:90f11ff637fe8798933fb29f5ae1148c978cccb0452005bf4c69e13db951e765"},
{file = "regex-2021.4.4-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:919859aa909429fb5aa9cf8807f6045592c85ef56fdd30a9a3747e513db2536e"},
{file = "regex-2021.4.4-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:339456e7d8c06dd36a22e451d58ef72cef293112b559010db3d054d5560ef439"},
{file = "regex-2021.4.4-cp37-cp37m-win32.whl", hash = "sha256:67bdb9702427ceddc6ef3dc382455e90f785af4c13d495f9626861763ee13f9d"},
{file = "regex-2021.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:32e65442138b7b76dd8173ffa2cf67356b7bc1768851dded39a7a13bf9223da3"},
{file = "regex-2021.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1e1c20e29358165242928c2de1482fb2cf4ea54a6a6dea2bd7a0e0d8ee321500"},
{file = "regex-2021.4.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:314d66636c494ed9c148a42731b3834496cc9a2c4251b1661e40936814542b14"},
{file = "regex-2021.4.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6d1b01031dedf2503631d0903cb563743f397ccaf6607a5e3b19a3d76fc10480"},
{file = "regex-2021.4.4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:741a9647fcf2e45f3a1cf0e24f5e17febf3efe8d4ba1281dcc3aa0459ef424dc"},
{file = "regex-2021.4.4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4c46e22a0933dd783467cf32b3516299fb98cfebd895817d685130cc50cd1093"},
{file = "regex-2021.4.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:e512d8ef5ad7b898cdb2d8ee1cb09a8339e4f8be706d27eaa180c2f177248a10"},
{file = "regex-2021.4.4-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:980d7be47c84979d9136328d882f67ec5e50008681d94ecc8afa8a65ed1f4a6f"},
{file = "regex-2021.4.4-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:ce15b6d103daff8e9fee13cf7f0add05245a05d866e73926c358e871221eae87"},
{file = "regex-2021.4.4-cp38-cp38-win32.whl", hash = "sha256:a91aa8619b23b79bcbeb37abe286f2f408d2f2d6f29a17237afda55bb54e7aac"},
{file = "regex-2021.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:c0502c0fadef0d23b128605d69b58edb2c681c25d44574fc673b0e52dce71ee2"},
{file = "regex-2021.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:598585c9f0af8374c28edd609eb291b5726d7cbce16be6a8b95aa074d252ee17"},
{file = "regex-2021.4.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:ee54ff27bf0afaf4c3b3a62bcd016c12c3fdb4ec4f413391a90bd38bc3624605"},
{file = "regex-2021.4.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7d9884d86dd4dd489e981d94a65cd30d6f07203d90e98f6f657f05170f6324c9"},
{file = "regex-2021.4.4-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:bf5824bfac591ddb2c1f0a5f4ab72da28994548c708d2191e3b87dd207eb3ad7"},
{file = "regex-2021.4.4-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:563085e55b0d4fb8f746f6a335893bda5c2cef43b2f0258fe1020ab1dd874df8"},
{file = "regex-2021.4.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9c3db21af35e3b3c05764461b262d6f05bbca08a71a7849fd79d47ba7bc33ed"},
{file = "regex-2021.4.4-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:3916d08be28a1149fb97f7728fca1f7c15d309a9f9682d89d79db75d5e52091c"},
{file = "regex-2021.4.4-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:fd45ff9293d9274c5008a2054ecef86a9bfe819a67c7be1afb65e69b405b3042"},
{file = "regex-2021.4.4-cp39-cp39-win32.whl", hash = "sha256:fa4537fb4a98fe8fde99626e4681cc644bdcf2a795038533f9f711513a862ae6"},
{file = "regex-2021.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:97f29f57d5b84e73fbaf99ab3e26134e6687348e95ef6b48cfd2c06807005a07"},
{file = "regex-2021.4.4.tar.gz", hash = "sha256:52ba3d3f9b942c49d7e4bc105bb28551c44065f139a65062ab7912bef10c9afb"},
]
reorder-python-imports = [
{file = "reorder_python_imports-2.4.0-py2.py3-none-any.whl", hash = "sha256:995a2a93684af31837f30cf2bcddce2e7eb17f0d2d69c9905da103baf8cec42b"},
{file = "reorder_python_imports-2.4.0.tar.gz", hash = "sha256:9a9e7774d66e9b410b619f934e8206a63dce5be26bd894f5006eb764bba6a26d"},
@ -516,44 +859,27 @@ toml = [
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
]
typed-ast = [
{file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"},
{file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"},
{file = "typed_ast-1.4.3-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:1b3ead4a96c9101bef08f9f7d1217c096f31667617b58de957f690c92378b528"},
{file = "typed_ast-1.4.3-cp35-cp35m-win32.whl", hash = "sha256:dde816ca9dac1d9c01dd504ea5967821606f02e510438120091b84e852367428"},
{file = "typed_ast-1.4.3-cp35-cp35m-win_amd64.whl", hash = "sha256:777a26c84bea6cd934422ac2e3b78863a37017618b6e5c08f92ef69853e765d3"},
{file = "typed_ast-1.4.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f8afcf15cc511ada719a88e013cec87c11aff7b91f019295eb4530f96fe5ef2f"},
{file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:52b1eb8c83f178ab787f3a4283f68258525f8d70f778a2f6dd54d3b5e5fb4341"},
{file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace"},
{file = "typed_ast-1.4.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c190f0899e9f9f8b6b7863debfb739abcb21a5c054f911ca3596d12b8a4c4c7f"},
{file = "typed_ast-1.4.3-cp36-cp36m-win32.whl", hash = "sha256:398e44cd480f4d2b7ee8d98385ca104e35c81525dd98c519acff1b79bdaac363"},
{file = "typed_ast-1.4.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bff6ad71c81b3bba8fa35f0f1921fb24ff4476235a6e94a26ada2e54370e6da7"},
{file = "typed_ast-1.4.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0fb71b8c643187d7492c1f8352f2c15b4c4af3f6338f21681d3681b3dc31a266"},
{file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:760ad187b1041a154f0e4d0f6aae3e40fdb51d6de16e5c99aedadd9246450e9e"},
{file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5feca99c17af94057417d744607b82dd0a664fd5e4ca98061480fd8b14b18d04"},
{file = "typed_ast-1.4.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:95431a26309a21874005845c21118c83991c63ea800dd44843e42a916aec5899"},
{file = "typed_ast-1.4.3-cp37-cp37m-win32.whl", hash = "sha256:aee0c1256be6c07bd3e1263ff920c325b59849dc95392a05f258bb9b259cf39c"},
{file = "typed_ast-1.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9ad2c92ec681e02baf81fdfa056fe0d818645efa9af1f1cd5fd6f1bd2bdfd805"},
{file = "typed_ast-1.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b36b4f3920103a25e1d5d024d155c504080959582b928e91cb608a65c3a49e1a"},
{file = "typed_ast-1.4.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:067a74454df670dcaa4e59349a2e5c81e567d8d65458d480a5b3dfecec08c5ff"},
{file = "typed_ast-1.4.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7538e495704e2ccda9b234b82423a4038f324f3a10c43bc088a1636180f11a41"},
{file = "typed_ast-1.4.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:af3d4a73793725138d6b334d9d247ce7e5f084d96284ed23f22ee626a7b88e39"},
{file = "typed_ast-1.4.3-cp38-cp38-win32.whl", hash = "sha256:f2362f3cb0f3172c42938946dbc5b7843c2a28aec307c49100c8b38764eb6927"},
{file = "typed_ast-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:dd4a21253f42b8d2b48410cb31fe501d32f8b9fbeb1f55063ad102fe9c425e40"},
{file = "typed_ast-1.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f328adcfebed9f11301eaedfa48e15bdece9b519fb27e6a8c01aa52a17ec31b3"},
{file = "typed_ast-1.4.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:2c726c276d09fc5c414693a2de063f521052d9ea7c240ce553316f70656c84d4"},
{file = "typed_ast-1.4.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:cae53c389825d3b46fb37538441f75d6aecc4174f615d048321b716df2757fb0"},
{file = "typed_ast-1.4.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9574c6f03f685070d859e75c7f9eeca02d6933273b5e69572e5ff9d5e3931c3"},
{file = "typed_ast-1.4.3-cp39-cp39-win32.whl", hash = "sha256:209596a4ec71d990d71d5e0d312ac935d86930e6eecff6ccc7007fe54d703808"},
{file = "typed_ast-1.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:9c6d1a54552b5330bc657b7ef0eae25d00ba7ffe85d9ea8ae6540d2197a3788c"},
{file = "typed_ast-1.4.3.tar.gz", hash = "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65"},
tomli = [
{file = "tomli-1.2.1-py3-none-any.whl", hash = "sha256:8dd0e9524d6f386271a36b41dbf6c57d8e32fd96fd22b6584679dc569d20899f"},
{file = "tomli-1.2.1.tar.gz", hash = "sha256:a5b75cb6f3968abb47af1b40c1819dc519ea82bcc065776a866e8d74c5ca9442"},
]
traitlets = [
{file = "traitlets-5.1.0-py3-none-any.whl", hash = "sha256:03f172516916220b58c9f19d7f854734136dd9528103d04e9bf139a92c9f54c4"},
{file = "traitlets-5.1.0.tar.gz", hash = "sha256:bd382d7ea181fbbcce157c133db9a829ce06edffe097bcf3ab945b435452b46d"},
]
typing-extensions = [
{file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"},
{file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"},
{file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"},
{file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"},
{file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"},
]
virtualenv = [
{file = "virtualenv-20.4.4-py2.py3-none-any.whl", hash = "sha256:a935126db63128861987a7d5d30e23e8ec045a73840eeccb467c148514e29535"},
{file = "virtualenv-20.4.4.tar.gz", hash = "sha256:09c61377ef072f43568207dc8e46ddeac6bcdcaf288d49011bda0e7f4d38c4a2"},
]
wcwidth = [
{file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
{file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
]
zipp = [
{file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"},
{file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"},
]

View File

@ -0,0 +1,42 @@
---
title: Behemouth Waterworks from the Age of Steam
description: >-
The Metropolitan Waterworks Museum in Boston Massachusetts was once the centerpoint of the most
advanced municipal water system in America. Today, it educates visitors on the evolution of
Boston's incredible water system and perserves the amazing steam engines that made it possible.
location:
title: Boston, MA
link: https://maps.google.com
date: 2019-05-18
banner: allis
links:
- title: Instagram
icon: fab fa-instagram
url: https://www.instagram.com/p/B1j4w3cgPBq/
- title: Metropolitan Waterworks Museum
url: https://waterworksmuseum.org/
media:
- title: Chestnut Hill Reservoir
link: chestnut-hill
content: >-
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
- title: The Cathedral of Steam
link: high-service-pumping-station
content: >-
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
- title: "Mechanical Art: The Leavitt Engine"
link: leavitt-internals
content: >-
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

View File

@ -0,0 +1,8 @@
---
title: The three hundred year old fort with delusions of grandeur
location:
title: Hull, MA
link: https://maps.google.com
date: 2021-04-12
banner: hull-overlook
media: []

View File

@ -0,0 +1,8 @@
---
title: Talcott's "Castle on the Mountain" does not dissapoint
location:
title: Simsbury, CT
link: https://maps.google.com
date: 2021-04-01
banner: heubline-tower
media: []

View File

@ -0,0 +1,8 @@
---
title: Supervillian lair or air traffic control station?
location:
title: North Truro, MA
link: https://maps.google.com
date: 2021-02-28
banner: north-turo-air-station
media: []

View File

@ -0,0 +1,8 @@
---
title: The Most Essential Lighthouse
location:
title: York, ME
link: https://maps.google.com
date: 2020-11-29
banner: nubble-lighthouse
media: []

View File

@ -10,12 +10,16 @@ python = "^3.8"
"ruamel.yaml" = "^0.17.4"
Jinja2 = "^2.11.3"
marshmallow = "^3.11.1"
minify-html = "^0.8.0"
jsmin = "^3.0.0"
[tool.poetry.dev-dependencies]
black = "^20.8b1"
ipython = "^7.28.0"
mdformat = "^0.7.10"
pre-commit = "^2.12.1"
reorder-python-imports = "^2.4.0"
pre-commit-hooks = "^3.4.0"
reorder-python-imports = "^2.4.0"
black = "^22.1.0"
[build-system]
requires = ["poetry-core>=1.0.0"]

View File

@ -1,9 +0,0 @@
# Allow all bots
User-agent: *
# Disallow access to non-content directories
Disallow: /css
Disallow: /js
Disallow: /error
Sitemap: https://allaroundhere.org/sitemap.xml

40
templates/explore.html.j2 Normal file
View File

@ -0,0 +1,40 @@
{% from "macros.html.j2" import make_header %}{% from "macros.html.j2" import make_social_links %}<!DOCTYPE html>
<html lang="en">
{{ make_header(config, alttitle="Explore " + config.title, css_bundle=css_bundle, js_bundle=js_bundle) }}
<body>
<div id="background-image"><div class="overlay"></div></div>
<div id="preloader" class="nojs"><div class="spinner"><div></div></div></div>
<div id="toggle-description" class="nojs active"><i class="fas fa-paragraph"></i></div>
<div id="content">
<div id="header">
<h1>
Explore {{ config.title }}
<span class="float-right">
{{ make_social_links(config) }}
</span>
</h1>
</div>
<ul>
{% for post in posts %}
<li class="article primary-text{{ ' hidden' if loop.index > 10 else '' }}">
<div class="article-banner" style="background-image: url('{{ post.banner_url(config) }}');">
<a href="{{ post.slug }}/" class="article-content">
<h2>{{ post.title }}</h2>
<p>
<i class="fas fa-map-marker-alt"></i>{{ post.location.title }}
<i class="far fa-calendar-alt"></i>{{ post.date }}
</p>
</a>
</div>
</li>
{% endfor %}
</ul>
</div>
</body>
</html>

View File

@ -1,100 +1,43 @@
<!DOCTYPE html>
{% from "macros.html.j2" import make_header %}{% from "macros.html.j2" import make_social_links %}<!DOCTYPE html>
<html lang="en">
<head>
<!-- Web crawler and search indexing meta -->
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="author" content="admin@allaroundhere.org"/>
<meta name="description" content="Some of the best places are all around here"/>
<meta name="robots" content="index follow"/>
<meta
name="keywords"
content="travel photography explore exploration urbex urban nature all around here local museum history historical society"
/>
<!-- Facebook integration meta -->
<meta property="og:title" content="All Around Here"/>
<meta property="og:url" content="https://allaroundhere.org/explore/"/>
<meta property='og:site_name' content="All Around Here"/>
<meta property="og:type" content="website"/>
<meta property='og:locale' content="en_US"/>
<meta property="og:image" content="https://cdn.enp.one/img/backgrounds/cl-photo-boston.jpg"/>
<meta property='og:description' content="Some of the best places are all around here"/>
<!-- Twitter integration meta -->
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="https://allaroundhere.org/explore/">
<meta name="twitter:title" content="All Around Here">
<meta name="twitter:description" content="Some of the best places are all around here">
<meta name="twitter:image" content="https://cdn.enp.one/img/backgrounds/cl-photo-boston.jpg">
<meta name="twitter:image:alt" content="All Around Here">
<title>Explore All Around Here</title>
<link rel="shortcut icon" href="https://cdn.enp.one/img/logos/aah-b-sm.png">
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.enp.one/img/logos/aah-b-sm.png">
<link rel="icon" type="image/png" sizes="32x32" href="https://cdn.enp.one/img/logos/aah-b-sm.png" >
<link rel="icon" type="image/png" sizes="16x16" href="https://cdn.enp.one/img/logos/aah-b-sm.png">
<link rel="stylesheet" href="../css/explore.css"/>
<link
rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.6.3/css/all.css"
integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/"
crossorigin="anonymous"
/>
<script type="text/javascript" src="../js/custom.js"></script>
<noscript><style>.nojs { display: none; }</style></noscript>
</head>
{{ make_header(config, css_bundle=css_bundle, js_bundle=js_bundle) }}
<body>
<div id="background-image"><div class="overlay"></div></div>
<div id="background-image"></div>
<div id="preloader" class="nojs"><div class="spinner"><div></div></div></div>
<div id="toggle-description" class="nojs"><i class="fas fa-paragraph"></i></div>
<div id="content">
<div id="header">
<h1>
Explore All Around Here
<img
id="logo"
alt="Road to the great wide nowhere"
src="https://cdn.enp.one/img/logos/aah-md.jpg"
/>
<span class="float-right">
<a
class="button instagram"
title="Follow All Around Here on instagram @allaroundhere"
href="https://www.instagram.com/allaroundhere/"
>
<i class="fab fa-instagram"></i>
</a>
<a
class="button twitter"
title="Follow me on twitter @enpaul_"
href="https://www.twitter.com/enpaul_/"
>
<i class="fab fa-twitter"></i>
</a>
</span>
</h1>
</div>
<h1>{{ config.title }}</h1>
<ul>
{% for post in config.posts %}
<li class="article">
<div class="article-banner" style="background-image: url('{{ post.banner }}');">
<a href="{{ post.slug }}/" class="article-content">
<h2>{{ post.title }}</h2>
<p>
<i class="fas fa-map-marker-alt"></i>{{ post.location.title }}
<i class="far fa-calendar-alt"></i>{{ post.date }}
</p>
</a>
</div>
<p>
This is a project of mine where I turn my random travels, undirected wanderings, and
unexpected discoveries into something other people can enjoy along with me. There are a
lot of cool things in the world and I like to find them, wherever I happen to be. If you're
interested in seeing some of these arbitrary oddities then check out the links below.
</p>
<ul class="buttons">
<li>
<a class="button nav" title="Explore All Around Here" href="{{ config.baseurl }}{{ config.build.post_base }}">
<i class="fas fa-binoculars"></i>&nbsp;Explore
</a>
</li>
{% endfor %}
</ul>
<footer>
<div>
{{ make_social_links(config) }}
</div>
<div>
<a title="Personal website" href="https://enpaul.net/">&copy;2022-{{ today.year }} enpaul</a>
</div>
</footer>
</div>
</body>

62
templates/macros.html.j2 Normal file
View File

@ -0,0 +1,62 @@
{% macro make_header(config, alttitle=none, css_bundle=none, js_bundle=none) %}
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<!-- Web crawler and search indexing meta -->
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="author" content="{{ config.email }}"/>
<meta name="description" content="{{ config.description }}"/>
<meta name="robots" content="index follow"/>
<meta name="keywords" content="{{ config.keywords | join(' ') }}"/>
<!-- Facebook integration meta -->
<meta property="og:title" content="{{ alttitle or config.title }}"/>
<meta property="og:url" content="{{ config.url }}{{ config.build.post_base }}"/>
<meta property='og:site_name' content="{{ config.title }}"/>
<meta property="og:type" content="website"/>
<meta property='og:locale' content="en_US"/>
<meta property="og:image" content="https://cdn.enp.one/img/backgrounds/cl-photo-boston.jpg"/>
<meta property='og:description' content="{{ config.description }}"/>
<!-- Twitter integration meta -->
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="{{ config.url }}{{ config.build.post_base }}">
<meta name="twitter:title" content="{{ alttitle or config.title }}">
<meta name="twitter:description" content="{{ config.description }}">
<meta name="twitter:image" content="https://cdn.enp.one/img/backgrounds/cl-photo-boston.jpg">
<meta name="twitter:image:alt" content="{{ config.title }}">
<title>{{ alttitle or config.title }}</title>
<link rel="shortcut icon" href="https://cdn.enp.one/img/logos/aah-b-sm.png">
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.enp.one/img/logos/aah-b-sm.png">
<link rel="icon" type="image/png" sizes="32x32" href="https://cdn.enp.one/img/logos/aah-b-sm.png" >
<link rel="icon" type="image/png" sizes="16x16" href="https://cdn.enp.one/img/logos/aah-b-sm.png">
{% if css_bundle %}<link rel="stylesheet" href="{{ config.baseurl }}css/{{ css_bundle }}.css"/>{% endif %}
<link
rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.6.3/css/all.css"
integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/"
crossorigin="anonymous"
/>
{% if js_bundle %}<script type="text/javascript" src="{{ config.baseurl }}js/{{ js_bundle }}.js"></script>{% endif %}
<noscript><style>.nojs { display: none; }</style></noscript>
</head>
{% endmacro %}
{% macro make_social_links(config) %}
{% for social, link in config.social.items() %}
<a
class="button {{ social }}"
title="Follow me on {{ social }} @{{ link.rstrip('/').rpartition('/')[-1] }}"
href="{{ link }}"
>
<i class="fab fa-{{ social }}"></i>
</a>
{% endfor %}
{% endmacro %}

View File

@ -0,0 +1,43 @@
{% from "macros.html.j2" import make_header %}{% from "macros.html.j2" import make_social_links %}<!DOCTYPE html>
<html lang="en">
{{ make_header(config, alttitle=post.title, css_bundle=css_bundle, js_bundle=js_bundle) }}
<body>
<div id="preloader" class="nojs"><div class="spinner"><div></div></div></div>
{% for media in post.media %}
<div class="post-media" style="background-image: url('{{ media.preload_url(config) }}')"><div class="overlay"></div></div>
{% endfor %}
<div id="download-source" class="nojs"><i class="fas fa-cloud-download-alt"></i></div>
<div id="link" class="nojs"><i class="fas fa-link"></i></div>
<div id="media-previous" class="nojs"><i class="fas fa-chevron-left"></i></div>
<div id="media-next" class="nojs"><i class="fas fa-chevron-right"></i></div>
<div id="content">
<div id="header">
<h1>
Explore {{ config.title }}
<span class="float-right">
{{ make_social_links(config) }}
</span>
</h1>
</div>
<ul>
{% for post in posts %}
<li class="article primary-text">
<div class="article-banner" style="background-image: url('{{ post.banner_url(config) }}');">
<a href="{{ post.slug }}/" class="article-content">
<h2>{{ post.title }}</h2>
<p>
<i class="fas fa-map-marker-alt"></i>{{ post.location.title }}
<i class="far fa-calendar-alt"></i>{{ post.date }}
</p>
</a>
</div>
</li>
{% endfor %}
</ul>
</div>
</body>
</html>

7
templates/robots.txt.j2 Normal file
View File

@ -0,0 +1,7 @@
# Allow all bots
User-agent: *
# Disallow access to non-content directories{% for path in disallowed %}
Disallow: {{ path }}{% endfor %}
Sitemap: {{ config.url }}sitemap.xml

View File

@ -7,21 +7,22 @@
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
<loc>https://allaroundhere.org/</loc>
<lastmod>2021-02-01T00:30:55+00:00</lastmod>
<priority>1.00</priority>
<loc>{{ config.url }}</loc>
<lastmod>{{ today.strftime('%Y-%m-%dT%H:%M:%S') }}+00:00</lastmod>
<priority>0.90</priority>
</url>
<url>
<loc>https://allaroundhere.org/explore/</loc>
<lastmod>2021-02-01T00:30:55+00:00</lastmod>
<priority>1.10</priority>
<loc>{{ config.url }}{{ config.build.post_base }}</loc>
<lastmod>{{ today.strftime('%Y-%m-%dT%H:%M:%S') }}+00:00</lastmod>
<priority>1.00</priority>
</url>
{% for post in config.posts %}
{% for post in config.posts %}
<url>
<loc>https://allaroundhere.org/explore/{{ post.slug }}/</loc>
<lastmod>2021-02-01T00:30:55+00:00</lastmod>
<priority>0.90</priority>
<loc>{{ config.url }}{{ config.build.post_base }}{{ post.slug }}</loc>
<lastmod>{{ today.strftime('%Y-%m-%dT%H:%M:%S') }}+00:00</lastmod>
<priority>0.80</priority>
</url>
{% endfor %}
{% endfor %}
</urlset>