mirror of
https://github.com/bluxmit/alnoda-workspaces.git
synced 2024-06-29 11:40:21 +12:00
FIX: env variable in mkdocs macro (for all workspaces)
This commit is contained in:
parent
c96e7e6e8c
commit
fb17f9f15e
|
@ -1,5 +1,5 @@
|
|||
ARG docker_registry=docker.io/alnoda
|
||||
ARG image_tag=18.04-0.7
|
||||
ARG image_tag=18.04-0.11
|
||||
|
||||
## Images used:
|
||||
ARG BUILD_IMAGE=node:12.18.3
|
||||
|
@ -63,10 +63,12 @@ COPY ./mkdocs/mkdocs.yml /home/docs/mkdocs.yml
|
|||
COPY ./mkdocs/home.md /home/docs/docs/pages/home
|
||||
COPY ./mkdocs/Ara.png /home/docs/docs/pages/home/home/
|
||||
COPY ./mkdocs/Blast-radius.png /home/docs/docs/pages/home/home/
|
||||
COPY ./mkdocs/Terraform-Rover.png /home/docs/docs/pages/home/home/
|
||||
COPY ./mkdocs/helpers.py /home/docs/macros
|
||||
COPY README.md /home/docs/docs/docs.md
|
||||
|
||||
RUN echo "------------------------------------------------------ ansible ara" \
|
||||
RUN apt-get -y update \
|
||||
&& echo "------------------------------------------------------ ansible ara" \
|
||||
&& echo "UTC" > /etc/timezone \
|
||||
&& mkdir -p /home/abc/.ara/server \
|
||||
&& ara-manage makemigrations \
|
||||
|
@ -79,7 +81,6 @@ RUN echo "------------------------------------------------------ ansible ara" \
|
|||
&& rm /tmp/terraform_0.14.6_linux_amd64.zip \
|
||||
&& echo "------------------------------------------------------ blast-radius" \
|
||||
&& apt-get install -y graphviz \
|
||||
&& mkdir -p /home/terraform \
|
||||
&& echo "------------------------------------------------------ terraform-docs" \
|
||||
&& cd /tmp && curl -Lo ./terraform-docs.tar.gz https://github.com/terraform-docs/terraform-docs/releases/download/v0.15.0/terraform-docs-v0.15.0-linux-amd64.tar.gz \
|
||||
&& tar -xzf terraform-docs.tar.gz \
|
||||
|
@ -134,6 +135,8 @@ RUN echo "------------------------------------------------------ ansible ara" \
|
|||
&& find /home -type d | xargs -I{} chown -R abc {} \
|
||||
&& find /home -type f | xargs -I{} chown abc {}
|
||||
|
||||
ENV TERRAFORM_ROVER="http://localhost:9000"
|
||||
|
||||
USER abc
|
||||
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 455 KiB |
|
@ -14,7 +14,8 @@ port_increments = {
|
|||
"TERMINAL_URL": 6,
|
||||
"MC_URL": 7,
|
||||
"HTOP_URL": 8,
|
||||
"ANSIBLE_ARA": 9
|
||||
"ANSIBLE_ARA": 9,
|
||||
"BLAST_RADIUS": 10
|
||||
}
|
||||
|
||||
# this function name should not be changed
|
||||
|
@ -29,7 +30,7 @@ def define_env(env):
|
|||
@env.macro
|
||||
def get_tool_url(env):
|
||||
try:
|
||||
return os.environ[name]
|
||||
return os.environ[env]
|
||||
except:
|
||||
# Get host
|
||||
host = "localhost"
|
||||
|
|
|
@ -72,6 +72,24 @@
|
|||
"image": "Filebrowser.png",
|
||||
"description": "Browse, upload and download files and folders to and from the Workspace"
|
||||
},
|
||||
{
|
||||
"env": "ANSIBLE_ARA",
|
||||
"name": "Ansible Ara",
|
||||
"image": "Ara.png",
|
||||
"description": "Monitor for all Ansible plays"
|
||||
},
|
||||
{
|
||||
"env": "TERRAFORM_ROVER",
|
||||
"name": "Terraform Rover",
|
||||
"image": "Terraform-Rover.png",
|
||||
"description": "Not started! Start manually with your Terraform project dir, i.e. <b>cd /home/examples/terraform-scaleway/; terraform init; rover --workingDir /home/examples/terraform-scaleway/</b>"
|
||||
},
|
||||
{
|
||||
"env": "BLAST_RADIUS",
|
||||
"name": "Blast Radius",
|
||||
"image": "Blast-radius.png",
|
||||
"description": "Not started! Start manually with your Terraform project dir, i.e. <b>cd /home/examples/terraform-scaleway; terraform init; blast-radius --serve --port 8030</b>"
|
||||
},
|
||||
{
|
||||
"env": "CRONICLE_URL",
|
||||
"name": "Cronicle",
|
||||
|
@ -101,12 +119,6 @@
|
|||
"name": "Process monitor",
|
||||
"image": "Htop.jpg",
|
||||
"description": "Monitor running process and resource utilization"
|
||||
},
|
||||
{
|
||||
"env": "ANSIBLE_ARA",
|
||||
"name": "Ansible Ara",
|
||||
"image": "Ara.png",
|
||||
"description": "Monitor for all Ansible plays"
|
||||
}
|
||||
]
|
||||
%}
|
||||
|
|
|
@ -28,7 +28,7 @@ def define_env(env):
|
|||
@env.macro
|
||||
def get_tool_url(env):
|
||||
try:
|
||||
return os.environ[name]
|
||||
return os.environ[env]
|
||||
except:
|
||||
# Get host
|
||||
host = "localhost"
|
||||
|
|
|
@ -28,7 +28,7 @@ def define_env(env):
|
|||
@env.macro
|
||||
def get_tool_url(env):
|
||||
try:
|
||||
return os.environ[name]
|
||||
return os.environ[env]
|
||||
except:
|
||||
# Get host
|
||||
host = "localhost"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
ARG docker_registry=docker.io/alnoda
|
||||
ARG image_tag=18.04-0.5
|
||||
ARG image_tag=18.04-0.11
|
||||
|
||||
FROM ${docker_registry}/workspace-in-docker:${image_tag}
|
||||
|
||||
|
@ -14,6 +14,10 @@ COPY mkdocs-requirements.txt /home/abc/installed-python-packages
|
|||
COPY ./mkdocs/IDE.jpg /home/docs/docs/pages/home/home/
|
||||
COPY ./mkdocs/showcase.md /home/docs/docs/showcase.md
|
||||
COPY ./mkdocs/mkdocs.yml /home/docs/mkdocs.yml
|
||||
COPY ./mkdocs/home.md /home/docs/docs/pages/home
|
||||
COPY ./mkdocs/helpers.py /home/docs/macros
|
||||
COPY ./mkdocs/Magicspace-web.png /home/docs/docs/pages/home/home/
|
||||
COPY ./examples/ /home/examples/
|
||||
|
||||
RUN apt-get -y update \
|
||||
&& echo "-------------------------------------------- weasyprint" \
|
||||
|
@ -26,6 +30,7 @@ RUN apt-get -y update \
|
|||
&& mv /tmp/alnoda-workspaces/utils /home/abc/ \
|
||||
&& rm -rf /tmp/alnoda-workspaces \
|
||||
&& echo "------------------------------------------------------ user" \
|
||||
&& chown -R abc /home/examples \
|
||||
&& chown -R abc /home/abc/utils \
|
||||
&& chown -R abc /home/abc/installed-python-packages
|
||||
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
Few of the Extended Markdown features
|
||||
|
||||
#### Code
|
||||
```{.py3 linenums="1" hl_lines="5-7"}
|
||||
def insertion_sort(nums):
|
||||
for i in range(1, len(nums)):
|
||||
item_to_insert = nums[i]
|
||||
j = i - 1
|
||||
while j >= 0 and nums[j] > item_to_insert:
|
||||
nums[j + 1] = nums[j]
|
||||
j -= 1
|
||||
nums[j + 1] = item_to_insert
|
||||
```
|
||||
|
||||
#### Emoji
|
||||
|
||||
:smile: :heart: :thumbsup: :100: :muscle: :accept: :point_up: :airplane: :champagne: :raised_hands: :boom: :laughing: :metal: :handshake: :older_man: :sheep: :no_entry: :mouse: :relieved: :question: :wink: :wave: :rainbow: :sleeping:
|
||||
|
||||
#### Critic
|
||||
|
||||
We Uber drivers never know whom we’re going to end up with as a passenger {--in the same car--}.
|
||||
One day, I was driving over a new bridge, the design of which was very {~~confusing~>ugly~~}.
|
||||
Completely confounded, {==I muttered==}{>>Actually I said it out loud<<}, “I’d love to meet the {~~genius~>retard~~}
|
||||
who designed this mess.” With that, my passenger {==extended his hand in my direction==}{>>I thought he wanted to choke me<<}
|
||||
and said, “Well, today is your {--*very*--} lucky day. My name is Mike, I work for the county engineer’s office,
|
||||
and I’m the {==genius==}{>>obviously an irony<<} who designed this!”. Surprisingly, he still gave me a tip {++**of 2 dollars**++}.
|
||||
|
||||
#### Keys
|
||||
|
||||
++enter++ ++tab++ ++space++ ++arrow-up++ ++arrow-down++ ++page-up++ ++home++ ++backspace++ ++insert++
|
||||
|
||||
#### Tabls, lists & admonitions
|
||||
|
||||
!!! example "Tasklist"
|
||||
=== "Output"
|
||||
- [X] Plans at work
|
||||
* [X] Make vanilla pudding. Put in mayo jar. Eat in the office during the lunch break
|
||||
* [X] Wear shirt that says “Life”. Hand out lemons to colleagues.
|
||||
* [ ] Hire two private investigators. Get them to follow each other.
|
||||
- [ ] Personal plans
|
||||
* [X] Make an alcoholic beverage and name it “responsibly.” Start drinking Responsibly.
|
||||
* [ ] Sneeze in front of the Pope. Get blessed.
|
||||
* [ ] Buy a horse, name it “Oscar Takes The Lead,” enter it in horse races.
|
||||
|
||||
=== "Markdown"
|
||||
```
|
||||
- [X] Plans at work
|
||||
* [X] Make vanilla pudding. Put in mayo jar. Eat in the office during the lunch break
|
||||
* [X] Wear shirt that says “Life”. Hand out lemons to colleagues.
|
||||
* [ ] Hire two private investigators. Get them to follow each other.
|
||||
- [ ] Personal plans
|
||||
* [X] Make an alcoholic beverage and name it “responsibly.” Start drinking Responsibly.
|
||||
* [ ] Sneeze in front of the Pope. Get blessed.
|
||||
* [ ] Buy a horse, name it “Oscar Takes The Lead,” enter it in horse races.
|
||||
```
|
||||
|
||||
#### Tables
|
||||
|
||||
**Substance** | **Description**
|
||||
:--- | ---:
|
||||
**Bombastium** | Rarest element in the world. Dropped into a barrel of water becomes one barrel of ice cream
|
||||
**Jerktonium** | Ingestion of jerktonium causes a bad attitude, but the effects are curable by song.
|
||||
**Philote** | The smallest possible particle, occupying no space at all.
|
||||
|
||||
#### Formulas
|
||||
|
||||
$$
|
||||
\left(\frac{\left(\sqrt{\frac{73^2}{12x}}\sqrt{\frac{x|x|}{\log_x}}\right)}{\sqrt[3]{\frac xy}}\right)
|
||||
$$
|
||||
|
||||
#### Diargams
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
Animal <|-- Duck
|
||||
Animal <|-- Fish
|
||||
Animal <|-- Zebra
|
||||
class Animal{
|
||||
+int age
|
||||
+String gender
|
||||
+isMammal()
|
||||
+mate()
|
||||
}
|
||||
class Duck{
|
||||
+String beakColor
|
||||
+swim()
|
||||
+quack()
|
||||
}
|
||||
class Fish{
|
||||
-int sizeInFeet
|
||||
-canEat()
|
||||
}
|
||||
class Zebra{
|
||||
+bool is_wild
|
||||
+run()
|
||||
}
|
||||
```
|
|
@ -0,0 +1,99 @@
|
|||
# ===========================================================
|
||||
# NAVIGATION
|
||||
# ===========================================================
|
||||
|
||||
nav:
|
||||
- Home: index.md
|
||||
|
||||
|
||||
# ===========================================================
|
||||
# CONFIGURATION
|
||||
# ===========================================================
|
||||
|
||||
site_name: MkDocs Showcase
|
||||
edit_uri: ""
|
||||
|
||||
# ===========================================================
|
||||
# APPEARANCE
|
||||
# ===========================================================
|
||||
|
||||
theme:
|
||||
name: 'material'
|
||||
icon:
|
||||
repo: fontawesome/brands/github
|
||||
features:
|
||||
- search.suggest
|
||||
palette:
|
||||
- scheme: default
|
||||
toggle:
|
||||
icon: material/weather-sunny
|
||||
name: Switch to light mode
|
||||
primary: indigo
|
||||
accent: blue
|
||||
- scheme: slate
|
||||
toggle:
|
||||
icon: material/weather-night
|
||||
name: Switch to dark mode
|
||||
primary: deep orange
|
||||
accent: red
|
||||
|
||||
extra:
|
||||
# Link to open when your logo is clicked
|
||||
homepage: https://alnoda.org
|
||||
host_url: http://localhost
|
||||
|
||||
plugins:
|
||||
- search
|
||||
- include-markdown
|
||||
# Enable Macros and jinja2 templates
|
||||
- awesome-pages
|
||||
# mermaid2 diagrams: https://mermaid-js.github.io/mermaid/#/
|
||||
- mermaid2:
|
||||
arguments:
|
||||
theme: forest # default, forest, dark, neutral, base
|
||||
themeCSS: ".er.entityLabel{fill: black;} .messageLine0{stroke: orange;} .messageLine1{stroke: orange;} #arrowhead{fill: orange;} .messageText{fill: black; stroke: black}"
|
||||
|
||||
|
||||
markdown_extensions:
|
||||
- def_list
|
||||
- pymdownx.tasklist:
|
||||
custom_checkbox: true
|
||||
- pymdownx.arithmatex:
|
||||
generic: true
|
||||
- admonition
|
||||
- pymdownx.inlinehilite
|
||||
- pymdownx.details
|
||||
- pymdownx.superfences:
|
||||
# make exceptions to highlighting of code:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:mermaid2.fence_mermaid
|
||||
- pymdownx.tabbed
|
||||
- abbr
|
||||
- pymdownx.snippets
|
||||
- attr_list
|
||||
- pymdownx.emoji:
|
||||
emoji_index: !!python/name:materialx.emoji.twemoji
|
||||
emoji_generator: !!python/name:materialx.emoji.to_svg
|
||||
- pymdownx.keys
|
||||
- pymdownx.betterem
|
||||
- pymdownx.caret
|
||||
- pymdownx.critic
|
||||
- pymdownx.escapeall
|
||||
- pymdownx.smartsymbols
|
||||
- pymdownx.tilde:
|
||||
smart_delete: true
|
||||
- footnotes
|
||||
|
||||
|
||||
extra_javascript:
|
||||
- https://polyfill.io/v3/polyfill.min.js?features=es6
|
||||
- https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js
|
||||
- https://unpkg.com/mermaid/dist/mermaid.min.js
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
BIN
workspaces/mkdocs-magicspace/mkdocs/Magicspace-web.png
Normal file
BIN
workspaces/mkdocs-magicspace/mkdocs/Magicspace-web.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 358 KiB |
58
workspaces/mkdocs-magicspace/mkdocs/helpers.py
Normal file
58
workspaces/mkdocs-magicspace/mkdocs/helpers.py
Normal file
|
@ -0,0 +1,58 @@
|
|||
"""
|
||||
Basic example of a Mkdocs-macros module.
|
||||
Include this {{ macros_info() }} in any page to get complete macro info
|
||||
"""
|
||||
import os
|
||||
|
||||
port_increments = {
|
||||
"DOCS_URL": 0,
|
||||
"FILEBROWSER_URL": 1,
|
||||
"STATICFS_URL": 2,
|
||||
"CRONICLE_URL": 3,
|
||||
"UNGIT_URL": 4,
|
||||
"IDE_URL": 5,
|
||||
"TERMINAL_URL": 6,
|
||||
"MC_URL": 7,
|
||||
"HTOP_URL": 8,
|
||||
"MKDOCS_LIVE": 10
|
||||
}
|
||||
|
||||
# this function name should not be changed
|
||||
def define_env(env):
|
||||
"""
|
||||
This is the hook for defining variables, macros and filters
|
||||
- variables: the dictionary that contains the environment variables
|
||||
- macro: a decorator function, to declare a macro.
|
||||
- filter: a function with one of more arguments,
|
||||
used to perform a transformation
|
||||
"""
|
||||
@env.macro
|
||||
def get_tool_url(env):
|
||||
try:
|
||||
return os.environ[env]
|
||||
except:
|
||||
# Get host
|
||||
host = "localhost"
|
||||
try:
|
||||
host = os.environ["WRK_HOST"]
|
||||
except:
|
||||
pass
|
||||
proto = "http"
|
||||
try:
|
||||
proto = os.environ["WRK_PROTO"]
|
||||
except:
|
||||
pass
|
||||
# Entry port - port relative to which other ports will be calculated
|
||||
entry_port = 8020
|
||||
try:
|
||||
entry_port = int(os.environ["ENTRY_PORT"])
|
||||
except:
|
||||
pass
|
||||
# Assign port
|
||||
try:
|
||||
port = port_increments[env] + entry_port
|
||||
except:
|
||||
port = 80
|
||||
return f"{proto}://{host}:{port}"
|
||||
|
||||
|
133
workspaces/mkdocs-magicspace/mkdocs/home.md
Normal file
133
workspaces/mkdocs-magicspace/mkdocs/home.md
Normal file
|
@ -0,0 +1,133 @@
|
|||
<style>
|
||||
/* These styles apply only to this page! */
|
||||
.md-content__button {
|
||||
display: none;
|
||||
}
|
||||
.md-typeset h1 {
|
||||
line-height: 0;
|
||||
margin: 0;
|
||||
margin-left: -9999px;
|
||||
}
|
||||
.quickstart-wrapper {
|
||||
min-width: 300px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
padding-left: -50px;
|
||||
column-gap: 50px;
|
||||
row-gap: 50px;
|
||||
}
|
||||
.quickstart-wrapper > div {
|
||||
flex: 300px;
|
||||
max-width: 300px;
|
||||
}
|
||||
.tool-img{
|
||||
box-shadow: rgba(0, 0, 0, 0.24) 0px 5px 5px;
|
||||
border-radius: 5px;
|
||||
min-width: 300px;
|
||||
max-width: 300px;
|
||||
max-height: 170px;
|
||||
min-height: 170px;
|
||||
}
|
||||
.tool-caption{
|
||||
font-family: Roboto, Helvetica, sans-serif;
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
|
||||
/* font-size: 1.25em;
|
||||
font-weight: 400; */
|
||||
letter-spacing: -.02em;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.tool-description{
|
||||
font-family: Helvetica, sans-serif;
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
font-size: 0.7rem;
|
||||
font-style: oblique;
|
||||
/* font-weight: bold; */
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
{%
|
||||
set tools = [
|
||||
{
|
||||
"env": "IDE_URL",
|
||||
"name": "IDE",
|
||||
"image": "IDE.jpg",
|
||||
"description": "Browser-based version of Visual Studio Code. Develop in any language, install hundreeds of extensions"
|
||||
},
|
||||
{
|
||||
"env": "TERMINAL_URL",
|
||||
"name": "Terminal",
|
||||
"image": "Terminal.png",
|
||||
"description": "Full-fledged browser-based terminal with Z-shell"
|
||||
},
|
||||
{
|
||||
"env": "FILEBROWSER_URL",
|
||||
"name": "File Browser",
|
||||
"image": "Filebrowser.png",
|
||||
"description": "Browse, upload and download files and folders to and from the Workspace"
|
||||
},
|
||||
{
|
||||
"env": "MKDOCS_LIVE",
|
||||
"name": "MkDocs live server",
|
||||
"image": "Magicspace-web.png",
|
||||
"description": "Serve your MkDocs project with live reload. For example, <b>cd /home/examples/mkdocs-material; mkdocs serve -a 0.0.0.0:8030</b>"
|
||||
},
|
||||
{
|
||||
"env": "CRONICLE_URL",
|
||||
"name": "Cronicle",
|
||||
"image": "Cronicle.jpg",
|
||||
"description": "Schedule jobs, manage schedules, observe and monitor executions (user/pass - admin/admin)"
|
||||
},
|
||||
{
|
||||
"env": "UNGIT_URL",
|
||||
"name": "Ungit",
|
||||
"image": "Ungit.jpg",
|
||||
"description": "Manage Git repositories and work flow using beautiful UI"
|
||||
},
|
||||
{
|
||||
"env": "STATICFS_URL",
|
||||
"name": "Static File Server",
|
||||
"image": "Static-server.png",
|
||||
"description": "Serve any static websites like a breeze"
|
||||
},
|
||||
{
|
||||
"env": "MC_URL",
|
||||
"name": "M.Commander",
|
||||
"image": "MC.jpg",
|
||||
"description": "Feature rich visual file manager with internal text viewer and editor"
|
||||
},
|
||||
{
|
||||
"env": "HTOP_URL",
|
||||
"name": "Process monitor",
|
||||
"image": "Htop.jpg",
|
||||
"description": "Monitor running process and resource utilization"
|
||||
}
|
||||
]
|
||||
%}
|
||||
|
||||
|
||||
<div class="quickstart-wrapper">
|
||||
{% for tool in tools %}
|
||||
{% set tool_url = get_tool_url(tool.env) %}
|
||||
<div>
|
||||
<a href="{{ tool_url }}" target="_blank" rel="noopener noreferrer">
|
||||
<img src="{{ tool.image }}" class="tool-img"/>
|
||||
</a>
|
||||
<a href="{{ tool_url }}">
|
||||
<div class="tool-caption">{{ tool.name }}</div>
|
||||
</a>
|
||||
<div class="tool-description">{{ tool.description }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
ARG docker_registry=docker.io/alnoda
|
||||
ARG image_tag=18.04-0.9
|
||||
ARG image_tag=18.04-0.11
|
||||
|
||||
FROM ${docker_registry}/workspace-in-docker:${image_tag}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Python workspace
|
||||
|
||||
Python development enviroment inside the isolated docker container. Includes VS-code IDE,
|
||||
Python development environment inside the isolated docker container. Includes VS-code IDE,
|
||||
job scheduler and other tools for linting, testing, auto-documentation and profiling.
|
||||
|
||||
<p align="center">
|
||||
|
|
|
@ -31,3 +31,4 @@ pytest-regressions==2.2.0
|
|||
logzero==1.7.0
|
||||
pylint==2.10.2
|
||||
|
||||
jupyter==1.0.0
|
||||
|
|
|
@ -29,7 +29,7 @@ def define_env(env):
|
|||
@env.macro
|
||||
def get_tool_url(env):
|
||||
try:
|
||||
return os.environ[name]
|
||||
return os.environ[env]
|
||||
except:
|
||||
# Get host
|
||||
host = "localhost"
|
||||
|
|
|
@ -28,7 +28,7 @@ def define_env(env):
|
|||
@env.macro
|
||||
def get_tool_url(env):
|
||||
try:
|
||||
return os.environ[name]
|
||||
return os.environ[env]
|
||||
except:
|
||||
# Get host
|
||||
host = "localhost"
|
||||
|
|
Loading…
Reference in a new issue