Browse Source

start svelte rewrite

svelte
James Fenn 6 months ago
parent
commit
b77c263337
83 changed files with 3026 additions and 7204 deletions
  1. +0
    -60
      .eleventy.js
  2. +0
    -3
      .eleventyignore
  3. +0
    -13
      .github/workflows/build.yml
  4. +0
    -22
      .github/workflows/deploy.yml
  5. +4
    -5
      .gitignore
  6. +0
    -6
      404.md
  7. +0
    -1
      CNAME
  8. +4
    -4
      Makefile
  9. +99
    -10
      README.md
  10. +0
    -23
      _data/events.json
  11. +0
    -29
      _data/meta.json
  12. +0
    -7
      _includes/footer.liquid
  13. +0
    -17
      _includes/form-beta.liquid
  14. +0
    -64
      _includes/head.liquid
  15. +0
    -20
      _includes/header.liquid
  16. +0
    -15
      _includes/layouts/default.liquid
  17. +0
    -13
      _includes/layouts/page.liquid
  18. +0
    -32
      _includes/layouts/wiki.liquid
  19. +0
    -10
      _includes/nav.liquid
  20. BIN
      assets/images/android-icon-144x144.png
  21. BIN
      assets/images/android-icon-192x192.png
  22. BIN
      assets/images/android-icon-36x36.png
  23. BIN
      assets/images/android-icon-48x48.png
  24. BIN
      assets/images/android-icon-512x512.png
  25. BIN
      assets/images/android-icon-72x72.png
  26. BIN
      assets/images/android-icon-96x96.png
  27. BIN
      assets/images/apple-icon-114x114.png
  28. BIN
      assets/images/apple-icon-120x120.png
  29. BIN
      assets/images/apple-icon-144x144.png
  30. BIN
      assets/images/apple-icon-152x152.png
  31. BIN
      assets/images/apple-icon-180x180.png
  32. BIN
      assets/images/apple-icon-57x57.png
  33. BIN
      assets/images/apple-icon-60x60.png
  34. BIN
      assets/images/apple-icon-72x72.png
  35. BIN
      assets/images/apple-icon-76x76.png
  36. BIN
      assets/images/apple-icon-precomposed.png
  37. BIN
      assets/images/apple-icon.png
  38. +0
    -21
      assets/images/badges/powered-by-horrific.svg
  39. BIN
      assets/images/favicon-16x16.png
  40. BIN
      assets/images/favicon-32x32.png
  41. BIN
      assets/images/favicon-96x96.png
  42. BIN
      assets/images/logo-transparent.png
  43. BIN
      assets/images/logo.png
  44. BIN
      assets/images/ms-icon-144x144.png
  45. BIN
      assets/images/ms-icon-150x150.png
  46. BIN
      assets/images/ms-icon-310x310.png
  47. BIN
      assets/images/ms-icon-70x70.png
  48. BIN
      assets/images/store/shirt-1.png
  49. +0
    -7
      assets/js/libs/bootstrap.min.js
  50. +0
    -2
      assets/js/libs/jquery-3.4.1.min.js
  51. +0
    -5
      assets/js/libs/popper.min.js
  52. +0
    -11
      browserconfig.xml
  53. +0
    -22
      events-page.liquid
  54. +0
    -67
      events.liquid
  55. BIN
      favicon.ico
  56. +0
    -22
      hosting.md
  57. +0
    -38
      index.md
  58. +0
    -41
      manifest.json
  59. +0
    -66
      manifesto.md
  60. +0
    -6073
      package-lock.json
  61. +26
    -25
      package.json
  62. +2606
    -0
      pnpm-lock.yaml
  63. BIN
      public/favicon.png
  64. +9
    -1
      public/global.scss
  65. +20
    -0
      public/index.html
  66. +84
    -0
      rollup.config.js
  67. +31
    -0
      src/App.svelte
  68. +18
    -0
      src/components/Card.svelte
  69. +17
    -0
      src/components/NavLink.svelte
  70. +7
    -0
      src/main.ts
  71. +19
    -0
      src/routes/About.svx
  72. +24
    -0
      src/routes/Home.svx
  73. +52
    -0
      src/routes/Join.svx
  74. +6
    -0
      tsconfig.json
  75. +0
    -82
      wiki/Configuration.md
  76. +0
    -203
      wiki/HP-ProLiant-DL380-G7-User-Manual.md
  77. +0
    -3
      wiki/Hardware.md
  78. +0
    -9
      wiki/Maintenance.md
  79. +0
    -11
      wiki/Software.md
  80. +0
    -29
      wiki/Timeframe.md
  81. +0
    -54
      wiki/atrocious.md
  82. +0
    -6
      wiki/index.md
  83. +0
    -52
      wiki/wiki.json

+ 0
- 60
.eleventy.js View File

@@ -1,60 +0,0 @@
const _fs = require("fs");
const _markdown = require("markdown-it");
const _markdownAnchor = require("markdown-it-anchor");

module.exports = function(eleventyConfig) {
eleventyConfig.setDataDeepMerge(true);

eleventyConfig.addLayoutAlias("default", "layouts/default.liquid");
eleventyConfig.addLayoutAlias("page", "layouts/page.liquid");

eleventyConfig.addPassthroughCopy("assets");
eleventyConfig.addPassthroughCopy("browserconfig.xml");
eleventyConfig.addPassthroughCopy("manifest.json");
eleventyConfig.addPassthroughCopy("favicon.ico");

const markdownItRenderer = new _markdown();
eleventyConfig.addFilter("markdownify", function(str) {
return markdownItRenderer.renderInline(str);
});

/*eleventyConfig.setBrowserSyncConfig({
callbacks: {
ready: function(err, browserSync) {
const content_404 = _fs.readFileSync('_site/404.html');

browserSync.addMiddleware("*", (req, res) => {
// Provides the 404 content without redirect.
res.write(content_404);
res.end();
});
}
}
});*/

return {
templateFormats: [
"md",
"njk",
"html",
"liquid"
],

// If your site lives in a different subdirectory, change this.
// Leading or trailing slashes are all normalized away, so don’t worry about it.
// If you don’t have a subdirectory, use "" or "/" (they do the same thing)
// This is only used for URLs (it does not affect your file structure)
pathPrefix: "/",

markdownTemplateEngine: "liquid",
htmlTemplateEngine: "liquid",
dataTemplateEngine: "liquid",
passthroughFileCopy: true,
dir: {
input: ".",
includes: "_includes",
data: "_data",
output: "_site"
}
};
};

+ 0
- 3
.eleventyignore View File

@@ -1,3 +0,0 @@
node_modules/
_site/
README.md

+ 0
- 13
.github/workflows/build.yml View File

@@ -1,13 +0,0 @@
name: Test Build

on: [push]

jobs:
build:
name: "Build and Test"
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@master
- name: Build 11ty
run: make build

+ 0
- 22
.github/workflows/deploy.yml View File

@@ -1,22 +0,0 @@
name: Build and Deploy

on:
push:
branches:
- master

jobs:
deploy:
name: "Build and Deploy"
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Build 11ty
run: make build
- name: Deploy to GitHub Pages
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
BRANCH: gh-pages
FOLDER: _site

+ 4
- 5
.gitignore View File

@@ -1,7 +1,6 @@
.vscode/
node_modules/
_site/
assets/css/styles.css
assets/css/styles.css.map
/public/build/
/public/global.css*
.vscode/
.DS_Store
package-install.lock
pnpm-lock.yaml

+ 0
- 6
404.md View File

@@ -1,6 +0,0 @@
---
layout: page
title: "404"
---

Oh no!

+ 0
- 1
CNAME View File

@@ -1 +0,0 @@
horrific.dev

+ 4
- 4
Makefile View File

@@ -17,16 +17,16 @@ package-install.lock: package.json
${NPM} install
touch package-install.lock

assets/css/styles.css: assets/css/styles.scss
public/global.css: public/global.scss
${NPX} sass $^ $@.tmp
${NPX} -p postcss-cli postcss $@.tmp -o $@
rm $@.tmp $@.tmp.map

build: install assets/css/styles.css
build: install public/global.css
${NPX} @11ty/eleventy

serve: install assets/css/styles.css
${NPX} @11ty/eleventy --serve
serve: install public/global.css
${NPM} run dev

clean:
rm package-install.lock


+ 99
- 10
README.md View File

