Compare commits
123 Commits
@ -0,0 +1,28 @@
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
trigger:
|
||||
event:
|
||||
- cron
|
||||
- custom
|
||||
- tag
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: plugins/docker
|
||||
settings:
|
||||
registry: registry.fk.jochum.dev
|
||||
username: robot$jochum+drone
|
||||
password:
|
||||
from_secret: registry.fk.jochum.dev-robot
|
||||
repo: registry.fk.jochum.dev/jochum/homepage
|
||||
auto_tag: true
|
||||
build_args:
|
||||
- HUGO_VERSION=${DRONE_TAG:1}
|
||||
- URL=https://jochum.dev
|
@ -1,22 +0,0 @@
|
||||
stages:
|
||||
- name: Build
|
||||
steps:
|
||||
- publishImageConfig:
|
||||
dockerfilePath: ./Dockerfile
|
||||
buildContext: .
|
||||
tag: registry.wmk8s.com/rene.jochums.at/homepage:${CICD_GIT_TAG}
|
||||
pushRemote: true
|
||||
registry: registry.wmk8s.com
|
||||
- name: Deploy
|
||||
steps:
|
||||
- applyYamlConfig:
|
||||
path: ./deployment.yaml
|
||||
timeout: 60
|
||||
notification:
|
||||
recipients:
|
||||
- recipient: rene@webmeisterei.com
|
||||
notifier: local:n-pjmh6
|
||||
condition:
|
||||
- Success
|
||||
- Changed
|
||||
- Failed
|
@ -1,18 +1,20 @@
|
||||
# Build public with hugo
|
||||
FROM jguyomard/hugo-builder:latest
|
||||
# Build with selfmade hugo
|
||||
FROM registry.fk.jochum.dev/jochum/hugo:latest
|
||||
|
||||
COPY . /build
|
||||
ARG HUGO_VERSION=unknown
|
||||
ENV HUGO_VERSION ${HUGO_VERSION}
|
||||
|
||||
WORKDIR /build
|
||||
ARG URL=https://example.com
|
||||
|
||||
RUN hugo -b https://rene.jochums.at -v -t persona
|
||||
COPY . /build
|
||||
WORKDIR /build
|
||||
RUN /go/bin/hugo -b $URL -v -t persona
|
||||
|
||||
# Copy to a nginx container
|
||||
FROM nginx:1.17-alpine
|
||||
# Copy to a caddy container
|
||||
FROM registry.fk.jochum.dev/docker_hub_cache/library/caddy:alpine
|
||||
|
||||
LABEL maintainer="René Jochum <rene@jochums.at>"
|
||||
LABEL maintainer="René Jochum <rene@jochum.dev>"
|
||||
|
||||
COPY docker/nginx/nginx.conf /etc/nginx/
|
||||
COPY docker/nginx/default.conf /etc/nginx/conf.d/
|
||||
COPY docker/caddy/Caddyfile /etc/caddy/
|
||||
|
||||
COPY --from=0 /build/public /var/www/rene.jochums.at
|
||||
COPY --from=0 /build/public/ /usr/share/caddy/
|
||||
|
@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
go get github.com/spf13/hugo
|
||||
$GOPATH/bin/hugo server --bind="::1" -b http://localhost:3031/ -w -D -v -t persona --disableFastRender
|
||||
podman build --build-arg HUGO_VERSION=1.2.3-development --build-arg URL=http://localhost:8080 -t homepage:latest .
|
||||
podman run --rm -p "8080:80" homepage:latest
|
@ -0,0 +1,351 @@
|
||||
---
|
||||
date: 2020-09-08T23:00:00+01:00
|
||||
title: Flutter simple router
|
||||
author: jochum
|
||||
tags:
|
||||
- flutter
|
||||
- Let's Check
|
||||
---
|
||||
|
||||
For the [Let's Check](https://forum.checkmk.com/t/lets-check-an-android-ios-app-for-check-mk/20895/2) App I'm writing I needed a simple router. I haven't found anything that suited my needs so I decided to role my own.
|
||||
|
||||
<!--more-->
|
||||
|
||||
My implementation supports:
|
||||
|
||||
* Regex named Args
|
||||
* All routes named, this allows usage like: ( `GlobalRouter().buildUri(routeSettingsConnection, buildArgs: {"alias": "JOCHUM"});`)
|
||||
* Static/Dynamic routes (Static string or Regex)
|
||||
* Dynamicaly register/deregister routes as needed
|
||||
|
||||
#### The Router implementation
|
||||
|
||||
I have this saved as **GlobalRouter.dart**
|
||||
|
||||
```dart
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
const routeHome = 'home';
|
||||
const routeSplash = 'splash';
|
||||
const routeSettings = 'settings';
|
||||
const routeSettingsConnection = 'settings_connection';
|
||||
const routeNotFound = 'not_found';
|
||||
const routeHosts = 'hosts';
|
||||
const routeServices = 'services';
|
||||
const routeHost = 'host';
|
||||
const routeService = 'service';
|
||||
|
||||
typedef RouteBuilder = Route<dynamic> Function(RouteSettings context);
|
||||
|
||||
class BuildError implements Exception {
|
||||
final String message;
|
||||
BuildError(this.message);
|
||||
|
||||
String toString() => message;
|
||||
}
|
||||
|
||||
abstract class GlobalRoute {
|
||||
String get key;
|
||||
RouteBuilder get route;
|
||||
bool matchesRoute(String route);
|
||||
Map<String, String> extractNamedArgs(BuildContext context);
|
||||
String buildUri({Map<String, String> buildArgs});
|
||||
}
|
||||
|
||||
class ExactRoute implements GlobalRoute {
|
||||
final String key;
|
||||
final String uri;
|
||||
final RouteBuilder route;
|
||||
|
||||
ExactRoute({@required this.key, @required this.uri, @required this.route});
|
||||
|
||||
bool matchesRoute(String route) => route == uri;
|
||||
|
||||
Map<String, String> extractNamedArgs(BuildContext context) => {};
|
||||
|
||||
String buildUri({Map<String, String> buildArgs}) {
|
||||
assert(buildArgs == null);
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
|
||||
class NamedArgsRoute implements GlobalRoute {
|
||||
final String key;
|
||||
final String builderUri;
|
||||
final RegExp regex;
|
||||
final Map<String, int> args;
|
||||
final RouteBuilder route;
|
||||
final bool lastArgOptional;
|
||||
|
||||
NamedArgsRoute(
|
||||
{@required this.key,
|
||||
@required this.builderUri,
|
||||
@required this.regex,
|
||||
@required this.args,
|
||||
@required this.route,
|
||||
this.lastArgOptional = false});
|
||||
|
||||
bool matchesRoute(String route) {
|
||||
return regex.hasMatch(route);
|
||||
}
|
||||
|
||||
Map<String, String> extractNamedArgs(BuildContext context) {
|
||||
var uri = ModalRoute.of(context).settings.name;
|
||||
if (!matchesRoute(uri)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
final match = regex.firstMatch(uri);
|
||||
|
||||
Map<String, String> result = {};
|
||||
for (var name in args.keys) {
|
||||
if (match.groupCount >= args[name] && match.group(args[name]) != null) {
|
||||
result[name] = Uri.decodeComponent(match.group(args[name]));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String buildUri({Map<String, String> buildArgs}) {
|
||||
if (buildArgs == null && lastArgOptional && args.length == 1) {
|
||||
return builderUri.replaceFirst(r'/{' + args.keys.first + r'}', "");
|
||||
} else if (buildArgs == null) {
|
||||
throw new BuildError("BuildArgs are not optional for route '$key'");
|
||||
}
|
||||
|
||||
if (lastArgOptional && buildArgs.keys.length < args.keys.length - 1) {
|
||||
throw new BuildError("Not all args given for route '$key'");
|
||||
} else if (buildArgs.keys.length < args.keys.length) {
|
||||
throw new BuildError("Not all args given for route '$key'");
|
||||
}
|
||||
|
||||
var result = builderUri;
|
||||
for (var argName in buildArgs.keys) {
|
||||
result = result.replaceAll('{$argName}', Uri.encodeComponent(buildArgs[argName]));
|
||||
}
|
||||
|
||||
if (lastArgOptional && result.contains('{')) {
|
||||
result = result.replaceFirst(RegExp(r"(\/?\{\S+\})$"), "");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
GlobalRoute buildRoute(
|
||||
{@required String key,
|
||||
@required String uri,
|
||||
bool lastArgOptional = false,
|
||||
RouteBuilder route}) {
|
||||
var matches = RegExp(r"\{(\w+)\}").allMatches(uri);
|
||||
if (!matches.isNotEmpty) {
|
||||
return ExactRoute(key: key, uri: uri, route: route);
|
||||
}
|
||||
|
||||
Map<String, int> args = {};
|
||||
var regex = r'^' + uri.replaceAll("/", r"\/") + r'$';
|
||||
|
||||
var i = 1;
|
||||
for (var match in matches) {
|
||||
if (lastArgOptional && i == matches.length) {
|
||||
regex = regex.replaceFirst(r'\/{' + match.group(1) + r'}', r"((\/([^\/]+))?)\/?");
|
||||
args[match.group(1)] = i + 2;
|
||||
break;
|
||||
}
|
||||
|
||||
regex = regex.replaceFirst('{' + match.group(1) + '}', r"([^\/]+)");
|
||||
args[match.group(1)] = i;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return NamedArgsRoute(
|
||||
key: key,
|
||||
builderUri: uri,
|
||||
regex: new RegExp(regex),
|
||||
args: args,
|
||||
route: route,
|
||||
lastArgOptional: lastArgOptional);
|
||||
}
|
||||
|
||||
class GlobalRouter {
|
||||
Map<String, GlobalRoute> routes = {};
|
||||
List<GlobalRoute> dynamicRoutes = [];
|
||||
Map<String, ExactRoute> exactRoutes = {};
|
||||
|
||||
final List<String> requiredRoutes = [
|
||||
routeHome,
|
||||
routeSplash,
|
||||
routeSettings,
|
||||
routeSettingsConnection,
|
||||
routeNotFound
|
||||
];
|
||||
|
||||
static final GlobalRouter _singleton = GlobalRouter._internal();
|
||||
GlobalRouter._internal();
|
||||
|
||||
factory GlobalRouter() {
|
||||
return _singleton;
|
||||
}
|
||||
|
||||
bool validateRoutes() {
|
||||
requiredRoutes.forEach((name) {
|
||||
if (!routes.containsKey(name)) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
routes.clear();
|
||||
exactRoutes.clear();
|
||||
dynamicRoutes.clear();
|
||||
}
|
||||
|
||||
void add<T extends GlobalRoute>(T route) {
|
||||
routes[route.key] = route;
|
||||
if (route is ExactRoute) {
|
||||
exactRoutes[route.uri] = route;
|
||||
} else {
|
||||
dynamicRoutes.add(route);
|
||||
}
|
||||
}
|
||||
|
||||
String buildUri(String key, {Map<String, String> buildArgs}) {
|
||||
return routes[key].buildUri(buildArgs: buildArgs);
|
||||
}
|
||||
|
||||
Map<String, String> extractNamedArgs(BuildContext context, String key) {
|
||||
return routes[key].extractNamedArgs(context);
|
||||
}
|
||||
|
||||
bool isCurrentRoute(BuildContext context, String key) {
|
||||
return routes[key].matchesRoute(ModalRoute.of(context).settings.name);
|
||||
}
|
||||
|
||||
Route<dynamic> generateRoute(RouteSettings context) {
|
||||
if (kDebugMode) {
|
||||
print("Generating route for '${context.name}'");
|
||||
}
|
||||
|
||||
if (exactRoutes.containsKey(context.name)) {
|
||||
if (kDebugMode) {
|
||||
print("... found route: ${context.name}");
|
||||
}
|
||||
return exactRoutes[context.name].route(context);
|
||||
}
|
||||
|
||||
for (var route in dynamicRoutes) {
|
||||
if (route.matchesRoute(context.name)) {
|
||||
if (kDebugMode) {
|
||||
print("... found route: ${route.key}");
|
||||
}
|
||||
return route.route(context);
|
||||
}
|
||||
}
|
||||
|
||||
print("... going to 404");
|
||||
return routes[routeNotFound].route(context);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Usage of GlobalRouter
|
||||
|
||||
This is how a static route definition looks like:
|
||||
|
||||
```dart
|
||||
class HomeScreen extends BaseSlimScreen {
|
||||
static final route = buildRoute(
|
||||
key: routeHome,
|
||||
uri: "/",
|
||||
route: (context) => MaterialPageRoute(
|
||||
settings: context,
|
||||
builder: (context) => HomeScreen(),
|
||||
));
|
||||
```
|
||||
|
||||
And this is a Regex Route:
|
||||
|
||||
```dart
|
||||
class HostScreen extends BaseSlimScreen {
|
||||
static final route = buildRoute(
|
||||
key: routeHost,
|
||||
uri: "/conn/{alias}/host/{hostname}",
|
||||
lastArgOptional: false,
|
||||
route: (context) => MaterialPageRoute(
|
||||
settings: context,
|
||||
builder: (context) => HostScreen(),
|
||||
));
|
||||
```
|
||||
|
||||
Somewhere I have register Routes with GlobalRouter():
|
||||
|
||||
File is **lib/screen/slim/slim_router.dart**
|
||||
|
||||
```dart
|
||||
import '../../global_router.dart';
|
||||
import 'splash_screen.dart';
|
||||
import 'home_screen.dart';
|
||||
import 'settings_screen.dart';
|
||||
import 'settings_connection_screen.dart';
|
||||
import 'not_found_screen.dart';
|
||||
import 'hosts_screen.dart';
|
||||
import 'services_screen.dart';
|
||||
import 'host_screen.dart';
|
||||
import 'service_screen.dart';
|
||||
|
||||
export '../../global_router.dart';
|
||||
|
||||
void registerSlimRoutes() {
|
||||
GlobalRouter().add(HomeScreen.route);
|
||||
GlobalRouter().add(SplashScreen.route);
|
||||
GlobalRouter().add(SettingsScreen.route);
|
||||
GlobalRouter().add(SettingsConnectionScreen.route);
|
||||
GlobalRouter().add(NotFoundScreen.route);
|
||||
GlobalRouter().add(HostsScreen.route);
|
||||
GlobalRouter().add(ServicesScreen.route);
|
||||
GlobalRouter().add(HostScreen.route);
|
||||
GlobalRouter().add(ServiceScreen.route);
|
||||
|
||||
assert(GlobalRouter().validateRoutes());
|
||||
}
|
||||
```
|
||||
|
||||
In **main.dart** i configure the router:
|
||||
|
||||
```dart
|
||||
Future<void> main() async {
|
||||
var mediaWidth = MediaQueryData.fromWindow(window).size.width;
|
||||
mediaWidth >= ultraWideLayoutThreshold
|
||||
? registerSlimRoutes() // UltraWide
|
||||
: mediaWidth > wideLayoutThreshold
|
||||
? registerSlimRoutes() // Wide
|
||||
: registerSlimRoutes(); // Slim
|
||||
}
|
||||
```
|
||||
|
||||
And with that GlobalRouter() is in use:
|
||||
|
||||
```dart
|
||||
class App extends StatelessWidget {
|
||||
App({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
...
|
||||
onGenerateRoute: (routeContext) =>
|
||||
GlobalRouter().generateRoute(routeContext),
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### License
|
||||
|
||||
This is MIT Licensed do whatever you want with it but don't blame me. I hope it helps you to make your own Router.
|
@ -0,0 +1,150 @@
|
||||
---
|
||||
date: 2022-09-04T05:04:00+01:00
|
||||
title: Kubernetes/k3s Rancher with Traefik for HTTP/3
|
||||
author: jochum
|
||||
tags:
|
||||
- kubernetes
|
||||
- rancher
|
||||
- traefik
|
||||
---
|
||||
|
||||
Yesterday a friend of mine [Rei Bauer](https://my.stargazer.at/) told me about HTTP/3 and how much faster it made her website.
|
||||
|
||||
She got new tools, I WANT THAT TOO.
|
||||
|
||||
For me that wasn't a 5 minutes job as I had to replace [ingress-nginx](https://github.com/kubernetes/ingress-nginx) with [traefik](https://traefik.io/).
|
||||
<!--more-->
|
||||
|
||||
### Remove the current L7 Loadbalancer
|
||||
|
||||
- Remove Traefik
|
||||
|
||||
I have choosen to not use the k3s/rancher version (v2.6.x) of Traefik but use the latest and greatest (v2.8.x), so i modified my k3s with the following command:
|
||||
|
||||
**Do NOT use that command as is**
|
||||
|
||||
```bash
|
||||
curl -sfL https://get.k3s.io | sh -s - server --datastore-endpoint="mysql://k3s:<mysqlpw>@tcp(maxscale-rw.example.com:3306)/k3s" --disable servicelb --disable traefik
|
||||
```
|
||||
|
||||
Let's see what it does:
|
||||
|
||||
- *--disable servicelb* - Do not install servicelb, I replaced it with metallb.
|
||||
- *--disable traefik* - Do not install traefik
|
||||
|
||||
When you use the given command (with your own "datastore-endpoint") you will see that you loose access to all L7 Ingresses, so please be aware of that and make sure you have access over ssh to your cluster.
|
||||
|
||||
- Remove ingress-nginx
|
||||
|
||||
```bash
|
||||
helm uninstall -n kube-system ingress-nginx
|
||||
```
|
||||
|
||||
If you haven't lost layer 7 access to your cluster in the last step you will loose it now :)
|
||||
|
||||
### Install traefik from the upstream sources
|
||||
|
||||
- Add the upstream helm catalog
|
||||
|
||||
```bash
|
||||
helm repo add traefik https://helm.traefik.io/traefik
|
||||
```
|
||||
|
||||
- Save my *traefik-values.yaml* somewhere:
|
||||
|
||||
```yaml
|
||||
rbac:
|
||||
enabled: true
|
||||
ports:
|
||||
web:
|
||||
hostPort: 80
|
||||
http:
|
||||
redirections:
|
||||
entryPoint:
|
||||
to: websecure
|
||||
scheme: https
|
||||
|
||||
websecure:
|
||||
hostPort: 443
|
||||
http3:
|
||||
advertisedPort: 443
|
||||
tls:
|
||||
enabled: true
|
||||
websecure-udp:
|
||||
port: 8443
|
||||
hostPort: 443
|
||||
protocol: UDP
|
||||
podAnnotations:
|
||||
prometheus.io/port: "8082"
|
||||
prometheus.io/scrape: "true"
|
||||
providers:
|
||||
kubernetesIngress:
|
||||
publishedService:
|
||||
enabled: true
|
||||
allowExternalNameServices: true
|
||||
kubernetesCRD:
|
||||
allowExternalNameServices: true
|
||||
priorityClassName: "system-cluster-critical"
|
||||
tolerations:
|
||||
- key: "CriticalAddonsOnly"
|
||||
operator: "Exists"
|
||||
- key: "node-role.kubernetes.io/control-plane"
|
||||
operator: "Exists"
|
||||
effect: "NoSchedule"
|
||||
- key: "node-role.kubernetes.io/master"
|
||||
operator: "Exists"
|
||||
effect: "NoSchedule"
|
||||
|
||||
experimental:
|
||||
http3:
|
||||
enabled: true
|
||||
additionalArguments:
|
||||
- "--certificatesresolvers.letsencrypt-prod.acme.caserver=https://acme-v02.api.letsencrypt.org/directory"
|
||||
image:
|
||||
name: traefik
|
||||
tag: v2.8.4
|
||||
proxyProtocol:
|
||||
enabled: true
|
||||
trustedIPs:
|
||||
- 10.0.0.0/8
|
||||
forwardedHeaders:
|
||||
enabled: true
|
||||
trustedIPs:
|
||||
- 10.0.0.0/8
|
||||
ssl:
|
||||
enabled: true
|
||||
permanentRedirect: true
|
||||
|
||||
certResolvers:
|
||||
letsencrypt-prod:
|
||||
email: support@jochum.dev
|
||||
tlsChallenge: true
|
||||
storage: /data/acme.json
|
||||
|
||||
logs:
|
||||
# general:
|
||||
# format: json
|
||||
access:
|
||||
enabled: true
|
||||
# format: json
|
||||
fields:
|
||||
headers:
|
||||
defaultmode: drop
|
||||
names:
|
||||
User-Agent: keep
|
||||
Content-Type: keep
|
||||
RequestLine: keep
|
||||
|
||||
persistence:
|
||||
enabled: true
|
||||
```
|
||||
|
||||
- Change the acme email address there
|
||||
|
||||
- Install traefik
|
||||
|
||||
```bash
|
||||
helm install -n kube-system traefik traefik/traefik -f traefik-values.yaml
|
||||
```
|
||||
|
||||
Have fun with Traefik, it's internal ACME resolver and HTTP/3.
|
@ -0,0 +1,49 @@
|
||||
---
|
||||
date: 2022-09-16T04:33:00+01:00
|
||||
title: Homeserver
|
||||
author: jochum
|
||||
tags:
|
||||
- homeserver
|
||||
---
|
||||
|
||||
My Homeserver runs a lot of Free Open Source Software, maybe you find something for yourself?
|
||||
|
||||
<!--more-->
|
||||
|
||||
#### Debian GNU/Linux
|
||||
|
||||
[Debian](https://debian.org) what to say about Debian, I have it on my Desktop and all of my Servers since around version 4.0. On my Desktop i use Debian Testing/sid.
|
||||
|
||||
#### Proxmox VE and Proxmox Backup Server
|
||||
|
||||
Im a big fan of [Proxmox](https://proxmox.com/en/), I use theier [Virtual Environment](https://proxmox.com/en/proxmox-ve) which runs both LXC and KVM Machines since a long time and the [Backup Server](https://proxmox.com/en/proxmox-backup-server) since it's out there. It's just ROCK Stable.
|
||||
|
||||
#### SUSE Rancher with it's K3S
|
||||
|
||||
[k3s](https://k3s.io/) the lightweight alternative to Kubernetes Mainline, you can select your K/V storage, so no etcd which is using all of my disk IO/s :)
|
||||
|
||||
#### MariaDB
|
||||
|
||||
[MariaDB](https://mariadb.org) power's my K3S and some other stuff
|
||||
|
||||
#### PowerDNS with phpIPAM for splitdns
|
||||
|
||||
I have all my Domains in a splitdns environment for that I use a [PowerDNS](https://www.powerdns.com/) and [phpIPAM](https://phpipam.net/) as Mangement UI.
|
||||
|
||||
#### Unbound DNS Cacher
|
||||
|
||||
Rock solid DNS Cacher from cz labs
|
||||
|
||||
#### Public Services
|
||||
|
||||
- [Drone](https://www.drone.io/) for CI/CD Pipelines
|
||||
- [Gitea](https://gitea.io/en-us/) my private Github
|
||||
- [GoHarbor](https://goharbor.io/) docker registry WITH caching of other registries!
|
||||
- [Traefik](https://traefik.io/) HTTP/3 ready proxy which integrates nicely into Kubernetes.
|
||||
- [NextCloud](https://nextcloud.com/) Syncing files with it, also using Calobora CODE to have in Browser/online office.
|
||||
- Mail: Postfix, Dovecot, postfixAdmin, roundcube in custom build containers
|
||||
- [PostgreSQL](https://www.postgresql.org/) All apps that do Postgres are running on Postgres with help of PostgresOperator from Zalando.
|
||||
- [pgAdmin](https://www.pgadmin.org/)
|
||||
- [phpMyAdmin](https://www.phpmyadmin.net/)
|
||||
- [Vaultwarden](https://github.com/dani-garcia/vaultwarden) - Bitwarden Server replacement in lightweight rust
|
||||
- [Zitadel](https://zitadel.com/) My IAM of choice
|
@ -0,0 +1,246 @@
|
||||
---
|
||||
date: 2023-07-09T01:53:00+02:00
|
||||
title: Kubernetes/k3s Rancher with Traefik for HTTP/3 - v20230709
|
||||
author: jochum
|
||||
tags:
|
||||
- kubernetes
|
||||
- rancher
|
||||
- traefik
|
||||
---
|
||||
|
||||
A little update to [rancher-traefik](https://jochum.dev/20220904-rancher-traefik/), this contains the values in it's newest format.
|
||||
<!--more-->
|
||||
|
||||
### Install with helm
|
||||
|
||||
Save this as **2023-traefik-values.yaml** and adjust it for your needs:
|
||||
|
||||
```yaml
|
||||
additionalArguments: []
|
||||
additionalVolumeMounts: []
|
||||
affinity: {}
|
||||
autoscaling:
|
||||
enabled: false
|
||||
certResolvers:
|
||||
letsencrypt-prod:
|
||||
email: support@jochum.dev
|
||||
tlsChallenge: true
|
||||
httpChallenge:
|
||||
entryPoint: "web"
|
||||
# It has to match the path with a persistent volume
|
||||
storage: /data/acme.json
|
||||
commonLabels: {}
|
||||
deployment:
|
||||
additionalContainers: []
|
||||
additionalVolumes: []
|
||||
annotations: {}
|
||||
dnsConfig: {}
|
||||
enabled: true
|
||||
imagePullSecrets: []
|
||||
initContainers: []
|
||||
kind: Deployment
|
||||
labels: {}
|
||||
lifecycle: {}
|
||||
minReadySeconds: 0
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
replicas: 1
|
||||
shareProcessNamespace: false
|
||||
terminationGracePeriodSeconds: 60
|
||||
env: []
|
||||
envFrom: []
|
||||
experimental:
|
||||
kubernetesGateway:
|
||||
enabled: false
|
||||
gateway:
|
||||
enabled: true
|
||||
plugins:
|
||||
enabled: false
|
||||
v3:
|
||||
enabled: false
|
||||
http3:
|
||||
enabled: true
|
||||
extraObjects: []
|
||||
globalArguments: []
|
||||
hostNetwork: false
|
||||
image:
|
||||
pullPolicy: IfNotPresent
|
||||
registry: docker.io
|
||||
repository: traefik
|
||||
tag: v2.10.3
|
||||
name: traefik
|
||||
ingressClass:
|
||||
enabled: true
|
||||
isDefaultClass: true
|
||||
ingressRoute:
|
||||
dashboard:
|
||||
annotations: {}
|
||||
enabled: false
|
||||
entryPoints:
|
||||
- traefik
|
||||
labels: {}
|
||||
matchRule: PathPrefix(`/dashboard`) || PathPrefix(`/api`)
|
||||
middlewares: []
|
||||
tls: {}
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
initialDelaySeconds: 2
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 2
|
||||
logs:
|
||||
access:
|
||||
enabled: true
|
||||
fields:
|
||||
general:
|
||||
defaultmode: keep
|
||||
names: {}
|
||||
headers:
|
||||
defaultmode: drop
|
||||
names:
|
||||
Content-Type: keep
|
||||
RequestLine: keep
|
||||
User-Agent: keep
|
||||
filters: {}
|
||||
general:
|
||||
level: ERROR
|
||||
metrics:
|
||||
prometheus:
|
||||
entryPoint: metrics
|
||||
nodeSelector: {}
|
||||
persistence:
|
||||
accessMode: ReadWriteOnce
|
||||
annotations: {}
|
||||
enabled: true
|
||||
name: data
|
||||
path: /data
|
||||
size: 128Mi
|
||||
podDisruptionBudget:
|
||||
enabled: false
|
||||
podSecurityContext:
|
||||
fsGroupChangePolicy: OnRootMismatch
|
||||
runAsGroup: 65532
|
||||
runAsNonRoot: true
|
||||
runAsUser: 65532
|
||||
podSecurityPolicy:
|
||||
enabled: false
|
||||
ports:
|
||||
metrics:
|
||||
expose: false
|
||||
exposedPort: 9100
|
||||
port: 9100
|
||||
protocol: TCP
|
||||
traefik:
|
||||
expose: false
|
||||
exposedPort: 9000
|
||||
port: 9000
|
||||
protocol: TCP
|
||||
web:
|
||||
expose: true
|
||||
exposedPort: 80
|
||||
port: 80
|
||||
protocol: TCP
|
||||
nodePort: 80
|
||||
websecure:
|
||||
expose: true
|
||||
exposedPort: 443
|
||||
nodePort: 443
|
||||
http3:
|
||||
enabled: true
|
||||
advertisedPort: 443
|
||||
middlewares: []
|
||||
port: 443
|
||||
protocol: TCP
|
||||
tls:
|
||||
certResolver: 'letsencrypt-prod'
|
||||
domains: []
|
||||
enabled: true
|
||||
options: ''
|
||||
priorityClassName: system-cluster-critical
|
||||
providers:
|
||||
kubernetesCRD:
|
||||
allowCrossNamespace: false
|
||||
allowEmptyServices: false
|
||||
allowExternalNameServices: true
|
||||
enabled: true
|
||||
namespaces: []
|
||||
kubernetesIngress:
|
||||
allowEmptyServices: false
|
||||
allowExternalNameServices: true
|
||||
enabled: true
|
||||
namespaces: []
|
||||
publishedService:
|
||||
enabled: true
|
||||
rbac:
|
||||
enabled: true
|
||||
namespaced: false
|
||||
readinessProbe:
|
||||
failureThreshold: 1
|
||||
initialDelaySeconds: 2
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 2
|
||||
resources: {}
|
||||
securityContext:
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
readOnlyRootFilesystem: true
|
||||
service:
|
||||
annotations: {}
|
||||
annotationsTCP: {}
|
||||
annotationsUDP: {}
|
||||
enabled: true
|
||||
externalIPs: []
|
||||
labels: {}
|
||||
loadBalancerSourceRanges: []
|
||||
single: true
|
||||
spec: {}
|
||||
type: NodePort
|
||||
serviceAccount:
|
||||
name: ''
|
||||
serviceAccountAnnotations: {}
|
||||
tlsOptions: {}
|
||||
tlsStore: {}
|
||||
tolerations:
|
||||
- key: CriticalAddonsOnly
|
||||
operator: Exists
|
||||
- effect: NoSchedule
|
||||
key: node-role.kubernetes.io/control-plane
|
||||
operator: Exists
|
||||
- effect: NoSchedule
|
||||
key: node-role.kubernetes.io/master
|
||||
operator: Exists
|
||||
topologySpreadConstraints: []
|
||||
tracing: {}
|
||||
updateStrategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
type: RollingUpdate
|
||||
volumes: []
|
||||
forwardedHeaders:
|
||||
enabled: true
|
||||
trustedIPs:
|
||||
- 10.0.0.0/8
|
||||
global:
|
||||
cattle:
|
||||
systemDefaultRegistry: ''
|
||||
systemProjectId: p-g2j9j
|
||||
systemDefaultRegistry: ''
|
||||
proxyProtocol:
|
||||
enabled: true
|
||||
trustedIPs:
|
||||
- 10.0.0.0/8
|
||||
ssl:
|
||||
enabled: true
|
||||
permanentRedirect: true
|
||||
```
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
helm uninstall -n kube-system traefik
|
||||
helm repo update
|
||||
helm install traefik traefik/traefik -n kube-system -f 2023-traefik-values.yaml
|
||||
```
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
date: 2015-06-12T00:00:00+01:00
|
||||
title: Imprint
|
||||
author: pcdummy
|
||||
author: jochum
|
||||
|
||||
---
|
||||
As this blog is hosted in Germany, it is subject to German media regulations and German media law, the Telemediengesetz (TMG). Please note that your comments have no right to publication on Rene's blog and might be deleted or shortened by me. All content on this website is subject to German intellectual property law.
|
@ -1,88 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: List
|
||||
items:
|
||||
- apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
deployment.kubernetes.io/revision: "1"
|
||||
generation: 3
|
||||
name: nginx
|
||||
namespace: rene-jochums-at
|
||||
spec:
|
||||
progressDeadlineSeconds: 600
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 10
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
type: RollingUpdate
|
||||
selector:
|
||||
matchLabels:
|
||||
container: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
container: nginx
|
||||
spec:
|
||||
containers:
|
||||
- image: registry.wmk8s.com/rene.jochums.at/homepage:${CICD_GIT_TAG}
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: nginx
|
||||
resources: {}
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: {}
|
||||
privileged: false
|
||||
procMount: Default
|
||||
readOnlyRootFilesystem: false
|
||||
runAsNonRoot: false
|
||||
stdin: true
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
tty: true
|
||||
dnsPolicy: ClusterFirst
|
||||
imagePullSecrets:
|
||||
- name: wmk8s
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
|
||||
- kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: nginx
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
workloadID_nginx: "true"
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 80
|
||||
|
||||
- kind: Ingress
|
||||
apiVersion: extensions/v1beta1
|
||||
metadata:
|
||||
annotations:
|
||||
certmanager.k8s.io/cluster-issuer: letsencrypt-prod
|
||||
kubernetes.io/tls-acme: "true"
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
generation: 2
|
||||
name: website
|
||||
namespace: rene-jochums-at
|
||||
spec:
|
||||
rules:
|
||||
- host: rene.jochums.at
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: nginx
|
||||
servicePort: 80
|
||||
path: /
|
||||
tls:
|
||||
- hosts:
|
||||
- rene.jochums.at
|
||||
secretName: website-prod-tls
|
@ -1,141 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script will make a best-effort attempt at showing modifications
|
||||
# to package-provided config files on a Debian system.
|
||||
#
|
||||
# It's subject to some pretty significant limitations: most notably,
|
||||
# there's no way to identify all such config files. We approximate the
|
||||
# answer by looking first at dpkg-managed conffiles, and then hoping
|
||||
# that most of the time, if maintainer scripts are managing files
|
||||
# themselves, they're using ucf. So, DO NOT TRUST THIS SCRIPT to find
|
||||
# everything... but it should help to find most customisation.
|
||||
|
||||
|
||||
# Set this non-empty to see a diff against empty for apparently-deleted
|
||||
# files; leave it empty for a single 'file deleted' note.
|
||||
diff_empty=
|
||||
|
||||
# Space-separated list of directory *trees* to be searched for package
|
||||
# files. This is the only means of locating packages that can't be
|
||||
# installed by apt. Note that we do a recursive search in here *before*
|
||||
# we ask apt to download the package; don't point it at a stupidly-large
|
||||
# tree.
|
||||
local_packages="/var/cache/puppet"
|
||||
|
||||
|
||||
|
||||
package_version() {
|
||||
pkg="$1"
|
||||
dpkg-query -W -f='${Version}\n' "$pkg"
|
||||
}
|
||||
|
||||
# I've made no attempt to create a sensible overall ordering; we keep
|
||||
# files grouped by package within a particular section, then hope that
|
||||
# most packages won't mix config file types.
|
||||
|
||||
|
||||
#############
|
||||
# conffiles
|
||||
|
||||
package_file() {
|
||||
pkg="$1"
|
||||
|
||||
exec 3< <(dpkg-query -W -f='${Version} ${Architecture} ${Status}\n' "$pkg")
|
||||
read -u3 version arch status
|
||||
|
||||
if [ "$status" != "install ok installed" -o -z "$version" ]; then
|
||||
# Package isn't actually installed; ignore it.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
basename="${pkg}_${version//:/%3a}_${arch}.deb"
|
||||
filename="/var/cache/apt/archives/$basename"
|
||||
|
||||
if [ -f "$filename" ]; then
|
||||
echo "$filename"
|
||||
exit
|
||||
fi
|
||||
|
||||
found="$(find $local_packages -name "$basename" -print -quit)"
|
||||
if [ -n "$found" ]; then
|
||||
echo "$found"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ "$UID" -gt 0 ]; then
|
||||
echo "Package ${pkg} (${version}, ${arch}) is not available; need to install, but not root" >&2
|
||||
exit 1
|
||||
fi
|
||||
apt-get -qq --download-only --reinstall install "${pkg}=${version}"
|
||||
|
||||
if [ -f "$filename" ]; then
|
||||
echo "$filename"
|
||||
else
|
||||
echo "Failed to download ${pkg} (${version}, ${arch})" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
original_content() {
|
||||
pkg="$1"
|
||||
file="$2"
|
||||
|
||||
deb="$(package_file "$pkg")"
|
||||
if [ "$?" -ne 0 -o -z "$deb" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dpkg-deb --fsys-tarfile "$deb" | tar -x -O ".$file"
|
||||
}
|
||||
|
||||
|
||||
dpkg-query -W -f='${Conffiles}\n' '*' |
|
||||
awk 'OFS=" "{print $2,$1}' |
|
||||
md5sum -c 2>/dev/null |
|
||||
awk -F': ' '$2 !~ /OK/{print $1}' |
|
||||
xargs dpkg -S |
|
||||
sort -u |
|
||||
awk -F ': ' 'OFS=" "{print $1,$2}' |
|
||||
while read pkg file; do
|
||||
if [ ! -f "$file" -a -z "$diff_empty" ]; then
|
||||
echo "Deleted: $file (from $pkg)"
|
||||
else
|
||||
content="$(original_content "$pkg" "$file")"
|
||||
if [ "$?" -eq 0 ]; then
|
||||
echo "package $pkg"
|
||||
diff -u --new-file --report-identical-files --label "$pkg $(package_version "$pkg")" <(echo "$content") "$file"
|
||||
else
|
||||
echo "Failed to load original for $file from $pkg"
|
||||
fi
|
||||
fi
|
||||
echo
|
||||
done
|
||||
|
||||
|
||||
#######
|
||||
# ucf
|
||||
|
||||
md5sum -c /var/lib/ucf/hashfile 2>/dev/null |
|
||||
awk -F': ' '$2 !~ /OK/{print $1}' |
|
||||
xargs ucfq -w |
|
||||
sort -t ':' -k 2,1 | uniq |
|
||||
awk -F: 'OFS=" " {print $1,$2}' |
|
||||
while read file pkg; do
|
||||
if [ ! -f "$file" -a -z "$diff_empty" ]; then
|
||||
echo "Deleted: $file (from ${pkg:-??})"
|
||||
else
|
||||
cache="/var/lib/ucf/cache/${file//\//:}"
|
||||
if [ -f "$cache" ]; then
|
||||
if [ -n "$pkg" ]; then
|
||||
echo "package $pkg"
|
||||
label="$pkg $(package_version "$pkg")"
|
||||
else
|
||||
label="original"
|
||||
fi
|
||||
diff -u --new-file --report-identical-files --label "$label" "$cache" "$file"
|
||||
else
|
||||
echo "Failed to load original for $file from ${pkg:-??}"
|
||||
fi
|
||||
fi
|
||||
echo
|
||||
done
|
@ -0,0 +1,19 @@
|
||||
:80 {
|
||||
log
|
||||
|
||||
# Set this path to your site's directory.
|
||||
root * /usr/share/caddy
|
||||
|
||||
# Compress responses according to Accept-Encoding headers
|
||||
encode zstd gzip
|
||||
|
||||
# Client side caching
|
||||
@static {
|
||||
file
|
||||
path *.ico *.css *.js *.gif *.jpg *.jpeg *.png *.svg *.woff *.woff2
|
||||
}
|
||||
header @static Cache-Control max-age=31536000
|
||||
|
||||
# Enable the static file server.
|
||||
file_server
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
server {
|
||||
listen 80 default_server;
|
||||
|
||||
error_log /dev/stderr;
|
||||
access_log /dev/stdout;
|
||||
|
||||
root /var/www/rene.jochums.at;
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
user nginx;
|
||||
worker_processes 4;
|
||||
pid /run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 2048;
|
||||
multi_accept on;
|
||||
use epoll;
|
||||
}
|
||||
|
||||
http {
|
||||
server_tokens off;
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 15;
|
||||
types_hash_max_size 2048;
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
access_log off;
|
||||
error_log off;
|
||||
gzip on;
|
||||
gzip_disable "msie6";
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
include /etc/nginx/sites-enabled/*;
|
||||
open_file_cache max=100;
|
||||
client_body_temp_path /tmp 1 2;
|
||||
client_body_buffer_size 256k;
|
||||
client_body_in_file_only off;
|
||||
}
|
@ -1,11 +1,6 @@
|
||||
<div class="home_single_post comment_area">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-8 col-md-8 col-lg-8 col-xs-offset-0 col-sm-offset-2 col-md-offset-2 col-lg-offset-2">
|
||||
{{"<!-- begin comments //-->" | safeHTML}}
|
||||
<section id="isso-thread">
|
||||
|
||||
</section>
|
||||
{{"<!-- end comments //-->" | safeHTML}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,3 +1,10 @@
|
||||
{{ "<!-- isso -->" | safeHTML }}
|
||||
<script data-isso="{{ .Site.BaseURL }}isso/" src="{{ .Site.BaseURL }}isso/js/embed.min.js"></script>
|
||||
{{ "<!-- end isso -->" | safeHTML }}
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-9ET9Z12C0F"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'G-9ET9Z12C0F');
|
||||
</script>
|
||||
<!-- EDN GTAG -->
|
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
podman build --rm --build-arg=URL=http://localhost -t homepage:latest .
|
||||
podman run --rm -p "80:80" homepage:latest
|
@ -1 +0,0 @@
|
||||
google-site-verification: googled7a55c2994884381.html
|
@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="go-import" content="jochum.dev/jo-micro/auth2 git https://git.jochum.dev/jo-micro/auth2.git">
|
||||
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/jo-micro/auth2'">
|
||||
</head>
|
||||
<body>
|
||||
Redirecting you to the <a href="https://git.jochum.dev/jo-micro/auth2">project page</a>...
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="go-import" content="jochum.dev/jo-micro/buncomponent git https://git.jochum.dev/jo-micro/buncomponent.git">
|
||||
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/jo-micro/buncomponent'">
|
||||
</head>
|
||||
<body>
|
||||
Redirecting you to the <a href="https://git.jochum.dev/jo-micro/buncomponent">project page</a>...
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="go-import" content="jochum.dev/jo-micro/components git https://git.jochum.dev/jo-micro/components.git">
|
||||
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/jo-micro/components'">
|
||||
</head>
|
||||
<body>
|
||||
Redirecting you to the <a href="https://git.jochum.dev/jo-micro/components">project page</a>...
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="go-import" content="jochum.dev/jo-micro/geoip git https://git.jochum.dev/jo-micro/geoip.git">
|
||||
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/jo-micro/geoip'">
|
||||
</head>
|
||||
<body>
|
||||
Redirecting you to the <a href="https://git.jochum.dev/jo-micro/geoip">project page</a>...
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="go-import" content="jochum.dev/jo-micro/logruscomponent git https://git.jochum.dev/jo-micro/logruscomponent.git">
|
||||
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/jo-micro/logruscomponent'">
|
||||
</head>
|
||||
<body>
|
||||
Redirecting you to the <a href="https://git.jochum.dev/jo-micro/logruscomponent">project page</a>...
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="go-import" content="jochum.dev/jo-micro/router git https://git.jochum.dev/jo-micro/router.git">
|
||||
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/jo-micro/router'">
|
||||
</head>
|
||||
<body>
|
||||
Redirecting you to the <a href="https://git.jochum.dev/jo-micro/router">project page</a>...
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="go-import" content="jochum.dev/jo-micro/settings git https://git.jochum.dev/jo-micro/settings.git">
|
||||
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/jo-micro/settings'">
|
||||
</head>
|
||||
<body>
|
||||
Redirecting you to the <a href="https://git.jochum.dev/jo-micro/settings">project page</a>...
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="go-import" content="jochum.dev/orb/config git https://git.jochum.dev/orb-org/config.git">
|
||||
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/orb-org/config'">
|
||||
</head>
|
||||
<body>
|
||||
Redirecting you to the <a href="https://git.jochum.dev/orb-org/config">project page</a>...
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="go-import" content="jochum.dev/orb/orb git https://git.jochum.dev/orb-org/orb.git">
|
||||
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/orb-org/orb'">
|
||||
</head>
|
||||
<body>
|
||||
Redirecting you to the <a href="https://git.jochum.dev/orb-org/orb">project page</a>...
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
@ -0,0 +1,51 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQINBGMb6WMBEADTv3wx85Yudfzb8uiI/fIuEMVgnpXwdp/Wue5XQp9eJyK+lxRM
|
||||
oB3nwcS1S1Y3F6dZIrX7bWAWiFbYsn3Q6EfmE2w5xTtSQ/QEoZ0OZmxEFZs313Rc
|
||||
6wvraYgwX9Dz8vuA85w/FLwD1O7jSuBApx3p+04YlLoqJUXRBYbGYwSU+PgUMHZN
|
||||
td/1eh2U1OQzCuI+SBeYOR5pUbobodxS9dEkw/9sGtNHWnn2sRwEHrnIgXk/c86L
|
||||
bQ8g8h+7AV1ehW9QMBex+3heY6oMTYiSrVa1WHgZ1fC8+abrDtq8Dmv/xozRB/X0
|
||||
Qn1RrnKVqnUrvSRNaDKY2wQ+BLvBPlqHdilDAZFBImjs7Eo4BL8BrcXDgni4yKQZ
|
||||
ATH5PJe9XlS7L+o2Hh1P44j8GSQO6fFLmqXsIYI5NnumKLejjY4rbioh3THyMZNG
|
||||
ntBMCbSdsR4M4w5YG73OkJQUCNRgUISUyU2j+AoTDB1lSGJRZVYsNoLXfZ9H40jl
|
||||
set+YrO1mktH3v3bUYjtIWUIVblQf8uFQBppAXHwTlbo0BFDpElCdDZw4mDOqec7
|
||||
5ebIhVq6r9F3S5AvEv0V1EyIIdGbOQEyFUUGbd7rkM2I+WldEwZXJcnRy/Dul9Sn
|
||||
r4UE/nJxTDmHuNaRYwHFYvzNb+WpojiZFd/eH9gha2iMoJpw9yTpD52J0wARAQAB
|
||||
tB5SZW7DqSBKb2NodW0gPHJlbmVAam9jaHVtLmRldj6JAk4EEwEKADgWIQTypyNc
|
||||
Hs/S9+rbbR/32Qb15R6OXgUCYxvpYwIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIX
|
||||
gAAKCRD32Qb15R6OXoA3D/9wbf0k7ilyVbXXs1SVYn+LCP6l1XyJLgf3scklLCkL
|
||||
rjZCJjjCXiVz97AD8mkXiZvNDXjiKZg1rao+3d7q/JU597NAhTNXsg2l075c9ZDe
|
||||
tA2S3GmCNql67+egU9fg7Fxpa1kvHXgjh85HDRrXKGjEQYCpkXySIR2cmFsyK19w
|
||||
9v58oNR2vYBrTT8vL0vV3YvIvRlo98cp/KuL9bE7c79VIT3uB6ZltW6TsXzHVByX
|
||||
UIXkuX640UA0pIWPeyws2o4r1AKHTnQ7atwkn1itAh7EdUpNuprrLAeQaYfjylsx
|
||||
rwxHH8vxj31OASVMQfmXbj2pBrgM3gBPXUHWoULtEp+tJwOce7kPAkbMu5+F0WRZ
|
||||
QTaaMyBUY5OPljBwLvsFiwM1d0SSbty9FXBPrM7CJQDK+37i9k8U8vUfA17LxorL
|
||||
mOTxwm1Jd4U1V970wvY56a0+zpYpWrL0q36I4sSEYyhOJhezPgLssKMm3sqd9vFn
|
||||
MWSq72vn3Ivwhn+lnUCzcECvmpHHeENWrtCBVwj3jyMZoh+k2yMm13LKDI36kiM/
|
||||
l7bKlockBc/T3D/qnYfT27zeHxvYmwWLNDohXRKoGNJ2wN2TwMqUSD+5V6JI8gyH
|
||||
fjMYRNtSfJLmCu9LZ//kLMG4ssBsmkGKu699/AGJolb8tB0y3GuM4gMGw+hgQNW8
|
||||
DbkCDQRjG+ljARAAnrNPqN4IDb5KRJFIGBuWSe/9uELYhydN1rAoPiyYGrxulNG1
|
||||
7C7QWjC9fUTKGfUE2y14mtw6x1zztSPe8yhn65A5KLAXH7sJpEoJY/3QrqYx82Fc
|
||||
x8fzO7LzeYmA/BaRXL359hbzqj6SVX72xduEwiEZkIlSGAXxdzc31a1lZp9vICVK
|
||||
rlLA2iXX23HnnvUMN5WA3Z6EBfzLeC3IU07OkpnRer/o62Moaoqp4EeCFGF3l81/
|
||||
CBBk3QySIHxVLkh1/jXEzCmwsEgpuTq784d5HMeM3LqwYM/0Cx7xc38Ogsh8PVt3
|
||||
5/wXenaKSKXawnuYCcf+0ayQ9WPdtpNnIslR6VfPPSSJhpcVON4pqjKl6qMo9+or
|
||||
bfIomkodrb1YAQkIwOhRno34JnMabSP3y6NzNlBkuLPoV/XcUBSW7+iA/nTVqKBy
|
||||
Y4DOlBNBn9dX8Drd8GyzN5fPiyxIBqY4rD0Vz2W9AswCHR8Ec5MFVs6udg7kST6r
|
||||
ew9njXhxGQg4i9dlD2zsth/jxbfXtPE8LXxu3EmJR4FAQyTvIDCBdAh3+27dKC1w
|
||||
wYp9ln1GLsARIS9JfWwQVvCtvFdMgjybePXguUPDOD7QmtLSMIrSR/OGjfrtUGo7
|
||||
B3q5y6jXAp5qglogjcTW3SYeuPVyWKjkHjsdxePnwZ+ub/xKdIhtKhtkQEkAEQEA
|
||||
AYkCNgQYAQoAIBYhBPKnI1wez9L36tttH/fZBvXlHo5eBQJjG+ljAhsMAAoJEPfZ
|
||||
BvXlHo5eh4kP/18XXq3Nu93LFEiJpydTwKfrXUqrl44Y15nRU31MiB5cxAhJ3YJu
|
||||
K+HvG3luZg00U3FFhr4ybtaJcGul4KgVmi5LcNXgf6ZiVRJhiNnzoPCYuUtA8yxu
|
||||
9NVhlWi24TgOA2QUekigAeMjlr101yntwaxMN3SwxoGuVuJTp1OSj2WFuneYlKyd
|
||||
FEkXSq5wvufEI63uKwNjWhTCObNV6G+WdG4RHIbuDAcemOW8OKxlvtdO+gOcDB9B
|
||||
I8kDOmRO3OvT00EPzb+F3OeCFHezV+2YsKnFKJKNTPM/x1NyPEQnki93DnlPhqY2
|
||||
kRGDgU8YOunl/HN0sCaXH1pyz8+dkpuueOQVSMHRectstKJ4DP/3PXSbFILwgWkK
|
||||
KHmR+39wvjKkAn5OgbInIbD21piGntYmLFZJQjvATm5jFVBkMzA17B/Y5hCr78Nl
|
||||
1XxOJD502HhD0iMbScGmU6/7VKGGWrbKDNrONgaSoCFHQI36zKE4p1rqsCHXBbJm
|
||||
WtsY/pWqn9ky+k8K3bFsQrAvLDR0jSymtty5/Jd9IaICZgBzmy2Ts1lycjZK3tL8
|
||||
K77c6y+ceVGc87mDMM3ytzLydlK9CNfOPfA0v9L2dQOxWUTgWi3UcFcYI+6Cy3b5
|
||||
DfHrb9uRZIpscUG6RNX+kO7uGlFwmYirUPnPjIasM0a7fZOwsJmLoDyH
|
||||
=WT8e
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
@ -0,0 +1 @@
|
||||
node_modules/
|
@ -1,9 +0,0 @@
|
||||
[submodule "vendor/lightslider"]
|
||||
path = vendor/lightslider
|
||||
url = https://github.com/sachinchoolur/lightslider.git
|
||||
[submodule "vendor/lightGallery"]
|
||||
path = vendor/lightgallery
|
||||
url = https://github.com/sachinchoolur/lightGallery.git
|
||||
[submodule "vendor/fontawesome"]
|
||||
path = vendor/fontawesome
|
||||
url = https://github.com/FortAwesome/Font-Awesome.git
|
@ -0,0 +1,41 @@
|
||||
module.exports = function (grunt) {
|
||||
'use strict';
|
||||
|
||||
grunt.loadNpmTasks('grunt-contrib-copy');
|
||||
|
||||
grunt.initConfig({
|
||||
copy: {
|
||||
main: {
|
||||
files: [
|
||||
// jQuery
|
||||
{ expand: true, flatten: true, src: ['node_modules/jquery/dist/jquery.min.js'], dest: 'static/static/js/' },
|
||||
|
||||
// Bootstrap
|
||||
{ expand: true, flatten: true, src: ['node_modules/bootstrap/dist/css/bootstrap.min.css'], dest: 'static/static/css/' },
|
||||
{ expand: true, flatten: true, src: ['node_modules/bootstrap/dist/css/bootstrap-theme.min.css'], dest: 'static/static/css/' },
|
||||
{ expand: true, flatten: true, src: ['node_modules/bootstrap/dist/js/bootstrap.min.js'], dest: 'static/static/js/' },
|
||||
|
||||
// lightgallery
|
||||
{ expand: true, flatten: true, src: ['node_modules/lightgallery/dist/css/lightgallery.min.css'], dest: 'static/static/css/' },
|
||||
{ expand: true, flatten: true, src: ['node_modules/lightgallery/dist/js/lightgallery.min.js'], dest: 'static/static/js/' },
|
||||
{ expand: true, flatten: true, src: ['node_modules/lightgallery/dist/fonts/*'], dest: 'static/static/fonts/' },
|
||||
|
||||
// lightslider
|
||||
{ expand: true, flatten: true, src: ['node_modules/lightslider/dist/css/lightslider.min.css'], dest: 'static/static/css/' },
|
||||
{ expand: true, flatten: true, src: ['node_modules/lightslider/dist/js/lightslider.min.js'], dest: 'static/static/js/' },
|
||||
{ expand: true, flatten: true, src: ['node_modules/lightslider/dist/img/*'], dest: 'static/static/img/' },
|
||||
|
||||
// Fontawesome 4.x
|
||||
{ expand: true, flatten: true, src: ['node_modules/font-awesome/css/font-awesome.min.css'], dest: 'static/static/css/' },
|
||||
{ expand: true, flatten: true, src: ['node_modules/font-awesome/fonts/*'], dest: 'static/static/fonts/' },
|
||||
|
||||
// fortawesome
|
||||
// { expand: true, flatten: true, src: ['node_modules/@fortawesome/fontawesome-free/css/all.min.css'], dest: 'static/static/css/' },
|
||||
// { expand: true, flatten: true, src: ['node_modules/@fortawesome/fontawesome-free/webfonts/*'], dest: 'static/static/webfonts/' },
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
grunt.registerTask('default', ['copy:main']);
|
||||
};
|
@ -1,20 +1,16 @@
|
||||
|
||||
<script type="text/javascript" src="{{ .Site.BaseURL }}/static/js/thirdparties.js"></script>
|
||||
<script type="text/javascript" src="{{ .Site.BaseURL }}/static/js/jquery.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="{{ .Site.BaseURL }}/static/js/lightGallery.min.js"></script>
|
||||
<script type="text/javascript" src="{{ .Site.BaseURL }}/static/js/lightslider.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="{{ .Site.BaseURL }}/static/js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="{{ .Site.BaseURL }}/static/js/main.js"></script>
|
||||
|
||||
<script type="text/javascript" src="{{ .Site.BaseURL }}/static/js/highlight.pack.js"></script>
|
||||
<script>
|
||||
<!-- <script type="text/javascript" src="{{ .Site.BaseURL }}/static/js/highlight.pack.min.js"></script> -->
|
||||
<!-- <script>
|
||||
hljs.configure({
|
||||
languages: ['bash', 'html']
|
||||
});
|
||||
hljs.initHighlightingOnLoad();
|
||||
</script>
|
||||
</script> -->
|
||||
{{ partial "analytics.html" }}
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,20 +1,14 @@
|
||||
<link type="text/css" href="{{ .Site.BaseURL }}/static/css/bootstrap.min.css" rel="stylesheet"/>
|
||||
<link type="text/css" href="{{ .Site.BaseURL }}/static/css/bootstrap-theme.min.css" rel="stylesheet"/>
|
||||
|
||||
<link type="text/css" href="{{ .Site.BaseURL }}/static/css/persona-icons.css" rel="stylesheet"/>
|
||||
<link type="text/css" media="print" onload="this.onload=null;this.removeAttribute('media');" href="{{ .Site.BaseURL }}/static/css/persona-icons.css" rel="stylesheet"/>
|
||||
|
||||
<!-- Fonts ni style.css -->
|
||||
<link type="text/css" href="{{ .Site.BaseURL }}/static/css/lato-font.css" rel="stylesheet"/>
|
||||
<link type="text/css" href="{{ .Site.BaseURL }}/static/css/notoserif-font.css" rel="stylesheet"/>
|
||||
<link type="text/css" media="print" onload="this.onload=null;this.removeAttribute('media');" href="{{ .Site.BaseURL }}/static/css/font-awesome.min.css" rel="stylesheet" />
|
||||
<link type="text/css" media="print" onload="this.onload=null;this.removeAttribute('media');" href="{{ .Site.BaseURL }}/static/css/lato-font.css" rel="stylesheet"/>
|
||||
<link type="text/css" media="print" onload="this.onload=null;this.removeAttribute('media');" href="{{ .Site.BaseURL }}/static/css/notoserif-font.css" rel="stylesheet"/>
|
||||
|
||||
<link type="text/css" href="{{ .Site.BaseURL }}/static/css/style.css" rel="stylesheet"/>
|
||||
<link type="text/css" href="{{ .Site.BaseURL }}/static/css/responsive.css" rel="stylesheet"/>
|
||||
|
||||
<link type="text/css" href="{{ .Site.BaseURL }}/static/css/highlight/googlecode.css" rel="stylesheet"/>
|
||||
|
||||
<!-- start hugo lightslider -->
|
||||
<!-- you need this jquery include if you want lightslider without includejs="true". -->
|
||||
<script src="{{ $.Site.BaseURL }}/static/js/jquery.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="{{ .Site.BaseURL }}/static/css/lightGallery.css" />
|
||||
<link rel="stylesheet" type="text/css" href="{{ .Site.BaseURL }}/static/css/lightslider.css" />
|
||||
<!-- end hugo lightslider -->
|
||||
<link type="text/css" media="print" onload="this.onload=null;this.removeAttribute('media');" href="{{ .Site.BaseURL }}/static/css/chromastyles-monokai.css" rel="stylesheet"/>
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "@pcdummy/persona",
|
||||
"version": "1.0.0",
|
||||
"description": "Persona theme",
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bootstrap": "^3.4.1",
|
||||
"font-awesome": "^4.7.0",
|
||||
"grunt": "^1.5.3",
|
||||
"grunt-contrib-copy": "^1.0.0",
|
||||
"jquery": "^3.6.1",
|
||||
"lightgallery": "^2.6.0",
|
||||
"lightslider": "^1.1.6"
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
../../../vendor/bootstrap/css/bootstrap-theme.min.css
|
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
../../../vendor/bootstrap/css/bootstrap.min.css
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,85 @@
|
||||
/* Background */ .bg { color: #f8f8f2; background-color: #272822; }
|
||||
/* PreWrapper */ .chroma { color: #f8f8f2; background-color: #272822; }
|
||||
/* Other */ .chroma .x { }
|
||||
/* Error */ .chroma .err { color: #960050; background-color: #1e0010 }
|
||||
/* CodeLine */ .chroma .cl { }
|
||||
/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
|
||||
/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; }
|
||||
/* LineHighlight */ .chroma .hl { background-color: #ffffcc }
|
||||
/* LineNumbersTable */ .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
|
||||
/* LineNumbers */ .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
|
||||
/* Line */ .chroma .line { display: flex; }
|
||||
/* Keyword */ .chroma .k { color: #66d9ef }
|
||||
/* KeywordConstant */ .chroma .kc { color: #66d9ef }
|
||||
/* KeywordDeclaration */ .chroma .kd { color: #66d9ef }
|
||||
/* KeywordNamespace */ .chroma .kn { color: #f92672 }
|
||||
/* KeywordPseudo */ .chroma .kp { color: #66d9ef }
|
||||
/* KeywordReserved */ .chroma .kr { color: #66d9ef }
|
||||
/* KeywordType */ .chroma .kt { color: #66d9ef }
|
||||
/* Name */ .chroma .n { }
|
||||
/* NameAttribute */ .chroma .na { color: #a6e22e }
|
||||
/* NameBuiltin */ .chroma .nb { }
|
||||
/* NameBuiltinPseudo */ .chroma .bp { }
|
||||
/* NameClass */ .chroma .nc { color: #a6e22e }
|
||||
/* NameConstant */ .chroma .no { color: #66d9ef }
|
||||
/* NameDecorator */ .chroma .nd { color: #a6e22e }
|
||||
/* NameEntity */ .chroma .ni { }
|
||||
/* NameException */ .chroma .ne { color: #a6e22e }
|
||||
/* NameFunction */ .chroma .nf { color: #a6e22e }
|
||||
/* NameFunctionMagic */ .chroma .fm { }
|
||||
/* NameLabel */ .chroma .nl { }
|
||||
/* NameNamespace */ .chroma .nn { }
|
||||
/* NameOther */ .chroma .nx { color: #a6e22e }
|
||||
/* NameProperty */ .chroma .py { }
|
||||
/* NameTag */ .chroma .nt { color: #f92672 }
|
||||
/* NameVariable */ .chroma .nv { }
|
||||
/* NameVariableClass */ .chroma .vc { }
|
||||
/* NameVariableGlobal */ .chroma .vg { }
|
||||
/* NameVariableInstance */ .chroma .vi { }
|
||||
/* NameVariableMagic */ .chroma .vm { }
|
||||
/* Literal */ .chroma .l { color: #ae81ff }
|
||||
/* LiteralDate */ .chroma .ld { color: #e6db74 }
|
||||
/* LiteralString */ .chroma .s { color: #e6db74 }
|
||||
/* LiteralStringAffix */ .chroma .sa { color: #e6db74 }
|
||||
/* LiteralStringBacktick */ .chroma .sb { color: #e6db74 }
|
||||
/* LiteralStringChar */ .chroma .sc { color: #e6db74 }
|
||||
/* LiteralStringDelimiter */ .chroma .dl { color: #e6db74 }
|
||||
/* LiteralStringDoc */ .chroma .sd { color: #e6db74 }
|
||||
/* LiteralStringDouble */ .chroma .s2 { color: #e6db74 }
|
||||
/* LiteralStringEscape */ .chroma .se { color: #ae81ff }
|
||||
/* LiteralStringHeredoc */ .chroma .sh { color: #e6db74 }
|
||||
/* LiteralStringInterpol */ .chroma .si { color: #e6db74 }
|
||||
/* LiteralStringOther */ .chroma .sx { color: #e6db74 }
|
||||
/* LiteralStringRegex */ .chroma .sr { color: #e6db74 }
|
||||
/* LiteralStringSingle */ .chroma .s1 { color: #e6db74 }
|
||||
/* LiteralStringSymbol */ .chroma .ss { color: #e6db74 }
|
||||
/* LiteralNumber */ .chroma .m { color: #ae81ff }
|
||||
/* LiteralNumberBin */ .chroma .mb { color: #ae81ff }
|
||||
/* LiteralNumberFloat */ .chroma .mf { color: #ae81ff }
|
||||
/* LiteralNumberHex */ .chroma .mh { color: #ae81ff }
|
||||
/* LiteralNumberInteger */ .chroma .mi { color: #ae81ff }
|
||||
/* LiteralNumberIntegerLong */ .chroma .il { color: #ae81ff }
|
||||
/* LiteralNumberOct */ .chroma .mo { color: #ae81ff }
|
||||
/* Operator */ .chroma .o { color: #f92672 }
|
||||
/* OperatorWord */ .chroma .ow { color: #f92672 }
|
||||
/* Punctuation */ .chroma .p { }
|
||||
/* Comment */ .chroma .c { color: #75715e }
|
||||
/* CommentHashbang */ .chroma .ch { color: #75715e }
|
||||
/* CommentMultiline */ .chroma .cm { color: #75715e }
|
||||
/* CommentSingle */ .chroma .c1 { color: #75715e }
|
||||
/* CommentSpecial */ .chroma .cs { color: #75715e }
|
||||
/* CommentPreproc */ .chroma .cp { color: #75715e }
|
||||
/* CommentPreprocFile */ .chroma .cpf { color: #75715e }
|
||||
/* Generic */ .chroma .g { }
|
||||
/* GenericDeleted */ .chroma .gd { color: #f92672 }
|
||||
/* GenericEmph */ .chroma .ge { font-style: italic }
|
||||
/* GenericError */ .chroma .gr { }
|
||||
/* GenericHeading */ .chroma .gh { }
|
||||
/* GenericInserted */ .chroma .gi { color: #a6e22e }
|
||||
/* GenericOutput */ .chroma .go { }
|
||||
/* GenericPrompt */ .chroma .gp { }
|
||||
/* GenericStrong */ .chroma .gs { font-weight: bold }
|
||||
/* GenericSubheading */ .chroma .gu { color: #75715e }
|
||||
/* GenericTraceback */ .chroma .gt { }
|
||||
/* GenericUnderline */ .chroma .gl { }
|
||||
/* TextWhitespace */ .chroma .w { }
|
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
../../../../vendor/highlightjs/styles/arta.css
|
@ -1 +0,0 @@
|
||||
../../../../vendor/highlightjs/styles/ascetic.css
|
@ -1 +0,0 @@
|
||||
../../../../vendor/highlightjs/styles/atelier-dune.dark.css
|
@ -1 +0,0 @@
|
||||
../../../../vendor/highlightjs/styles/atelier-dune.light.css
|
@ -1 +0,0 @@
|
||||
../../../../vendor/highlightjs/styles/atelier-forest.dark.css
|
@ -1 +0,0 @@
|
||||
../../../../vendor/highlightjs/styles/atelier-forest.light.css
|
@ -1 +0,0 @@
|
||||
../../../../vendor/highlightjs/styles/atelier-heath.dark.css
|
@ -1 +0,0 @@
|
||||
../../../../vendor/highlightjs/styles/atelier-heath.light.css
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue