change page|
Gitea Actions Requirements / Explore-Gitea-Actions (push) Waiting to run
Details
Gitea Actions Requirements / Explore-Gitea-Actions (push) Waiting to run
Details
This commit is contained in:
parent
56dcd41052
commit
0f63e6efe4
|
@ -7,6 +7,7 @@ export {}
|
|||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
Home: typeof import('./src/components/Home.vue')['default']
|
||||
IMdi3dRotation: typeof import('~icons/mdi/3d-rotation')['default']
|
||||
IMdiCard: typeof import('~icons/mdi/card')['default']
|
||||
IMdiClarify: typeof import('~icons/mdi/clarify')['default']
|
||||
|
@ -14,6 +15,7 @@ declare module 'vue' {
|
|||
IMdiIcon: typeof import('~icons/mdi/icon')['default']
|
||||
IMdiPrinter: typeof import('~icons/mdi/printer')['default']
|
||||
IMdiVideo3d: typeof import('~icons/mdi/video3d')['default']
|
||||
Projects: typeof import('./src/components/Projects.vue')['default']
|
||||
RandomIcon: typeof import('./src/components/RandomIcon.vue')['default']
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
"pinia": "^2.1.7",
|
||||
"reset-css": "^5.0.2",
|
||||
"vue": "^3.4.21",
|
||||
"vue-3d-model": "^2.0.0-alpha.4"
|
||||
"vue-3d-model": "^2.0.0-alpha.4",
|
||||
"vue-router": "^4.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/mdi": "^1.1.66",
|
||||
|
@ -2284,6 +2285,20 @@
|
|||
"vue": ">=3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-router": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.2.tgz",
|
||||
"integrity": "sha512-hKQJ1vDAZ5LVkKEnHhmm1f9pMiWIBNGF5AwU67PdH7TyXCj/a4hTccuUuYCAMgJK6rO/NVYtQIEN3yL8CECa7Q==",
|
||||
"dependencies": {
|
||||
"@vue/devtools-api": "^6.5.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/posva"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-template-compiler": {
|
||||
"version": "2.7.16",
|
||||
"resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz",
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
"pinia": "^2.1.7",
|
||||
"reset-css": "^5.0.2",
|
||||
"vue": "^3.4.21",
|
||||
"vue-3d-model": "^2.0.0-alpha.4"
|
||||
"vue-3d-model": "^2.0.0-alpha.4",
|
||||
"vue-router": "^4.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/mdi": "^1.1.66",
|
||||
|
|
|
@ -1,129 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { ModelFbx } from 'vue-3d-model';
|
||||
import type { UseSwipeDirection } from '@vueuse/core';
|
||||
import { useSwipe } from '@vueuse/core';
|
||||
import RandomIcon from './components/RandomIcon.vue';
|
||||
import { useProductStore } from './stores/product';
|
||||
import type { ProductInfo } from './stores/product';
|
||||
import Fireworks from '@fireworks-js/vue';
|
||||
import type { FireworksOptions } from '@fireworks-js/vue'
|
||||
|
||||
const IMAGE_URL = import.meta.env.VITE_IMAGE_URL ?? window.location.origin
|
||||
|
||||
type StateType = {
|
||||
active_product?: ProductInfo
|
||||
show_model: boolean,
|
||||
show_fireworks: boolean
|
||||
}
|
||||
|
||||
const products = useProductStore()
|
||||
|
||||
const state: StateType = reactive({
|
||||
active_product: undefined,
|
||||
show_model: false,
|
||||
show_fireworks: false
|
||||
})
|
||||
|
||||
const reset = () => {
|
||||
state.active_product = undefined
|
||||
state.show_model = false
|
||||
state.show_fireworks = false
|
||||
}
|
||||
|
||||
const setActive = (id: number) => {
|
||||
state.active_product = products.list.find(el => el.id == id)
|
||||
state.show_model = false
|
||||
state.show_fireworks = false
|
||||
}
|
||||
|
||||
const toggleShowCanvas = () => {
|
||||
state.show_model = !state.show_model
|
||||
}
|
||||
|
||||
const target = ref<HTMLElement | null>(null)
|
||||
useSwipe(target, {
|
||||
onSwipeEnd(_: TouchEvent, direction: UseSwipeDirection) {
|
||||
if (state.show_model) {
|
||||
return
|
||||
}
|
||||
const index = products.list.findIndex(el => el.id == state.active_product?.id)
|
||||
if (direction === 'right') {
|
||||
if (index == products.list.length - 1) {
|
||||
setActive(products.list[0].id)
|
||||
} else {
|
||||
setActive(products.list[index + 1].id)
|
||||
}
|
||||
} else if (direction === 'left') {
|
||||
if (index == 0) {
|
||||
setActive(products.list[products.list.length - 1].id)
|
||||
} else {
|
||||
setActive(products.list[index - 1].id)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const fw = ref<InstanceType<typeof Fireworks>>()
|
||||
const options = ref<FireworksOptions>({
|
||||
lineStyle: 'square',
|
||||
intensity: 50,
|
||||
lineWidth: {
|
||||
explosion: { min: 7, max: 10 },
|
||||
trace: { min: 7, max: 10 },
|
||||
|
||||
}
|
||||
})
|
||||
onMounted(async () => {
|
||||
products.getData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="sidebar">
|
||||
<ul class="menu">
|
||||
<li v-for="item in products.list">
|
||||
<RandomIcon v-if="item.id === state.active_product?.id" />
|
||||
<a @click.stop.prevent="setActive(item.id)" :href="item.id.toString()">
|
||||
{{ item.title }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="header"><span class="logo-header" @click="reset">Проекты Кустарщины</span></div>
|
||||
<div class="main product" v-if="state.active_product" ref="target">
|
||||
<div class="product-image" v-if="!state.show_model && state.active_product.image1">
|
||||
<img :style="{
|
||||
clipPath: `polygon(
|
||||
0% 10%, 10% 0%,
|
||||
90% 0%, 100% 10%,
|
||||
100% 90%, 90% 100%,
|
||||
10% 100%, 0% 90%
|
||||
)`}" :src="`${IMAGE_URL}${state.active_product.image1}`" />
|
||||
</div>
|
||||
<div class="product-description" v-if="!state.show_model">
|
||||
{{ state.active_product.description }}
|
||||
</div>
|
||||
<a class="product-model-icon" v-if="state.active_product.model3d" @click.stop.prevent="toggleShowCanvas">
|
||||
<i-mdi-video-3d v-if="!state.show_model" />
|
||||
<i-mdi-file v-else />
|
||||
</a>
|
||||
<model-fbx v-if="state.show_model && state.active_product.model3d" class="product-model"
|
||||
:src="`${IMAGE_URL}/${state.active_product.model3d.replace('/back', '')}`" :backgroundAlpha="0"></model-fbx>
|
||||
</div>
|
||||
<div class="main" v-else>
|
||||
<img class="logo-img" src="./assets/logo_color.png"
|
||||
@click="() => { state.show_fireworks = !state.show_fireworks }" />
|
||||
<Fireworks ref="fw" v-if="state.show_fireworks" :autostart="true" :options="options" :style="{
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
position: 'fixed',
|
||||
zIndex: -1,
|
||||
pointerEvents: 'none',
|
||||
}" />
|
||||
</div>
|
||||
</div>
|
||||
<RouterView />
|
||||
</template>
|
|
@ -0,0 +1,27 @@
|
|||
@import '../../node_modules/reset-css/sass/reset';
|
||||
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-columns: 25vw 1fr;
|
||||
grid-template-rows: 15vh 1fr;
|
||||
gap: 0px 0px;
|
||||
grid-template-areas:
|
||||
"header header"
|
||||
"sidebar content";
|
||||
|
||||
min-height: 100vh;
|
||||
padding: 0 2rem;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
grid-area: sidebar;
|
||||
}
|
||||
|
||||
.header {
|
||||
grid-area: header;
|
||||
|
||||
}
|
||||
|
||||
.main {
|
||||
grid-area: content;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
@font-face {
|
||||
font-family: 'open-sans';
|
||||
src: url('../fonts/open-sans.ttf');
|
||||
}
|
||||
|
||||
$accentColor: rgb(126, 126, 223);
|
||||
|
||||
.container {
|
||||
font-family: 'open-sans';
|
||||
}
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 6rem;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.main {
|
||||
ul {
|
||||
font-size: 4rem;
|
||||
|
||||
li {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: initial;
|
||||
|
||||
&:hover,
|
||||
&:active {
|
||||
color: $accentColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,136 +1 @@
|
|||
@import '../../node_modules/reset-css/sass/reset';
|
||||
|
||||
$blackColor: #181818;
|
||||
$accentColor: #ef570c;
|
||||
$redColor: #f83300;
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'logo';
|
||||
src: url('../fonts/logo.ttf');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'main';
|
||||
src: url('../fonts/main.otf');
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'main';
|
||||
background: linear-gradient(to bottom, rgba(255, 255, 255, 0.15) 0%, rgba(0, 0, 0, 0.15) 100%), radial-gradient(at top center, rgba(255, 255, 255, 0.40) 0%, rgba(0, 0, 0, 0.40) 120%) $blackColor;
|
||||
background-blend-mode: multiply, multiply;
|
||||
color: #fff;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-columns: 25vw 1fr;
|
||||
grid-template-rows: 15vh 1fr;
|
||||
gap: 0px 0px;
|
||||
grid-template-areas:
|
||||
"header header"
|
||||
"sidebar content";
|
||||
|
||||
min-height: 100vh;
|
||||
padding: 0 2rem;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
grid-area: sidebar;
|
||||
}
|
||||
|
||||
.header {
|
||||
grid-area: header;
|
||||
justify-content: center;
|
||||
|
||||
}
|
||||
|
||||
.main {
|
||||
grid-area: content;
|
||||
}
|
||||
|
||||
.main,
|
||||
.header,
|
||||
.sidebar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.menu {
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
font-size: 2.5rem;
|
||||
|
||||
li {
|
||||
padding: 0.5rem 0;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
|
||||
&,
|
||||
&:hover,
|
||||
&:active,
|
||||
&:visited {
|
||||
color: $accentColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.model {
|
||||
max-width: 33vw;
|
||||
}
|
||||
|
||||
.product {
|
||||
gap: 1rem;
|
||||
position: relative;
|
||||
|
||||
&-image {
|
||||
flex-basis: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&-description {
|
||||
font-size: 1.75rem;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
&-model {
|
||||
max-height: 80%;
|
||||
|
||||
&-icon {
|
||||
position: absolute;
|
||||
font-size: 4rem;
|
||||
right: 0;
|
||||
top: 0;
|
||||
color: $accentColor;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.logo {
|
||||
&-header {
|
||||
font-family: 'logo';
|
||||
font-size: 4rem;
|
||||
padding: 1rem;
|
||||
|
||||
background: linear-gradient(45deg, $redColor, $accentColor);
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
&-img {
|
||||
width: 54%;
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
@import 'grid.scss';
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
|
||||
$blackColor: #181818;
|
||||
$accentColor: #ef570c;
|
||||
$redColor: #f83300;
|
||||
|
||||
@font-face {
|
||||
font-family: 'logo';
|
||||
src: url('../fonts/logo.ttf');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'main';
|
||||
src: url('../fonts/main.otf');
|
||||
}
|
||||
|
||||
.container {
|
||||
font-family: 'main';
|
||||
background: linear-gradient(to bottom, rgba(255, 255, 255, 0.15) 0%, rgba(0, 0, 0, 0.15) 100%), radial-gradient(at top center, rgba(255, 255, 255, 0.40) 0%, rgba(0, 0, 0, 0.40) 120%) $blackColor;
|
||||
background-blend-mode: multiply, multiply;
|
||||
color: #fff;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.header {
|
||||
justify-content: center;
|
||||
}
|
||||
.main,
|
||||
.header,
|
||||
.sidebar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.menu {
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
font-size: 2.5rem;
|
||||
|
||||
li {
|
||||
padding: 0.5rem 0;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
|
||||
&,
|
||||
&:hover,
|
||||
&:active,
|
||||
&:visited {
|
||||
color: $accentColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.model {
|
||||
max-width: 33vw;
|
||||
}
|
||||
|
||||
.product {
|
||||
gap: 1rem;
|
||||
position: relative;
|
||||
|
||||
&-image {
|
||||
flex-basis: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&-description {
|
||||
font-size: 1.75rem;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
&-model {
|
||||
max-height: 80%;
|
||||
|
||||
&-icon {
|
||||
position: absolute;
|
||||
font-size: 4rem;
|
||||
right: 0;
|
||||
top: 0;
|
||||
color: $accentColor;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.logo {
|
||||
&-header {
|
||||
font-family: 'logo';
|
||||
font-size: 4rem;
|
||||
padding: 1rem;
|
||||
|
||||
background: linear-gradient(45deg, $redColor, $accentColor);
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
&-img {
|
||||
width: 54%;
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<style lang="scss" scoped>
|
||||
@import '../assets/home.scss';
|
||||
</style>
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
Выберите шаблон (демо)
|
||||
</div>
|
||||
<div class="sidebar"></div>
|
||||
<div class="main">
|
||||
<ul>
|
||||
<li>
|
||||
<RouterLink to="projects">Проекты</RouterLink>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://timesheet.kustarshina.ru/">Табель рабочего времени</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://zoo.svs-tech.pro/">Билетная система зоопарка</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,137 @@
|
|||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { ModelFbx } from 'vue-3d-model';
|
||||
|
||||
import type { UseSwipeDirection } from '@vueuse/core';
|
||||
import { useSwipe } from '@vueuse/core';
|
||||
|
||||
import Fireworks from '@fireworks-js/vue';
|
||||
import type { FireworksOptions } from '@fireworks-js/vue'
|
||||
|
||||
import RandomIcon from '../components/RandomIcon.vue';
|
||||
import { useProductStore } from '../stores/product';
|
||||
import type { ProductInfo } from '../stores/product';
|
||||
|
||||
const IMAGE_URL = import.meta.env.VITE_IMAGE_URL ?? window.location.origin
|
||||
|
||||
type StateType = {
|
||||
active_product?: ProductInfo
|
||||
show_model: boolean,
|
||||
show_fireworks: boolean
|
||||
}
|
||||
|
||||
const products = useProductStore()
|
||||
|
||||
const state: StateType = reactive({
|
||||
active_product: undefined,
|
||||
show_model: false,
|
||||
show_fireworks: false
|
||||
})
|
||||
|
||||
const reset = () => {
|
||||
state.active_product = undefined
|
||||
state.show_model = false
|
||||
state.show_fireworks = false
|
||||
}
|
||||
|
||||
const setActive = (id: number) => {
|
||||
state.active_product = products.list.find(el => el.id == id)
|
||||
state.show_model = false
|
||||
state.show_fireworks = false
|
||||
}
|
||||
|
||||
const toggleShowCanvas = () => {
|
||||
state.show_model = !state.show_model
|
||||
}
|
||||
|
||||
const target = ref<HTMLElement | null>(null)
|
||||
useSwipe(target, {
|
||||
onSwipeEnd(_: TouchEvent, direction: UseSwipeDirection) {
|
||||
if (state.show_model) {
|
||||
return
|
||||
}
|
||||
const index = products.list.findIndex(el => el.id == state.active_product?.id)
|
||||
if (direction === 'right') {
|
||||
if (index == products.list.length - 1) {
|
||||
setActive(products.list[0].id)
|
||||
} else {
|
||||
setActive(products.list[index + 1].id)
|
||||
}
|
||||
} else if (direction === 'left') {
|
||||
if (index == 0) {
|
||||
setActive(products.list[products.list.length - 1].id)
|
||||
} else {
|
||||
setActive(products.list[index - 1].id)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const fw = ref<InstanceType<typeof Fireworks>>()
|
||||
const options = ref<FireworksOptions>({
|
||||
lineStyle: 'square',
|
||||
intensity: 50,
|
||||
lineWidth: {
|
||||
explosion: { min: 7, max: 10 },
|
||||
trace: { min: 7, max: 10 },
|
||||
|
||||
}
|
||||
})
|
||||
onMounted(async () => {
|
||||
products.getData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '../assets/projects.scss';
|
||||
</style>
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="sidebar">
|
||||
<ul class="menu">
|
||||
<li v-for="item in products.list">
|
||||
<RandomIcon v-if="item.id === state.active_product?.id" />
|
||||
<a @click.stop.prevent="setActive(item.id)" :href="item.id.toString()">
|
||||
{{ item.title }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="header"><span class="logo-header" @click="reset">Проекты Кустарщины</span></div>
|
||||
<div class="main product" v-if="state.active_product" ref="target">
|
||||
<div class="product-image" v-if="!state.show_model && state.active_product.image1">
|
||||
<img :style="{
|
||||
clipPath: `polygon(
|
||||
0% 10%, 10% 0%,
|
||||
90% 0%, 100% 10%,
|
||||
100% 90%, 90% 100%,
|
||||
10% 100%, 0% 90%
|
||||
)`}" :src="`${IMAGE_URL}${state.active_product.image1}`" />
|
||||
</div>
|
||||
<div class="product-description" v-if="!state.show_model">
|
||||
{{ state.active_product.description }}
|
||||
</div>
|
||||
<a class="product-model-icon" v-if="state.active_product.model3d" @click.stop.prevent="toggleShowCanvas">
|
||||
<i-mdi-video-3d v-if="!state.show_model" />
|
||||
<i-mdi-file v-else />
|
||||
</a>
|
||||
<model-fbx v-if="state.show_model && state.active_product.model3d" class="product-model"
|
||||
:src="`${IMAGE_URL}/${state.active_product.model3d.replace('/back', '')}`"
|
||||
:backgroundAlpha="0"></model-fbx>
|
||||
</div>
|
||||
<div class="main" v-else>
|
||||
<img class="logo-img" src="../assets/logo_color.png"
|
||||
@click="() => { state.show_fireworks = !state.show_fireworks }" />
|
||||
<Fireworks ref="fw" v-if="state.show_fireworks" :autostart="true" :options="options" :style="{
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
position: 'fixed',
|
||||
zIndex: -1,
|
||||
pointerEvents: 'none',
|
||||
}" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
Binary file not shown.
|
@ -1,10 +1,27 @@
|
|||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import { createWebHistory, createRouter } from 'vue-router'
|
||||
|
||||
import './assets/main.scss'
|
||||
|
||||
|
||||
import App from './App.vue'
|
||||
import Home from './components/Home.vue'
|
||||
import Projects from './components/Projects.vue'
|
||||
|
||||
const routes = [
|
||||
{ path: '/', component: Home },
|
||||
{ path: '/projects', component: Projects },
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
})
|
||||
|
||||
|
||||
const pinia = createPinia()
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(router)
|
||||
app.use(pinia)
|
||||
app.mount('#app')
|
Loading…
Reference in New Issue