Compare commits

..

26 Commits

Author SHA1 Message Date
c4c6265852 Terrace Books has moved locations.
Some checks are pending
ci/woodpecker/push/woodpecker Pipeline is running
2024-09-07 23:59:54 +00:00
8d2f7d238f Two new combination eatery/bookstore locations, Honey Moon and Sullaluna
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-08-16 00:17:59 +00:00
ae5f2b7270 Merge pull request 'Update dependency cheerio to v1.0.0' (#13) from renovate/cheerio-1.x-lockfile into main
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #13
2024-08-13 01:16:30 +00:00
a3f4c45733 Update dependency cheerio to v1.0.0
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-08-09 20:01:41 +00:00
d1600e763a [skip] Merge pull request 'scope when jobs run' (#12) from scope-when into main
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #12
2024-07-08 19:25:40 -04:00
92cea97430 scope when jobs run
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-07-08 19:24:41 -04:00
dc9c4c0ca7 Merge pull request 'Update node Docker tag to v22' (#10) from renovate/node-22.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #10
2024-07-08 19:20:03 -04:00
48c4e817d7 add build step for branches
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-07-08 19:17:03 -04:00
0f954d30a9 fix import syntax
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-07-08 19:14:46 -04:00
24f9aff11d Update node Docker tag to v22 2024-07-08 19:14:46 -04:00
e5f0a70f97 Add Liz's Book Bar in Brooklyn
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-07-03 00:36:42 +00:00
1e476c767b Merge pull request 'Update caddy Docker tag to v2.8.4' (#11) from renovate/caddy-2.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #11
2024-06-09 14:48:52 +00:00
e28078402f Update caddy Docker tag to v2.8.4
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-06-03 19:01:14 +00:00
66c1682b0b Update to note that La Joie de Vivre has a café now
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-03-30 01:02:45 +00:00
bc49f31237 Shakespeare and Co opens a new Upper West Side location
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-03-06 22:05:57 -05:00
3def1a40ce add [ignore] to the magic list of changelog exclusions
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-21 21:53:42 -05:00
1b3dc47f4e add missing required og tag [skip] 2024-02-21 01:29:58 +00:00
cd97756ec2 move Yu and Me back to its original location (congrats!)
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-28 16:27:29 +00:00
0d796eb63c update cached index [skip]
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-21 21:32:04 -05:00
f49a1d3bc7 Merge pull request 'Update node Docker tag to v21' (#8) from renovate/node-21.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #8
2024-01-22 02:30:01 +00:00
5c49dc346c Add Bibliotheque and The World's Borough Bookshop
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-01 17:53:39 +00:00
0467591053 add La Joie de Vivre, a French/English bookstore in the Flatiron Distirct
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-12-28 00:40:18 +00:00
c3f917faa5 add canonical link
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-12-22 02:56:27 +00:00
97503c3d68 Merge pull request 'Update caddy Docker tag to v2.7.6' (#9) from renovate/caddy-2.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #9
2023-12-15 14:43:33 +00:00
cf0dddd4a6 Update caddy Docker tag to v2.7.6
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-12-14 22:01:03 +00:00
9528b39d6d Update node Docker tag to v21
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-10-24 00:01:05 +00:00
7 changed files with 584 additions and 279 deletions

View File

@ -6,6 +6,18 @@
depth: 15 depth: 15
steps: steps:
test:
image: docker
commands:
- apk add curl
- docker build .
when:
- event: push
branch:
exclude: ["main"]
volumes:
- /var/run/docker.sock:/var/run/docker.sock
build: build:
image: docker image: docker
commands: commands:
@ -17,6 +29,8 @@ steps:
- 'curl http://100.113.98.36:4000/api/update -H "Authorization: Bearer $COMPOSE_TOKEN"' - 'curl http://100.113.98.36:4000/api/update -H "Authorization: Bearer $COMPOSE_TOKEN"'
secrets: [docker_username, docker_password, compose_token] secrets: [docker_username, docker_password, compose_token]
when: when:
branch: "master" - event: push
branch:
include: ["main"]
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock

View File

@ -1,10 +1,10 @@
FROM node:20 AS builder FROM node:22 AS builder
COPY . /src COPY . /src
WORKDIR /src WORKDIR /src
RUN npm install && node ./index.js RUN npm install && node ./index.js
FROM caddy:2.7.5 FROM caddy:2.8.4
COPY img /usr/share/caddy/img COPY img /usr/share/caddy/img
COPY css /usr/share/caddy/css COPY css /usr/share/caddy/css

View File

@ -1,33 +1,38 @@
/* Page Specific CSS */
body { body {
font-family: "Lato", sans-serif; font-family: "Lato", sans-serif;
background: #fff; background: #fff;
color: #333; color: #333;
font-size: 16px; font-size: 18px;
margin: 0px; margin: 0px;
padding: 0px; padding: 20px 0px;
} }
h1 { h1 {
font-size: 40px; font-size: 80px;
font-family: "Acme", sans-serif; font-family: "Acme", sans-serif;
font-weight: normal; font-weight: normal;
margin: 0px; margin: 0px;
} }
h2 { h2 {
font-size: 30px; font-size: 40px;
font-family: "Acme", sans-serif; font-family: "Acme", sans-serif;
font-weight: normal; font-weight: normal;
margin: 0px 0px; margin: 0px 0px;
} }
h3 { h3 {
font-family: "Acme", sans-serif; font-family: "Acme", sans-serif;
font-size: 20px; font-size: 30px;
margin: 10px 0px; margin: 10px 0px;
} }
h4 { h4 {
font-family: "Lato", sans-serif; font-family: "Lato", sans-serif;
font-size: 14px; font-size: 24px;
} }
img {
width: 100%;
}
p a, p a,
a { a {
color: #333; color: #333;
@ -38,6 +43,10 @@ a {
a:hover { a:hover {
color: #47ccfc; color: #47ccfc;
} }
small {
padding: 10px 0px;
font-size: 10px;
}
p { p {
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
@ -47,14 +56,22 @@ li {
line-height: 19px; line-height: 19px;
font-size: 15px; font-size: 15px;
} }
ol {
line-height: 24px;
}
.clearfix {
clear: both;
}
.hidden { .hidden {
display: none; display: none;
} }
#map { #map {
height: 100vh; height: 500px;
width: 100%; width: 480px;
min-width: 300px;
background: #ffffff; background: #ffffff;
float: left;
} }
#map a { #map a {
border: none; border: none;
@ -66,19 +83,13 @@ li {
} }
#wrapper { #wrapper {
max-width: 500px; margin: 0px auto;
position: absolute; padding: 40px;
top: 10px; max-width: 1000px;
right: 10px;
bottom: 10px;
overflow: scroll;
} }
.bubble { .container {
background-color: white; margin: 24px 0px;
margin: 10px 0px;
padding: 10px;
border-radius: 3px;
} }
ul.nav { ul.nav {
@ -94,7 +105,7 @@ ul.nav li {
} }
ul.nav li:not(:first-child) { ul.nav li:not(:first-child) {
border-left: 1px #333 solid; border-left: 1px #333 solid;
padding-left: 5px; padding-left: 10px;
} }
ul.nav li h2 { ul.nav li h2 {
font-family: "Lato"; font-family: "Lato";
@ -115,9 +126,15 @@ ul.nav li a:hover {
font-weight: 700; font-weight: 700;
} }
#selected {
max-width: 500px;
width: 100%;
float: left;
padding: 5px 10px;
}
#selected .description { #selected .description {
padding-top: 7px;
font-size: 16px; font-size: 16px;
padding: 4px 0px;
line-height: 22px; line-height: 22px;
text-align: justify; text-align: justify;
} }
@ -126,17 +143,27 @@ ul.nav li a:hover {
margin: 15px 0px; margin: 15px 0px;
padding: 0px; padding: 0px;
} }
#info {
max-width: 500px;
width: 100%;
float: left;
padding: 5px 10px;
}
.storeDetails { .storeDetails {
font-size: 15px; font-size: 15px;
display: inline; display: inline;
padding-right: 6px;
} }
#info p { #info p {
font-size: 15px; font-size: 15px;
padding: 4px;
line-height: 22px; line-height: 22px;
text-align: justify; text-align: justify;
} }
#info details { #info details {
font-size: 15px; font-size: 15px;
padding: 4px;
line-height: 22px; line-height: 22px;
text-align: justify; text-align: justify;
} }
@ -147,34 +174,40 @@ ul.nav li a:hover {
#Stores { #Stores {
margin: 0 auto; margin: 0 auto;
width: 80%;
} }
#Stores tr { #Stores tr {
cursor: pointer; cursor: pointer;
} }
#Stores tr td { #Stores tr td {
padding: 2px 0px; padding: 4px 10px;
} }
#Stores tr:not(:last-child) td { #Stores tr:not(:last-child) td {
border-bottom: 1px #ddd solid; border-bottom: 1px #ddd solid;
} }
@media only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 320px) and (max-width: 1120px) { @media only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 320px) and (max-width: 1120px) {
#wrapper { h1 {
position: static; font-size: 60px;
padding: 10px;
} }
.bubble { body {
margin: 0px; margin: 0px;
padding: 0px; padding: 5px;
border-radius: 0px;
} }
#map { #wrapper {
height: 400px; max-width: 480px;
padding-top: 20px;
} }
#Stores, #Stores,
#map {
min-width: 224px;
width: 100%;
}
#map, #map,
#info, #info,
#selected { #selected {
width: 100%; width: 100%;
margin: 10px 0px;
padding: 0;
} }
} }