@@ -1,15 +1,104 @@
# [horrific.dev](https://horrific.dev/)
*Looking for a shareable component template? Go here --> [sveltejs/component-template](https://github.com/sveltejs/component-template)*

The website for Horrific Development. Contains a bunch of stuff.
---

## Building
# svelte app

I use [`make`](https://gnu.org/software/make/) for local testing and
development. To install the project's dependencies, run `make install`. Once
that is finished, simply running `make` should build and serve a local version
of the site. To clean up build files and such afterwards, run `make clean`.
This is a project template for [Svelte](https://svelte.dev) apps. It lives at https://github.com/sveltejs/template.

## Contributing
To create a new project based on this template using [degit](https://github.com/Rich-Harris/degit):

Pull requests / issue reports are welcome. We don't have any contributing guides
or guidelines yet, but those should be added sometime in the future. Hopefully.
```bash
npx degit sveltejs/template svelte-app
cd svelte-app
```

*Note that you will need to have [Node.js](https://nodejs.org) installed.*


## Get started

Install the dependencies...

```bash
cd svelte-app
npm install
```

...then start [Rollup](https://rollupjs.org):

```bash
npm run dev
```

Navigate to [localhost:5000](http://localhost:5000). You should see your app running. Edit a component file in `src`, save it, and reload the page to see your changes.

By default, the server will only respond to requests from localhost. To allow connections from other computers, edit the `sirv` commands in package.json to include the option `--host 0.0.0.0`.


## Building and running in production mode

To create an optimised version of the app:

```bash
npm run build
```

You can run the newly built app with `npm run start`. This uses [sirv](https://github.com/lukeed/sirv), which is included in your package.json's `dependencies` so that the app will work when you deploy to platforms like [Heroku](https://heroku.com).


## Single-page app mode

By default, sirv will only respond to requests that match files in `public`. This is to maximise compatibility with static fileservers, allowing you to deploy your app anywhere.

If you're building a single-page app (SPA) with multiple routes, sirv needs to be able to respond to requests for *any* path. You can make it so by editing the `"start"` command in package.json:

```js
"start": "sirv public --single"
```

## Using TypeScript

This template comes with a script to set up a TypeScript development environment, you can run it immediately after cloning the template with:

```bash
node scripts/setupTypeScript.js
```

Or remove the script via:

```bash
rm scripts/setupTypeScript.js
```

## Deploying to the web

### With [Vercel](https://vercel.com)

Install `vercel` if you haven't already:

```bash
npm install -g vercel
```

Then, from within your project folder:

```bash
cd public
vercel deploy --name my-project
```

### With [surge](https://surge.sh/)

Install `surge` if you haven't already:

```bash
npm install -g surge
```

Then, from within your project folder:

```bash
npm run build
surge public my-project.surge.sh
```

+ 0
- 23
_data/events.json View File

@@ -1,23 +0,0 @@
[
{
"title": "HorrificDev Planning Meeting",
"location": "Pittsburgh",
"address": "Redhawk Coffee\n120 Meyran Avenue\nPittsburgh, PA 15213",
"date": "2020-02-07T15:00:00",
"description": "A meeting to plan work on the [aight documentary](https://github.com/theonesean/aight), discuss deployment of the atrocious server, and to enjoy both caffeinated beverages and the company of good friends."
},
{
"title": "Personal Website Hack Session",
"location": "Pittsburgh",
"address": "The Big Idea Bookstore\n4812 Liberty Ave\nPittsburgh, PA 15224",
"date": "2020-02-14T15:30:00",
"description": "Open to everyone! We'll be spending time relaxing and working on our personal websites. Pittsburgh doesn't appear to have a [Homebrew Website Club](https://indieweb.org/Homebrew_Website_Club) yet, but that might be something we could start if people are interested in this sort of thing."
},
{
"title": "SIGBOVIK Conference",
"location": "Pittsburgh",
"address": "Gates Hillman Complex\n4902 Forbes Ave\nPittsburgh, PA 15213",
"date": "2020-04-01T17:00:00",
"description": "The [SIGBOVIK conference](http://sigbovik.org/2020/) is a forum organized by the Association for Computational Heresy, containing presentations and demos on a variety of neglected areas of research. This is _not_ organized by / affiliated with horrific.dev - but it's very cool, and we encourage anyone to follow their live stream if you are interested."
}
]

+ 0
- 29
_data/meta.json View File

@@ -1,29 +0,0 @@
{
"name": "horrific.dev",
"email": "mail@horrific.dev",
"description": "Breaking things since 2019.",
"icon": "/assets/images/logo.png",
"pages": {
"nav": [{
"icon": "home",
"title": "Home",
"url": "/"
},{
"icon": "info",
"title": "About",
"url": "/manifesto/"
},{
"icon": "event",
"title": "Events",
"url": "/events/"
},{
"icon": "book",
"title": "Wiki",
"url": "/wiki/"
},{
"icon": "person",
"title": "Services",
"url": "/hosting/"
}]
}
}

+ 0
- 7
_includes/footer.liquid View File

@@ -1,7 +0,0 @@
<footer class="footer">
<div class="container">
<a class="footer-link" href="https://code.horrific.dev/horrific">code.horrific.dev</a>
<a class="footer-link" href="https://twitter.com/HorrificDev">twitter.com/HorrificDev</a>
<a class="footer-link" href="mailto:mail@horrific.dev">mail@horrific.dev</a>
</div>
</footer>

+ 0
- 17
_includes/form-beta.liquid View File

@@ -1,17 +0,0 @@
<form action="https://formspree.io/xoqlapvv" method="POST">
<div class="input">
<label for="name">Name</label>
<input type="text" id="name" placeholder="Enter your name" name="name" required="true" aria-required="true">
</div>
<div class="input">
<label for="email">Email address</label>
<input type="text" id="email" aria-describedby="emailHelp" placeholder="Enter email" name="_replyto" required="true" aria-required="true"><br>
</div>
<small>We'll never share your data.</small>
<br>
<div class="input d-block">
<label for="comments">What services are you looking for?</label>
<textarea style="width: 300px;" rows="3" id="comments" name="comment"></textarea>
</div><br>
<input class="button" type="submit">
</form>

+ 0
- 64
_includes/head.liquid View File

@@ -1,64 +0,0 @@
<meta charset="utf-8">

{% assign separator = " | " %}
{% assign head_title = meta.name %}
{% if title %}
{% assign head_title = title | append: separator | append: meta.name %}
{% elsif renderData.title %}
{% assign head_title = renderData.title | append: separator | append: meta.name %}
{% endif %}

{% assign head_description = meta.description %}
{% if description %}
{% assign head_description = description %}
{% elsif renderData.description %}
{% assign head_description = renderData.description %}
{% endif %}

<meta name="description" content="{{ head_description }}">
<meta name="author" content="{{ meta.author }}">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>{{ head_title }}</title>

<meta name="theme-color" content="#FFFFFF">
<meta name="mobile-web-app-capable" content="yes">
<link rel="manifest" href="/manifest.json">

<meta name="application-name" content="{{ meta.name }}">
<meta name="msapplication-TileColor" content="#FFFFFF">
<meta name="msapplication-TileImage" content="/assets/images/ms-icon-144x144.png">
<meta name="msapplication-tooltip" content="{{ meta.description }}">
<meta name="msapplication-config" content="/ieconfig.xml">

<link rel="apple-touch-icon" sizes="57x57" href="/assets/images/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/assets/images/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/assets/images/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/assets/images/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/assets/images/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/assets/images/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/assets/images/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/assets/images/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/assets/images/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="/assets/images/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="/assets/images/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="/assets/images/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/images/favicon-16x16.png">

<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="white">
<meta name="apple-mobile-web-app-title" content="{{ meta.name }}">

<link href="//fonts.googleapis.com/css?family=Arvo" rel="stylesheet">
<link href="/assets/css/styles.css" rel="stylesheet">

<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="{{ head_title }}">
<meta name="twitter:description" content="{{ head_description }}">
<meta name="twitter:image" content="https://horrific.dev{{ meta.icon }}">
<meta name="twitter:creator" content="@HorrificDev">
<meta name="twitter:site" content="@HorrificDev">

<meta name="og:type" content="website">
<meta name="og:image" content="https://horrific.dev{{ meta.icon }}">
<meta name="og:locale" content="en_US">
<meta name="og:site_name" content="{{ meta.name }}">

+ 0
- 20
_includes/header.liquid View File

@@ -1,20 +0,0 @@
<div class="d-flex align-items-center my-4">
<img src="/assets/images/logo.png" width="50" height="50" style="border-radius: 4px;" alt="The horrific dev logo, a pixelated burning computer.">
<div style="line-height: 1; display: inline-block; margin-left: 1em;">
<span style="font-size: 1.2em;">{{ meta.name }}</span><br>
<small id="nav-tagline">Breaking things since 2019.</small>
<script type="text/javascript">
(function() {
let taglines = [
"Software is bad.",
"The computers must burn.",
"Breaking things since 2019.",
"Have fun and break things.",
"Start with the meme.",
"Everyone is bad at this. It's okay."
];
document.getElementById("nav-tagline").innerText = taglines[Math.floor(Math.random() * taglines.length)];
})();
</script>
</div>
</div>

+ 0
- 15
_includes/layouts/default.liquid View File

@@ -1,15 +0,0 @@
<!DOCTYPE html>

<html lang="en">
<head>
{% include head.liquid %}
</head>
<body class="nav-container footer-container preload">
{{ content | safe }}

<script type="text/javascript" src="/assets/js/libs/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
$('body').removeClass("preload");
</script>
</body>
</html>

+ 0
- 13
_includes/layouts/page.liquid View File

@@ -1,13 +0,0 @@
---
layout: default
---

{% include nav.liquid %}

<main class="container">
{% include header.liquid %}

{{ content | safe }}
</main>

{% include footer.liquid %}

+ 0
- 32
_includes/layouts/wiki.liquid View File

@@ -1,32 +0,0 @@
<!DOCTYPE html>

<html lang="en">
<head>
{% include head.liquid %}
</head>
<body class="nav-container footer-container">
<sidebar class="sidebar">
{% for entry in sidebar %}
<div style="margin: 1.5em 0;">
<b>{{ entry.title }}</b>
<ul style="margin: 0;">
{% for p in entry.pages %}
<li><a href="/wiki/{{ p.url }}">{{ p.title }}</a></li>
{% endfor %}
</ul>
</div>
{% endfor %}
</sidebar>

{% include nav.liquid %}

<main class="container">
{% include header.liquid %}
{{ content | safe }}
</main>

{% include footer.liquid %}

<script type="text/javascript" src="/assets/js/libs/jquery-3.4.1.min.js"></script>
</body>
</html>

+ 0
- 10
_includes/nav.liquid View File

@@ -1,10 +0,0 @@
<nav class="nav">
{% assign url_split = page.url | split: "/" %}
{% assign url_current = '/' | append: url_split[1] | append: '/' %}
{% for item in meta.pages.nav %}
<a class="nav-item{% if page.url == item.url or url_current == item.url %} active{% endif %}" href="{{ item.url }}">
<span class="nav-item-img material-icons">{{ item.icon }}</span>
<span class="nav-item-title">{{ item.title }}</span>
</a>
{% endfor %}
</nav>

BIN
assets/images/android-icon-144x144.png View File

Before After
Width: 144  |  Height: 144  |  Size: 2.9 KiB

BIN
assets/images/android-icon-192x192.png View File

Before After
Width: 192  |  Height: 192  |  Size: 5.9 KiB

BIN
assets/images/android-icon-36x36.png View File

Before After
Width: 36  |  Height: 36  |  Size: 2.1 KiB

BIN
assets/images/android-icon-48x48.png View File

Before After
Width: 48  |  Height: 48  |  Size: 2.3 KiB

BIN
assets/images/android-icon-512x512.png View File

Before After
Width: 512  |  Height: 512  |  Size: 15 KiB

BIN
assets/images/android-icon-72x72.png View File

Before After
Width: 72  |  Height: 72  |  Size: 2.5 KiB

BIN
assets/images/android-icon-96x96.png View File

Before After
Width: 96  |  Height: 96  |  Size: 2.6 KiB

BIN
assets/images/apple-icon-114x114.png View File

Before After
Width: 114  |  Height: 114  |  Size: 2.7 KiB

BIN
assets/images/apple-icon-120x120.png View File

Before After
Width: 120  |  Height: 120  |  Size: 2.8 KiB

BIN
assets/images/apple-icon-144x144.png View File

Before After
Width: 144  |  Height: 144  |  Size: 2.9 KiB

BIN
assets/images/apple-icon-152x152.png View File

Before After
Width: 152  |  Height: 152  |  Size: 2.9 KiB

BIN
assets/images/apple-icon-180x180.png View File

Before After
Width: 180  |  Height: 180  |  Size: 3.1 KiB

BIN
assets/images/apple-icon-57x57.png View File

Before After
Width: 57  |  Height: 57  |  Size: 2.5 KiB

BIN
assets/images/apple-icon-60x60.png View File

Before After
Width: 60  |  Height: 60  |  Size: 2.4 KiB

BIN
assets/images/apple-icon-72x72.png View File

Before After
Width: 72  |  Height: 72  |  Size: 2.5 KiB

BIN
assets/images/apple-icon-76x76.png View File

Before After
Width: 76  |  Height: 76  |  Size: 2.5 KiB

BIN
assets/images/apple-icon-precomposed.png View File

Before After
Width: 192  |  Height: 192  |  Size: 4.3 KiB

BIN
assets/images/apple-icon.png View File

Before After
Width: 192  |  Height: 192  |  Size: 4.3 KiB

+ 0
- 21
assets/images/badges/powered-by-horrific.svg View File

@@ -1,21 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="165" height="20">
<linearGradient id="s" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<clipPath id="r">
<rect width="165" height="20" rx="3" fill="#fff"/>
</clipPath>
<g clip-path="url(#r)">
<rect width="92" height="20" fill="#BBB"/>
<rect x="92" width="73" height="20" fill="#e05d44"/>
<rect width="165" height="20" fill="url(#s)"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110">
<image x="5" y="3" width="14" height="14" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAADsQAAA7EB9YPtSQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGISURBVDiNpZExS8NAFMf/raFLMojN0JBkaSzVQWwGlwjZSqEgdPEzCEIH55v7GVyUTFL8AE4umoIOGiqUQop1qnIIqUP1hgw1DnolSSMOPjju8Xj3+//fO+CfsZJVJISolUqlbJpmqd/vvx5v6FHtoH3S6/Xe/wQQQtTxeGzu3l+7j2uli1arxW4jYTCfz2fNZlNIQ/Lpx5RSOQxDmdeGw2G94XsOY0zPcptPFxhjesP3HEsVEYahHM8ppTIhRM0EZKnzxzxnjOlpiPCbuqFJAABDk/D0/AEAiMGDhIMs9UJZwKa9ikJZgKFJsFQRDd9zACDuIuGAq+9PPoGzt6WFHeWXXQjpJkOTgMkM56MuivjuLUKOzKqZs1QR8D3natvaS4zQ6XRe4tYBYIogfnILeCoWv6AoSgAAp90FC9OfXfGbw0VRnPCexAh3Vr22c3P5AACH1faSGodzsYQDPgafz7btyLbtCAC2+tWESLw/4UBRlIBSCgBwXTfH6wNzBA5fV5QgvrN/xxeDvb+rPQjZkwAAAABJRU5ErkJggg=="/>
<text x="555" y="150" fill="#FFFFFF" fill-opacity=".3" transform="scale(.1)" textLength="650">Powered By</text>
<text x="555" y="140" fill="#010101" transform="scale(.1)" textLength="650">Powered By</text>
<text x="1275" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="630">horrific.dev</text>
<text x="1275" y="140" transform="scale(.1)" textLength="630">horrific.dev</text>
</g>
</svg>

BIN
assets/images/favicon-16x16.png View File

Before After
Width: 16  |  Height: 16  |  Size: 943 B

BIN
assets/images/favicon-32x32.png View File

Before After
Width: 32  |  Height: 32  |  Size: 2.1 KiB

BIN
assets/images/favicon-96x96.png View File

Before After
Width: 96  |  Height: 96  |  Size: 2.6 KiB

BIN
assets/images/logo-transparent.png View File

Before After
Width: 1024  |  Height: 1024  |  Size: 7.5 KiB

BIN
assets/images/logo.png View File

Before After
Width: 1024  |  Height: 1024  |  Size: 7.4 KiB

BIN
assets/images/ms-icon-144x144.png View File

Before After
Width: 144  |  Height: 144  |  Size: 4.1 KiB

BIN
assets/images/ms-icon-150x150.png View File

Before After
Width: 150  |  Height: 150  |  Size: 4.9 KiB

BIN
assets/images/ms-icon-310x310.png View File

Before After
Width: 310  |  Height: 310  |  Size: 11 KiB

BIN
assets/images/ms-icon-70x70.png View File

Before After
Width: 70  |  Height: 70  |  Size: 3.7 KiB

BIN
assets/images/store/shirt-1.png View File

Before After
Width: 2400  |  Height: 2400  |  Size: 4.0 MiB

+ 0
- 7
assets/js/libs/bootstrap.min.js
File diff suppressed because it is too large
View File


+ 0
- 2
assets/js/libs/jquery-3.4.1.min.js
File diff suppressed because it is too large
View File


+ 0
- 5
assets/js/libs/popper.min.js
File diff suppressed because it is too large
View File


+ 0
- 11
browserconfig.xml View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square70x70logo src="/assets/images/ms-icon-70x70.png"/>
<square150x150logo src="/assets/images/ms-icon-150x150.png"/>
<square310x310logo src="/assets/images/ms-icon-310x310.png"/>
<TileColor>#ffffff</TileColor>
</tile>
</msapplication>
</browserconfig>

+ 0
- 22
events-page.liquid View File

@@ -1,22 +0,0 @@
---
layout: page
pagination:
data: events
size: 1
alias: event
permalink: "/events/{{ event.date | date: '%m-%d-%Y' }}/{{ event.title | slug }}/index.html"
renderData:
title: "{{ event.title }}"
description: "{{ event.description | markdownify | strip_html | truncate: 100 }}"
---

<h1>{{ event.title }}</h1>
<p>
<time datetime="{{ event.date }}">{{ event.date | date: "%A, %B %d, %Y<br>@ %I:%M %P" }}</time>
</p>
<p style="font-size: 0.9em; opacity: 0.8;">{{ event.address | newline_to_br }}</p>
<p>{{ event.description | markdownify }}</p>

<p>
<a href="https://maps.google.com/?q={{ event.address | newline_to_br | replace: '<br />', ' ' }}">Directions (maps.google)</a>
</p>

+ 0
- 67
events.liquid View File

@@ -1,67 +0,0 @@
---
layout: page
title: Community Events
---

{% capture page_desc %}
We organize events and meetings from time to time for various reasons - often
just to chill out and enjoy good company. Most meetings are open to the public;
however, we ask that you RSVP if you plan on attending, as this will help us
keep track of the available space and switch locations if necessary.

There is an informal mailing list to keep everyone up to date - to sign up,
just... yeet an email to [mail@horrific.dev](mailto:mail@horrific.dev), I
guess? We'll work on improving that process at a later date.
{% endcapture %}
<p>{{ page_desc | markdownify | newline_to_br | replace: '<br /><br />', '<brrr />' | replace: '<br />', ' ' | replace: '<brrr />', '</p><p>' }}</p>

{% assign events_sorted = events | sort: date %}

<hr>
<h1>Upcoming Events...</h1>
{% assign noevents = true %}
{% for event in events_sorted %}
{% capture time_now %}{{ 'now' | date: '%s' }}{% endcapture %}
{% capture time_event %}{{ event.date | date: '%s' }}{% endcapture %}
{% if time_now <= time_event %}
{% assign noevents = false %}
<div class="card mb-3">
<a class="card-title" href="/events/{{ event.date | date: "%m-%d-%Y" }}/{{ event.title | slug }}/">{{ event.title }}</a>
<div class="card-body">
<p>
<time datetime="{{ event.date }}">{{ event.date | date: "%A, %B %d, %Y @ %I:%M %P" }}</time>
<br>
<small class="text-tertiary-3">{{ event.address | newline_to_br | replace: '<br />', ', ' }}</small>
</p>
{{ event.description | markdownify }}
</div>
</div>
{% endif %}
{% endfor %}

{% if noevents %}
<p>
There are no planned events at this time. Check back later!
<br><br>
</p>
{% endif %}

<h1>Past Events...</h1>
{% assign events_sorted_reverse = events_sorted | reverse %}
{% for event in events_sorted_reverse %}
{% capture time_now %}{{ 'now' | date: '%s' }}{% endcapture %}
{% capture time_event %}{{ event.date | date: '%s' }}{% endcapture %}
{% if time_now > time_event %}
<div class="card mb-3">
<a class="card-title" href="/events/{{ event.date | date: "%m-%d-%Y" }}/{{ event.title | slug }}/">{{ event.title }}</a>
<div class="card-body">
<p>
<time datetime="{{ event.date }}">{{ event.date | date: "%A, %B %d, %Y @ %I:%M %P" }}</time>
<br>
<small class="text-tertiary-3">{{ event.address | newline_to_br | replace: '<br />', ', ' }}</small>
</p>
{{ event.description | markdownify }}
</div>
</div>
{% endif %}
{% endfor %}

BIN
favicon.ico View File

Before After

+ 0
- 22
hosting.md View File

@@ -1,22 +0,0 @@
---
layout: page
title: Hosting
---

Part of Horrific.Dev will include an indieweb hosting service, using ethical and
open-source software, offered close-to-cost for those who want it. Currently,
we're testing our equipment, software, and workflow, targeting a public launch
in the summer of 2020.

## Private Beta

Over the next few months, we'll be testing a variety of hosting offerings
for friends and trusted early adopters. If you're interested in extremely-low-cost
web hosting or other services, sign up below and we'll reach out.

Early adopters will have a chance to help us stress-test our services and
are vital to the growth of our indieweb offerings.

## Sign Up

{% include form-beta.liquid %}

+ 0
- 38
index.md View File

@@ -1,38 +0,0 @@
---
layout: page
---

**horrific.dev** is a collective organization of individual developers and
enthusiasts with a focus on independent services, software, and technology. We
advocate for open code, ethical computing, and tools that you control.

Movements that we generally support include:
- [Free Software](https://www.fsf.org/)
- [Right to Repair](https://repair.org/)
- [IndieWeb](https://indieweb.org/)
- [Responsible Data](https://responsibledata.io/)
- [The A11Y Project](https://a11yproject.com/)
- [Reproducible Builds](https://reproducible-builds.org/)

For a more detailed explanation of our values, see the
[horrific.dev manifesto](./manifesto/).

## Current Goals

We are working on getting a [hosting service](/wiki/Timeframe)
running, as well as writing [some scripts and automation](https://code.horrific.dev/horrific/hosting)
to manage it. Once this is complete, we will be able to offer small-scale
hosting services and potentially expand our website a little.

The organization needs some general maintenance. We plan to set up a page on
[Open Collective](https://opencollective.com/) to manage and track funding. We
need to connect social media accounts to a central "mailing list" (which is
waiting on the server before it can be set up). We also need to put some work
into more clearly defining our values as a group.

Depending on our members having free time, we have [semi-regular meetings](./events/) in Pittsburgh, PA where we drink tea and discuss software projects and current events.

## Get Involved

There's no membership process for our group; if you're interested, get involved. Most of our communications are through [a Discord server](https://discord.gg/Pr8eZdR)
at the moment, though there are plans to potentially change this in the future. If you're interested in inexpensive, customizable hosting and other web services, [sign up](./beta/) for our private beta.

+ 0
- 41
manifest.json View File

@@ -1,41 +0,0 @@
{
"name": "horrific.dev",
"icons": [
{
"src": "\/assets\/images\/android-icon-36x36.png",
"sizes": "36x36",
"type": "image\/png",
"density": "0.75"
},
{
"src": "\/assets\/images\/android-icon-48x48.png",
"sizes": "48x48",
"type": "image\/png",
"density": "1.0"
},
{
"src": "\/assets\/images\/android-icon-72x72.png",
"sizes": "72x72",
"type": "image\/png",
"density": "1.5"
},
{
"src": "\/assets\/images\/android-icon-96x96.png",
"sizes": "96x96",
"type": "image\/png",
"density": "2.0"
},
{
"src": "\/assets\/images\/android-icon-144x144.png",
"sizes": "144x144",
"type": "image\/png",
"density": "3.0"
},
{
"src": "\/assets\/images\/android-icon-192x192.png",
"sizes": "192x192",
"type": "image\/png",
"density": "4.0"
}
]
}

+ 0
- 66
manifesto.md View File

@@ -1,66 +0,0 @@
---
layout: page
title: Manifesto
---

## The computers must burn

Experience breeds in failure, not success. Being a "good" programmer means
nothing; one that can fail will learn the most. Embrace it. Write things that
break. Hack a program together without thinking of the consequences, and laugh
maniacally while you watch it burn.

However, it is important to make a distinction between code "failing" and code
"being bad"; those ideas are not necessarily synonymous. The stereotype of a
"perfect developer" that never makes mistakes is particularly harmful in this
regard because it furthers the idea that a bug in your software is a reflection
of you as a person.

> A [1x Engineer](https://1x.engineer/)...
> - Writes code that - _gasp_ - has bugs.
> - Makes mistakes from time to time, and finds growth in those mistakes.
> - Can feel like an imposter at times, and understands that others may, too.

The point of saying this is to suggest the idea that Other Developers Make
Mistakes Too, and that this might not be such a bad thing. Promoting resources
for [self care in tech](https://selfcare.tech/) and being vocal about these
issues is a step towards reducing the impact that impostor syndrome has on our
community, and preventing anxiety that leads to eventual burnout.

## Software is bad

Computers suck. Nothing is perfect. In a lot of computer science, nothing _can_
be perfect. Improvement is an ongoing goal, but it can never be reached. As
such, it seems wrong that it's often placed as a target. Perfection doesn't
exist, and it's not for us.

However, building something imperfectly doesn't mean that it's bad. The way that
most software is perceived is subjective - there is no universal solution to any
problem, but that's a good thing. Our individuality, the difference in our goals
in life and view of the world, is part of what makes us human. No piece of
software can satisfy every possible use in this regard. It can be designed to
meet as many as possible, which some companies have put a vast amount of effort
into doing, but it will never be perfect.

Aiming for perfection caters to the majority. It implies a disregard of issues
in a minor context, and makes decisions to suit a larger scope. To some extent,
this has to exist everywhere, as we've already established that nothing can be
perfect. In implementation, though, it means that a lot of software is built and
designed for "most people". It's built with most people in mind, so that the
product is used by the most customers and gains the most profit. It's built for
everyone, and the outcome is perfect for no one.

## Have fun and break things

A lot of the people here are not programmers because they want to make money -
we are programmers because we enjoy what we do. This is a bit of a dangerous
idea; I am in no way suggesting that we shouldn't be paid for our work, but it
would be foolish to assume that money is the only factor that influences it.
Simply put, there is more to work than making money, and there is more to
programming than getting paid.

Enjoying our work means that we are able to freely dictate how we write our
code. We aren't held back by stressful deadlines or management issues, and we
are free to explore and build our software in the way that we think is right. We
have the privilege to be motivated by enjoyment over monetary value, and that is
something that we want to share. Software as a hobby instead of a job.

+ 0
- 6073
package-lock.json
File diff suppressed because it is too large
View File


+ 26
- 25
package.json View File

@@ -1,34 +1,35 @@
{
"name": "horrific.dev",
"name": "svelte-app",
"version": "1.0.0",
"description": "The website for Horrific Development.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"build": "rollup -c",
"dev": "rollup -c -w",
"start": "sirv public --single",
"validate": "svelte-check"
},
"repository": {
"type": "git",
"url": "git+https://code.horrific.dev/horrific/horrific.dev.git"
},
"keywords": [],
"author": "James Fenn <me@jfenn.me> (https://jfenn.me/)",
"license": "UNLICENSED",
"bugs": {
"url": "https://code.horrific.dev/horrific/horrific.dev/issues"
},
"homepage": "https://horrific.dev/",
"devDependencies": {
"@11ty/eleventy": "^0.9.0",
"@11ty/eleventy-plugin-rss": "^1.0.7",
"@11ty/eleventy-plugin-syntaxhighlight": "^2.0.3",
"@doubledotlabs/dot.css": "0.1.2",
"autoprefixer": "^9.8.5",
"bootstrap": "^4.5.0",
"@doubledotlabs/dot.css": "^0.1.3",
"@rollup/plugin-commonjs": "^12.0.0",
"@rollup/plugin-node-resolve": "^8.0.0",
"@rollup/plugin-typescript": "^4.0.0",
"@tsconfig/svelte": "^1.0.0",
"autoprefixer": "^9.8.6",
"cssnano": "^4.1.10",
"fs": "0.0.1-security",
"markdown-it": "^10.0.0",
"markdown-it-anchor": "^5.2.5",
"mdsvex": "^0.8.3",
"postcss-cli": "^7.1.1",
"sass": "^1.23.2"
"rollup": "^2.3.4",
"rollup-plugin-livereload": "^1.0.0",
"rollup-plugin-svelte": "^5.0.3",
"rollup-plugin-terser": "^5.1.2",
"sass": "^1.26.10",
"svelte": "^3.0.0",
"svelte-check": "^1.0.0",
"svelte-preprocess": "^4.0.0",
"svelte-routing": "^1.4.2",
"tslib": "^2.0.0",
"typescript": "^3.9.3"
},
"dependencies": {
"sirv-cli": "^1.0.0"
}
}

+ 2606
- 0
pnpm-lock.yaml
File diff suppressed because it is too large
View File


BIN
public/favicon.png View File

Before After
Width: 128  |  Height: 128  |  Size: 3.1 KiB

assets/css/styles.scss → public/global.scss View File

@@ -50,7 +50,7 @@ $theme-dark: (

);

@import "../../node_modules/@doubledotlabs/dot.css/scss/styles.scss";
@import "../node_modules/@doubledotlabs/dot.css/scss/styles.scss";

h1, h2, h3, h4, h5 {
@include var(background-color, "primary");
@@ -69,3 +69,11 @@ h1, h2, h3, h4, h5 {
p {
line-height: 1.5;
}

b, strong {
@include var(color, "tertiary-1");
}

* {
animation: none;
}

+ 20
- 0
public/index.html View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>

<title>Svelte app</title>

<link rel='icon' type='image/png' href='/favicon.png'>
<link href="//fonts.googleapis.com/css?family=Arvo" rel="stylesheet">
<link href="//fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel='stylesheet' href='/global.css'>
<link rel='stylesheet' href='/build/bundle.css'>

<script defer src='/build/bundle.js'></script>
</head>

<body class="nav-container footer-container">
</body>
</html>

+ 84
- 0
rollup.config.js View File

@@ -0,0 +1,84 @@
import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
import preprocess from 'svelte-preprocess';
import { mdsvex } from 'mdsvex';
import typescript from '@rollup/plugin-typescript';

const production = !process.env.ROLLUP_WATCH;

function serve() {
let server;

function toExit() {
if (server) server.kill(0);
}

return {
writeBundle() {
if (server) return;
server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true
});

process.on('SIGTERM', toExit);
process.on('exit', toExit);
}
};
}

export default {
input: 'src/main.ts',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/build/bundle.js'
},
plugins: [
svelte({
extensions: ['.svelte', '.svx'],
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file - better for performance
css: css => {
css.write('public/build/bundle.css');
},
preprocess: [
preprocess(),
mdsvex()
]
}),

// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({
browser: true,
dedupe: ['svelte']
}),
commonjs(),
typescript({ sourceMap: !production }),

// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),

// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),

// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};

+ 31
- 0
src/App.svelte View File

@@ -0,0 +1,31 @@
<script lang="ts">
import { Router, Route } from 'svelte-routing';
import NavLink from './components/NavLink.svelte';
import Home from './routes/Home.svx';
import About from './routes/About.svx';
import Join from './routes/Join.svx';

export let url = "";
</script>

<Router url="{url}">
<nav class="nav">
<NavLink to="/" title="Home" icon="home" />
<NavLink to="/about/" title="About" icon="info" />
<NavLink to="/events/" title="Events" icon="event" />
<NavLink to="/wiki/" title="Wiki" icon="book" />
<NavLink to="/join/" title="Join" icon="person_add" />
</nav>
<main class="container">
<Route path="/"><Home /></Route>
<Route path="/about/"><About /></Route>
<Route path="/join/"><Join /></Route>
</main>
<footer class="footer">
<div class="container">
<a class="footer-link" href="https://code.horrific.dev/horrific">code.horrific.dev</a>
<a class="footer-link" href="https://twitter.com/HorrificDev">twitter.com/HorrificDev</a>
<a class="footer-link" href="mailto:mail@horrific.dev">mail@horrific.dev</a>
</div>
</footer>
</Router>

+ 18
- 0
src/components/Card.svelte View File

@@ -0,0 +1,18 @@
<script lang="ts">
export let href = "";
export let title = "";
</script>

<div class="card w-100 h-100">
{#if title}
{#if href}
<a class="card-title" href="{href}">{title}</a>
{:else}
<span class="card-title">{title}</span>
{/if}
{/if}

<div class="card-body">
<slot/>
</div>
</div>

+ 17
- 0
src/components/NavLink.svelte View File

@@ -0,0 +1,17 @@
<script lang="ts">
import { Link } from "svelte-routing";

export let to = "";
export let title = "";
export let icon = "";

function getProps({ location, href, isPartiallyCurrent, isCurrent }) {
const isActive = href === "/" ? isCurrent : isPartiallyCurrent || isCurrent;
return { class: "nav-item" + (isActive ? " active" : "") };
}
</script>

<Link to="{to}" getProps="{getProps}">
<i class="nav-item-img material-icons">{icon}</i>
<span class="nav-item-title">{title}</span>
</Link>

+ 7
- 0
src/main.ts View File

@@ -0,0 +1,7 @@
import App from './App.svelte';

const app = new App({
target: document.body
});

export default app;

+ 19
- 0
src/routes/About.svx View File

@@ -0,0 +1,19 @@
# What is horrific.dev?

**horrific.dev** is a collective organization of individual developers and enthusiasts with a focus on independent services, software, and technology. We advocate for open code, ethical computing, and tools that you control.

[TODO: err, expand on this a little]

# What's up with the name?

horrific.dev's identity is derived from a common mindset shared by many of our members: namely, the idea of software development as a perpetually imperfect pursuit - and the idea that, sometimes, failure is okay.

> Experience breeds in failure, not success. Being a ["good" programmer](http://10x.engineer/) means nothing; one that can fail will learn the most. Embrace it. Write things that break. Hack a program together without thinking of the consequences, and laugh maniacally while you watch it burn.

The way that most software is perceived is subjective - there is no universal solution to any problem - and that's a good thing. Our individuality, the difference in our goals in life and view of the world, is part of what makes us human. No piece of software can satisfy every possible use in this regard. It can be designed to meet as many as possible, which some companies have put a vast amount of effort into doing, but it will never be perfect.

In many ways, aiming for perfection caters to the majority. It implies a disregard of issues in a minor context, and makes decisions to suit a larger scope. To some extent, this priority is inevitable, as we've already established that nothing can be perfect. In implementation, though, it means that a lot of software is built and designed for "most people". It's built with most people in mind, so that the product is used by the most customers and gains the most profit. It's built for everyone, and the outcome is perfect for no one.

# What is our Code of Conduct?

[TODO: code of conduct]

+ 24
- 0
src/routes/Home.svx View File

@@ -0,0 +1,24 @@
**horrific.dev** is a collective organization of individual developers and enthusiasts with a focus on independent services, software, and technology. We advocate for open code, ethical computing, and tools that you control.

Movements that we generally support include:
- [Free Software](https://www.fsf.org/)
- [Ethical Source](https://ethicalsource.dev/)
- [Right to Repair](https://repair.org/)
- [IndieWeb](https://indieweb.org/)
- [Responsible Data](https://responsibledata.io/)
- [The A11Y Project](https://a11yproject.com/)
- [Reproducible Builds](https://reproducible-builds.org/)

For a more detailed explanation of our values, see our [about page](/about/).

## Current Goals

We are working on getting a [hosting service](/wiki/Timeframe) running, as well as writing [some scripts and automation](https://code.horrific.dev/horrific/hosting) to manage it. Once this is complete, we will be able to offer small-scale hosting services and potentially expand our website a little.

The organization needs some general maintenance. We now have a page on [Open Collective](https://opencollective.com/horrific-dev) to manage and track expenses. We need to connect social media accounts to a central "mailing list" (which is waiting on the server before it can be set up). We also need to put some work into more clearly defining our values as a group.

Depending on our members having free time, we have [semi-regular meetings](./events/) in Pittsburgh, PA where we drink tea and discuss software projects and current events.

## Get Involved

Most of our communications are through [a Discord server](https://discord.jfenn.me/) at the moment, though there are plans to potentially change this in the future. If you're interested in inexpensive, customizable hosting and other web services, [sign up](/hosting/) for our private beta.

+ 52
- 0
src/routes/Join.svx View File

@@ -0,0 +1,52 @@
<script lang="ts">
import Card from '../components/Card.svelte';

const memberships = [
{
title: "Participatory Membership",
description: "Zero-cost access to shared services and community involvement.",
items: [
"Gitea Repository Hosting",
"Mastodon Account @is.a.horrific.dev",
"Minecraft Server Access"
]
},
{
title: "Computing Membership",
description: "Full access to shared services and reliable web hosting at a fixed rate.",
items: [
"Web Hosting at $7/month per project",
"Automated Deployment Dashboard",
"LetsEncrypt SSL Certificates",
"Uptime Reports & Notifications",
"Weekly Offsite Backups"
]
},
{
title: "Core Membership",
description: "Direct involvement in the organization, ability to participate and vote in meetings, with shared hosting expenses.",
items: []
}
];
</script>

# Join Horrific.Dev

Something something TODO general description of services/membership options.

<div class="row">
{#each memberships as membership}
<div class="col col-12 col-md-6 pb-4">
<Card title="{membership.title}">
<span>{membership.description}</span>
<br><br>
<strong>Includes:</strong>
<ul>
{#each membership.items as item}
<li>{item}</li>
{/each}
</ul>
</Card>
</div>
{/each}
</div>

+ 6
- 0
tsconfig.json View File

@@ -0,0 +1,6 @@
{
"extends": "./node_modules/@tsconfig/svelte/tsconfig.json",

"include": ["src/**/*"],
"exclude": ["node_modules/*", "__sapper__/*", "public/*"]
}

+ 0
- 82
wiki/Configuration.md View File

@@ -1,82 +0,0 @@
This page contains general configuration details in all horrific machines; for machine-specific configuration, see [Hardware](/wiki/Hardware).

# Server configuration:

## Users

Any new hosting user will have an account that can ssh onto our machines with limited access; a console/dashboard will automate most functionality - creating docker containers (which can then be ssh'd into with full access), exposing ports of a docker container, linking to domains (reverse proxy through nginx), creating/uploading SSL certs, etc.

The "horrific" CLI in this repo will manage most of these features, as well as providing an admin CLI & monitoring functionality to keep track of resource usage.

## Config

### Nginx

[Proxying containerized docker apps](https://www.thepolyglotdeveloper.com/2017/03/nginx-reverse-proxy-containerized-docker-applications/)
## Security

### SSH access

No passwords are set; all authentication is by RSA keys only.

### [fail2ban](https://www.fail2ban.org/) configuration

`/etc/fail2ban/jail.local`
```ini
[DEFAULT]
destemail = someone@horrific.dev
sendername = Fail2Ban

[sshd]
enabled = true
port = 22

[sshd-ddos]
enabled = true
port = 22
```

### [iptables](https://wiki.debian.org/iptables) rules

[`iptables-persistent`](https://salsa.debian.org/debian/iptables-persistent/) saves/restores the iptables configuration on boot.

`/etc/iptables/rules.v4`
```ini

*filter

# Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

# Accept all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow all outbound traffic - you can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

# Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

# Allow SSH connections
# The -dport number should be the same port number you set in sshd_config
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

# Allow ping
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

# Log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

# Reject all other inbound - default deny unless explicitly allowed policy
-A INPUT -j REJECT
-A FORWARD -j REJECT

COMMIT
```

### user management

https://medium.com/@mccode/processes-in-containers-should-not-run-as-root-2feae3f0df3b

+ 0
- 203
wiki/HP-ProLiant-DL380-G7-User-Manual.md View File

@@ -1,203 +0,0 @@
This is a simplified transcription of the user manual for the server, which can be found [here](https://galtsystems.com/sites/default/files/server-model/DL380G7%20User%20Manual.pdf), to make it somewhat easier to find things.

Note: [hard drive compatibility](http://dascomputerconsultants.com/HPCompaqServerDrives.htm)

# Table of Contents

- [Component Identification](#component-identification)
- [Front panel](#front-panel)
- [Rear panel](#rear-panel)
- [System board components](#system-board-components)
- System maintenance switch
- NMI functionality
- [SAS and SATA hard drive LEDs](#sas-and-sata-hard-drive-leds)
- [Hot-plug fans](#hot-plug-fans)
- [Operations](#operations)
- [Power up the server](#power-up-the-server)
- [Power down the server](#power-down-the-server)
- [Extend the server from the rack](#extend-the-server-from-the-rack)
- [Remove the access panel](#remove-the-access-panel)
- [Install the access panel](#install-the-access-panel)

# Component Identification

## Front panel

- Hard drive bays (8)
- SATA optical drive bay
- Video connector
- USB connectors (2)

### LEDs & Buttons

| Item | Status |
|-------------------------|--------|
| UID LED and button | Blue = Activated<br>Flashing blue = System being remotely managed<br>Off = Deactivated |
| System health LED | Green = Normal<br>Amber = System degraded.<br>Red = System critical.<br>To identify components in degraded or critical state, see [Systems Insight Display](#systems-insight-display-led-combinations). |
| Power On / Standby button & system power LED | Green = System on<br>Amber = System in standby, but power is still applied<br>Off = Power cord not attached or power supply failure. |

### Systems Insight Display LED Combinations

| Display LED & color | Health LED | System power LED | Status |
|----------------------------|------------|------------------|--------|
| Processor (amber) | Red | Amber | One or more of the following conditions may exist:<br> - Processor in socket X has failed.<br> - Processor X is not installed in the socket.<br> - Processor X is unsupported.<br> - ROM detects a failed processor during POST. |
| Processor (amber) | Amber | Green | Processor in socket X is in a pre-failure condition. |
| DIMM (amber) | Red | Green | One or more DIMMs have failed. |
| DIMM (amber) | Amber | Green | DIMM in slot X is in a pre-failure condition. |
| Overtemperature (amber) | Amber | Green | The Health Driver has detected a cautionary temperature level. |
| Overtemperature (amber) | Red | Amber | The server has detected a hardware critical temperature level. |
| Fan (amber) | Amber | Green | One fan has failed or has been removed. |
| Fan (amber) | Red | Green | Two or more fans have failed or been removed. |
| Power supply (amber) | Red | Amber | - Only one power supply is installed and that power supply is in standby.<br> - Power supply fault<br> - System board fault |
| Power supply (amber) | Amber | Green | - Redundant power supply is installed and only one power supply is functional.<br> - AC power cord is not plugged into redundant power supply.<br> - Redundant power supply fault<br> - Power supply mismatch at POST or power supply mismatch through hot-plug addition. |
| Power cap (off) | - | Amber | Standby |
| Power cap (green) | - | Flashing green | Waiting for power |
| Power cap (flashing amber) | - | Amber | Power cap has been exceeded |
| Power cap (green) | - | Green | Power is available |

## Rear panel

- PCI slots (1-6)
- Power supply bays (1,2)
- USB connectors (2)
- Video connector
- NIC connectors (1,2,3,4)
- Mouse connector (PS/2)
- Keyboard connector (PS/2)
- Serial connector
- iLO 3 connector

### LEDs & Buttons

| Item | Status |
|------------------------|--------|
| Power supply LED | Green = Normal<br>Off = System is off or power supply has failed |
| UID LED/button | Blue = Activated<br>Flashing blue = System is being managed remotely<br>Off = Deactivated |
| NIC/iLO 3 activity LED | Green = Network activity<br>Flashing green = Network activity<br>Off = No network activity |
| NIC/iLO 3 link LED | Green = Network link<br>Off = No network link |

## System board components

- SAS power connectors (A,B)
- SAS connectors (A,B)
- Front I/O connector
- SATA optical drive connector
- Internal USB connector
- System battery
- Power supply backplane connector
- NMI jumper
- System maintenance switch
- Processor sockets (1,2)
- Processor DIMM slots (9) {1,2}
- Riser connectors (primary,secondary)
- SD card slot
- TPM connector
- Cache module connector
- Fan connectors (1-6)

### System maintenance switch

| Position | Default | Function |
|----------|---------|----------|
| S1 | Off | Off = iLO 3 security is enabled<br>On = iLO 3 security is disabled |
| S2 | Off | Off = System configuration can be changed<br>On = System configuration is locked |
| S3 | Off | Reserved |
| S4 | Off | Reserved |
| S5 | Off | Off = Power-on password is enabled<br>On = Power-on password is disabled |
| S6 | Off | Off = No function<br>On = Clear NVRAM |
| S7 | - | Reserved |
| S8 | - | Reserved |
| S9 | - | Reserved |
| S10 | - | Reserved |

When the system maintenance switch position 6 is set to the On position, the system is prepared to erase all system configuration settings from both CMOS and NVRAM.<br>
**CAUTION:** Clearing CMOS and/or NVRAM deletes configuration information. Be sure to properly configure the server or data loss could occur.

### NMI functionality

An NMI crash dump enables administrators to create crash dump files when a system is hung and not responding to traditional debug mechanisms.

Crash dump log analysis is an essential part of diagnosing reliability problems, such as hangs in operating systems, device drivers, and applications. Many crashes freeze a system, and the only available action for administrators is to cycle the system power. Resetting the system erases any information that could support Component identification 16 problem analysis, but the NMI feature preserves that information by performing a memory dump before a hard reset.

To force the OS to invoke the NMI handler and generate a crash dump log, the administrator can do any of the following:
- Short the NMI jumper pins
- Press the NMI switch
- Use the iLO Virtual NMI feature

For additional information, see the whitepaper on the HP website: [http://h20000.www2.hp.com/bc/docs/support/SupportManual/c00797875/c00797875.pdf](http://h20000.www2.hp.com/bc/docs/support/SupportManual/c00797875/c00797875.pdf)

## SAS and SATA hard drive LEDs

| Item | Description |
|------------------|-------------|
| 1 (top right) | Fault/UID LED (amber/blue) |
| 2 (bottom right) | Online LED (green) |

**LED combinations**

| Online/activity LED (green) | Fault/UID LED (amber/blue) | Interpretation |
|-----------------------------|---------------------------------|----------------|
| On, off, or flashing | Alternating amber & blue | The drive has failed, or a predictive failure alert has been received for this drive; it also has been selected by a management application. |
| On, off, or flashing | Steadily blue | The drive is operating normally, and it has been selected by a management application. |
| On | Off | The drive is online, but it is not active currently. |
| Flashing regularly (1Hz) | Amber, flashing regularly (1Hz) | **Do not remove the drive. Removing a drive may terminate the current operation and cause data loss.** The drive is part of an array that is undergoing capacity expansion or stripe migration, but a predictive failure alert has been received for this drive. To minimize the risk of data loss, do not replace the drive until the expansion or migration is complete. |
| Flashing regularly (1Hz) | Off | **Do not remove the drive. Removing a drive may terminate the current operation and cause data loss.** The drive is rebuilding, or it is part of an array that is undergoing capacity expansion or stripe migration. |
| Flashing irregularly | Amber, flashing regularly (1Hz) | The drive is active, but a predictive failure alert has been received for this drive. Replace the drive as soon as possible. |
| Flashing irregularly | Off | The drive is active, and it is operating normally. |
| Off | Steadily amber | A critical fault condition has been identified for this drive, and the controller has placed it offline. Replace the drive as soon as possible. |
| Off | Amber, flashing regularly (1Hz) | A predictive failure alert has been received for this drive. Replace the drive as soon as possible. |
| Off | Off | The drive is offline, a spare, or not configured as part of an array. |

## Hot-plug fans

The only two valid fan configurations are listed in the following table.

| Configuration | bay 1 | bay 2 | bay 3 | bay 4 | bay 5 | bay 6 |
|---------------|-------|-------|-------|-------|-----------|-----------|
| 1 processor | Fan | Fan | Fan | Fan | Fan blank | Fan blank |
| 2 processors | Fan | Fan | Fan | Fan | Fan | Fan |

For a single-processor configuration, four fans and two blanks are required in specific fan bays for redundancy. A fan failure or missing fan causes all fans to spin at high speed. A second fan failure or missing fan causes an orderly shutdown of the server.

Installing more than the required number of fans in a single-processor configuration is not a supported configuration.

For a dual-processor configuration, six fans are required for redundancy. A fan failure or missing fan causes all fans to spin at high speed. A second fan failure or missing fan causes an orderly shutdown of the server.

The server supports variable fan speeds. The fans operate at minimum speed until a temperature change requires a fan speed increase to cool the server. The server shuts down during the following temperature-related scenarios:
- At POST and in the OS, iLO 3 performs an orderly shutdown if a cautionary temperature level is detected. If the server hardware detects a critical temperature level before an orderly shutdown occurs, the server performs an immediate shutdown.
- When the Thermal Shutdown feature is disabled in RBSU, iLO 3 does not perform an orderly shutdown when a cautionary temperature level is detected. Disabling this feature does not disable the server hardware from performing an immediate shutdown when a critical temperature level is detected.

**CAUTION:** A thermal event can damage server components when the Thermal Shutdown feature is disabled in RBSU.

# Operations

## Power up the server

Press the power button.

## Power down the server

**WARNING:** To reduce the risk of personal injury, electric shock, or damage to the equipment, remove the power cord to remove power from the server. The front panel Power On/Standby button does not completely shut off system power. Portions of the power supply and some internal circuitry remain active until AC power is removed.

**IMPORTANT:** If installing a hot-plug device, it is not necessary to power down the server.

1. Back up the server data.
2. Shut down the operating system as directed by the operating system documentation.<br>**NOTE:** If the operating system automatically places the server in Standby mode, omit the next step.
3. Press the Power On/Standby button to place the server in Standby mode. When the server activates Standby power mode, the system power LED changes to amber.<br>**IMPORTANT:** Pressing the UID button illuminates the blue UID LEDs on the front and rear panels. In a rack environment, this feature facilitates locating a server when moving between the front and rear of the rack.
4. Disconnect the power cords.

The system is now without power.

## Extend the server from the rack

1. Pull down the quick release levers on each side of the server.
2. Extend the server from the rack.<br>**WARNING:** To reduce the risk of personal injury or equipment damage, be sure that the rack is adequately stabilized before extending a component from the rack.
3. After performing the installation or maintenance procedure, slide the server back into the rack, and then press the server firmly into the rack to secure it in place.<br>**WARNING:** To reduce the risk of personal injury, be careful when pressing the server rail-release latches and sliding the server into the rack. The sliding rails could pinch your fingers.

## Remove the access panel

TODO

## Install the access panel

TODO

+ 0
- 3
wiki/Hardware.md View File

@@ -1,3 +0,0 @@
| Nickname / Configuration | Machine | User Manual |
|--------------------------|----------------------|-------------|
| [atrocious](/wiki/atrocious) | HP ProLiant DL380 G7 | [manual](/wiki/HP-ProLiant-DL380-G7-User-Manual) |

+ 0
- 9
wiki/Maintenance.md View File

@@ -1,9 +0,0 @@
## Users

New users can be created with the `useradd` command. As specified in `/etc/adduser.conf`, the default home directory mode should be `0700 / drwx------`.

To give users access to the `horrific` tool, you must run `horrific admin createUser <username>`. This will generate an RSA key pair in the user's home directory and create a corresponding entry in `/etc/horrific/users.json`.

## Status Page

The status page at [atrocious.horrific.dev](https://atrocious.horrific.dev) is updated by a cron job; its script is stored at `/var/scripts/update-status.sh`.

+ 0
- 11
wiki/Software.md View File

@@ -1,11 +0,0 @@
This is a non-exhaustive list of projects that will be installed on our servers, mostly for our own use. We should outline information like who these services are available to and how they can be moderated following future discussion.

- [0x0](https://github.com/lachs0r/0x0)
- [Mastodon](https://github.com/tootsuite/mastodon)
- [Gitea](https://gitea.io/) + Jenkins ([useful tutorial/blog to follow](https://mike42.me/blog/2019-05-how-to-integrate-gitea-and-jenkins))
- [IRC](http://www.irc.org/) / Matrix
- [F-Droid](https://f-droid.org/repomaker/)
- [JupyterLab](https://jupyter.org/)
- [Gopher Pages](https://sdf.org/?tutorials/gopher)
- [npm](https://docs.npmjs.com/misc/registry#can-i-run-my-own-private-registry)
- [entropic](https://github.com/entropic-dev/entropic)

+ 0
- 29
wiki/Timeframe.md View File

@@ -1,29 +0,0 @@
There are essentially three phases to setting up this server and realizing our (small but broad) vision for what we want to do, hosting-wise.

**Phase 1: Setup** This will mostly entail setting up the OS, deployment/containerization, and increasing our capacity to a working level. As of right now, we have a functional server with a 120GB PCIe SSD for OS/speed-critical stuff. This, plus a few assorted drives (target expenditure <$100, target capacity >1TB), is essentially all we need to have a viable server for essentially any computing project. (*timeframe: end of March 2020*)

**Phase 2: Usage** This is where we, and trusted/brave early adopters, start migrating our own computing projects permanently over to the server. It's important to not try to scale too quickly here, and to allow plenty of time to fix bugs, reconfigure stuff, and automate our workflows so we can scale without becoming full-time IT support. Personally, I think the end of this phase should be when we're comfortable using the server personally, plus one month for preparations. (*timeframe: end of May 2020*)

**Phase 3: Reliability** I wanted to name this phase "reliability-at-scale," but I wanted to stick with the one-word naming convention. This is the big-time. By now, we should no longer be making major breaking changes to infrastructure and foundational software, and creating new projects should be 90% automated. I'm completely fine with having to SSH in to accomplish a queue of tasks that are easier for humans to do every few days, but I'm really not fine with manually creating/hooking things up, for instance. Security should be 100% figured out, implemented, and independently audited. (It may be worth paying for this before a serious launch.) This phase will entail submitting our offerings to lists of indieweb hosting, publicizing our web presence, and solidifying our budget and payment model. (*timeframe: 90 days of launch preparations, then ongoing from July 2020*)

## Expansion

After we're semi-seriously launched, we should think about how next to majorly expand our offerings. Other servers, drive bays, etc. We're not likely to start hitting the limits of our current server for at least six months (according to other indieweb\* people I've talked to), so here, in no particular order, are what I think we should plan to upgrade over time, when we have the resources:

* automated offsite backups (Amazon Glacier)
* static hosting at a lower cost
* expanding software offerings to more plug-and-play CMS/app-type stuff (our own CPanel-lite would be great)
* file hosting/CDN services
* DNS and nameservers
* an HP-compatible 3.5" drive enclosure to expand storage for our current server
* a dedicated storage server with lots of 3.5" bays
* network switches
* dedicated rack-mounted power management
* a GPU-centered compute-powerful machine for scientific computing
* a dedicated business net connection
* colocation services
* offering VPSes (most likely need a dedicated machine)
* long-term data storage (tape drives)
* selling physical media (with OS images, standard stuff that we create, custom whatever, at whatever scale)

This is obviously an incomplete *and* aspirational list. It's entirely possible that there isn't demand for these services, or they're difficult to do at our small scale, but I think as we upgrade and expand, it's helpful to have guiding principles and goals in mind.

+ 0
- 54
wiki/atrocious.md View File

@@ -1,54 +0,0 @@
# Specifications

**Processor:** Dual Intel Xeon X5650<br>
**Memory:** 64GB<br>
**Swap Space:** 120GB<br>
**Storage:** 240GB SSD, 2.3TB HDD
**System:** Debian 10.3 (buster)

**SKU:** 583913-001<br>
**SN:** LWCR10A861S14T

# Storage Configuration

## Disk 0: 111.8 GiB

Disk model: Corsair Force MP300
Description: 120GB NVME PCIe SSD, used for swap space

| Device | Boot | Start | End | Sectors | Size | Id | Type |
| --- | --- | --- | --- | --- | --- | --- | --- |
| /dev/nvme0n1p1 | | 2046 | 234440703 | 234438658 | 111.8G | 5 | Extended |
| /dev/nvme0n1p5 | | 2048 | 234440703 | 234438656 | 111.8G | 82 | Linux swap / Solaris |


## Disk 1: 223.6 GiB

Disk model: LOGICAL VOLUME
Description: 240GB SAS SSD in single-disk RAID 0, contains all OS partitions

| Device | Boot | Start | End | Sectors | Size | Id | Type |
| --- | --- | --- | --- | --- | --- | --- | --- |
| /dev/sda1 | * | 2048 | 78125055 | 78123008 | 37.3G | 83 | Linux |
| /dev/sda2 | | 78127102 | 371093503 | 292966402 | 139.7G | 5 | Extended |
| /dev/sda5 | | 78127104 | 273436671 | 195309568 | 93.1G | 83 | Linux |
| /dev/sda6 | | 273438720 | 371093503 | 97654784 | 46.6G | 83 | Linux |

## Disk 2: 29.7 GiB

Disk model: Flash Reader
Description: 32GB SD card in motherboard slot; for file transfer and as emergency backup

| Device | Boot | Start | End | Sectors | Size | Id | Type |
| --- | --- | --- | --- | --- | --- | --- | --- |
| /dev/sdb1 | | 8192 | 62333951 | 62325760 | 29.7G | c | W95 FAT32 (LBA)

## Disk 3: 279.4 GiB

Disk model: LOGICAL VOLUME
Description: 300GB HP SAS HDD in single-disk RAID 0

## Disk 4: 931.5 GiB

Disk model: LOGICAL VOLUME
Description: 2x1TB HP SAS HDD in RAID 1 (very satisfying)

+ 0
- 6
wiki/index.md View File

@@ -1,6 +0,0 @@
Welcome to the horrific.dev hosting wiki!

- [Timeframe](./Timeframe) contains our long-term goals and progress.
- [Configuration](./Configuration) contains an overview of how are machines are configured.
- [Hardware](./Hardware) contains a list of our machines and specific configuration details.
- [Software](./Software) includes a list of services that the hosting will provide.

+ 0
- 52
wiki/wiki.json View File

@@ -1,52 +0,0 @@
{
"layout": "layouts/wiki.liquid",
"sidebar": [
{
"title": "",
"pages": [{
"title": "Home",
"url": "./"
}]
},
{
"title": "Timeframe",
"pages": [{
"title": "Planned phases",
"url": "Timeframe"
},{
"title": "Expansion",
"url": "Timeframe#expansion"
}]
},
{
"title": "Configuration",
"pages": [{
"title": "Server configuration",
"url": "Configuration#server-configuration"
},{
"title": "Maintenance",
"url": "Maintenance"
}]
},
{
"title": "Hardware",
"pages": [{
"title": "Overview",
"url": "Hardware"
},{
"title": "atrocious",
"url": "atrocious"
},{
"title": "User Manuals: HP ProLiant DL380 G7",
"url": "HP-ProLiant-DL380-G7-User-Manual"
}]
},
{
"title": "Software",
"pages": [{
"title": "Overview",
"url": "Software"
}]
}
]
}

Loading…
Cancel
Save