View File

@ -31,7 +31,7 @@
media="screen" media="screen"
rel="stylesheet" rel="stylesheet"
type="text/css" type="text/css"
href="/css/site.css?1698627633277" href="/css/site.css?1709780697849"
/> />
<meta <meta
property="title" property="title"
@ -55,6 +55,7 @@
content="https://www.nycbookstores.org/img/social.jpg" content="https://www.nycbookstores.org/img/social.jpg"
/> />
<meta property="og:url" content="https://www.nycbookstores.org/" /> <meta property="og:url" content="https://www.nycbookstores.org/" />
<meta property="og:type" content="website" />
<meta property="og:title" content="NYC Bookstores" /> <meta property="og:title" content="NYC Bookstores" />
<meta <meta
property="og:description" property="og:description"
@ -64,13 +65,18 @@
property="og:image" property="og:image"
content="https://www.nycbookstores.org/img/social.jpg" content="https://www.nycbookstores.org/img/social.jpg"
/> />
<link rel="canonical" href="https://www.nycbookstores.org/" />
</head> </head>
<body> <body>
<div id="map"></div>
<div id="wrapper"> <div id="wrapper">
<header class="bubble"> <h1>NYC Bookstores</h1>
<h1>NYC Bookstores</h1> <div>
<ul class="nav"> <ul class="nav">
<li>
<h2 id="subhed">
The Many Independent Bookstores of New York City
</h2>
</li>
<li> <li>
<a id="viewInfo" href="#info" onclick="event.preventDefault()" <a id="viewInfo" href="#info" onclick="event.preventDefault()"
>intro</a >intro</a
@ -89,81 +95,85 @@
> >
</li> </li>
</ul> </ul>
</header> </div>
<div id="info" class="bubble"> <div class="container">
<p> <div id="map"></div>
New York City loves its independent bookstores. It <div id="info">
<a <p>
href="https://www.nytimes.com/2006/10/15/nyregion/thecity/15book.html" New York City loves its independent bookstores. It
target="_blank" <a
>eulogizes those that have faded</a href="https://www.nytimes.com/2006/10/15/nyregion/thecity/15book.html"
> target="_blank"
and celebrates when new ventures are launched. And while the historic >eulogizes those that have faded</a
<a >
href="https://untappedcities.com/2015/08/26/4th-avenue-the-history-of-nycs-book-row/" and celebrates when new ventures are launched. And while the
target="_blank" historic
>Book Row may have passed away in the 80s</a <a
>, there are still many indie bookstores dotting the map, across all href="https://untappedcities.com/2015/08/26/4th-avenue-the-history-of-nycs-book-row/"
five boroughs. Here, I have attempted to collect all of the target="_blank"
currently-open general-interest independent booksellers in NYC. Any >Book Row may have passed away in the 80s</a
store with regular-ish hours (excluding religious booksellers and >, there are still many indie bookstores dotting the map, across all
appointment-only rare book sellers) is included. five boroughs. Here, I have attempted to collect all of the
</p> currently-open general-interest independent booksellers in NYC. Any
<p> store with regular-ish hours (excluding religious booksellers and
While Manhattan and Brooklyn still lead the pack, Queens has a appointment-only rare book sellers) is included.
respectable number of stores, and all five boroughs are represented, </p>
with the Bronx and Staten Island both hosting lone independent stores. <p>
Lower Manhattan has the highest density of booksellers. While Manhattan and Brooklyn still lead the pack, Queens has a
</p> respectable number of stores, and all five boroughs are represented,
<p> with the Bronx and Staten Island both hosting lone independent
The listings here are kept up-to-date to the best of my ability; stores. Lower Manhattan has the highest density of booksellers.
however, I make no promises about either the accuracy or reliability </p>
of the information. If you spot an error, or I've missed a shop, <p>
please let me know by The listings here are kept up-to-date to the best of my ability;
<a href="mailto:delta.mu.alpha@gmail.com" target="_blank">email</a>, however, I make no promises about either the accuracy or reliability
<a href="https://icosahedron.website/@lazyreader" target="_blank" of the information. If you spot an error, or I've missed a shop,
>mastodon</a please let me know by
>, or <a href="mailto:delta.mu.alpha@gmail.com" target="_blank">email</a>,
<a href="https://www.twitter.com/alazyreader" target="_blank" <a href="https://icosahedron.website/@lazyreader" target="_blank"
>twitter</a >mastodon</a
>. Originally based on the "<a >, or
href="https://github.com/jlord/hack-spots" <a href="https://www.twitter.com/alazyreader" target="_blank"
target="_blank" >twitter</a
>Hack Spots</a >. Originally based on the "<a
>" website by href="https://github.com/jlord/hack-spots"
<a href="https://www.twitter.com/jllord" target="_blank">@jllord</a> target="_blank"
(although I don't believe any of the actual underlying code still >Hack Spots</a
survives at this point). >" website by
</p> <a href="https://www.twitter.com/jllord" target="_blank">@jllord</a>
<p> (although I don't believe any of the actual underlying code still
There are currently <span id="storeCount">114</span> stores indexed on survives at this point).
this page. Last updated <span id="updatedOn">October 29, 2023</span>. </p>
</p> <p>
<details> There are currently <span id="storeCount">118</span> stores indexed
<summary>Recent Changes</summary> on this page. Last updated
<ul id="changesList"> <span id="updatedOn">March 6, 2024</span>.
<li> </p>
October 26, 2023 - Return Three Lives to its original corner <details>
location. <summary>Recent Changes</summary>
</li> <ul id="changesList">
<li> <li>
October 26, 2023 - Idlewild Books appears to have transitioned January 28, 2024 - move Yu and Me back to its original location
entirely to language classes as opposed to bookselling (congrats!)
</li> </li>
<li> <li>
October 26, 2023 - remove Boulevard Books; correct Alabaster January 1, 2024 - Add Bibliotheque and The World's Borough
Bookshop Instagram link Bookshop
</li> </li>
<li> <li>
October 26, 2023 - Add Topos Too, currently in a "soft opening" December 27, 2023 - add La Joie de Vivre, a French/English
</li> bookstore in the Flatiron Distirct
</ul> </li>
</details> <li>December 21, 2023 - add canonical link</li>
</ul>
</details>
</div>
<div id="selected"></div>
</div> </div>
<div id="selected" class="bubble hidden"></div> <div class="clearfix"></div>
<div class="bubble"> <div class="container">
<div id="Stores"> <div id="Stores">
<table> <table>
<tbody> <tbody>
@ -216,414 +226,433 @@
<td>90 Kosciuszko St, Brooklyn</td> <td>90 Kosciuszko St, Brooklyn</td>
</tr> </tr>
<tr id="12" class="spotRow"> <tr id="12" class="spotRow">
<td class="name">Bibliotheque</td>
<td>54 Mercer St, New York</td>
</tr>
<tr id="13" class="spotRow">
<td class="name">Black Spring Books</td> <td class="name">Black Spring Books</td>
<td>672 Driggs Ave, Brooklyn</td> <td>672 Driggs Ave, Brooklyn</td>
</tr> </tr>
<tr id="13" class="spotRow"> <tr id="14" class="spotRow">
<td class="name">Bluestockings Cooperative</td> <td class="name">Bluestockings Cooperative</td>
<td>116 Suffolk Street, New York</td> <td>116 Suffolk Street, New York</td>
</tr> </tr>
<tr id="14" class="spotRow"> <tr id="15" class="spotRow">
<td class="name">Bonnie Slotnick Cookbooks</td> <td class="name">Bonnie Slotnick Cookbooks</td>
<td>28 East 2nd St, New York</td> <td>28 East 2nd St, New York</td>
</tr> </tr>
<tr id="15" class="spotRow"> <tr id="16" class="spotRow">
<td class="name">Book Club Bar</td> <td class="name">Book Club Bar</td>
<td>197 E 3rd St, New York</td> <td>197 E 3rd St, New York</td>
</tr> </tr>
<tr id="16" class="spotRow"> <tr id="17" class="spotRow">
<td class="name">Book Culture</td> <td class="name">Book Culture</td>
<td>536 W 112th St, New York</td> <td>536 W 112th St, New York</td>
</tr> </tr>
<tr id="17" class="spotRow"> <tr id="18" class="spotRow">
<td class="name">Book Culture LIC</td> <td class="name">Book Culture LIC</td>
<td>26-09 Jackson Ave, Queens</td> <td>26-09 Jackson Ave, Queens</td>
</tr> </tr>
<tr id="18" class="spotRow"> <tr id="19" class="spotRow">
<td class="name">Book Culture on Broadway</td> <td class="name">Book Culture on Broadway</td>
<td>2915 Broadway, New York</td> <td>2915 Broadway, New York</td>
</tr> </tr>
<tr id="19" class="spotRow"> <tr id="20" class="spotRow">
<td class="name">Book Thug Nation</td> <td class="name">Book Thug Nation</td>
<td>100 North 3rd St, Brooklyn</td> <td>100 North 3rd St, Brooklyn</td>
</tr> </tr>
<tr id="20" class="spotRow"> <tr id="21" class="spotRow">
<td class="name">Bookmarc</td> <td class="name">Bookmarc</td>
<td>400 Bleecker St, New York</td> <td>400 Bleecker St, New York</td>
</tr> </tr>
<tr id="21" class="spotRow"> <tr id="22" class="spotRow">
<td class="name">BookMark Shoppe</td> <td class="name">BookMark Shoppe</td>
<td>8415 3rd Avenue, Brooklyn</td> <td>8415 3rd Avenue, Brooklyn</td>
</tr> </tr>
<tr id="22" class="spotRow"> <tr id="23" class="spotRow">
<td class="name">Bookoff</td> <td class="name">Bookoff</td>
<td>49 W 45nd St, New York</td> <td>49 W 45nd St, New York</td>
</tr> </tr>
<tr id="23" class="spotRow"> <tr id="24" class="spotRow">
<td class="name">Bookoff Brooklyn</td> <td class="name">Bookoff Brooklyn</td>
<td>934 3rd Ave, Brooklyn</td> <td>934 3rd Ave, Brooklyn</td>
</tr> </tr>
<tr id="24" class="spotRow"> <tr id="25" class="spotRow">
<td class="name">Books Are Magic (Montague St.)</td> <td class="name">Books Are Magic (Montague St.)</td>
<td>122 Montague St, Brooklyn</td> <td>122 Montague St, Brooklyn</td>
</tr> </tr>
<tr id="25" class="spotRow"> <tr id="26" class="spotRow">
<td class="name">Books Are Magic (Smith St.)</td> <td class="name">Books Are Magic (Smith St.)</td>
<td>225 Smith St, Brooklyn</td> <td>225 Smith St, Brooklyn</td>
</tr> </tr>
<tr id="26" class="spotRow"> <tr id="27" class="spotRow">
<td class="name">Books Of Wonder</td> <td class="name">Books Of Wonder</td>
<td>42 West 17th St, New York</td> <td>42 West 17th St, New York</td>
</tr> </tr>
<tr id="27" class="spotRow"> <tr id="28" class="spotRow">
<td class="name">Bravo's Book Nook</td> <td class="name">Bravo's Book Nook</td>
<td>115 MacDougal St, New York</td> <td>115 MacDougal St, New York</td>
</tr> </tr>
<tr id="28" class="spotRow"> <tr id="29" class="spotRow">
<td class="name">Burnt Books</td> <td class="name">Burnt Books</td>
<td>157 Huron St, Brooklyn</td> <td>157 Huron St, Brooklyn</td>
</tr> </tr>
<tr id="29" class="spotRow"> <tr id="30" class="spotRow">
<td class="name">Cafe con Libros</td> <td class="name">Cafe con Libros</td>
<td>724 Prospect Place, Brooklyn</td> <td>724 Prospect Place, Brooklyn</td>
</tr> </tr>
<tr id="30" class="spotRow"> <tr id="31" class="spotRow">
<td class="name">Catland</td> <td class="name">Catland</td>
<td>985 Flushing Ave, Brooklyn</td> <td>985 Flushing Ave, Brooklyn</td>
</tr> </tr>
<tr id="31" class="spotRow"> <tr id="32" class="spotRow">
<td class="name">Chartwell Booksellers</td> <td class="name">Chartwell Booksellers</td>
<td>55 E 52nd St, New York</td> <td>55 E 52nd St, New York</td>
</tr> </tr>
<tr id="32" class="spotRow"> <tr id="33" class="spotRow">
<td class="name">Codex Books</td> <td class="name">Codex Books</td>
<td>1 Bleecker St, New York</td> <td>1 Bleecker St, New York</td>
</tr> </tr>
<tr id="33" class="spotRow"> <tr id="34" class="spotRow">
<td class="name">Community Bookstore</td> <td class="name">Community Bookstore</td>
<td>143 7th Ave, Brooklyn</td> <td>143 7th Ave, Brooklyn</td>
</tr> </tr>
<tr id="34" class="spotRow"> <tr id="35" class="spotRow">
<td class="name">Cups and Books</td> <td class="name">Cups and Books</td>
<td>2024 Bedford Ave, Brooklyn</td> <td>2024 Bedford Ave, Brooklyn</td>
</tr> </tr>
<tr id="35" class="spotRow"> <tr id="36" class="spotRow">
<td class="name">Dashwood Books</td> <td class="name">Dashwood Books</td>
<td>33 Bond St, New York</td> <td>33 Bond St, New York</td>
</tr> </tr>
<tr id="36" class="spotRow"> <tr id="37" class="spotRow">
<td class="name">Dear Friend Books</td> <td class="name">Dear Friend Books</td>
<td>343A Tompkins Ave, Brooklyn</td> <td>343A Tompkins Ave, Brooklyn</td>
</tr> </tr>
<tr id="37" class="spotRow"> <tr id="38" class="spotRow">
<td class="name">Desert Island Comics</td> <td class="name">Desert Island Comics</td>
<td>540 Metropolitan Ave, Brooklyn</td> <td>540 Metropolitan Ave, Brooklyn</td>
</tr> </tr>
<tr id="38" class="spotRow"> <tr id="39" class="spotRow">
<td class="name">East Village Books</td> <td class="name">East Village Books</td>
<td>99 St. Mark's Place, New York</td> <td>99 St. Mark's Place, New York</td>
</tr> </tr>
<tr id="39" class="spotRow"> <tr id="40" class="spotRow">
<td class="name">ETG Book Cafe</td> <td class="name">ETG Book Cafe</td>
<td>208 Bay St, Staten Island</td> <td>208 Bay St, Staten Island</td>
</tr> </tr>
<tr id="40" class="spotRow"> <tr id="41" class="spotRow">
<td class="name">Freebird Books</td> <td class="name">Freebird Books</td>
<td>123 Columbia St, Brooklyn</td> <td>123 Columbia St, Brooklyn</td>
</tr> </tr>
<tr id="41" class="spotRow"> <tr id="42" class="spotRow">
<td class="name">Greenlight Bookstore</td> <td class="name">Greenlight Bookstore</td>
<td>686 Fulton St, Brooklyn</td> <td>686 Fulton St, Brooklyn</td>
</tr> </tr>
<tr id="42" class="spotRow"> <tr id="43" class="spotRow">
<td class="name">Here's A Book Store</td> <td class="name">Here's A Book Store</td>
<td>1964 Coney Island Ave, Brooklyn</td> <td>1964 Coney Island Ave, Brooklyn</td>
</tr> </tr>
<tr id="43" class="spotRow"> <tr id="44" class="spotRow">
<td class="name">Hey Kids! Comics</td> <td class="name">Hey Kids! Comics</td>
<td>157 Huron St, Brooklyn</td> <td>157 Huron St, Brooklyn</td>
</tr> </tr>
<tr id="44" class="spotRow"> <tr id="45" class="spotRow">
<td class="name">Housing Works Bookstore Café</td> <td class="name">Housing Works Bookstore Café</td>
<td>126 Crosby St, New York</td> <td>126 Crosby St, New York</td>
</tr> </tr>
<tr id="45" class="spotRow"> <tr id="46" class="spotRow">
<td class="name">Human Relations Books</td> <td class="name">Human Relations Books</td>
<td>1067 Flushing Ave, Brooklyn</td> <td>1067 Flushing Ave, Brooklyn</td>
</tr> </tr>
<tr id="46" class="spotRow"> <tr id="47" class="spotRow">
<td class="name">James Cummins Bookseller</td> <td class="name">James Cummins Bookseller</td>
<td>699 Madison Ave, 7th Floor, New York</td> <td>699 Madison Ave, 7th Floor, New York</td>
</tr> </tr>
<tr id="47" class="spotRow"> <tr id="48" class="spotRow">
<td class="name">Joanne Hendricks Cookbooks</td> <td class="name">Joanne Hendricks Cookbooks</td>
<td>488 Greenwich St, New York</td> <td>488 Greenwich St, New York</td>
</tr> </tr>
<tr id="48" class="spotRow"> <tr id="49" class="spotRow">
<td class="name">Karma Bookstore</td> <td class="name">Karma Bookstore</td>
<td>136 East Third St, New York</td> <td>136 East Third St, New York</td>
</tr> </tr>
<tr id="49" class="spotRow"> <tr id="50" class="spotRow">
<td class="name">Kew &amp; Willow Books</td> <td class="name">Kew &amp; Willow Books</td>
<td>81-63 Lefferts Boulevard, New York</td> <td>81-63 Lefferts Boulevard, New York</td>
</tr> </tr>
<tr id="50" class="spotRow"> <tr id="51" class="spotRow">
<td class="name">Kinokunya</td> <td class="name">Kinokunya</td>
<td>1073 Avenue of the Americas, New York</td> <td>1073 Avenue of the Americas, New York</td>
</tr> </tr>
<tr id="51" class="spotRow"> <tr id="52" class="spotRow">
<td class="name">Kitchen Arts &amp; Letters</td> <td class="name">Kitchen Arts &amp; Letters</td>
<td>1435 Lexington Ave, New York</td> <td>1435 Lexington Ave, New York</td>
</tr> </tr>
<tr id="52" class="spotRow"> <tr id="53" class="spotRow">
<td class="name">La Joie de Vivre</td>
<td>145 W 27th St, New York</td>
</tr>
<tr id="54" class="spotRow">
<td class="name">Leaves Bookstore</td> <td class="name">Leaves Bookstore</td>
<td>140 Nassau Ave, Brooklyn</td> <td>140 Nassau Ave, Brooklyn</td>
</tr> </tr>
<tr id="53" class="spotRow"> <tr id="55" class="spotRow">
<td class="name">Left Bank Books</td> <td class="name">Left Bank Books</td>
<td>41 Perry St, New York</td> <td>41 Perry St, New York</td>
</tr> </tr>
<tr id="54" class="spotRow"> <tr id="56" class="spotRow">
<td class="name">Lofty Pigeon Books</td> <td class="name">Lofty Pigeon Books</td>
<td>743 Church Ave, Brooklyn</td> <td>743 Church Ave, Brooklyn</td>
</tr> </tr>
<tr id="55" class="spotRow"> <tr id="57" class="spotRow">
<td class="name">Logos Bookstore</td> <td class="name">Logos Bookstore</td>
<td>1575 York Ave, New York</td> <td>1575 York Ave, New York</td>
</tr> </tr>
<tr id="56" class="spotRow"> <tr id="58" class="spotRow">
<td class="name">Mast Books</td> <td class="name">Mast Books</td>
<td>72 Avenue A, New York</td> <td>72 Avenue A, New York</td>
</tr> </tr>
<tr id="57" class="spotRow"> <tr id="59" class="spotRow">
<td class="name">McNally Jackson Books</td> <td class="name">McNally Jackson Books</td>
<td>134 Prince St, New York</td> <td>134 Prince St, New York</td>
</tr> </tr>
<tr id="58" class="spotRow"> <tr id="60" class="spotRow">
<td class="name">McNally Jackson Books City Point</td> <td class="name">McNally Jackson Books City Point</td>
<td>445 Albee Square W, Unit G112, Brooklyn</td> <td>445 Albee Square W, Unit G112, Brooklyn</td>
</tr> </tr>
<tr id="59" class="spotRow"> <tr id="61" class="spotRow">
<td class="name">McNally Jackson Books Seaport</td> <td class="name">McNally Jackson Books Seaport</td>
<td>4 Fulton St, New York</td> <td>4 Fulton St, New York</td>
</tr> </tr>
<tr id="60" class="spotRow"> <tr id="62" class="spotRow">
<td class="name">McNally Jackson Books Williamsburg</td> <td class="name">McNally Jackson Books Williamsburg</td>
<td>76 North 4th St, Brooklyn</td> <td>76 North 4th St, Brooklyn</td>
</tr> </tr>
<tr id="61" class="spotRow"> <tr id="63" class="spotRow">
<td class="name">McNally Jackson Rockefeller Center</td> <td class="name">McNally Jackson Rockefeller Center</td>
<td>1 Rockefeller Plaza, New York</td> <td>1 Rockefeller Plaza, New York</td>
</tr> </tr>
<tr id="62" class="spotRow"> <tr id="64" class="spotRow">
<td class="name">Melville House Publishers</td> <td class="name">Melville House Publishers</td>
<td>46 John St, Brooklyn</td> <td>46 John St, Brooklyn</td>
</tr> </tr>
<tr id="63" class="spotRow"> <tr id="65" class="spotRow">
<td class="name">Mercer Street Books &amp; Records</td> <td class="name">Mercer Street Books &amp; Records</td>
<td>206 Mercer St, New York</td> <td>206 Mercer St, New York</td>
</tr> </tr>
<tr id="64" class="spotRow"> <tr id="66" class="spotRow">
<td class="name">Mil Mundos Books</td> <td class="name">Mil Mundos Books</td>
<td>323 Linden St, Brooklyn</td> <td>323 Linden St, Brooklyn</td>
</tr> </tr>
<tr id="65" class="spotRow"> <tr id="67" class="spotRow">
<td class="name">Molasses Books</td> <td class="name">Molasses Books</td>
<td>770 Hart St, Brooklyn</td> <td>770 Hart St, Brooklyn</td>
</tr> </tr>
<tr id="66" class="spotRow"> <tr id="68" class="spotRow">
<td class="name">Namaste Bookshop</td> <td class="name">Namaste Bookshop</td>
<td>2 W 14th St, New York</td> <td>2 W 14th St, New York</td>
</tr> </tr>
<tr id="67" class="spotRow"> <tr id="69" class="spotRow">
<td class="name">P&amp;T Knitwear</td> <td class="name">P&amp;T Knitwear</td>
<td>180 Orchard St, New York</td> <td>180 Orchard St, New York</td>
</tr> </tr>
<tr id="68" class="spotRow"> <tr id="70" class="spotRow">
<td class="name">Passageway Books</td> <td class="name">Passageway Books</td>
<td>150 9th Ave, New York</td> <td>150 9th Ave, New York</td>
</tr> </tr>
<tr id="69" class="spotRow"> <tr id="71" class="spotRow">
<td class="name">Pillow-Cat Books</td> <td class="name">Pillow-Cat Books</td>
<td>328 East 9th St, New York</td> <td>328 East 9th St, New York</td>
</tr> </tr>
<tr id="70" class="spotRow"> <tr id="72" class="spotRow">
<td class="name">Posman Books Chelsea Market</td> <td class="name">Posman Books Chelsea Market</td>
<td>75 9th Avenue, New York</td> <td>75 9th Avenue, New York</td>
</tr> </tr>
<tr id="71" class="spotRow"> <tr id="73" class="spotRow">
<td class="name">POWERHOUSE @ IC</td> <td class="name">POWERHOUSE @ IC</td>
<td>220 36th St, Building #2, Brooklyn</td> <td>220 36th St, Building #2, Brooklyn</td>
</tr> </tr>
<tr id="72" class="spotRow"> <tr id="74" class="spotRow">
<td class="name">POWERHOUSE Arena</td> <td class="name">POWERHOUSE Arena</td>
<td>28 Adams St, Brooklyn</td> <td>28 Adams St, Brooklyn</td>
</tr> </tr>
<tr id="73" class="spotRow"> <tr id="75" class="spotRow">
<td class="name">POWERHOUSE on 8th</td> <td class="name">POWERHOUSE on 8th</td>
<td>1111 8th Ave, Brooklyn</td> <td>1111 8th Ave, Brooklyn</td>
</tr> </tr>
<tr id="74" class="spotRow"> <tr id="76" class="spotRow">
<td class="name">Printed Matter</td> <td class="name">Printed Matter</td>
<td>231 11th Ave, New York</td> <td>231 11th Ave, New York</td>
</tr> </tr>
<tr id="75" class="spotRow"> <tr id="77" class="spotRow">
<td class="name">Printed Matter St. Marks</td> <td class="name">Printed Matter St. Marks</td>
<td>38 St. Marks Pl, New York</td> <td>38 St. Marks Pl, New York</td>
</tr> </tr>
<tr id="76" class="spotRow"> <tr id="78" class="spotRow">
<td class="name">Quest Bookshop</td> <td class="name">Quest Bookshop</td>
<td>240 E 53rd St, New York</td> <td>240 E 53rd St, New York</td>
</tr> </tr>
<tr id="77" class="spotRow"> <tr id="79" class="spotRow">
<td class="name">Quimby's Bookstore</td> <td class="name">Quimby's Bookstore</td>
<td>536 Metropolitan Ave, Brooklyn</td> <td>536 Metropolitan Ave, Brooklyn</td>
</tr> </tr>
<tr id="78" class="spotRow"> <tr id="80" class="spotRow">
<td class="name">Recirculation</td> <td class="name">Recirculation</td>
<td>876 Riverside Dr, New York</td> <td>876 Riverside Dr, New York</td>
</tr> </tr>
<tr id="79" class="spotRow"> <tr id="81" class="spotRow">
<td class="name">Respect For Life Books-N-Things</td> <td class="name">Respect For Life Books-N-Things</td>
<td>537 Nostrand Ave, Brooklyn</td> <td>537 Nostrand Ave, Brooklyn</td>
</tr> </tr>
<tr id="80" class="spotRow"> <tr id="82" class="spotRow">
<td class="name">Revolution Books</td> <td class="name">Revolution Books</td>
<td>437 Malcolm X Blvd, New York</td> <td>437 Malcolm X Blvd, New York</td>
</tr> </tr>
<tr id="81" class="spotRow"> <tr id="83" class="spotRow">
<td class="name">Rizzoli Bookstore</td> <td class="name">Rizzoli Bookstore</td>
<td>1133 Broadway, New York</td> <td>1133 Broadway, New York</td>
</tr> </tr>
<tr id="82" class="spotRow"> <tr id="84" class="spotRow">
<td class="name">Shakespeare &amp; Company</td> <td class="name">Shakespeare &amp; Company</td>
<td>939 Lexington Ave, New York</td> <td>939 Lexington Ave, New York</td>
</tr> </tr>
<tr id="83" class="spotRow"> <tr id="85" class="spotRow">
<td class="name">
Shakespeare &amp; Company (Manhattan Valley/Columbia
University)
</td>
<td>2736 Broadway, New York</td>
</tr>
<tr id="86" class="spotRow">
<td class="name"> <td class="name">
Shakespeare &amp; Company (Upper West Side) Shakespeare &amp; Company (Upper West Side)
</td> </td>
<td>2020 Broadway, New York</td> <td>2020 Broadway, New York</td>
</tr> </tr>
<tr id="84" class="spotRow"> <tr id="87" class="spotRow">
<td class="name">Sister's Uptown Bookstore</td> <td class="name">Sister's Uptown Bookstore</td>
<td>1942 Amsterdam Ave, New York</td> <td>1942 Amsterdam Ave, New York</td>
</tr> </tr>
<tr id="85" class="spotRow"> <tr id="88" class="spotRow">
<td class="name">Spoonbill &amp; Sugartown, Booksellers</td> <td class="name">Spoonbill &amp; Sugartown, Booksellers</td>
<td>218 Bedford Ave, Brooklyn</td> <td>218 Bedford Ave, Brooklyn</td>
</tr> </tr>
<tr id="86" class="spotRow"> <tr id="89" class="spotRow">
<td class="name">Standards Manual</td> <td class="name">Standards Manual</td>
<td>212 Franklin Street, Brooklyn</td> <td>212 Franklin Street, Brooklyn</td>
</tr> </tr>
<tr id="87" class="spotRow"> <tr id="90" class="spotRow">
<td class="name">Strand Bookstore</td> <td class="name">Strand Bookstore</td>
<td>828 Broadway, New York</td> <td>828 Broadway, New York</td>
</tr> </tr>
<tr id="88" class="spotRow"> <tr id="91" class="spotRow">
<td class="name">Sweet Pickle Books</td> <td class="name">Sweet Pickle Books</td>
<td>47 Orchard St, New York</td> <td>47 Orchard St, New York</td>
</tr> </tr>
<tr id="89" class="spotRow"> <tr id="92" class="spotRow">
<td class="name">Taylor &amp; Co. Books</td> <td class="name">Taylor &amp; Co. Books</td>
<td>1021 Cortelyou Rd, Brooklyn</td> <td>1021 Cortelyou Rd, Brooklyn</td>
</tr> </tr>
<tr id="90" class="spotRow"> <tr id="93" class="spotRow">
<td class="name">Terrace Books</td> <td class="name">Terrace Books</td>
<td>242 Prospect Park West, Brooklyn</td> <td>242 Prospect Park West, Brooklyn</td>
</tr> </tr>
<tr id="91" class="spotRow"> <tr id="94" class="spotRow">
<td class="name">The Austin Book Shop</td> <td class="name">The Austin Book Shop</td>
<td>104-29 Jamaica Ave, Richmond Hill</td> <td>104-29 Jamaica Ave, Richmond Hill</td>
</tr> </tr>
<tr id="92" class="spotRow"> <tr id="95" class="spotRow">
<td class="name">The Book Cellar</td> <td class="name">The Book Cellar</td>
<td>1465 York Ave, New York</td> <td>1465 York Ave, New York</td>
</tr> </tr>
<tr id="93" class="spotRow"> <tr id="96" class="spotRow">
<td class="name">The Center for Fiction</td> <td class="name">The Center for Fiction</td>
<td>15 Lafayette Ave, Brooklyn</td> <td>15 Lafayette Ave, Brooklyn</td>
</tr> </tr>
<tr id="94" class="spotRow"> <tr id="97" class="spotRow">
<td class="name">The Corner Bookstore</td> <td class="name">The Corner Bookstore</td>
<td>1313 Madison Ave, New York</td> <td>1313 Madison Ave, New York</td>
</tr> </tr>
<tr id="95" class="spotRow"> <tr id="98" class="spotRow">
<td class="name">The Drama Book Shop</td> <td class="name">The Drama Book Shop</td>
<td>266 W 39th St, New York</td> <td>266 W 39th St, New York</td>
</tr> </tr>
<tr id="96" class="spotRow"> <tr id="99" class="spotRow">
<td class="name">The Lit. Bar</td> <td class="name">The Lit. Bar</td>
<td>131 Alexander Ave, Bronx</td> <td>131 Alexander Ave, Bronx</td>
</tr> </tr>
<tr id="97" class="spotRow"> <tr id="100" class="spotRow">
<td class="name">The Mysterious Bookshop</td> <td class="name">The Mysterious Bookshop</td>
<td>58 Warren St, New York</td> <td>58 Warren St, New York</td>
</tr> </tr>
<tr id="98" class="spotRow"> <tr id="101" class="spotRow">
<td class="name">The Ripped Bodice</td> <td class="name">The Ripped Bodice</td>
<td>218 5th Ave, Brooklyn</td> <td>218 5th Ave, Brooklyn</td>
</tr> </tr>
<tr id="99" class="spotRow"> <tr id="102" class="spotRow">
<td class="name">The Strand At Columbus Ave</td> <td class="name">The Strand At Columbus Ave</td>
<td>450 Columbus Ave, New York</td> <td>450 Columbus Ave, New York</td>
</tr> </tr>
<tr id="100" class="spotRow"> <tr id="103" class="spotRow">
<td class="name">The Word Is Change</td> <td class="name">The Word Is Change</td>
<td>368 Tompkins Ave, Brooklyn</td> <td>368 Tompkins Ave, Brooklyn</td>
</tr> </tr>
<tr id="101" class="spotRow"> <tr id="104" class="spotRow">
<td class="name">The World's Borough Bookshop</td>
<td>3406 73rd St, Queens</td>
</tr>
<tr id="105" class="spotRow">
<td class="name">Three Lives &amp; Company</td> <td class="name">Three Lives &amp; Company</td>
<td>154 W 10th St, New York</td> <td>154 W 10th St, New York</td>
</tr> </tr>
<tr id="102" class="spotRow"> <tr id="106" class="spotRow">
<td class="name">Topos Bookstore Cafe</td> <td class="name">Topos Bookstore Cafe</td>
<td>788 Woodward Ave, Brooklyn</td> <td>788 Woodward Ave, Brooklyn</td>
</tr> </tr>
<tr id="103" class="spotRow"> <tr id="107" class="spotRow">
<td class="name">Topos Too</td> <td class="name">Topos Too</td>
<td>59-22 Myrtle Ave, Queens</td> <td>59-22 Myrtle Ave, Queens</td>
</tr> </tr>
<tr id="104" class="spotRow"> <tr id="108" class="spotRow">
<td class="name">Troubled Sleep Books</td> <td class="name">Troubled Sleep Books</td>
<td>129 6th Ave, Brooklyn</td> <td>129 6th Ave, Brooklyn</td>
</tr> </tr>
<tr id="105" class="spotRow"> <tr id="109" class="spotRow">
<td class="name">Turn The Page... Again</td> <td class="name">Turn The Page... Again</td>
<td>39-15a Bell Blvd, Flushing</td> <td>39-15a Bell Blvd, Flushing</td>
</tr> </tr>
<tr id="106" class="spotRow"> <tr id="110" class="spotRow">
<td class="name">Unnameable Books</td> <td class="name">Unnameable Books</td>
<td>600 Vanderbilt Ave, Brooklyn</td> <td>600 Vanderbilt Ave, Brooklyn</td>
</tr> </tr>
<tr id="107" class="spotRow"> <tr id="111" class="spotRow">
<td class="name">Ursus Books</td> <td class="name">Ursus Books</td>
<td>50 East 78th St, Suite 1C, New York</td> <td>50 East 78th St, Suite 1C, New York</td>
</tr> </tr>
<tr id="108" class="spotRow"> <tr id="112" class="spotRow">
<td class="name">Village Works</td> <td class="name">Village Works</td>
<td>12 St. Marks Pl, New York</td> <td>12 St. Marks Pl, New York</td>
</tr> </tr>
<tr id="109" class="spotRow"> <tr id="113" class="spotRow">
<td class="name">Westsider Rare &amp; Used Books</td> <td class="name">Westsider Rare &amp; Used Books</td>
<td>2246 Broadway, New York</td> <td>2246 Broadway, New York</td>
</tr> </tr>
<tr id="110" class="spotRow"> <tr id="114" class="spotRow">
<td class="name">Westsider Records</td> <td class="name">Westsider Records</td>
<td>233 West 72nd St, New York</td> <td>233 West 72nd St, New York</td>
</tr> </tr>
<tr id="111" class="spotRow"> <tr id="115" class="spotRow">
<td class="name">Word Bookstore</td> <td class="name">Word Bookstore</td>
<td>126 Franklin St, Brooklyn</td> <td>126 Franklin St, Brooklyn</td>
</tr> </tr>
<tr id="112" class="spotRow"> <tr id="116" class="spotRow">
<td class="name">Word Up Books</td> <td class="name">Word Up Books</td>
<td>2113 Amsterdam Ave, New York</td> <td>2113 Amsterdam Ave, New York</td>
</tr> </tr>
<tr id="113" class="spotRow"> <tr id="117" class="spotRow">
<td class="name">Yu and Me Books</td> <td class="name">Yu and Me Books</td>
<td>115 Delancey St Stall #11, New York</td> <td>44 Mulberry St, New York</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -683,6 +712,7 @@
${city}, NY ${postcode} ${city}, NY ${postcode}
</p> </p>
<p> <p>
View in:
<a <a
href="https://maps.google.com/maps?q=${encodeURIComponent( href="https://maps.google.com/maps?q=${encodeURIComponent(
name name
@ -703,13 +733,17 @@
: "" : ""
} }
</p> </p>
${ <ul>
website ${
? `<p><a href="${website}" target="_blank">${cleanWebsite( website
website ? `<li><a href="${website}" target="_blank">${cleanWebsite(
)}</a></p>` website
: "" )}</a></li>`
} : ""
}
<li class="storeDetails">Events: ${events}</li>
<li class="storeDetails">Caf&eacute;: ${cafe}</li>
</ul>
${description ? `<p class="description">${description}</p>` : ""}`; ${description ? `<p class="description">${description}</p>` : ""}`;
} }
@ -813,10 +847,6 @@
} }
} }
function isStacked() {
return screen.width < 1120;
}
function boundingBox(point) { function boundingBox(point) {
// add some buffer to a point to give the user some leeway // add some buffer to a point to give the user some leeway
return [ return [
@ -826,11 +856,7 @@
} }
function updateSelectedStore(store, pushState = false) { function updateSelectedStore(store, pushState = false) {
map.flyTo({ map.flyTo({ center: [store.long, store.lat], zoom: 12 });
center: [store.long, store.lat],
offset: [isStacked() ? 0 : -250, 0],
zoom: 13,
});
popup.setLngLat([store.long, store.lat]).setHTML(store.name).addTo(map); popup.setLngLat([store.long, store.lat]).setHTML(store.name).addTo(map);
@ -852,6 +878,8 @@
} }
function loadMap(data) { function loadMap(data) {
var geolocate = new mapboxgl.GeolocateControl();
var points = []; var points = [];
data.forEach((value, key) => { data.forEach((value, key) => {
points.push({ points.push({
@ -882,6 +910,7 @@
}, },
}); });
map.addControl(new mapboxgl.NavigationControl(), "top-left"); map.addControl(new mapboxgl.NavigationControl(), "top-left");
map.addControl(geolocate, "top-right");
updateViewBySlug(window.location.hash.split("#")[1]); updateViewBySlug(window.location.hash.split("#")[1]);
}); });
@ -914,12 +943,20 @@
map.getCanvas().style.cursor = features.length ? "pointer" : ""; map.getCanvas().style.cursor = features.length ? "pointer" : "";
}); });
geolocate.on("geolocate", function (e) {
map.setZoom(14);
popup
.setLngLat([e.coords.longitude, e.coords.latitude])
.setHTML("Current Location")
.addTo(map);
});
setContent("Stores", TableViewTemplate(data)); setContent("Stores", TableViewTemplate(data));
document.querySelectorAll("#Stores tbody tr").forEach((element) => { document.querySelectorAll("#Stores tbody tr").forEach((element) => {
element.addEventListener("click", () => { element.addEventListener("click", () => {
updateSelectedStore(data[element.id], true); updateSelectedStore(data[element.id], true);
document document
.getElementById(isStacked() ? "map" : "selected") .getElementById("subhed")
.scrollIntoView({ behavior: "smooth" }); .scrollIntoView({ behavior: "smooth" });
}); });
}); });

View File

@ -1,7 +1,7 @@
import { load } from "cheerio"; import { load } from "cheerio";
import { readFile, writeFile } from "fs"; import { readFile, writeFile } from "fs";
import process from "child_process"; import process from "child_process";
import stores from "./stores.json" assert { type: "json" }; import stores from "./stores.json" with { type: "json" };
function GetRecentChanges() { function GetRecentChanges() {
const res = process const res = process
@ -17,6 +17,7 @@ function ChangeLog(logs) {
if ( if (
i > 3 || i > 3 ||
l.includes("[skip]") || l.includes("[skip]") ||
l.includes("[ignore]") ||
l.includes("caddy") || l.includes("caddy") ||
l.includes("renovate") l.includes("renovate")
) { ) {

204
package-lock.json generated
View File

@ -18,20 +18,24 @@
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
}, },
"node_modules/cheerio": { "node_modules/cheerio": {
"version": "1.0.0-rc.12", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz",
"integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==",
"dependencies": { "dependencies": {
"cheerio-select": "^2.1.0", "cheerio-select": "^2.1.0",
"dom-serializer": "^2.0.0", "dom-serializer": "^2.0.0",
"domhandler": "^5.0.3", "domhandler": "^5.0.3",
"domutils": "^3.0.1", "domutils": "^3.1.0",
"htmlparser2": "^8.0.1", "encoding-sniffer": "^0.2.0",
"parse5": "^7.0.0", "htmlparser2": "^9.1.0",
"parse5-htmlparser2-tree-adapter": "^7.0.0" "parse5": "^7.1.2",
"parse5-htmlparser2-tree-adapter": "^7.0.0",
"parse5-parser-stream": "^7.1.2",
"undici": "^6.19.5",
"whatwg-mimetype": "^4.0.0"
}, },
"engines": { "engines": {
"node": ">= 6" "node": ">=18.17"
}, },
"funding": { "funding": {
"url": "https://github.com/cheeriojs/cheerio?sponsor=1" "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
@ -118,22 +122,34 @@
} }
}, },
"node_modules/domutils": { "node_modules/domutils": {
"version": "3.0.1", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"dependencies": { "dependencies": {
"dom-serializer": "^2.0.0", "dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0", "domelementtype": "^2.3.0",
"domhandler": "^5.0.1" "domhandler": "^5.0.3"
}, },
"funding": { "funding": {
"url": "https://github.com/fb55/domutils?sponsor=1" "url": "https://github.com/fb55/domutils?sponsor=1"
} }
}, },
"node_modules/encoding-sniffer": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz",
"integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==",
"dependencies": {
"iconv-lite": "^0.6.3",
"whatwg-encoding": "^3.1.1"
},
"funding": {
"url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
}
},
"node_modules/entities": { "node_modules/entities": {
"version": "4.4.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"engines": { "engines": {
"node": ">=0.12" "node": ">=0.12"
}, },
@ -142,9 +158,9 @@
} }
}, },
"node_modules/htmlparser2": { "node_modules/htmlparser2": {
"version": "8.0.1", "version": "9.1.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
"integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==",
"funding": [ "funding": [
"https://github.com/fb55/htmlparser2?sponsor=1", "https://github.com/fb55/htmlparser2?sponsor=1",
{ {
@ -154,9 +170,20 @@
], ],
"dependencies": { "dependencies": {
"domelementtype": "^2.3.0", "domelementtype": "^2.3.0",
"domhandler": "^5.0.2", "domhandler": "^5.0.3",
"domutils": "^3.0.1", "domutils": "^3.1.0",
"entities": "^4.3.0" "entities": "^4.5.0"
}
},
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
} }
}, },
"node_modules/nth-check": { "node_modules/nth-check": {
@ -192,6 +219,49 @@
"funding": { "funding": {
"url": "https://github.com/inikulin/parse5?sponsor=1" "url": "https://github.com/inikulin/parse5?sponsor=1"
} }
},
"node_modules/parse5-parser-stream": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
"integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
"dependencies": {
"parse5": "^7.0.0"
},
"funding": {
"url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/undici": {
"version": "6.19.7",
"resolved": "https://registry.npmjs.org/undici/-/undici-6.19.7.tgz",
"integrity": "sha512-HR3W/bMGPSr90i8AAp2C4DM3wChFdJPLrWYpIS++LxS8K+W535qftjt+4MyjNYHeWabMj1nvtmLIi7l++iq91A==",
"engines": {
"node": ">=18.17"
}
},
"node_modules/whatwg-encoding": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
"integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
"dependencies": {
"iconv-lite": "0.6.3"
},
"engines": {
"node": ">=18"
}
},
"node_modules/whatwg-mimetype": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
"integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
"engines": {
"node": ">=18"
}
} }
}, },
"dependencies": { "dependencies": {
@ -201,17 +271,21 @@
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
}, },
"cheerio": { "cheerio": {
"version": "1.0.0-rc.12", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz",
"integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==",
"requires": { "requires": {
"cheerio-select": "^2.1.0", "cheerio-select": "^2.1.0",
"dom-serializer": "^2.0.0", "dom-serializer": "^2.0.0",
"domhandler": "^5.0.3", "domhandler": "^5.0.3",
"domutils": "^3.0.1", "domutils": "^3.1.0",
"htmlparser2": "^8.0.1", "encoding-sniffer": "^0.2.0",
"parse5": "^7.0.0", "htmlparser2": "^9.1.0",
"parse5-htmlparser2-tree-adapter": "^7.0.0" "parse5": "^7.1.2",
"parse5-htmlparser2-tree-adapter": "^7.0.0",
"parse5-parser-stream": "^7.1.2",
"undici": "^6.19.5",
"whatwg-mimetype": "^4.0.0"
} }
}, },
"cheerio-select": { "cheerio-select": {
@ -268,29 +342,46 @@
} }
}, },
"domutils": { "domutils": {
"version": "3.0.1", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"requires": { "requires": {
"dom-serializer": "^2.0.0", "dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0", "domelementtype": "^2.3.0",
"domhandler": "^5.0.1" "domhandler": "^5.0.3"
}
},
"encoding-sniffer": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz",
"integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==",
"requires": {
"iconv-lite": "^0.6.3",
"whatwg-encoding": "^3.1.1"
} }
}, },
"entities": { "entities": {
"version": "4.4.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==" "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="
}, },
"htmlparser2": { "htmlparser2": {
"version": "8.0.1", "version": "9.1.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
"integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==",
"requires": { "requires": {
"domelementtype": "^2.3.0", "domelementtype": "^2.3.0",
"domhandler": "^5.0.2", "domhandler": "^5.0.3",
"domutils": "^3.0.1", "domutils": "^3.1.0",
"entities": "^4.3.0" "entities": "^4.5.0"
}
},
"iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
} }
}, },
"nth-check": { "nth-check": {
@ -317,6 +408,37 @@
"domhandler": "^5.0.2", "domhandler": "^5.0.2",
"parse5": "^7.0.0" "parse5": "^7.0.0"
} }
},
"parse5-parser-stream": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
"integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
"requires": {
"parse5": "^7.0.0"
}
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"undici": {
"version": "6.19.7",
"resolved": "https://registry.npmjs.org/undici/-/undici-6.19.7.tgz",
"integrity": "sha512-HR3W/bMGPSr90i8AAp2C4DM3wChFdJPLrWYpIS++LxS8K+W535qftjt+4MyjNYHeWabMj1nvtmLIi7l++iq91A=="
},
"whatwg-encoding": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
"integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
"requires": {
"iconv-lite": "0.6.3"
}
},
"whatwg-mimetype": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
"integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="
} }
} }
} }

View File

@ -631,15 +631,15 @@
}, },
{ {
"name": "Terrace Books", "name": "Terrace Books",
"address": "242 Prospect Park West", "address": "1624 10th Ave",
"city": "Brooklyn", "city": "Brooklyn",
"state": "NY", "state": "NY",
"postcode": "11215", "postcode": "11215",
"description": "", "description": "",
"lat": "40.6594197", "lat": "40.658837917110674",
"long": "-73.9815551", "long": "-73.97862196042948",
"country": "USA", "country": "USA",
"website": "https://www.communitybookstore.net/terrace-books", "website": "https://www.communitybookstore.net/",
"events": "Yes", "events": "Yes",
"cafe": "No" "cafe": "No"
}, },
@ -1247,13 +1247,13 @@
}, },
{ {
"name": "Yu and Me Books", "name": "Yu and Me Books",
"address": "115 Delancey St Stall #11", "address": "44 Mulberry St",
"city": "New York", "city": "New York",
"state": "NY", "state": "NY",
"postcode": "10002", "postcode": "10013",
"description": "Temporarily located in Essex Market after a fire ruined their original Chinatown location.", "description": "",
"lat": "40.71799108242515", "lat": "40.7149679450257",
"long": "-73.98821173877292", "long": "-73.99957025134032",
"country": "USA", "country": "USA",
"website": "https://www.yuandmebooks.com/", "website": "https://www.yuandmebooks.com/",
"events": "Yes", "events": "Yes",
@ -1594,5 +1594,103 @@
"website": "https://www.toposbookstore.com/", "website": "https://www.toposbookstore.com/",
"events": "?", "events": "?",
"cafe": "No" "cafe": "No"
},
{
"name": "La Joie de Vivre",
"address": "145 W 27th St",
"city": "New York",
"state": "NY",
"postcode": "10001",
"description": "",
"lat": "40.74632167078788",
"long": "-73.99278487079545",
"country": "USA",
"website": "https://www.lajoiedevivre.nyc/",
"events": "No",
"cafe": "Yes"
},
{
"name": "The World's Borough Bookshop",
"address": "3406 73rd St",
"city": "Queens",
"state": "NY",
"postcode": "11372",
"description": "",
"lat": "40.752560480822325",
"long": "-73.89347162552359",
"country": "USA",
"website": "https://www.theworldsboroughbookshop.com/",
"events": "Yes",
"cafe": "No"
},
{
"name": "Bibliotheque",
"address": "54 Mercer St",
"city": "New York",
"state": "NY",
"postcode": "10013",
"description": "",
"lat": "40.72186506996318",
"long": "-74.0008362961281",
"country": "USA",
"website": "https://www.bibliothequenyc.com/",
"events": "No",
"cafe": "Yes"
},
{
"name": "Shakespeare & Company (Manhattan Valley/Columbia University)",
"address": "2736 Broadway",
"city": "New York",
"state": "NY",
"postcode": "10025",
"description": "",
"lat": "40.800259699774",
"long": "-73.96768731230581",
"country": "USA",
"website": "https://shop.shakeandco.com/",
"events": "Yes",
"cafe": "No"
},
{
"name": "Liz's Book Bar",
"address": "315 Smith St",
"city": "Brooklyn",
"state": "NY",
"postcode": "11231",
"description": "",
"lat": "40.68121559370364",
"long": "-73.99405889694158",
"country": "USA",
"website": "https://www.lizsbookbar.com/",
"events": "Yes",
"cafe": "Yes"
},
{
"name": "Honey Moon Coffee Shop",
"address": "517 Onderdonk Ave",
"city": "Ridgewood",
"state": "NY",
"postcode": "11385",
"description": "Sells a selection of books curated by Molasses Books in the back.",
"lat": "40.70609496846375",
"long": "-73.91045381955465",
"country": "USA",
"website": "https://honeymooncoffee.shop/",
"events": "Yes",
"cafe": "Yes"
},
{
"name": "Sullaluna Bistrot & Bookshop",
"address": "41 Carmine St",
"city": "New York",
"state": "NY",
"postcode": "10014",
"description": "Books for sale throughout the bistro.",
"lat": "40.73011439736975",
"long": "-74.00356955956845",
"country": "USA",
"website": "https://www.instagram.com/sullaluna.nyc/",
"events": "Yes",
"cafe": "Yes"
} }
] ]