Compare commits
58 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aa62240d27 | |||
| a699c9851f | |||
| d7c1f8c5b4 | |||
| c1c01c496a | |||
| a7f92d3ec5 | |||
| ae7be6d6f8 | |||
| bf204d5e36 | |||
| 459876f5b4 | |||
| 4a1a840c16 | |||
| c0552e890c | |||
| 80d6f2b85f | |||
| 17882e3e6e | |||
| 4a03535b07 | |||
| 0a76842e82 | |||
| 0bc2ac1d15 | |||
| 428dd822a2 | |||
| d932ebfa50 | |||
| cbe983f96c | |||
| 7362d4ffbd | |||
| 17266248e3 | |||
| 6cfea4c9b8 | |||
| cb561395ff | |||
| dda67ad993 | |||
| 073288c8a9 | |||
| e532c9f2da | |||
| 1e92c64ae6 | |||
| 407363221b | |||
| 4884b3af2c | |||
| 31745cf4dd | |||
| 956f77cab5 | |||
| 7c3eb12a31 | |||
| 5ba9e95547 | |||
| 79d5413638 | |||
| 105aeddde1 | |||
| 5c840a7525 | |||
| 1fa3d4c3a1 | |||
| 89ceb6ae7f | |||
| 445b799ff5 | |||
| 8678e9393c | |||
| b9a8bacc78 | |||
| 885cb49f2f | |||
| 6eb73ba743 | |||
| fa610f6ee1 | |||
| eff1256265 | |||
| 97e7dc26cc | |||
| 17c0af5696 | |||
| e4d8ec5e9f | |||
| 4d48e88641 | |||
| 27f9403c2d | |||
| 678c40dd9b | |||
| cc06d5cb0a | |||
| 419b01b53f | |||
| d5d008f43f | |||
| f92c47447e | |||
| 65701bee74 | |||
| 76912ceacb | |||
| 839ce80a62 | |||
| 8a87842e0b |
@@ -6,6 +6,7 @@ node_modules
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
.env
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
@@ -21,4 +22,7 @@ pnpm-debug.log*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
node_modules
|
||||
node_modules
|
||||
|
||||
# Dev files
|
||||
stockInfoDev.json
|
||||
@@ -1,22 +1,24 @@
|
||||
{
|
||||
"name": "pojazdownik",
|
||||
"version": "1.3.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc --noEmit && vite build",
|
||||
"preview": "yarn build && vite preview --port 4174"
|
||||
},
|
||||
"dependencies": {
|
||||
"pinia": "^2.0.17",
|
||||
"vue": "^3.2.37"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^3.2.0",
|
||||
"sass": "^1.55.0",
|
||||
"typescript": "^4.8.4",
|
||||
"vite": "^3.2.1",
|
||||
"vite-plugin-pwa": "^0.13.3",
|
||||
"vue-tsc": "^1.0.9"
|
||||
}
|
||||
}
|
||||
{
|
||||
"name": "pojazdownik",
|
||||
"version": "1.6.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc --noEmit && vite build",
|
||||
"preview": "yarn build && vite preview --port 4174"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.4.0",
|
||||
"pinia": "^2.0.17",
|
||||
"vue": "^3.2.37",
|
||||
"vue-i18n": "9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^4.1.0",
|
||||
"sass": "^1.59.3",
|
||||
"typescript": "^5.0.2",
|
||||
"vite": "^4.2.1",
|
||||
"vite-plugin-pwa": "^0.14.6",
|
||||
"vue-tsc": "^1.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" fill="white" width="48"><path d="M314.696-195.478q-32.507 0-55.862-23.356-23.356-23.355-23.356-55.862v-549.826q0-32.74 23.356-56.262 23.355-23.522 55.862-23.522h429.826q32.74 0 56.262 23.522t23.522 56.262v549.826q0 32.507-23.522 55.862-23.522 23.356-56.262 23.356H314.696Zm0-79.218h429.826v-549.826H314.696v549.826ZM175.478-55.694q-32.74 0-56.262-23.522t-23.522-56.262v-629.044h79.784v629.044h509.044v79.784H175.478Zm139.218-219.002v-549.826 549.826Z"/></svg>
|
||||
|
After Width: | Height: | Size: 536 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" fill="white" width="48"><path d="M480-318.087 266.651-531.436l57.131-56.001 116.609 116.609v-343.868h79.218v343.868l116.609-116.609 57.131 56.001L480-318.087ZM225.087-145.869q-32.507 0-55.862-23.356-23.356-23.355-23.356-55.862v-143h79.218v143h509.826v-143h79.783v143q0 32.478-23.521 55.848-23.522 23.37-56.262 23.37H225.087Z"/></svg>
|
||||
|
After Width: | Height: | Size: 410 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" fill="white" width="48"><path d="M451-107.304q-128.652-10.565-216.892-105.522-88.239-94.956-88.239-225.609 0-78.13 35.5-147.543 35.5-69.413 99.5-114.674l56.566 56.565q-52.609 32.435-82.478 87.957-29.87 55.521-29.87 117.695 0 98.305 64.587 169.609T451-187.087v79.783Zm60 0v-79.783q98.304-11.435 161.609-82.239 63.304-70.804 63.304-169.109 0-103.913-70.978-177.434-70.978-73.522-174.891-76.913h-21.696l62.261 62.826-47.522 47.522-152.783-152.784 152.783-153.349 47.522 47.522-68.479 68.479h22.261q138.522 0 234.914 98.022 96.391 98.022 96.391 236.109 0 130.653-88.022 225.609Q639.652-117.869 511-107.304Z"/></svg>
|
||||
|
After Width: | Height: | Size: 688 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" fill="white" width="48"><path d="M575.913-143.782v-72.436h115.956l-173.26-172.825 51.043-51.479 175.261 172.695v-117.391h73v241.436h-242Zm-382.783 2.826L142.652-193l551.217-551.782H575.913v-72.436h242v241.436h-73v-116.391L193.13-140.956Zm198.479-378.522L142.652-768l51.478-52.044 250.088 248.522-52.609 52.044Z"/></svg>
|
||||
|
After Width: | Height: | Size: 396 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" fill="white" width="48"><path d="M440.391-318.087v-343.868L323.782-544.782l-57.131-56.566L480-814.696l213.349 213.348-57.131 56.566-116.609-117.173v343.868h-79.218ZM225.087-145.869q-32.507 0-55.862-23.356-23.356-23.355-23.356-55.862v-143h79.218v143h509.826v-143h79.783v143q0 32.478-23.521 55.848-23.522 23.37-56.262 23.37H225.087Z"/></svg>
|
||||
|
After Width: | Height: | Size: 416 B |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 25 KiB |
@@ -1,94 +1,37 @@
|
||||
<template>
|
||||
<div class="image-preview" v-if="store.vehiclePreviewSrc != ''" @click="() => (store.vehiclePreviewSrc = '')">
|
||||
<img :src="store.vehiclePreviewSrc" alt="preview" />
|
||||
</div>
|
||||
|
||||
<div class="g-card-dimmer" v-if="store.isRandomizerCardOpen" @click="store.isRandomizerCardOpen = false"></div>
|
||||
<div class="g-card-dimmer" v-if="store.isRealStockListCardOpen" @click="store.isRealStockListCardOpen = false"></div>
|
||||
|
||||
<keep-alive>
|
||||
<transition name="card-appear">
|
||||
<RealStockCard />
|
||||
</transition>
|
||||
</keep-alive>
|
||||
|
||||
<div class="app_container">
|
||||
<main>
|
||||
<LogoSection />
|
||||
|
||||
<InputsSection />
|
||||
|
||||
<TrainImageSection />
|
||||
|
||||
<StockSection />
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<div class="text--grayed" style="margin-bottom: 0.25em">
|
||||
Ta strona ma charakter informacyjny. Autor nie ponosi odpowiedzialności za tworzenie pociągów niezgodnych z
|
||||
<a
|
||||
style="color: #ccc"
|
||||
href="https://docs.google.com/document/d/1UAAPUtN0d_RoS4RgOzEzllJZJhA0VcizzCzKW4QylbY/edit"
|
||||
target="_blank"
|
||||
>
|
||||
regulaminem symulatora Train Driver 2</a
|
||||
>!
|
||||
</div>
|
||||
<div class="text--grayed" style="margin-bottom: 0.25em">Strona jest kompletna dla wersji 2022.2.2 symulatora TD2</div>
|
||||
©
|
||||
<a href="https://td2.info.pl/profile/?u=20777" target="_blank">Spythere</a>
|
||||
{{ new Date().getUTCFullYear() }} | v{{ VERSION }}
|
||||
</footer>
|
||||
</div>
|
||||
<AppModals />
|
||||
<ImageFullscreenPreview v-if="store.vehiclePreviewSrc" />
|
||||
<AppContainerView />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import packageInfo from '.././package.json';
|
||||
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
import InputsSection from './components/sections/InputsSection.vue';
|
||||
|
||||
import { useStore } from './store';
|
||||
import TrainImageSection from './components/sections/TrainImageSection.vue';
|
||||
import LogoSection from './components/sections/LogoSection.vue';
|
||||
import RealStockCard from './components/cards/RealStockCard.vue';
|
||||
import StockSection from './components/sections/StockSection.vue';
|
||||
import ImageFullscreenPreview from './components/utils/ImageFullscreenPreview.vue';
|
||||
import AppContainerView from './views/AppContainerView.vue';
|
||||
import AppModals from './components/app/AppModals.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
StockSection,
|
||||
InputsSection,
|
||||
TrainImageSection,
|
||||
LogoSection,
|
||||
RealStockCard,
|
||||
data() {
|
||||
return {
|
||||
store: useStore(),
|
||||
};
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
VERSION: packageInfo.version,
|
||||
store: useStore(),
|
||||
}),
|
||||
|
||||
async created() {
|
||||
const stockData = await (
|
||||
await fetch(`https://spythere.github.io/api/td2/data/stockInfo.json?t=${Math.floor(Date.now() / 60000)}`)
|
||||
).json();
|
||||
|
||||
this.store.stockData = stockData;
|
||||
/* dev info testing */
|
||||
// if (import.meta.env['VITE_STOCK_DEV'] == '1') {
|
||||
// const data = await import('../stockInfoDev.json');
|
||||
// this.store.stockData = data.default as any;
|
||||
// }
|
||||
this.store.fetchStockInfoData();
|
||||
this.store.handleRouting();
|
||||
},
|
||||
components: { ImageFullscreenPreview, AppContainerView, AppModals },
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import './styles/global';
|
||||
|
||||
.app_container {
|
||||
min-height: 100vh;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
@import './styles/global.scss';
|
||||
|
||||
/* APP */
|
||||
#app {
|
||||
@@ -117,65 +60,10 @@ h2 {
|
||||
color: #d1d1d1;
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background: rgba(black, 0.85);
|
||||
|
||||
img {
|
||||
width: 90%;
|
||||
max-width: 800px;
|
||||
}
|
||||
}
|
||||
|
||||
/* MAIN SECTION */
|
||||
|
||||
main {
|
||||
display: grid;
|
||||
gap: 1em 3em;
|
||||
|
||||
width: 100%;
|
||||
max-width: 1300px;
|
||||
min-height: 75vh;
|
||||
|
||||
grid-template-columns: 1fr 2fr;
|
||||
grid-template-rows: auto 360px minmax(400px, 1fr);
|
||||
|
||||
// padding: 0 1em;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
/* FOOTER SECTION */
|
||||
|
||||
footer {
|
||||
margin-top: auto;
|
||||
text-align: center;
|
||||
padding: 0 1em;
|
||||
}
|
||||
|
||||
/* MOBILE VIEWS */
|
||||
|
||||
@media screen and (max-width: $breakpointMd) {
|
||||
#app {
|
||||
font-size: calc(0.7rem + 0.75vw);
|
||||
}
|
||||
|
||||
main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<div>
|
||||
<keep-alive>
|
||||
<RealStockCard v-if="store.isRealStockListCardOpen" />
|
||||
</keep-alive>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { useStore } from '../../store';
|
||||
import RealStockCard from '../cards/RealStockCard.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: { RealStockCard },
|
||||
data() {
|
||||
return {
|
||||
store: useStore(),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<footer>
|
||||
<i18n-t keypath="footer.disclaimer" tag="div" class="text--grayed">
|
||||
<template #tos>
|
||||
<a style="color: #ccc" :href="$t('footer.tos-href')" target="_blank">
|
||||
{{ $t('footer.tos') }}
|
||||
</a>
|
||||
</template>
|
||||
</i18n-t>
|
||||
|
||||
<div class="text--grayed" v-if="store.stockData">
|
||||
{{ $t('footer.version-check', { version: store.stockData.version }) }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
©
|
||||
<a href="https://td2.info.pl/profile/?u=20777" target="_blank">Spythere</a>
|
||||
{{ new Date().getUTCFullYear() }} | v{{ VERSION }}{{ !isOnProductionHost ? 'dev' : '' }}
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import packageInfo from '../../../package.json';
|
||||
import { useStore } from '../../store';
|
||||
|
||||
export default defineComponent({
|
||||
data() {
|
||||
return {
|
||||
isOnProductionHost: location.hostname == 'pojazdownik-td2.web.app',
|
||||
VERSION: packageInfo.version,
|
||||
store: useStore(),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
footer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25em;
|
||||
|
||||
text-align: center;
|
||||
padding: 1em 1em 0 1em;
|
||||
margin-top: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<main>
|
||||
<LogoSection />
|
||||
<InputsSection />
|
||||
<TrainImageSection />
|
||||
<StockSection />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import LogoSection from '../sections/LogoSection.vue';
|
||||
import InputsSection from '../sections/InputsSection.vue';
|
||||
import TrainImageSection from '../sections/TrainImageSection.vue';
|
||||
import StockSection from '../sections/StockSection.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: { LogoSection, InputsSection, TrainImageSection, StockSection },
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '../../styles/global.scss';
|
||||
|
||||
main {
|
||||
display: grid;
|
||||
gap: 1em;
|
||||
|
||||
width: 100%;
|
||||
max-width: 1500px;
|
||||
min-height: 75vh;
|
||||
|
||||
grid-template-columns: 1fr 2fr;
|
||||
grid-template-rows: auto 360px minmax(400px, 1fr);
|
||||
}
|
||||
|
||||
@media screen and (max-width: $breakpointMd) {
|
||||
main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,39 +1,74 @@
|
||||
<template>
|
||||
<div class="real-stock-card g-card" v-if="store.isRealStockListCardOpen">
|
||||
<div class="real-stock-card g-card" @keydown.esc="store.isRealStockListCardOpen = false">
|
||||
<div class="g-card_bg" @click="store.isRealStockListCardOpen = false"></div>
|
||||
|
||||
<div class="card_content">
|
||||
<div class="top-sticky">
|
||||
<button class="btn btn--text exit-btn" @click="store.isRealStockListCardOpen = false">< POWRÓT</button>
|
||||
|
||||
<div class="header">
|
||||
<div class="card_nav">
|
||||
<div class="top-pane">
|
||||
<h1>
|
||||
REALNE ZESTAWIENIA
|
||||
<div>by <a href="https://td2.info.pl/profile/?u=17708" target="_blank">Railtrains997</a></div>
|
||||
{{ $t('realstock.title') }} <a href="https://td2.info.pl/profile/?u=17708" target="_blank">Railtrains997</a>
|
||||
</h1>
|
||||
<p>
|
||||
Pełne informacje o zestawieniach dostępne na stronie
|
||||
<a href="http://bocznica.eu/files/archiwum/2021r_2021-11-04.html" target="_blank">bocznica.eu</a> (stan na
|
||||
listopad 2021r.)
|
||||
</p>
|
||||
<button class="btn exit-btn" @click="store.isRealStockListCardOpen = false">⨯</button>
|
||||
</div>
|
||||
|
||||
<input type="text" tabindex="0" v-model="searchedReadyStockName" placeholder="Szukaj zestawienia..." />
|
||||
<div class="filters" ref="focus" tabindex="0">
|
||||
<input
|
||||
list="readyStockDataList"
|
||||
v-model="searchedReadyStockName"
|
||||
:placeholder="$t('realstock.search-name')"
|
||||
/>
|
||||
|
||||
<datalist id="readyStockDataList">
|
||||
<option v-for="stock in store.readyStockList" :value="stock.stockId">
|
||||
{{ stock.stockId }}
|
||||
</option>
|
||||
</datalist>
|
||||
|
||||
<input
|
||||
list="readyStockStringList"
|
||||
v-model="searchedReadyStockString"
|
||||
:placeholder="$t('realstock.search-stock')"
|
||||
/>
|
||||
|
||||
<datalist id="readyStockStringList">
|
||||
<option v-for="stock in computedAvailableStockTypes" :value="stock">
|
||||
{{ stock }}
|
||||
</option>
|
||||
</datalist>
|
||||
|
||||
<button class="btn" @click="resetStockFilters">{{ $t('realstock.action-reset') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul v-if="responseStatus == 'loaded'">
|
||||
<ul class="card_list" ref="list" @scroll="onListScroll">
|
||||
<li
|
||||
v-for="(stock, key) in computedReadyStockList"
|
||||
:key="key"
|
||||
tabindex="0"
|
||||
@click="choseStock(stock.name, stock.type, stock.number, stock.stockString)"
|
||||
@keydown.enter="choseStock(stock.name, stock.type, stock.number, stock.stockString)"
|
||||
v-for="rStock in computedReadyStockList"
|
||||
:key="rStock.stockId"
|
||||
:data-last-selected="store.chosenRealStockName === rStock.stockId"
|
||||
>
|
||||
<img :src="getIconURL(stock.type)" :alt="stock.type" />
|
||||
<div class="stock-title" tabindex="0" @click="chooseStock(rStock)" @keydown.enter="chooseStock(rStock)">
|
||||
<img class="stock-icon" :src="getIconURL(rStock.type)" :alt="rStock.type" />
|
||||
<b class="text--accent" style="margin-left: 5px"> {{ rStock.name }}</b>
|
||||
<div>{{ rStock.number }}</div>
|
||||
</div>
|
||||
|
||||
<b class="text--accent"> {{ stock.name }}</b>
|
||||
<div>{{ stock.number }}</div>
|
||||
<div class="stock-thumbnails" ref="thumbnailsRef">
|
||||
<div class="thumbnail-item" v-for="stockType in rStock.stockString.split(';')">
|
||||
<div class="thumbnail-container">
|
||||
<div>{{ stockType }}</div>
|
||||
<img
|
||||
:src="`https://rj.td2.info.pl/dist/img/thumbnails/${stockType}.png`"
|
||||
:title="stockType"
|
||||
style="opacity: 0"
|
||||
@error="(e) => onStockItemError(e, stockType)"
|
||||
@load="e => (e.target as HTMLElement).style.opacity = '1'"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<div class="bottom" ref="bottom"></div>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -41,85 +76,155 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { Vehicle, IReadyStockList } from '../../types';
|
||||
|
||||
import { useStore } from '../../store';
|
||||
import imageMixin from '../../mixins/imageMixin';
|
||||
import stockMixin from '../../mixins/stockMixin';
|
||||
|
||||
import { IReadyStockItem } from '../../types';
|
||||
|
||||
interface ResponseJSONData {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
function getVehicleType(stockType: string) {
|
||||
if (/^E/.test(stockType)) return 'loco-e';
|
||||
if (/^S/.test(stockType)) return 'loco-s';
|
||||
|
||||
return 'car-passenger';
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
mixins: [imageMixin, stockMixin],
|
||||
|
||||
setup() {
|
||||
return {
|
||||
store: useStore(),
|
||||
};
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
store: useStore(),
|
||||
responseStatus: 'loading',
|
||||
isMobile: 'ontouchstart' in document.documentElement && navigator.userAgent.match(/Mobi/) ? true : false,
|
||||
|
||||
observer: null as IntersectionObserver | null,
|
||||
searchedReadyStockName: '',
|
||||
searchedReadyStockString: '',
|
||||
visibleIndexesTo: 0,
|
||||
lastSelectedStockId: null as string | null,
|
||||
scrollTop: 0,
|
||||
}),
|
||||
|
||||
async mounted() {
|
||||
this.mountObserver();
|
||||
this.fetchStockListData();
|
||||
},
|
||||
|
||||
activated() {
|
||||
(this.$refs['focus'] as HTMLElement).focus();
|
||||
|
||||
(this.$refs['list'] as HTMLElement).scrollTo({
|
||||
top: this.scrollTop,
|
||||
behavior: 'auto',
|
||||
});
|
||||
},
|
||||
|
||||
computed: {
|
||||
computedReadyStockList() {
|
||||
if (this.searchedReadyStockName == null) return this.store.readyStockList;
|
||||
|
||||
let filtered: IReadyStockList = {};
|
||||
return this.store.readyStockList
|
||||
.filter(
|
||||
(rs) =>
|
||||
rs.stockId.toLocaleLowerCase().includes(this.searchedReadyStockName.toLocaleLowerCase()) &&
|
||||
rs.stockString.toLocaleLowerCase().includes(this.searchedReadyStockString.toLocaleLowerCase())
|
||||
)
|
||||
.filter((_, i) => i <= this.visibleIndexesTo);
|
||||
},
|
||||
|
||||
for (let key in this.store.readyStockList) {
|
||||
if (key.toLocaleLowerCase().includes(this.searchedReadyStockName.toLocaleLowerCase()))
|
||||
filtered[key] = this.store.readyStockList[key];
|
||||
computedAvailableStockTypes() {
|
||||
return this.store.readyStockList
|
||||
.reduce((acc, rs) => {
|
||||
rs.stockString.split(';').forEach((s) => {
|
||||
if (!acc.includes(s)) acc.push(s);
|
||||
});
|
||||
|
||||
return acc;
|
||||
}, [] as string[])
|
||||
.sort((a, b) => (a > b ? 1 : -1));
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
computedReadyStockList(curr, prev) {
|
||||
if (curr.length < prev.length) {
|
||||
this.visibleIndexesTo = 20;
|
||||
(this.$refs['list'] as HTMLElement).scrollTo({
|
||||
top: 0,
|
||||
});
|
||||
}
|
||||
|
||||
return filtered;
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
async fetchStockListData() {
|
||||
const readyStockJSONData: ResponseJSONData = await (
|
||||
await fetch(`https://spythere.github.io/api/td2/data/readyStock.json?t=${Math.floor(Date.now() / 60000)}`)
|
||||
).json();
|
||||
|
||||
if (!readyStockJSONData) {
|
||||
this.responseStatus = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
for (let stockKey in readyStockJSONData) {
|
||||
const [type, number, ...name] = stockKey.split(' ');
|
||||
|
||||
const obj = {
|
||||
number: number.replace(/_/g, '/'),
|
||||
name: name.join(' '),
|
||||
stockString: readyStockJSONData[stockKey],
|
||||
type,
|
||||
};
|
||||
|
||||
this.store.readyStockList.push({
|
||||
...obj,
|
||||
stockId: `${obj.type} ${obj.number} ${obj.name}`,
|
||||
});
|
||||
}
|
||||
|
||||
this.responseStatus = 'loaded';
|
||||
},
|
||||
|
||||
mountObserver() {
|
||||
this.observer = new IntersectionObserver((entries) => {
|
||||
if (entries[0].intersectionRatio > 0) this.visibleIndexesTo += 20;
|
||||
});
|
||||
|
||||
this.observer.observe(this.$refs['bottom'] as HTMLElement);
|
||||
},
|
||||
|
||||
getImageUrl(name: string) {
|
||||
return new URL(`./dir/${name}.png`, import.meta.url).href;
|
||||
},
|
||||
|
||||
choseStock(name: string, type: string, number: string, stockString: string) {
|
||||
this.loadStockFromString(stockString);
|
||||
resetStockFilters() {
|
||||
this.searchedReadyStockName = '';
|
||||
this.searchedReadyStockString = '';
|
||||
},
|
||||
|
||||
chooseStock(stockItem: IReadyStockItem) {
|
||||
this.loadStockFromString(stockItem.stockString);
|
||||
this.lastSelectedStockId = stockItem.stockId;
|
||||
this.store.isRealStockListCardOpen = false;
|
||||
},
|
||||
},
|
||||
|
||||
async mounted() {
|
||||
const readyStockJSONData: ResponseJSONData = await (
|
||||
await fetch(`https://spythere.github.io/api/td2/data/readyStock.json?t=${Math.floor(Date.now() / 60000)}`)
|
||||
).json();
|
||||
onStockItemError(e: Event, stockType: string) {
|
||||
const imageEl = e.target as HTMLImageElement;
|
||||
imageEl.src = `images/${getVehicleType(stockType)}-unknown.png`;
|
||||
imageEl.style.opacity = '1';
|
||||
},
|
||||
|
||||
if (!readyStockJSONData) {
|
||||
this.responseStatus = 'error';
|
||||
return;
|
||||
}
|
||||
onListScroll(e: Event) {
|
||||
const listElement = e.target as HTMLElement;
|
||||
const scrollTop = listElement.scrollTop;
|
||||
|
||||
for (let stockKey in readyStockJSONData) {
|
||||
const splittedKey = stockKey.split(' ');
|
||||
|
||||
let name = '';
|
||||
for (let i = 2; i < splittedKey.length; i++) {
|
||||
name += ' ' + splittedKey[i];
|
||||
}
|
||||
|
||||
this.store.readyStockList[stockKey] = {
|
||||
type: splittedKey[0],
|
||||
number: splittedKey[1].replace(/_/g, '/'),
|
||||
name,
|
||||
stockString: readyStockJSONData[stockKey],
|
||||
};
|
||||
}
|
||||
|
||||
this.responseStatus = 'loaded';
|
||||
this.scrollTop = scrollTop;
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -129,106 +234,148 @@ export default defineComponent({
|
||||
|
||||
.exit-btn {
|
||||
font-size: 1.2em;
|
||||
margin: 0.5em 0;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
max-width: 250px;
|
||||
|
||||
&::placeholder {
|
||||
font-size: 0.9em;
|
||||
text-align: center;
|
||||
}
|
||||
.btn {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
.card_content {
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
gap: 0.5em;
|
||||
|
||||
background-color: #1c1c1c;
|
||||
border-radius: 1em;
|
||||
|
||||
height: 85vh;
|
||||
height: 95vh;
|
||||
max-width: 1000px;
|
||||
width: 90vw;
|
||||
|
||||
padding: 0 1em;
|
||||
|
||||
overflow-y: auto;
|
||||
z-index: 100;
|
||||
|
||||
.top-sticky {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background: #1c1c1c;
|
||||
@media screen and (max-width: $breakpointSm) {
|
||||
height: 80vh;
|
||||
}
|
||||
}
|
||||
|
||||
.top-pane {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 0.5em;
|
||||
|
||||
h1 {
|
||||
color: #aaa;
|
||||
}
|
||||
}
|
||||
|
||||
.top-sticky {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background: #1c1c1c;
|
||||
}
|
||||
|
||||
.filters {
|
||||
display: flex;
|
||||
gap: 0.5em;
|
||||
|
||||
padding: 0.5em 0;
|
||||
|
||||
input {
|
||||
width: 35%;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding-bottom: 1.5em;
|
||||
padding-top: 0.5em;
|
||||
@media screen and (max-width: $breakpointSm) {
|
||||
flex-wrap: wrap;
|
||||
|
||||
text-align: center;
|
||||
font-size: 1.3em;
|
||||
|
||||
h1 {
|
||||
line-height: 0.9em;
|
||||
margin: 0.5em 0;
|
||||
|
||||
div {
|
||||
font-size: 0.65em;
|
||||
color: #ccc;
|
||||
}
|
||||
input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 1em 0;
|
||||
color: #999;
|
||||
font-size: 0.95em;
|
||||
.btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
ul {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5em;
|
||||
|
||||
overflow: auto;
|
||||
|
||||
li {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 1em;
|
||||
|
||||
@media screen and (max-width: 700px) {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 550px) {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 400px) {
|
||||
grid-template-columns: repeat(1, 1fr);
|
||||
}
|
||||
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
ul li {
|
||||
padding: 0.5em;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
grid-template-columns: 1fr 2fr;
|
||||
background: #2b2b2b;
|
||||
gap: 1rem;
|
||||
padding: 0.1em;
|
||||
|
||||
img {
|
||||
height: 0.85em;
|
||||
&[data-last-selected='true'] .stock-title {
|
||||
border: 1px solid $accentColor;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #999;
|
||||
font-weight: bold;
|
||||
.stock-title {
|
||||
cursor: pointer;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.stock-icon {
|
||||
height: 0.85em;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #222;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 1px solid white;
|
||||
@media screen and (max-width: $breakpointSm) {
|
||||
grid-template-columns: 1fr;
|
||||
// grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.stock-thumbnails {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
|
||||
width: 100%;
|
||||
|
||||
overflow: auto;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.thumbnail-item {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
|
||||
div {
|
||||
font-size: 0.9em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 250px;
|
||||
max-height: 50px;
|
||||
}
|
||||
|
||||
& > .thumbnail-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
padding: 1em;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<section class="inputs-section">
|
||||
<div class="input_container">
|
||||
<h2 class="input_header">WYBIERZ POJAZDY / WAGONY</h2>
|
||||
<h2 class="input_header">{{ $t('inputs.title') }}</h2>
|
||||
|
||||
<div class="input_list type">
|
||||
<div class="vehicle-types locos">
|
||||
@@ -11,7 +11,7 @@
|
||||
:data-selected="locoType.id == store.chosenLocoPower"
|
||||
@click="selectLocoType(locoType.id)"
|
||||
>
|
||||
{{ locoType.value }}
|
||||
{{ $t(`inputs.${locoType.id}`) }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
@keydown.enter.prevent="addOrSwitchVehicle"
|
||||
@keydown.backspace="removeVehicle"
|
||||
>
|
||||
<option :value="null" disabled>Wybierz pojazd trakcyjny</option>
|
||||
<option :value="null" disabled>{{ $t('inputs.input-vehicle') }}</option>
|
||||
<option v-for="loco in locoOptions" :value="loco" :key="loco.type">
|
||||
{{ loco.type }}
|
||||
{{ loco.type }}<b v-if="loco.supportersOnly">*</b>
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
@@ -38,7 +38,7 @@
|
||||
:data-selected="carType.id == store.chosenCarUseType"
|
||||
@click="selectCarWagonType(carType.id)"
|
||||
>
|
||||
{{ carType.value }}
|
||||
{{ $t(`inputs.${carType.id}`) }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -50,16 +50,16 @@
|
||||
@keydown.enter.prevent="addOrSwitchVehicle"
|
||||
@keydown.backspace="removeVehicle"
|
||||
>
|
||||
<option :value="null" disabled>Wybierz wagon</option>
|
||||
<option :value="null" disabled>{{ $t('inputs.input-carwagon') }}</option>
|
||||
|
||||
<option v-for="car in carOptions" :value="car" :key="car.type">
|
||||
{{ car.type }}
|
||||
{{ car.type }}<b v-if="car.supportersOnly">*</b>
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="input_list cargo">
|
||||
<label for="cargo-select">Ładunek (tylko wybrane towarowe)</label>
|
||||
<label for="cargo-select">{{ $t('inputs.cargo-title') }}</label>
|
||||
<select
|
||||
id="cargo-select"
|
||||
:disabled="
|
||||
@@ -75,8 +75,10 @@
|
||||
@keydown.enter.prevent="addOrSwitchVehicle"
|
||||
@keydown.backspace="removeVehicle"
|
||||
>
|
||||
<option :value="null" v-if="!store.chosenCar || !store.chosenCar.loadable">brak dostępnych ładunków</option>
|
||||
<option :value="null" v-else>próżny</option>
|
||||
<option :value="null" v-if="!store.chosenCar || !store.chosenCar.loadable">
|
||||
{{ $t('inputs.no-cargo-available') }}
|
||||
</option>
|
||||
<option :value="null" v-else>{{ $t('inputs.cargo-empty') }}</option>
|
||||
|
||||
<option v-for="cargo in store.chosenCar?.cargoList" :value="cargo" :key="cargo.id">
|
||||
{{ cargo.id }}
|
||||
@@ -85,20 +87,24 @@
|
||||
</div>
|
||||
|
||||
<div class="input_actions">
|
||||
<button class="btn" @click="addVehicle(store.chosenVehicle, store.chosenCargo)">DODAJ NOWY</button>
|
||||
<button class="btn" @click="addVehicle(store.chosenVehicle, store.chosenCargo)">
|
||||
{{ $t('inputs.action-add') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn"
|
||||
@click="switchVehicles"
|
||||
:disabled="store.chosenStockListIndex == -1"
|
||||
:data-disabled="store.chosenStockListIndex == -1"
|
||||
>
|
||||
ZAMIEŃ ZA
|
||||
{{ $t('inputs.action-swap') }}
|
||||
<b class="text--accent">
|
||||
{{ store.chosenStockListIndex == -1 ? '' : `${store.chosenStockListIndex + 1}.` }}
|
||||
</b>
|
||||
</button>
|
||||
|
||||
<button class="btn" @click="store.isRealStockListCardOpen = true"><b>REALNE ZESTAWIENIA</b></button>
|
||||
<button class="btn" @click="store.isRealStockListCardOpen = true">
|
||||
<b>{{ $t('inputs.real-stock') }}</b>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -107,19 +113,11 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
import { IStock } from '../../types';
|
||||
import imageMixin from '../../mixins/imageMixin';
|
||||
import { useStore } from '../../store';
|
||||
import { isLocomotive } from '../../utils/vehicleUtils';
|
||||
import stockPreviewMixin from '../../mixins/stockPreviewMixin';
|
||||
import stockMixin from '../../mixins/stockMixin';
|
||||
|
||||
interface ILocoType {
|
||||
id: string;
|
||||
value: string;
|
||||
desc: string;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
mixins: [imageMixin, stockPreviewMixin, stockMixin],
|
||||
|
||||
@@ -127,35 +125,29 @@ export default defineComponent({
|
||||
locomotiveTypeList: [
|
||||
{
|
||||
id: 'loco-e',
|
||||
value: 'ELEKTR',
|
||||
desc: 'ELEKTRYCZNE',
|
||||
},
|
||||
{
|
||||
id: 'loco-s',
|
||||
value: 'SPAL',
|
||||
desc: 'SPALINOWE',
|
||||
},
|
||||
{
|
||||
id: 'loco-ezt',
|
||||
value: 'EZT',
|
||||
desc: 'ELEKTR. ZESPOŁY TRAKCYJNE',
|
||||
},
|
||||
{
|
||||
id: 'loco-szt',
|
||||
value: 'SZT',
|
||||
desc: 'SPAL. ZESPOŁY TRAKCYJNE',
|
||||
},
|
||||
] as ILocoType[],
|
||||
],
|
||||
|
||||
carTypeList: [
|
||||
{
|
||||
id: 'car-passenger',
|
||||
value: 'PAS',
|
||||
desc: 'PASAŻERSKIE',
|
||||
},
|
||||
{
|
||||
id: 'car-cargo',
|
||||
value: 'TOW',
|
||||
desc: 'TOWAROWE',
|
||||
},
|
||||
],
|
||||
@@ -197,22 +189,8 @@ export default defineComponent({
|
||||
|
||||
if (!vehicle) return;
|
||||
|
||||
const stockObj: IStock = {
|
||||
id: `${Date.now()}`,
|
||||
useType: isLocomotive(vehicle) ? vehicle.power : vehicle.useType,
|
||||
type: vehicle.type,
|
||||
length: vehicle.length,
|
||||
mass: vehicle.mass,
|
||||
maxSpeed: vehicle.maxSpeed,
|
||||
isLoco: isLocomotive(vehicle),
|
||||
cargo:
|
||||
!isLocomotive(vehicle) && vehicle.loadable && this.store.chosenCargo ? this.store.chosenCargo : undefined,
|
||||
count: 1,
|
||||
imgSrc: vehicle.imageSrc,
|
||||
supportersOnly: vehicle.supportersOnly,
|
||||
};
|
||||
|
||||
this.store.stockList[this.store.chosenStockListIndex] = stockObj;
|
||||
const stockObject = this.getStockObject(vehicle, this.store.chosenCargo);
|
||||
this.store.stockList[this.store.chosenStockListIndex] = stockObject;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,31 +1,79 @@
|
||||
<template>
|
||||
<section class="logo-section">
|
||||
<img src="/images/logo.svg" alt="logo pojazdownik" />
|
||||
<img :src="`/logo-${$i18n.locale}.svg`" alt="logo pojazdownik" @click="navigate" />
|
||||
|
||||
<div class="actions">
|
||||
<button
|
||||
class="btn btn--text"
|
||||
v-for="action in localeActions"
|
||||
:data-selected="$i18n.locale == action.locale"
|
||||
@click="chooseLocale(action.locale)"
|
||||
>
|
||||
{{ action.name }}
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
setup() {
|
||||
return {};
|
||||
data() {
|
||||
return {
|
||||
localeActions: [
|
||||
{
|
||||
name: 'POLSKI',
|
||||
locale: 'pl',
|
||||
},
|
||||
{
|
||||
name: 'ENGLISH',
|
||||
locale: 'en',
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
navigate() {
|
||||
window.location.pathname = '';
|
||||
},
|
||||
|
||||
chooseLocale(locale: string) {
|
||||
this.$i18n.locale = locale;
|
||||
window.localStorage.setItem('locale', locale);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '../../styles/global.scss';
|
||||
|
||||
.logo-section {
|
||||
grid-row: 1;
|
||||
grid-column: 1;
|
||||
margin-bottom: 1.5em;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
gap: 0.5em;
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 0.5em;
|
||||
|
||||
button[data-selected='true'] {
|
||||
font-weight: bold;
|
||||
color: $accentColor;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 25em;
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
<div class="section_modes">
|
||||
<button
|
||||
class="btn"
|
||||
v-for="(id, name) in sectionModes"
|
||||
ref="sectionButtonRefs"
|
||||
v-for="(id, i) in sectionModes"
|
||||
@click="chooseSection(id)"
|
||||
:data-selected="store.stockSectionMode == id"
|
||||
>
|
||||
{{ name }}
|
||||
<span class="text--accent">{{ i + 1 }}.</span> {{ $t(`topbar.${id}`) }}
|
||||
<span v-if="id == 'stock-list'">({{ store.stockList.length }})</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -20,26 +22,40 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, KeepAlive } from 'vue';
|
||||
import { computed, KeepAlive, onMounted, ref } from 'vue';
|
||||
import { useStore } from '../../store';
|
||||
import StockListTab from '../tabs/StockListTab.vue';
|
||||
import StockGeneratorTab from '../tabs/StockGeneratorTab.vue';
|
||||
import NumberGeneratorTab from '../tabs/NumberGeneratorTab.vue';
|
||||
import WikiListTab from '../tabs/WikiListTab.vue';
|
||||
|
||||
const sectionButtonRefs = ref([]);
|
||||
|
||||
const store = useStore();
|
||||
type SectionMode = typeof store.stockSectionMode;
|
||||
|
||||
const sectionModes: { [key: string]: SectionMode } = {
|
||||
SKŁAD: 'stock-list',
|
||||
'GNR. NUMERU': 'number-generator',
|
||||
'GNR. SKŁADU': 'stock-generator',
|
||||
};
|
||||
const sectionModes: SectionMode[] = ['stock-list', 'wiki-list', 'number-generator', 'stock-generator'];
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('keydown', (e) => {
|
||||
if (e.target instanceof HTMLInputElement) return;
|
||||
|
||||
if (/[1234]/.test(e.key)) {
|
||||
const keyNum = Number(e.key);
|
||||
store.stockSectionMode = sectionModes[keyNum - 1];
|
||||
(sectionButtonRefs.value[keyNum - 1] as HTMLButtonElement).focus();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const chosenSectionComponent = computed(() => {
|
||||
switch (store.stockSectionMode) {
|
||||
case 'stock-list':
|
||||
return StockListTab;
|
||||
|
||||
case 'wiki-list':
|
||||
return WikiListTab;
|
||||
|
||||
case 'stock-generator':
|
||||
return StockGeneratorTab;
|
||||
|
||||
@@ -83,10 +99,11 @@ function chooseSection(sectionId: SectionMode) {
|
||||
|
||||
.section_modes {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
|
||||
gap: 0.5em;
|
||||
|
||||
margin-bottom: 0.5em;
|
||||
margin-bottom: 1em;
|
||||
|
||||
button {
|
||||
position: relative;
|
||||
@@ -110,5 +127,11 @@ function chooseSection(sectionId: SectionMode) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 650px) {
|
||||
.section_modes {
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<section class="train-image-section">
|
||||
<div class="train-image__wrapper">
|
||||
<div class="train-image__content">
|
||||
<div class="train-image__content" :class="{ supporter: store.chosenVehicle?.supportersOnly }">
|
||||
<transition name="img-message-anim">
|
||||
<div class="empty-message" v-if="store.imageLoading && store.chosenVehicle?.imageSrc">
|
||||
ŁADOWANIE OBRAZU...
|
||||
{{ $t('preview.loading') }}
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<div class="no-img" v-if="!store.chosenVehicle">PODGLĄD WYBRANEGO POJAZDU</div>
|
||||
<div class="no-img" v-if="!store.chosenVehicle">{{ $t('preview.title') }}</div>
|
||||
|
||||
<img
|
||||
v-if="store.chosenVehicle"
|
||||
@@ -23,11 +23,11 @@
|
||||
|
||||
<div class="train-image__info" v-if="store.chosenVehicle">
|
||||
<b class="text--accent">{{ store.chosenVehicle.type }}</b> •
|
||||
<b style="color: #ccc">{{
|
||||
vehicleTypes[
|
||||
isLocomotive(store.chosenVehicle) ? store.chosenVehicle.power : store.chosenVehicle.useType || 'loco-e'
|
||||
]
|
||||
}}</b>
|
||||
<b style="color: #ccc">
|
||||
{{
|
||||
$t(`preview.${isLocomotive(store.chosenVehicle) ? store.chosenVehicle.power : store.chosenVehicle.useType}`)
|
||||
}}
|
||||
</b>
|
||||
|
||||
<div style="color: #ccc">
|
||||
<div>
|
||||
@@ -35,19 +35,23 @@
|
||||
{{ store.chosenVehicle.maxSpeed }} km/h
|
||||
</div>
|
||||
|
||||
<div v-if="isLocomotive(store.chosenVehicle)">Typ kabiny: {{ store.chosenVehicle.cabinType }}</div>
|
||||
<div v-if="isLocomotive(store.chosenVehicle)">
|
||||
{{ $t('preview.cabin') }} {{ store.chosenVehicle.cabinType }}
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
{{
|
||||
store.chosenVehicle.useType == 'car-cargo'
|
||||
? store.stockData?.usage[store.chosenVehicle.constructionType]
|
||||
: 'Typ konstrukcji: ' + store.chosenVehicle.constructionType
|
||||
store.chosenVehicle.useType == 'car-cargo' // ? store.stockData?.usage[store.chosenVehicle.constructionType]
|
||||
? $t(`usage.${store.chosenVehicle.constructionType}`)
|
||||
: `${$t('preview.construction')} ${store.chosenVehicle.constructionType}`
|
||||
}}
|
||||
</div>
|
||||
|
||||
<b style="color: salmon" v-if="store.chosenVehicle.supportersOnly">{{ $t('preview.sponsor-only') }}</b>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="train-image__info" v-else>Wybierz pojazd lub wagon, aby zobaczyć jego podgląd powyżej</div>
|
||||
<div class="train-image__info" v-else>{{ $t('preview.desc') }}</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -68,19 +72,6 @@ export default defineComponent({
|
||||
};
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
vehicleTypes: {
|
||||
'loco-e': 'ELEKTROWÓZ',
|
||||
'loco-s': 'SPALINOWÓZ',
|
||||
'loco-ezt': 'EZT',
|
||||
'loco-szt': 'SZT',
|
||||
'car-passenger': 'WAGON PASAŻERSKI',
|
||||
'car-cargo': 'WAGON TOWAROWY',
|
||||
} as { [key: string]: string },
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
chosenVehicle(vehicle: Vehicle, prevVehicle: Vehicle) {
|
||||
if (vehicle && vehicle.type != prevVehicle?.type) {
|
||||
@@ -142,7 +133,7 @@ export default defineComponent({
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
cursor: pointer;
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
.empty-message,
|
||||
|
||||
@@ -1,36 +1,64 @@
|
||||
<template>
|
||||
<div class="number-generator tab">
|
||||
<div class="tab_header">
|
||||
<h2>GENERATOR NUMERU POCIĄGU</h2>
|
||||
<h2>{{ $t('numgen.title') }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="tab_content">
|
||||
<div class="options">
|
||||
<select v-model="beginRegionName" @change="randomizeTrainNumber">
|
||||
<option :value="null" disabled>Początkowy obszar konstrukcyjny</option>
|
||||
<select v-model="chosenCategory" @change="randomizeTrainNumber()">
|
||||
<option :value="null" disabled>{{ $t('numgen.train-category') }}</option>
|
||||
<option v-for="(_, category) in genData.categories" :value="category">
|
||||
{{ $t(`numgen.categories.${category}`) }}
|
||||
</option>
|
||||
</select>
|
||||
|
||||
<select v-model="beginRegionName" @change="randomizeTrainNumber()">
|
||||
<option :value="null" disabled>{{ $t('numgen.start-region') }}</option>
|
||||
<option v-for="(_, name) in genData.regionNumbers" :value="name">{{ name }}</option>
|
||||
</select>
|
||||
|
||||
<select v-model="endRegionName" @change="randomizeTrainNumber">
|
||||
<option :value="null" disabled>Końcowy obszar konstrukcyjny</option>
|
||||
<select v-model="endRegionName" @change="randomizeTrainNumber()">
|
||||
<option :value="null" disabled>{{ $t('numgen.end-region') }}</option>
|
||||
<option v-for="(_, name) in genData.regionNumbers" :value="name">{{ name }}</option>
|
||||
</select>
|
||||
|
||||
<select v-model="categoryRules" @change="randomizeTrainNumber">
|
||||
<option :value="null" disabled>Kategoria pociągu</option>
|
||||
<option v-for="(rules, category) in genData.categories" :value="rules">{{ category }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="generated-number">
|
||||
<span v-if="trainNumber">Wygenerowany numer pociągu: <b class="text--accent">{{ trainNumber }}</b></span>
|
||||
<span v-else>Wybierz obszary konstrukcyjne i kategorię!</span>
|
||||
<div class="generated-number" @click="copyNumber">
|
||||
<span v-if="trainNumber">
|
||||
{{ $t('numgen.number-info') }} <b class="text--accent">{{ trainNumber }}</b>
|
||||
</span>
|
||||
<span v-else>{{ $t('numgen.warning') }}</span>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- <div v-if="chosenCategory">
|
||||
Current numbering rules: {{ $t(`numgen.rules.${chosenCategory}`) }};
|
||||
|
||||
<span v-if="beginRegionName && endRegionName">
|
||||
<span v-if="beginRegionName == endRegionName">
|
||||
pierwsze dwie cyfry:
|
||||
{{ genData.sameRegions[beginRegionName].join(', ') }}
|
||||
(numer w obrębie obszaru {{ beginRegionName }})
|
||||
</span>
|
||||
|
||||
<span v-else>
|
||||
pierwsza cyfra: {{ genData.regionNumbers[beginRegionName] }}; druga cyfra:
|
||||
{{ genData.regionNumbers[endRegionName] }}
|
||||
</span>
|
||||
</span>
|
||||
</div> -->
|
||||
|
||||
<div class="tab_links">
|
||||
<a :href="$t('numgen.td2-wiki-link')" target="_blank">
|
||||
{{ $t('numgen.td2-wiki') }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="tab_actions">
|
||||
<button class="btn" @click="randomizeTrainNumber">PRZELOSUJ</button>
|
||||
<button class="btn" @click="randomizeTrainNumber(true)">{{ $t('numgen.action-random-region') }}</button>
|
||||
<button class="btn" @click="randomizeTrainNumber(false)">{{ $t('numgen.action-random-number') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -38,34 +66,60 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Ref, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import genData from '../../constants/numberGeneratorData.json';
|
||||
|
||||
const i18n = useI18n();
|
||||
type RegionName = keyof typeof genData.regionNumbers;
|
||||
type Category = keyof typeof genData.categories;
|
||||
|
||||
const beginRegionName = ref(null) as Ref<RegionName | null>;
|
||||
const endRegionName = ref(null) as Ref<RegionName | null>;
|
||||
const categoryRules = ref(null) as Ref<string | null>;
|
||||
const chosenCategory = ref(null) as Ref<Category | null>;
|
||||
|
||||
const trainNumber = ref(null) as Ref<string | null>;
|
||||
|
||||
const randomizeTrainNumber = () => {
|
||||
if (beginRegionName.value == null || endRegionName.value == null || categoryRules.value == null) return '';
|
||||
const copyNumber = () => {
|
||||
if (trainNumber.value) {
|
||||
navigator.clipboard.writeText(trainNumber.value);
|
||||
alert(i18n.t('numgen.alert'));
|
||||
}
|
||||
};
|
||||
|
||||
const randomizeTrainNumber = (randomizeRegions = false) => {
|
||||
// if (categoryRules.value == null) return;
|
||||
|
||||
const regionKeys = Object.keys(genData.regionNumbers);
|
||||
|
||||
if (beginRegionName.value == null || randomizeRegions)
|
||||
beginRegionName.value = regionKeys[(regionKeys.length * Math.random()) << 0] as RegionName;
|
||||
|
||||
if (endRegionName.value == null || randomizeRegions)
|
||||
endRegionName.value = regionKeys[(regionKeys.length * Math.random()) << 0] as RegionName;
|
||||
|
||||
let number = '';
|
||||
|
||||
if (beginRegionName.value == endRegionName.value) {
|
||||
const sameRegionsNumbers = genData.sameRegions[beginRegionName.value];
|
||||
const sameRegionsNumbers = genData.sameRegions[beginRegionName.value!];
|
||||
const randRegionNumber = sameRegionsNumbers[Math.floor(Math.random() * sameRegionsNumbers.length)];
|
||||
number += randRegionNumber.toString();
|
||||
} else {
|
||||
const beginRegionNumber = genData.regionNumbers[beginRegionName.value];
|
||||
const endRegionNumber = genData.regionNumbers[endRegionName.value];
|
||||
const beginRegionNumber = genData.regionNumbers[beginRegionName.value!];
|
||||
const endRegionNumber = genData.regionNumbers[endRegionName.value!];
|
||||
|
||||
number += `${beginRegionNumber}${endRegionNumber}`;
|
||||
}
|
||||
|
||||
const rulesArray = categoryRules.value.split(';').map((r) => ({
|
||||
// Do not roll the rest of number again if only randomize regions and category rules are already selected
|
||||
if (randomizeRegions && chosenCategory.value != null) {
|
||||
trainNumber.value = number + trainNumber.value?.substring(2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (chosenCategory.value == null) chosenCategory.value = 'EI';
|
||||
|
||||
const rulesArray = genData.categories[chosenCategory.value].split(';').map((r) => ({
|
||||
index: r.split(':')[0],
|
||||
rule: r.split(':')[1],
|
||||
nums: Number(r.split(':')[2] || '1'),
|
||||
@@ -92,18 +146,21 @@ const randomizeTrainNumber = () => {
|
||||
@import '../../styles/global.scss';
|
||||
|
||||
.options {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: 0.5em;
|
||||
|
||||
select {
|
||||
width: calc(50% - 0.5em);
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.generated-number {
|
||||
font-size: 1.3em;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
margin: 0.5em 0;
|
||||
padding: 0.5em;
|
||||
@@ -111,11 +168,13 @@ const randomizeTrainNumber = () => {
|
||||
}
|
||||
|
||||
.tab_actions {
|
||||
margin-top: 0.5em;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
button {
|
||||
grid-column: 3;
|
||||
}
|
||||
.tab_links {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $breakpointMd) {
|
||||
|
||||
@@ -1,62 +1,61 @@
|
||||
<template>
|
||||
<div class="stock-generator tab">
|
||||
<div class="tab_header">
|
||||
<h2>GENERATOR SKŁADU TOWAROWEGO</h2>
|
||||
<h2>{{ $t('stockgen.title') }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="tab_content">
|
||||
<div>
|
||||
<h2>WŁAŚCIWOŚCI SKŁADU</h2>
|
||||
<h2>{{ $t('stockgen.properties-title') }}</h2>
|
||||
|
||||
<b class="text--accent">
|
||||
⇐ Dodaj lokomotywę na pierwsze miejsce listy, aby uwzględnić ją przy losowaniu składu!
|
||||
{{ $t('stockgen.properties-desc') }}
|
||||
</b>
|
||||
|
||||
<div class="tab_attributes">
|
||||
<label>
|
||||
Maksymalna masa (t)
|
||||
{{ $t('stockgen.input-mass') }}
|
||||
<input type="number" v-model="maxMass" step="100" max="4000" min="0" />
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Maks. długość (m)
|
||||
{{ $t('stockgen.input-length') }}
|
||||
<input type="number" v-model="maxLength" step="25" max="650" min="0" />
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Maks. liczba wagonów
|
||||
{{ $t('stockgen.input-carcount') }}
|
||||
<input type="number" v-model="maxCarCount" step="1" max="60" min="1" />
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>ŁADUNEK</h2>
|
||||
<b>Wybierz ładunki, którymi chcesz wypełnić dostępne wagony:</b>
|
||||
<h2>{{ $t('stockgen.cargo-title') }}</h2>
|
||||
<b>{{ $t('stockgen.cargo-desc') }}</b>
|
||||
</div>
|
||||
|
||||
<div class="generator_cargo">
|
||||
<button
|
||||
class="btn"
|
||||
:data-chosen="chosenCargoTypes.includes(k.toString())"
|
||||
v-for="(v, k) in store.stockData?.generator.cargo"
|
||||
@click="toggleCargoChosen(k.toString(), v)"
|
||||
:data-chosen="chosenCargoTypes.includes(cargoName.toString())"
|
||||
v-for="(cargoArray, cargoName) in store.stockData?.generator.cargo"
|
||||
@click="toggleCargoChosen(cargoName.toString(), cargoArray)"
|
||||
>
|
||||
{{ k }}
|
||||
{{ $t(`cargo.${cargoName}`) }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>WAGONY Z WYBRANYMI ŁADUNKAMI</h2>
|
||||
<h2>{{ $t('stockgen.chosen-title') }}</h2>
|
||||
|
||||
<div class="generator_warning">
|
||||
<span v-if="computedChosenCarTypes.size == 0">
|
||||
Wybierz co najmniej jeden ładunek, aby zobaczyć wagony, które go posiadają!
|
||||
{{ $t('stockgen.chosen-empty-warning') }}
|
||||
</span>
|
||||
|
||||
<span v-else>
|
||||
Wagony posiadające wybrane ładunki. Najedź na nazwę, aby zobaczyć podgląd wagonu. Kliknij, aby wyłączyć z
|
||||
losowania (tylko podświetlone nazwy będą uwzględnione).
|
||||
{{ $t('stockgen.chosen-warning') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -80,14 +79,15 @@
|
||||
|
||||
<div class="tab_actions">
|
||||
<button class="btn" :data-disabled="computedChosenCarTypes.size == 0" @click="generateStock()">
|
||||
WYGENERUJ
|
||||
{{ $t('stockgen.action-generate') }}
|
||||
</button>
|
||||
|
||||
<button class="btn" :data-disabled="computedChosenCarTypes.size == 0" @click="generateStock(true)">
|
||||
WYGENERUJ PRÓŻNE WAGONY
|
||||
{{ $t('stockgen.action-generate-empty') }}
|
||||
</button>
|
||||
|
||||
<button class="btn" :data-disabled="computedChosenCarTypes.size == 0" @click="resetChosenCargo">
|
||||
ZRESETUJ ŁADUNKI
|
||||
{{ $t('stockgen.action-reset') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -99,7 +99,7 @@ import { defineComponent } from 'vue';
|
||||
import { useStore } from '../../store';
|
||||
|
||||
import stockMixin from '../../mixins/stockMixin';
|
||||
import { ICargo, ICarWagon } from '../../types';
|
||||
import { ICargo, ICarWagon, IStock } from '../../types';
|
||||
import warningsMixin from '../../mixins/warningsMixin';
|
||||
|
||||
export default defineComponent({
|
||||
@@ -180,21 +180,42 @@ export default defineComponent({
|
||||
return acc;
|
||||
}, [] as { constructionType: string; carPool: { carWagon: ICarWagon; cargo?: ICargo }[] }[]);
|
||||
|
||||
const headingLoco = this.store.stockList[0]?.isLoco ? this.store.stockList[0] : undefined;
|
||||
let bestGeneration: { stockList: IStock[]; value: number } = { stockList: [], value: 0 };
|
||||
|
||||
this.store.stockList.length = headingLoco ? 1 : 0;
|
||||
const maxMass = this.store.acceptableMass || this.maxMass;
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const headingLoco = this.store.stockList[0]?.isLoco ? this.store.stockList[0] : undefined;
|
||||
this.store.stockList.length = headingLoco ? 1 : 0;
|
||||
|
||||
new Array(this.maxCarCount).fill(0).forEach(() => {
|
||||
const randomStockType = generatedChosenStockList[~~(Math.random() * generatedChosenStockList.length)];
|
||||
const { carWagon, cargo } = randomStockType.carPool[~~(Math.random() * randomStockType.carPool.length)];
|
||||
const maxMass =
|
||||
this.store.acceptableMass > 0 ? Math.min(this.store.acceptableMass, this.maxMass) : this.maxMass;
|
||||
|
||||
if (this.store.totalMass + (cargo?.totalMass || carWagon.mass) > maxMass) return;
|
||||
if (this.store.totalLength + carWagon.length > this.maxLength) return;
|
||||
let exceeded = false;
|
||||
|
||||
this.addCarWagon(carWagon, cargo);
|
||||
});
|
||||
while (!exceeded) {
|
||||
const randomStockType = generatedChosenStockList[~~(Math.random() * generatedChosenStockList.length)];
|
||||
const { carWagon, cargo } = randomStockType.carPool[~~(Math.random() * randomStockType.carPool.length)];
|
||||
|
||||
if (
|
||||
this.store.totalMass + (cargo?.totalMass || carWagon.mass) > maxMass ||
|
||||
this.store.totalLength + carWagon.length > this.maxLength ||
|
||||
this.store.stockList.length > this.maxCarCount
|
||||
) {
|
||||
exceeded = true;
|
||||
break;
|
||||
}
|
||||
|
||||
this.addCarWagon(carWagon, cargo);
|
||||
}
|
||||
|
||||
const currentGenerationValue = this.store.totalLength + this.store.totalMass + this.store.stockList.length;
|
||||
|
||||
if (bestGeneration.value < currentGenerationValue) {
|
||||
bestGeneration.stockList = this.store.stockList;
|
||||
bestGeneration.value = currentGenerationValue;
|
||||
}
|
||||
}
|
||||
|
||||
this.store.stockList = bestGeneration.stockList;
|
||||
this.store.stockSectionMode = 'stock-list';
|
||||
},
|
||||
|
||||
@@ -244,7 +265,7 @@ export default defineComponent({
|
||||
.generator_vehicles {
|
||||
display: grid;
|
||||
gap: 0.5em;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
|
||||
|
||||
button {
|
||||
position: relative;
|
||||
@@ -294,12 +315,5 @@ export default defineComponent({
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 470px) {
|
||||
.generator_cargo,
|
||||
.generator_vehicles {
|
||||
grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,8 +1,47 @@
|
||||
<template>
|
||||
<section class="stock-list">
|
||||
<section class="stock-list-tab">
|
||||
<div class="tab_header">
|
||||
<h2>{{ $t('stocklist.title') }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="stock_actions">
|
||||
<label class="file-label">
|
||||
<div class="btn btn--image">
|
||||
<img src="/images/icon-upload.svg" alt="" />
|
||||
{{ $t('stocklist.action-upload') }}
|
||||
</div>
|
||||
|
||||
<input type="file" @change="uploadStock" ref="conFile" accept=".con,.txt" />
|
||||
</label>
|
||||
|
||||
<button class="btn btn--image" :data-disabled="stockIsEmpty" :disabled="stockIsEmpty" @click="downloadStock">
|
||||
<img src="/images/icon-download.svg" alt="download icon" />
|
||||
{{ $t('stocklist.action-download') }}
|
||||
</button>
|
||||
|
||||
<button class="btn btn--image" :data-disabled="stockIsEmpty" :disabled="stockIsEmpty" @click="copyToClipboard">
|
||||
<img src="/images/icon-copy.svg" alt="copy icon" />
|
||||
{{ $t('stocklist.action-copy') }}
|
||||
</button>
|
||||
|
||||
<button class="btn btn--image" :data-disabled="stockIsEmpty" :disabled="stockIsEmpty" @click="resetStock">
|
||||
<img src="/images/icon-reset.svg" alt="reset icon" />
|
||||
{{ $t('stocklist.action-reset') }}
|
||||
</button>
|
||||
|
||||
<button class="btn btn--image" :data-disabled="stockIsEmpty" :disabled="stockIsEmpty" @click="shuffleCars">
|
||||
<img src="/images/icon-shuffle.svg" alt="shuffle icon" />
|
||||
{{ $t('stocklist.action-shuffle') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="stock_controls" :data-disabled="store.chosenStockListIndex == -1">
|
||||
<b class="no">
|
||||
POJAZD NR <span class="text--accent">{{ store.chosenStockListIndex + 1 }}</span>
|
||||
<b v-if="store.chosenStockListIndex >= 0">
|
||||
{{ $t('stocklist.vehicle-no') }} <span class="text--accent">{{ store.chosenStockListIndex + 1 }}</span>
|
||||
</b>
|
||||
|
||||
<b v-else>
|
||||
{{ $t('stocklist.no-vehicle-chosen') }}
|
||||
</b>
|
||||
|
||||
<button
|
||||
@@ -11,7 +50,7 @@
|
||||
@click="moveUpStock(store.chosenStockListIndex)"
|
||||
>
|
||||
<img :src="getIconURL('higher')" alt="move up vehicle" />
|
||||
PRZENIEŚ WYŻEJ
|
||||
{{ $t('stocklist.action-move-up') }}
|
||||
</button>
|
||||
|
||||
<button
|
||||
@@ -20,7 +59,7 @@
|
||||
@click="moveDownStock(store.chosenStockListIndex)"
|
||||
>
|
||||
<img :src="getIconURL('lower')" alt="move down vehicle" />
|
||||
PRZENIEŚ NIŻEJ
|
||||
{{ $t('stocklist.action-move-down') }}
|
||||
</button>
|
||||
|
||||
<button
|
||||
@@ -29,27 +68,10 @@
|
||||
@click="removeStock(store.chosenStockListIndex)"
|
||||
>
|
||||
<img :src="getIconURL('remove')" alt="remove vehicle" />
|
||||
USUŃ
|
||||
{{ $t('stocklist.action-remove') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="stock_actions">
|
||||
<label class="file-label">
|
||||
<div class="btn">WCZYTAJ</div>
|
||||
<input type="file" @change="uploadStock" ref="conFile" accept=".con,.txt" />
|
||||
</label>
|
||||
|
||||
<button class="btn" :data-disabled="stockIsEmpty" :disabled="stockIsEmpty" @click="downloadStock">POBIERZ</button>
|
||||
|
||||
<button class="btn" :data-disabled="stockIsEmpty" :disabled="stockIsEmpty" @click="copyToClipboard">
|
||||
SKOPIUJ
|
||||
</button>
|
||||
|
||||
<button class="btn" :data-disabled="stockIsEmpty" :disabled="stockIsEmpty" @click="resetStock">ZRESETUJ</button>
|
||||
|
||||
<button class="btn" :data-disabled="stockIsEmpty" :disabled="stockIsEmpty" @click="shuffleCars">PRZETASUJ</button>
|
||||
</div>
|
||||
|
||||
<div class="stock_specs">
|
||||
<b class="real-stock-info" v-if="store.chosenRealStock">
|
||||
<span class="text--accent">
|
||||
@@ -60,46 +82,62 @@
|
||||
</b>
|
||||
|
||||
<span>
|
||||
Masa: <span class="text--accent">{{ store.totalMass }}t</span> (dopuszczalna:
|
||||
<span class="text--accent">{{ store.acceptableMass ? store.acceptableMass + 't' : '-' }}</span
|
||||
>) - Długość:
|
||||
{{ $t('stocklist.mass') }} <span class="text--accent">{{ store.totalMass }}t</span> ({{
|
||||
$t('stocklist.mass-accepted')
|
||||
}}: <span class="text--accent">{{ store.acceptableMass ? store.acceptableMass + 't' : '-' }}</span
|
||||
>) - {{ $t('stocklist.length') }}:
|
||||
<span class="text--accent">{{ store.totalLength }}m</span>
|
||||
- vMax: <span class="text--accent">{{ store.maxStockSpeed }} km/h</span>
|
||||
- {{ $t('stocklist.vmax') }}: <span class="text--accent">{{ store.maxStockSpeed }} km/h</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="stock_warnings">
|
||||
<div class="warning" v-if="locoNotSuitable">
|
||||
Lokomotywy EP07 i EP08 są przeznaczone jedynie do ruchu pasażerskiego!
|
||||
</div>
|
||||
<div class="stock_cold-start">
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
v-model="store.isColdStart"
|
||||
:disabled="!locoSupportsColdStart(store.stockList[0]?.constructionType || '')"
|
||||
/>
|
||||
{{ $t('stocklist.coldstart-info') }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="stock_warnings" v-if="stockHasWarnings">
|
||||
<div class="warning" v-if="locoNotSuitable">(!) {{ $t('stocklist.warning-not-suitable') }}</div>
|
||||
|
||||
<div class="warning" v-if="trainTooLong && store.isTrainPassenger">
|
||||
Maksymalna długość składów pasażerskich nie może przekraczać 350m!
|
||||
(!) {{ $t('stocklist.warning-passenger-too-long') }}
|
||||
</div>
|
||||
|
||||
<div class="warning" v-if="trainTooLong && !store.isTrainPassenger">
|
||||
Maksymalna długość składów innych niż pasażerskie nie może przekraczać 650m!
|
||||
(!) {{ $t('stocklist.warning-freight-too-long') }}
|
||||
</div>
|
||||
|
||||
<div class="warning" v-if="trainTooHeavy">
|
||||
Ten skład jest za ciężki! Sprawdź
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://docs.google.com/spreadsheets/d/1bFXUsHsAu4youmNz-46Q1HslZaaoklvfoBDS553TnNk/edit"
|
||||
>
|
||||
dopuszczalne masy składów
|
||||
</a>
|
||||
(!)
|
||||
<i18n-t keypath="stocklist.warning-too-heavy">
|
||||
<template #href>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://docs.google.com/spreadsheets/d/1bFXUsHsAu4youmNz-46Q1HslZaaoklvfoBDS553TnNk/edit"
|
||||
>
|
||||
{{ $t('stocklist.acceptable-mass-docs') }}
|
||||
</a>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</div>
|
||||
|
||||
<div class="warning" v-if="tooManyLocomotives">Ten skład posiada za dużo pojazdów trakcyjnych!</div>
|
||||
<div class="warning" v-if="tooManyLocomotives">
|
||||
{{ $t('stocklist.warning-too-many-locos') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<StockThumbnails :onListItemClick="onListItemClick" :onStockImageError="stockImageError" />
|
||||
<StockThumbnails :onListItemClick="onListItemClick" />
|
||||
|
||||
<!-- Stock list -->
|
||||
<ul ref="stock_list">
|
||||
<li v-if="stockIsEmpty" class="list-empty">
|
||||
<div class="stock-info">Lista pojazdów jest pusta!</div>
|
||||
<div class="stock-info">{{ $t('stocklist.list-empty') }}</div>
|
||||
</li>
|
||||
|
||||
<TransitionGroup name="stock-list-anim">
|
||||
@@ -127,7 +165,7 @@
|
||||
{{ i + 1 }}.
|
||||
</span>
|
||||
|
||||
<span class="stock-info__type">
|
||||
<span class="stock-info__type" :class="{ supporter: stock.supportersOnly }">
|
||||
{{ stock.isLoco ? stock.type : getCarSpecFromType(stock.type) }}
|
||||
</span>
|
||||
|
||||
@@ -147,10 +185,11 @@ import { defineComponent } from 'vue';
|
||||
import TrainImage from '../sections/TrainImageSection.vue';
|
||||
|
||||
import { useStore } from '../../store';
|
||||
|
||||
import { locoSupportsColdStart } from '../../utils/locoUtils';
|
||||
import warningsMixin from '../../mixins/warningsMixin';
|
||||
import imageMixin from '../../mixins/imageMixin';
|
||||
import stockPreviewMixin from '../../mixins/stockPreviewMixin';
|
||||
import { IStock } from '../../types';
|
||||
import StockThumbnails from '../utils/StockThumbnails.vue';
|
||||
import stockMixin from '../../mixins/stockMixin';
|
||||
|
||||
@@ -170,20 +209,20 @@ export default defineComponent({
|
||||
|
||||
data: () => ({
|
||||
imageOffsetY: 0,
|
||||
|
||||
draggedVehicleID: -1,
|
||||
|
||||
stockActions: [{}],
|
||||
}),
|
||||
|
||||
computed: {
|
||||
stockString() {
|
||||
return this.store.stockList
|
||||
.map((stock) => {
|
||||
let s = stock.isLoco || !stock.cargo ? stock.type : `${stock.type}:${stock.cargo.id}`;
|
||||
.map((stock, i) => {
|
||||
let stockTypeStr = stock.isLoco || !stock.cargo ? stock.type : `${stock.type}:${stock.cargo.id}`;
|
||||
let coldStart =
|
||||
i == 0 && this.store.isColdStart && locoSupportsColdStart(stock.constructionType || '') ? ',c' : '';
|
||||
|
||||
let final = s;
|
||||
for (let i = 0; i < stock.count - 1; i++) final += `;${s}`;
|
||||
|
||||
return final;
|
||||
return stockTypeStr + coldStart;
|
||||
})
|
||||
.join(';');
|
||||
},
|
||||
@@ -195,27 +234,20 @@ export default defineComponent({
|
||||
chosenStockVehicle() {
|
||||
return this.store.chosenStockListIndex == -1 ? undefined : this.store.stockList[this.store.chosenStockListIndex];
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
stockHasWarnings() {
|
||||
return this.tooManyLocomotives || this.trainTooHeavy || this.trainTooLong || this.locoNotSuitable;
|
||||
},
|
||||
},
|
||||
|
||||
stockImageError(e: Event, stock: IStock): void {
|
||||
(e.target as HTMLImageElement).src = `images/${stock.useType}-unknown.png`;
|
||||
},
|
||||
methods: {
|
||||
locoSupportsColdStart,
|
||||
|
||||
copyToClipboard() {
|
||||
// if (this.stockHasWarnings()) {
|
||||
// alert('Jazda tym pociągiem jest niezgodna z regulaminem symulatora! Zmień parametry zestawienia!');
|
||||
// return;
|
||||
// }
|
||||
|
||||
navigator.clipboard.writeText(this.stockString);
|
||||
|
||||
setTimeout(() => {
|
||||
alert('Pociąg został skopiowany do schowka!');
|
||||
alert(this.$t('stocklist.alert-copied'));
|
||||
}, 20);
|
||||
},
|
||||
|
||||
@@ -318,19 +350,13 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
downloadStock() {
|
||||
if (this.store.stockList.length == 0) return alert('Lista pojazdów jest pusta!');
|
||||
|
||||
// if (this.stockHasWarnings())
|
||||
// return alert('Jazda tym pociągiem jest niezgodna z regulaminem symulatora! Zmień parametry zestawienia!');
|
||||
if (this.store.stockList.length == 0) return alert(this.$t('stocklist.alert-empty'));
|
||||
|
||||
const defaultName = `${this.store.chosenRealStockName || this.store.stockList[0].type} ${
|
||||
this.store.totalMass
|
||||
}t; ${this.store.totalLength}m; vmax ${this.store.maxStockSpeed}`;
|
||||
|
||||
const fileName = prompt(
|
||||
'Nazwij plik, a następnie pobierz do folderu Presets (Dokumenty/TTSK/TrainDriver2):',
|
||||
defaultName
|
||||
);
|
||||
const fileName = prompt(this.$t('stocklist.prompt-file'), defaultName);
|
||||
|
||||
if (!fileName) return;
|
||||
|
||||
@@ -397,6 +423,12 @@ export default defineComponent({
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '../../styles/global';
|
||||
@import '../../styles/tab.scss';
|
||||
|
||||
.stock-list-tab {
|
||||
display: grid;
|
||||
grid-gap: 0.5em;
|
||||
}
|
||||
|
||||
.warning {
|
||||
padding: 0.25em;
|
||||
@@ -420,7 +452,6 @@ export default defineComponent({
|
||||
flex-wrap: wrap;
|
||||
|
||||
padding: 0.5em;
|
||||
margin-bottom: 1em;
|
||||
|
||||
background-color: #353a57;
|
||||
|
||||
@@ -453,9 +484,8 @@ export default defineComponent({
|
||||
.stock_actions {
|
||||
display: grid;
|
||||
gap: 0.5em;
|
||||
margin-bottom: 1em;
|
||||
|
||||
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
|
||||
label.file-label {
|
||||
text-align: center;
|
||||
@@ -475,9 +505,7 @@ export default defineComponent({
|
||||
|
||||
ul {
|
||||
position: relative;
|
||||
|
||||
overflow: auto;
|
||||
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
@@ -521,8 +549,8 @@ li > .stock-info {
|
||||
}
|
||||
}
|
||||
|
||||
.stock_warnings {
|
||||
margin: 0.5em 0;
|
||||
.supporter {
|
||||
color: salmon;
|
||||
}
|
||||
|
||||
.stock-info {
|
||||
|
||||
@@ -0,0 +1,356 @@
|
||||
<template>
|
||||
<section class="wiki-list tab">
|
||||
<div class="tab_header">
|
||||
<h2>{{ $t('wiki.title') }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="tab_content">
|
||||
<div class="actions-panel">
|
||||
<div class="actions-panel_vehicles">
|
||||
<button class="btn btn--choice" @click="changeWikiMode('locomotives')">
|
||||
{{ $t('wiki.action-vehicles') }}
|
||||
</button>
|
||||
<button class="btn btn--choice" @click="changeWikiMode('carWagons')">
|
||||
{{ $t('wiki.action-carriages') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="actions-panel_search">
|
||||
<input type="text" :placeholder="$t('wiki.search')" v-model="searchedVehicleTypeName" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-wrapper" @scroll="scrollEvent" ref="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th v-for="header in wikiMode == 'locomotives' ? locoHeaders : carHeaders" @click="toggleSorter(header)">
|
||||
{{ $t(`wiki.header.${header.id}`) }}
|
||||
|
||||
<span v-if="currentModeSorter.id == header.id">
|
||||
{{ currentModeSorter.direction == 1 ? `⇑` : `⇓` }}
|
||||
</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody v-if="wikiMode == 'locomotives'">
|
||||
<tr
|
||||
v-for="loco in computedLocoList"
|
||||
@click="previewLocomotive(loco)"
|
||||
@keydown.enter="previewLocomotive(loco)"
|
||||
@dblclick="addLocomotive(loco)"
|
||||
tabindex="0"
|
||||
>
|
||||
<td>
|
||||
<img
|
||||
:src="`https://spythere.github.io/api/td2/images/${loco.type}--300px.jpg`"
|
||||
loading="lazy"
|
||||
:alt="`Lokomotywa ${loco.type}`"
|
||||
/>
|
||||
</td>
|
||||
|
||||
<td>{{ loco.type }}</td>
|
||||
<td>{{ $t(`wiki.${loco.power}`) }}</td>
|
||||
<td>{{ loco.constructionType }}</td>
|
||||
<td>{{ locoSupportsColdStart(loco.constructionType) ? `✓` : '✗' }}</td>
|
||||
<td>{{ loco.length }}m</td>
|
||||
<td>{{ loco.mass }}t</td>
|
||||
<td>{{ loco.maxSpeed }}km/h</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
<tbody v-else>
|
||||
<tr
|
||||
v-for="car in computedCarList"
|
||||
@keydow.enter="previewCarWagon(car)"
|
||||
@click="previewCarWagon(car)"
|
||||
@dblclick="addCarWagon(car)"
|
||||
tabindex="0"
|
||||
>
|
||||
<td>
|
||||
<img
|
||||
:src="`https://spythere.github.io/api/td2/images/${car.type}--300px.jpg`"
|
||||
loading="lazy"
|
||||
:alt="`Lokomotywa ${car.type}`"
|
||||
/>
|
||||
</td>
|
||||
|
||||
<td>{{ car.type }}</td>
|
||||
<td>{{ car.constructionType }}</td>
|
||||
<td>{{ car.length }}m</td>
|
||||
<td>{{ car.mass }}t</td>
|
||||
<td>{{ car.maxSpeed }}km/h</td>
|
||||
<td>{{ car.cargoList.length == 0 ? '-' : car.cargoList.length }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { useStore } from '../../store';
|
||||
import stockPreviewMixin from '../../mixins/stockPreviewMixin';
|
||||
import { Vehicle } from '../../types';
|
||||
import { isLocomotive } from '../../utils/vehicleUtils';
|
||||
import stockMixin from '../../mixins/stockMixin';
|
||||
import { locoSupportsColdStart } from '../../utils/locoUtils';
|
||||
|
||||
type WikiMode = 'locomotives' | 'carWagons';
|
||||
type SorterID =
|
||||
| 'type'
|
||||
| 'constructionType'
|
||||
| 'image'
|
||||
| 'length'
|
||||
| 'mass'
|
||||
| 'maxSpeed'
|
||||
| 'cargoCount'
|
||||
| 'power'
|
||||
| 'coldStart';
|
||||
|
||||
interface WikiHeader {
|
||||
id: SorterID;
|
||||
sortable: boolean;
|
||||
}
|
||||
|
||||
const locoHeaders: WikiHeader[] = [
|
||||
{ id: 'image', sortable: false },
|
||||
{ id: 'type', sortable: true },
|
||||
{ id: 'power', sortable: true },
|
||||
{ id: 'constructionType', sortable: true },
|
||||
{ id: 'coldStart', sortable: true },
|
||||
{ id: 'length', sortable: true },
|
||||
{ id: 'mass', sortable: true },
|
||||
{ id: 'maxSpeed', sortable: true },
|
||||
];
|
||||
|
||||
const carHeaders: WikiHeader[] = [
|
||||
{ id: 'image', sortable: false },
|
||||
{ id: 'type', sortable: true },
|
||||
{ id: 'constructionType', sortable: true },
|
||||
{ id: 'length', sortable: true },
|
||||
{ id: 'mass', sortable: true },
|
||||
{ id: 'maxSpeed', sortable: true },
|
||||
{ id: 'cargoCount', sortable: true },
|
||||
];
|
||||
|
||||
export default defineComponent({
|
||||
mixins: [stockPreviewMixin, stockMixin],
|
||||
|
||||
data() {
|
||||
return {
|
||||
store: useStore(),
|
||||
locoHeaders,
|
||||
carHeaders,
|
||||
|
||||
locosScrollTop: 0,
|
||||
carsScrollTop: 0,
|
||||
|
||||
wikiMode: 'locomotives' as WikiMode,
|
||||
searchedVehicleTypeName: '',
|
||||
|
||||
currentLocoSorter: {
|
||||
id: 'type' as SorterID,
|
||||
direction: 1,
|
||||
},
|
||||
|
||||
currentCarSorter: {
|
||||
id: 'type' as SorterID,
|
||||
direction: 1,
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
activated() {
|
||||
const tableWrapperRef = this.$refs['table-wrapper'] as HTMLElement;
|
||||
tableWrapperRef.scrollTo({ top: this.wikiMode == 'locomotives' ? this.locosScrollTop : this.carsScrollTop });
|
||||
},
|
||||
|
||||
methods: {
|
||||
locoSupportsColdStart,
|
||||
|
||||
scrollEvent(e: Event) {
|
||||
const tableScrollTop = (e.target as HTMLElement).scrollTop;
|
||||
|
||||
if (this.wikiMode == 'locomotives') this.locosScrollTop = tableScrollTop;
|
||||
else this.carsScrollTop = tableScrollTop;
|
||||
},
|
||||
|
||||
changeWikiMode(wikiMode: WikiMode) {
|
||||
this.searchedVehicleTypeName = '';
|
||||
this.wikiMode = wikiMode;
|
||||
},
|
||||
|
||||
toggleSorter(header: WikiHeader) {
|
||||
if (!header.sortable) return;
|
||||
|
||||
if (header.id == this.currentModeSorter.id) this.currentModeSorter.direction *= -1;
|
||||
this.currentModeSorter.id = header.id;
|
||||
},
|
||||
|
||||
sortVehicles(vA: Vehicle, vB: Vehicle) {
|
||||
const { id, direction } = this.currentModeSorter;
|
||||
const vehiclesAreLocos = isLocomotive(vA) && isLocomotive(vB);
|
||||
const vehiclesAreCars = !isLocomotive(vA) && !isLocomotive(vB);
|
||||
|
||||
switch (id) {
|
||||
case 'type':
|
||||
case 'constructionType':
|
||||
return direction == 1 ? vA[id].localeCompare(vB[id]) : vB[id].localeCompare(vA[id]);
|
||||
|
||||
case 'mass':
|
||||
case 'length':
|
||||
case 'maxSpeed':
|
||||
return Math.sign(vA[id] - vB[id]) * direction;
|
||||
|
||||
case 'cargoCount':
|
||||
if (vehiclesAreCars) return Math.sign((vA.cargoList.length || -1) - (vB.cargoList.length || -1)) * direction;
|
||||
|
||||
case 'coldStart':
|
||||
if (vehiclesAreLocos)
|
||||
return (
|
||||
(locoSupportsColdStart(vA.constructionType) > locoSupportsColdStart(vB.constructionType) ? 1 : -1) *
|
||||
direction
|
||||
);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return direction == 1 ? vA.type.localeCompare(vB.type) : vB.type.localeCompare(vA.type);
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
currentModeSorter() {
|
||||
return this.wikiMode == 'carWagons' ? this.currentCarSorter : this.currentLocoSorter;
|
||||
},
|
||||
|
||||
computedLocoList() {
|
||||
const trimmedSearchValue = this.searchedVehicleTypeName.trim();
|
||||
|
||||
return this.store.locoDataList
|
||||
.filter((loco) => new RegExp(`${trimmedSearchValue}`, 'i').test(loco.type))
|
||||
.sort(this.sortVehicles);
|
||||
},
|
||||
|
||||
computedCarList() {
|
||||
const trimmedSearchValue = this.searchedVehicleTypeName.trim();
|
||||
|
||||
return this.store.carDataList
|
||||
.filter((car) => new RegExp(`${trimmedSearchValue}`, 'i').test(car.type))
|
||||
.sort(this.sortVehicles);
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '../../styles/tab.scss';
|
||||
|
||||
.actions-panel {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5em;
|
||||
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
.actions-panel_vehicles {
|
||||
display: flex;
|
||||
gap: 0.5em;
|
||||
}
|
||||
|
||||
.actions-panel_search {
|
||||
input {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.table-wrapper {
|
||||
overflow: auto;
|
||||
height: 750px;
|
||||
max-height: 95vh;
|
||||
}
|
||||
|
||||
.wiki-list table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
|
||||
thead {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #111;
|
||||
padding: 0.5em;
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
tr {
|
||||
cursor: pointer;
|
||||
background-color: #333;
|
||||
|
||||
&:nth-child(odd) {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
text-align: center;
|
||||
padding: 0.25em;
|
||||
height: 85px;
|
||||
}
|
||||
|
||||
td:first-child {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
td img {
|
||||
display: block;
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $breakpointMd) {
|
||||
.wiki-list table {
|
||||
td {
|
||||
width: 100px;
|
||||
height: auto;
|
||||
|
||||
img {
|
||||
width: 6em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $breakpointSm) {
|
||||
.actions-panel {
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.actions-panel_vehicles {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
|
||||
.actions-panel_search {
|
||||
display: grid;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<div
|
||||
class="image-preview"
|
||||
@click="store.vehiclePreviewSrc = ''"
|
||||
@keydown.esc="store.vehiclePreviewSrc = ''"
|
||||
tabindex="0"
|
||||
>
|
||||
<img :src="store.vehiclePreviewSrc" alt="preview" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { useStore } from '../../store';
|
||||
|
||||
export default defineComponent({
|
||||
data() {
|
||||
return {
|
||||
store: useStore(),
|
||||
};
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.$el.focus();
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.image-preview {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background: rgba(black, 0.85);
|
||||
cursor: zoom-out;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -9,7 +9,7 @@
|
||||
@dragover="allowDrop"
|
||||
>
|
||||
<span @click="onListItemClick(stockIndex)" :key="stock.id">
|
||||
<b>
|
||||
<b :class="{ supporter: stock.supportersOnly }">
|
||||
{{ stock.type }}
|
||||
</b>
|
||||
|
||||
@@ -33,7 +33,7 @@ import { useStore } from '../../store';
|
||||
import { IStock } from '../../types';
|
||||
|
||||
const store = useStore();
|
||||
const emit = defineEmits(['listItemClick', 'stockImageError']);
|
||||
const emit = defineEmits(['listItemClick']);
|
||||
|
||||
const thumbnailsRef = ref() as Ref<HTMLElement>;
|
||||
const draggedIndex = ref(-1);
|
||||
@@ -43,7 +43,7 @@ const onListItemClick = (index: number) => {
|
||||
};
|
||||
|
||||
const stockImageError = (e: Event, stock: IStock) => {
|
||||
emit('stockImageError', e, stock);
|
||||
(e.target as HTMLImageElement).src = `images/${stock.useType}-unknown.png`;
|
||||
};
|
||||
|
||||
watch(
|
||||
@@ -86,10 +86,7 @@ const allowDrop = (e: DragEvent) => {
|
||||
<style lang="scss" scoped>
|
||||
.stock_thumbnails {
|
||||
display: flex;
|
||||
margin: 1em 0;
|
||||
|
||||
overflow: auto;
|
||||
|
||||
background-color: #353a57;
|
||||
|
||||
> div {
|
||||
@@ -120,5 +117,9 @@ const allowDrop = (e: DragEvent) => {
|
||||
max-height: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
.supporter {
|
||||
color: salmon;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -26,14 +26,13 @@
|
||||
"Rezerwa": [89, 92, 98]
|
||||
},
|
||||
"categories": {
|
||||
"ekspres krajowy (EI)": "2:00-99:2",
|
||||
"międzywojewódzki pośpieszny (MP)": "2:050-169:3",
|
||||
"wojewódzki pośpieszny (RP)": "2:050-169:3",
|
||||
"wojewódzki osobowy (RO)": "2:200-999:3",
|
||||
"próżny \"służbowy\" (PW)": "2:6;3:0-899:3",
|
||||
"towarowy do przewozów masowych (TM)": "2:4;3:0-899:3",
|
||||
"towarowy do obsługi stacji (TK)": "2:3;3:0-899:3",
|
||||
"lokomotywa luzem (LT)": "2:5;3:0-899:3"
|
||||
"EI": "2:00-99:2",
|
||||
"MP/RP": "2:050-169:3",
|
||||
"RO": "2:200-999:3",
|
||||
"PW": "2:6;3:0-899:3",
|
||||
"TM": "2:4;3:0-899:3",
|
||||
"TK": "2:3;3:0-899:3",
|
||||
"LT": "2:5;3:0-899:3"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,14 @@
|
||||
"2000": 70
|
||||
}
|
||||
},
|
||||
"EU07E": {
|
||||
"passenger": {
|
||||
"650": 125
|
||||
},
|
||||
"cargo": {
|
||||
"2000": 70
|
||||
}
|
||||
},
|
||||
"EP07": {
|
||||
"passenger": {
|
||||
"650": 125
|
||||
@@ -51,3 +59,4 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import localePL from './locales/pl.json';
|
||||
import localeEN from './locales/en.json';
|
||||
import { createI18n } from 'vue-i18n';
|
||||
import axios from 'axios';
|
||||
|
||||
type LocaleMessageSchema = typeof localePL;
|
||||
type LocaleKey = 'en' | 'pl';
|
||||
|
||||
const locales: { [key in LocaleKey]: LocaleMessageSchema } = {
|
||||
en: localeEN,
|
||||
pl: localePL,
|
||||
};
|
||||
|
||||
const locale = window.localStorage.getItem('locale') || (/^pl\b/.test(navigator.language) ? 'pl' : 'en');
|
||||
|
||||
const i18n = createI18n<[LocaleMessageSchema], 'en' | 'pl'>({
|
||||
locale,
|
||||
fallbackLocale: 'pl',
|
||||
legacy: false,
|
||||
globalInjection: true,
|
||||
messages: locales,
|
||||
});
|
||||
|
||||
async function fetchBackendTranslations() {
|
||||
const localeData = (await axios.get(`https://spythere.github.io/api/td2/data/locales.json`)).data;
|
||||
|
||||
i18n.global.mergeLocaleMessage('pl', localeData.pl);
|
||||
i18n.global.mergeLocaleMessage('en', localeData.en);
|
||||
}
|
||||
|
||||
fetchBackendTranslations();
|
||||
|
||||
export default i18n;
|
||||
@@ -0,0 +1,150 @@
|
||||
{
|
||||
"app": {
|
||||
"title": "ROLLING STOCK EDITOR"
|
||||
},
|
||||
"footer": {
|
||||
"disclaimer": "This site has only an informational intent. The author does not carry any responsibility for creating trains against {tos}!",
|
||||
"tos": "Train Driver 2 simulator rules",
|
||||
"tos-href": "https://docs.google.com/document/d/1UAAPUtN0d_RoS4RgOzEzllJZJhA0VcizzCzKW4QylbY/edit#heading=h.1ldcvhomwjp9",
|
||||
"version-check": "Site is complete for version {version} of Train Driver 2 simulator"
|
||||
},
|
||||
"inputs": {
|
||||
"title": "CHOOSE A VEHICLE",
|
||||
"input-vehicle": "Choose a traction unit",
|
||||
"input-carwagon": "Choose a carriage",
|
||||
"cargo-title": "Cargo (only selected freight cars)",
|
||||
"no-cargo-available": "no cargo available",
|
||||
"cargo-empty": "empty",
|
||||
"loco-e": "ELECTR.",
|
||||
"loco-s": "DIESEL",
|
||||
"loco-ezt": "EMU",
|
||||
"loco-szt": "DMU",
|
||||
"car-passenger": "PASSENGER",
|
||||
"car-cargo": "FREIGHT",
|
||||
"action-add": "ADD NEW",
|
||||
"action-swap": "SWAP WITH",
|
||||
"real-stock": "POLISH TRAIN COMPOSITIONS"
|
||||
},
|
||||
"preview": {
|
||||
"title": "RAILWAY VEHICLE PREVIEW",
|
||||
"loading": "IMAGE LOADING...",
|
||||
"desc": "Choose a railway vehicle above to see its preview",
|
||||
"sponsor-only": "* SPONSORS ONLY",
|
||||
"loco-e": "ELECTRIC LOCO",
|
||||
"loco-s": "DIESEL LOCO",
|
||||
"loco-ezt": "ELECTRIC M.U.",
|
||||
"loco-szt": "DIESEL M.U.",
|
||||
"car-passenger": "PASSENGER CARRIAGE",
|
||||
"car-cargo": "FREIGHT CAR",
|
||||
"cabin": "Cabin type:",
|
||||
"construction": "Construction type:"
|
||||
},
|
||||
"topbar": {
|
||||
"stock-list": "STOCK",
|
||||
"wiki-list": "VEHICLES",
|
||||
"number-generator": "NUMBER GEN.",
|
||||
"stock-generator": "STOCK GEN."
|
||||
},
|
||||
"stocklist": {
|
||||
"title": "STOCK EDITOR",
|
||||
"alert-copied": "The rolling stock has been copied to your clipboard!",
|
||||
"alert-empty": "Lista pojazdów jest pusta!",
|
||||
"prompt-file": "Name a file and download it to the Presets folder (Documents/TTSK/TrainDriver2):",
|
||||
"vehicle-no": "VEHICLE NO.",
|
||||
"no-vehicle-chosen": "NO VEHICLE CHOSEN",
|
||||
"action-move-up": "MOVE UP",
|
||||
"action-move-down": "MOVE DOWN",
|
||||
"action-remove": "REMOVE",
|
||||
"action-upload": "LOAD",
|
||||
"action-download": "DOWNLOAD",
|
||||
"action-copy": "COPY",
|
||||
"action-reset": "RESET",
|
||||
"action-shuffle": "SHUFFLE",
|
||||
"mass": "Mass",
|
||||
"mass-accepted": "accepted",
|
||||
"length": "Length",
|
||||
"vmax": "vMax",
|
||||
"coldstart-info": "Cold start heading locomotive (only locos 303E & 203E type)",
|
||||
"list-empty": "Stock list is empty!",
|
||||
"warning-not-suitable": "EP07 & EP08 type locomotives are designed for passenger traffic only!",
|
||||
"warning-passenger-too-long": "Maximum length of a passenger train may not be greater than 350m!",
|
||||
"warning-freight-too-long": "Maximum length of a freight train may not be greater than 650m!",
|
||||
"warning-too-many-locos": "This train has too many traction units!",
|
||||
"warning-too-heavy": "This train is too heavy! Check {href}",
|
||||
"acceptable-mass-docs": "acceptable rolling stock masses (PL)"
|
||||
},
|
||||
"stockgen": {
|
||||
"title": "FREIGHT TRAIN GENERATOR",
|
||||
"properties-title": "ROLLING STOCK PROPERTIES",
|
||||
"properties-desc": "⇐ Add a locomotive in the first place of the stock list to include it in a drawing!",
|
||||
"input-mass": "Max. mass (t)",
|
||||
"input-length": "Max. length (m)",
|
||||
"input-carcount": "Max. car count",
|
||||
"cargo-title": "CARGO",
|
||||
"cargo-desc": "Choose cargo you want to fill available cars with:",
|
||||
"chosen-title": "CARS WITH CHOSEN CARGO",
|
||||
"chosen-empty-warning": "Choose at least one cargo type to see available cars!",
|
||||
"chosen-warning": "Cars containing chosen cargo are shown below. Hover over a type to see a preview of the car. Click it to include/exclude it from a drawing (only highlighted types will be included).",
|
||||
"action-generate": "GENERATE",
|
||||
"action-generate-empty": "GENERATE EMPTY",
|
||||
"action-reset": "RESET CARGO"
|
||||
},
|
||||
"numgen": {
|
||||
"title": "TRAIN NUMBER GENERATOR",
|
||||
"alert": "The number has been copied to your clipboard!",
|
||||
"start-region": "Beginning construction region",
|
||||
"end-region": "Terminating construction region",
|
||||
"train-category": "Train category",
|
||||
"number-info": "Generated train number:",
|
||||
"warning": "Choose category and (optionally) construction regions",
|
||||
"td2-wiki": "> Polish rules of train numbering (TD2 wiki)",
|
||||
"td2-wiki-link": "https://wiki.td2.info.pl/index.php?title=Zasady_numeracji_poci%C4%85g%C3%B3w/en",
|
||||
"action-random-region": "DRAW REGIONS",
|
||||
"action-random-number": "DRAW A NUMBER",
|
||||
"categories": {
|
||||
"EI": "domestic express (EI)",
|
||||
"MP/RP": "(inter)voivodeship bullet (MP/RP)",
|
||||
"RO": "regional passenger (RO)",
|
||||
"PW": "empty passenger (PW)",
|
||||
"TM": "mass transport freight (TM)",
|
||||
"TK": "non-mass transport freight (TK)",
|
||||
"LT": "locomotive alone (LT)"
|
||||
},
|
||||
"rules": {
|
||||
"EI": "4 digits - ends within the range of 00-99",
|
||||
"MP/RP": "5 digits - ends within the range of 050-169",
|
||||
"RO": "5 digits - ends within the range of 200-999",
|
||||
"PW": "6 digits - '6' on the 3rd place; ends within the range of 000-899",
|
||||
"TM": "6 digits - '4' on the 3rd place; ends within the range of 000-899",
|
||||
"TK": "6 digits - '3' on the 3rd place; ends within the range of 000-899",
|
||||
"LT": "6 digits - '5' on the 3rd place; ends within the range of 000-899"
|
||||
}
|
||||
},
|
||||
"wiki": {
|
||||
"title": "LIST OF AVAILABLE VEHICLES",
|
||||
"action-vehicles": "TRACTION UNITS",
|
||||
"action-carriages": "CARRIAGES",
|
||||
"search": "Search for a vehicle...",
|
||||
"header": {
|
||||
"image": "Image",
|
||||
"type": "Name",
|
||||
"power": "Type",
|
||||
"constructionType": "Construction",
|
||||
"coldStart": "Cold start",
|
||||
"length": "Length",
|
||||
"mass": "Mass",
|
||||
"maxSpeed": "Speed",
|
||||
"cargoCount": "Cargo count"
|
||||
},
|
||||
"loco-ezt": "EMU",
|
||||
"loco-szt": "DMU",
|
||||
"loco-s": "Diesel locomotive",
|
||||
"loco-e": "Electric locomotive"
|
||||
},
|
||||
"realstock": {
|
||||
"title": "POLISH TRAIN COMPOSITIONS by",
|
||||
"search-name": "Search by name",
|
||||
"search-stock": "Search by vehicles",
|
||||
"action-reset": "RESET"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
{
|
||||
"app": {
|
||||
"title": "EDYTOR SKŁADÓW ONLINE"
|
||||
},
|
||||
"footer": {
|
||||
"disclaimer": "Ta strona ma charakter informacyjny. Autor nie ponosi odpowiedzialności za tworzenie pociągów niezgodnych z {tos}!",
|
||||
"tos": "regulaminem symulatora Train Driver 2",
|
||||
"tos-href": "https://docs.google.com/document/d/1UAAPUtN0d_RoS4RgOzEzllJZJhA0VcizzCzKW4QylbY/edit",
|
||||
"version-check": "Strona jest kompletna dla wersji {version} symulatora TD2"
|
||||
},
|
||||
"inputs": {
|
||||
"title": "WYBIERZ POJAZD SZYNOWY",
|
||||
"input-vehicle": "Wybierz pojazd trakcyjny",
|
||||
"input-carwagon": "Wybierz wagon",
|
||||
"cargo-title": "Ładunek (tylko wybrane towarowe)",
|
||||
"no-cargo-available": "brak dostępnych ładunków",
|
||||
"cargo-empty": "próżny",
|
||||
"loco-e": "ELEKTR.",
|
||||
"loco-s": "SPAL.",
|
||||
"loco-ezt": "EZT",
|
||||
"loco-szt": "SZT",
|
||||
"car-passenger": "PASAŻERSKIE",
|
||||
"car-cargo": "TOWAROWE",
|
||||
"action-add": "DODAJ NOWY",
|
||||
"action-swap": "ZAMIEŃ ZA",
|
||||
"real-stock": "REALNE ZESTAWIENIA"
|
||||
},
|
||||
"preview": {
|
||||
"title": "PODGLĄD WYBRANEGO POJAZDU",
|
||||
"loading": "ŁADOWANIE OBRAZU...",
|
||||
"desc": "Wybierz pojazd lub wagon, aby zobaczyć jego podgląd powyżej",
|
||||
"sponsor-only": "* TYLKO DLA SPONSORÓW",
|
||||
"loco-e": "ELEKTROWÓZ",
|
||||
"loco-s": "SPALINOWÓZ",
|
||||
"loco-ezt": "EZT",
|
||||
"loco-szt": "SZT",
|
||||
"car-passenger": "WAGON PASAŻERSKI",
|
||||
"car-cargo": "WAGON TOWAROWY",
|
||||
"cabin": "Typ kabiny:",
|
||||
"construction": "Typ konstrukcji:"
|
||||
},
|
||||
"topbar": {
|
||||
"stock-list": "SKŁAD",
|
||||
"wiki-list": "POJAZDY",
|
||||
"number-generator": "GNR NUMERU",
|
||||
"stock-generator": "GNR SKŁADU"
|
||||
},
|
||||
"stocklist": {
|
||||
"title": "EDYTOR SKŁADU",
|
||||
"alert-copied": "Skład został skopiowany do twojego schowka!",
|
||||
"alert-empty": "Lista pojazdów jest pusta!",
|
||||
"prompt-file": "Nazwij plik, a następnie pobierz do folderu Presets (Dokumenty/TTSK/TrainDriver2):",
|
||||
"vehicle-no": "POJAZD NR",
|
||||
"no-vehicle-chosen": "NIE WYBRANO POJAZDU",
|
||||
"action-move-up": "PRZENIEŚ WYŻEJ",
|
||||
"action-move-down": "PRZENIEŚ NIŻEJ",
|
||||
"action-remove": "USUŃ",
|
||||
"action-upload": "WCZYTAJ",
|
||||
"action-download": "POBIERZ",
|
||||
"action-copy": "SKOPIUJ",
|
||||
"action-reset": "ZRESETUJ",
|
||||
"action-shuffle": "PRZETASUJ",
|
||||
"mass": "Masa",
|
||||
"mass-accepted": "dopuszczalna",
|
||||
"length": "Długość",
|
||||
"vmax": "vMax",
|
||||
"coldstart-info": "Zimny start lokomotywy czołowej (tylko elektrowozy typów 303E i 203E)",
|
||||
"list-empty": "Lista pojazdów jest pusta!",
|
||||
"warning-not-suitable": "Lokomotywy EP07 i EP08 są przeznaczone jedynie do ruchu pasażerskiego!",
|
||||
"warning-passenger-too-long": "Maksymalna długość składów pasażerskich nie może przekraczać 350m!",
|
||||
"warning-freight-too-long": "Maksymalna długość składów innych niż pasażerskie nie może przekraczać 650m!",
|
||||
"warning-too-many-locos": "Ten skład posiada za dużo pojazdów trakcyjnych!",
|
||||
"warning-too-heavy": "Ten skład jest za ciężki! Sprawdź {href}",
|
||||
"acceptable-mass-docs": "dopuszczalne masy składów"
|
||||
},
|
||||
"stockgen": {
|
||||
"title": "GENERATOR SKŁADU TOWAROWEGO",
|
||||
"properties-title": "WŁAŚCIWOŚCI SKŁADU",
|
||||
"properties-desc": "⇐ Dodaj lokomotywę na pierwsze miejsce listy, aby uwzględnić ją przy losowaniu składu!",
|
||||
"input-mass": "Maksymalna masa (t)",
|
||||
"input-length": "Maks. długość (m)",
|
||||
"input-carcount": "Maks. liczba wagonów",
|
||||
"cargo-title": "ŁADUNEK",
|
||||
"cargo-desc": "Wybierz ładunki, którymi chcesz wypełnić dostępne wagony:",
|
||||
"chosen-title": "WAGONY Z WYBRANYMI ŁADUNKAMI",
|
||||
"chosen-empty-warning": "Wybierz co najmniej jeden ładunek, aby zobaczyć wagony, które go posiadają!",
|
||||
"chosen-warning": "Wagony posiadające wybrane ładunki. Najedź na nazwę, aby zobaczyć podgląd wagonu. Kliknij, aby wyłączyć z losowania (tylko podświetlone nazwy będą uwzględnione).",
|
||||
"action-generate": "WYGENERUJ",
|
||||
"action-generate-empty": "WYGENERUJ PRÓŻNE WAGONY",
|
||||
"action-reset": "ZRESETUJ ŁADUNKI"
|
||||
},
|
||||
"numgen": {
|
||||
"title": "GENERATOR NUMERU POCIĄGU",
|
||||
"alert": "Numer został skopiowany do twojego schowka!",
|
||||
"start-region": "Początkowy obszar konstrukcyjny",
|
||||
"end-region": "Końcowy obszar konstrukcyjny",
|
||||
"train-category": "Kategoria pociągu",
|
||||
"number-info": "Wygenerowany numer pociągu:",
|
||||
"warning": "Wybierz kategorię oraz (opcjonalnie) obszary konstrukcyjne",
|
||||
"td2-wiki": "> Szczegółowe zasady numeracji (wikipedia TD2)",
|
||||
"td2-wiki-link": "https://wiki.td2.info.pl/index.php?title=Zasady_numeracji_poci%C4%85g%C3%B3w",
|
||||
"action-random-region": "LOSUJ OBSZARY",
|
||||
"action-random-number": "LOSUJ NUMER",
|
||||
"categories": {
|
||||
"EI": "ekspres krajowy (EI)",
|
||||
"MP/RP": "(między)wojewódzki pośpieszny (MP/RP)",
|
||||
"RO": "wojewódzki osobowy (RO)",
|
||||
"PW": "próżny \"służbowy\" (PW)",
|
||||
"TM": "towarowy do przewozów masowych (TM)",
|
||||
"TK": "towarowy do obsługi stacji (TK)",
|
||||
"LT": "lokomotywa luzem (LT)"
|
||||
},
|
||||
"rules": {
|
||||
"EI": "4 cyfry - końcówka z przedziału 00-99",
|
||||
"MP/RP": "5 cyfr - końcówka z przedziału 050-169",
|
||||
"RO": "5 cyfr - końcówka z przedziału 200-999",
|
||||
"PW": "6 cyfr - '6' na 3. miejscu; końcówka z przedziału 000-899",
|
||||
"TM": "6 cyfr - '4' na 3. miejscu; końcówka z przedziału 000-899",
|
||||
"TK": "6 cyfr - '3' na 3. miejscu; końcówka z przedziału 000-899",
|
||||
"LT": "6 cyfr - '5' na 3. miejscu; końcówka z przedziału 000-899"
|
||||
}
|
||||
},
|
||||
"wiki": {
|
||||
"title": "LISTA DOSTĘPNYCH POJAZDÓW",
|
||||
"action-vehicles": "POJ. TRAKCYJNE",
|
||||
"action-carriages": "WAGONY",
|
||||
"search": "Wyszukaj pojazd...",
|
||||
"header": {
|
||||
"image": "Zdjęcie",
|
||||
"type": "Nazwa",
|
||||
"power": "Rodzaj",
|
||||
"constructionType": "Konstrukcja",
|
||||
"coldStart": "Zimny start",
|
||||
"length": "Długość",
|
||||
"mass": "Masa",
|
||||
"maxSpeed": "Prędkość",
|
||||
"cargoCount": "Ładunki"
|
||||
},
|
||||
"loco-ezt": "EZT",
|
||||
"loco-szt": "SZT",
|
||||
"loco-s": "Spalinowóz",
|
||||
"loco-e": "Elektrowóz"
|
||||
},
|
||||
"realstock": {
|
||||
"title": "ZESTAWIENIA REALNE by",
|
||||
"search-name": "Szukaj po nazwie",
|
||||
"search-stock": "Szukaj po pojazdach",
|
||||
"action-reset": "RESETUJ"
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,12 @@ import { createPinia } from 'pinia';
|
||||
import { registerSW } from 'virtual:pwa-register';
|
||||
|
||||
import App from './App.vue';
|
||||
|
||||
import i18n from './i18n-setup';
|
||||
const pinia = createPinia();
|
||||
|
||||
const updateSW = registerSW({
|
||||
registerSW({
|
||||
immediate: true,
|
||||
});
|
||||
|
||||
createApp(App).use(pinia).mount('#app');
|
||||
createApp(App).use(pinia).use(i18n).mount('#app');
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@ export default defineComponent({
|
||||
count,
|
||||
imgSrc: vehicle.imageSrc,
|
||||
useType: isLoco ? vehicle.power : vehicle.useType,
|
||||
supportersOnly: false,
|
||||
supportersOnly: vehicle.supportersOnly,
|
||||
constructionType: vehicle.constructionType,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -43,13 +44,6 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
addLocomotive(loco: ILocomotive) {
|
||||
// const previousStock =
|
||||
// this.store.stockList.length > 0 ? this.store.stockList[this.store.stockList.length - 1] : null;
|
||||
// if (previousStock && previousStock.type == loco.type) {
|
||||
// this.store.stockList[this.store.stockList.length - 1].count++;
|
||||
// return;
|
||||
// }
|
||||
|
||||
const stockObj = this.getStockObject(loco);
|
||||
|
||||
if (this.store.stockList.length > 0 && !this.store.stockList[0].isLoco) this.store.stockList.unshift(stockObj);
|
||||
@@ -57,15 +51,6 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
addCarWagon(car: ICarWagon, cargo?: ICargo) {
|
||||
// const previousStock =
|
||||
// this.store.stockList.length > 0 ? this.store.stockList[this.store.stockList.length - 1] : null;
|
||||
|
||||
// if (previousStock && previousStock.type == car.type && previousStock.cargo?.id == cargo?.id) {
|
||||
// this.store.stockList[this.store.stockList.length - 1].count++;
|
||||
|
||||
// return;
|
||||
// }
|
||||
|
||||
const stockObj = this.getStockObject(car, cargo);
|
||||
|
||||
this.store.stockList.push(stockObj);
|
||||
@@ -83,13 +68,15 @@ export default defineComponent({
|
||||
|
||||
this.store.swapVehicles = false;
|
||||
|
||||
stockArray.forEach((type) => {
|
||||
stockArray.forEach((type, i) => {
|
||||
let vehicle: Vehicle | null = null;
|
||||
let vehicleCargo: ICargo | null = null;
|
||||
|
||||
if (/^(EU|EP|ET|SM|EN|2EN|SN)/.test(type)) {
|
||||
const [locoType, coldStart] = type.split(',');
|
||||
vehicle = this.store.locoDataList.find((loco) => loco.type == locoType) || null;
|
||||
|
||||
if (i == 0 && coldStart == 'c') this.store.isColdStart = true;
|
||||
} else {
|
||||
const [carType, cargo] = type.split(':');
|
||||
vehicle = this.store.carDataList.find((car) => car.type == carType) || null;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { defineComponent } from 'vue';
|
||||
import { useStore } from '../store';
|
||||
import { IStock, Vehicle } from '../types';
|
||||
import { ICarWagon, ILocomotive, IStock, Vehicle } from '../types';
|
||||
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
@@ -48,7 +48,7 @@ export default defineComponent({
|
||||
});
|
||||
},
|
||||
|
||||
previewStock(stock: IStock) {
|
||||
previewStock(stock: IStock) {
|
||||
if (this.store.chosenVehicle?.imageSrc != stock.imgSrc) this.store.imageLoading = true;
|
||||
|
||||
if (stock.isLoco) {
|
||||
@@ -67,14 +67,26 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
|
||||
previewLocomotive(loco: ILocomotive) {
|
||||
this.store.chosenLoco = loco;
|
||||
this.store.chosenVehicle = loco;
|
||||
this.store.chosenLocoPower = loco.power;
|
||||
},
|
||||
|
||||
previewCarWagon(carWagon: ICarWagon) {
|
||||
this.store.chosenCar = carWagon;
|
||||
this.store.chosenCarUseType = carWagon.useType;
|
||||
this.store.chosenVehicle = carWagon;
|
||||
|
||||
this.store.chosenCargo = null;
|
||||
},
|
||||
|
||||
resetPreview() {
|
||||
this.store.chosenVehicle = null;
|
||||
this.store.chosenCar = null;
|
||||
this.store.chosenCargo = null;
|
||||
this.store.chosenLoco = null;
|
||||
}
|
||||
this.store.chosenVehicle = null;
|
||||
this.store.chosenCar = null;
|
||||
this.store.chosenCargo = null;
|
||||
this.store.chosenLoco = null;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ export default defineComponent({
|
||||
!this.store.isTrainPassenger &&
|
||||
this.store.stockList.length > 1 &&
|
||||
!this.store.stockList.every((stock) => stock.isLoco) &&
|
||||
this.store.stockList.find((stock) => stock.isLoco && stock.type.startsWith('EP'))
|
||||
this.store.stockList.some((stock) => stock.isLoco && stock.type.startsWith('EP'))
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ export const useStore = defineStore({
|
||||
chosenCargo: null,
|
||||
chosenVehicle: null,
|
||||
|
||||
isColdStart: false,
|
||||
|
||||
showSupporter: false,
|
||||
imageLoading: false,
|
||||
|
||||
@@ -29,7 +31,7 @@ export const useStore = defineStore({
|
||||
stockList: [],
|
||||
cargoOptions: [],
|
||||
|
||||
readyStockList: {},
|
||||
readyStockList: [],
|
||||
|
||||
swapVehicles: false,
|
||||
|
||||
@@ -56,5 +58,29 @@ export const useStore = defineStore({
|
||||
chosenRealStock: (state) => chosenRealStock(state),
|
||||
acceptableMass: (state) => acceptableMass(state),
|
||||
},
|
||||
|
||||
actions: {
|
||||
async fetchStockInfoData() {
|
||||
const stockData = await (await fetch(`https://spythere.github.io/api/td2/data/stockInfo.json`)).json();
|
||||
this.stockData = stockData;
|
||||
},
|
||||
|
||||
handleRouting() {
|
||||
switch (window.location.pathname) {
|
||||
case '/numgnr':
|
||||
this.stockSectionMode = 'number-generator';
|
||||
break;
|
||||
case '/stockgnr':
|
||||
this.stockSectionMode = 'stock-generator';
|
||||
break;
|
||||
case '/vehicles':
|
||||
this.stockSectionMode = 'wiki-list';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
|
||||
transition: color 250ms;
|
||||
|
||||
&:visited {
|
||||
color: white;
|
||||
}
|
||||
@@ -119,6 +121,18 @@ button {
|
||||
background-color: #2b2b2b;
|
||||
}
|
||||
|
||||
&--image {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.5em;
|
||||
|
||||
img {
|
||||
width: 1.3em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
&--text {
|
||||
font-weight: bold;
|
||||
transition: all 250ms;
|
||||
@@ -132,9 +146,10 @@ button {
|
||||
}
|
||||
|
||||
select,
|
||||
input {
|
||||
input[type='text'],
|
||||
input[type='number'] {
|
||||
background: none;
|
||||
border: 2px solid white;
|
||||
border: 2px solid #aaa;
|
||||
outline: none;
|
||||
|
||||
padding: 0.25em 0.35em;
|
||||
@@ -154,8 +169,9 @@ input {
|
||||
}
|
||||
|
||||
option {
|
||||
color: black;
|
||||
color: white;
|
||||
border: none;
|
||||
background-color: $bgColor;
|
||||
}
|
||||
|
||||
ul {
|
||||
@@ -176,7 +192,7 @@ ul {
|
||||
|
||||
.g-card {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
top: 1em;
|
||||
left: 0;
|
||||
|
||||
width: 100vw;
|
||||
@@ -184,7 +200,6 @@ ul {
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
z-index: 200;
|
||||
|
||||
|
||||
@@ -5,9 +5,10 @@ export interface IStore {
|
||||
chosenCar: ICarWagon | null;
|
||||
chosenLoco: ILocomotive | null;
|
||||
chosenCargo: ICargo | null;
|
||||
|
||||
chosenVehicle: Vehicle | null;
|
||||
|
||||
isColdStart: boolean;
|
||||
|
||||
showSupporter: boolean;
|
||||
imageLoading: boolean;
|
||||
|
||||
@@ -15,7 +16,7 @@ export interface IStore {
|
||||
chosenCarUseType: string;
|
||||
|
||||
stockList: IStock[];
|
||||
readyStockList: IReadyStockList;
|
||||
readyStockList: IReadyStockItem[];
|
||||
cargoOptions: any[][];
|
||||
|
||||
chosenStockListIndex: number;
|
||||
@@ -27,7 +28,7 @@ export interface IStore {
|
||||
isRandomizerCardOpen: boolean;
|
||||
isRealStockListCardOpen: boolean;
|
||||
|
||||
stockSectionMode: 'stock-list' | 'stock-generator' | 'number-generator';
|
||||
stockSectionMode: 'stock-list' | 'stock-generator' | 'number-generator' | 'wiki-list';
|
||||
stockData?: IStockData;
|
||||
}
|
||||
|
||||
@@ -41,8 +42,10 @@ export interface IStockProps {
|
||||
}
|
||||
|
||||
export interface IStockData {
|
||||
version: string;
|
||||
|
||||
generator: {
|
||||
passenger: [];
|
||||
passenger: any;
|
||||
cargo: {
|
||||
[key: string]: string[];
|
||||
};
|
||||
@@ -97,8 +100,9 @@ export interface ICargo {
|
||||
|
||||
export interface IStock {
|
||||
id: string;
|
||||
useType: string;
|
||||
type: string;
|
||||
useType: string;
|
||||
constructionType: string;
|
||||
length: number;
|
||||
mass: number;
|
||||
maxSpeed: number;
|
||||
@@ -109,11 +113,11 @@ export interface IStock {
|
||||
imgSrc?: string;
|
||||
}
|
||||
|
||||
export interface IReadyStockList {
|
||||
[key: string]: { stockString: string; type: string; number: string; name: string };
|
||||
export interface IReadyStockItem {
|
||||
stockId: string;
|
||||
stockString: string;
|
||||
type: string;
|
||||
number: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
const supportedConstructions = ['303e', '203e'];
|
||||
|
||||
export function locoSupportsColdStart(constructionType: string) {
|
||||
return new RegExp(`(${supportedConstructions.join('|')})`).test(constructionType);
|
||||
}
|
||||
@@ -152,13 +152,9 @@ export function chosenRealStock(state: IStore) {
|
||||
}, [] as string[])
|
||||
.join(';');
|
||||
|
||||
const realStockObj = Object.values(state.readyStockList).find(
|
||||
(readyStock) => readyStock.stockString == currentStockString
|
||||
);
|
||||
const realStockObj = state.readyStockList.find((readyStock) => readyStock.stockString == currentStockString);
|
||||
|
||||
state.chosenRealStockName = realStockObj
|
||||
? `${realStockObj.type} ${realStockObj.number} ${realStockObj.name}`
|
||||
: undefined;
|
||||
state.chosenRealStockName = realStockObj?.stockId ?? undefined;
|
||||
|
||||
return realStockObj;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<MainContainer />
|
||||
<Footer />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { useStore } from '../store';
|
||||
|
||||
import MainContainer from '../components/app/MainContainer.vue';
|
||||
import Footer from '../components/app/Footer.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
MainContainer,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
store: useStore(),
|
||||
}),
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-container {
|
||||
min-height: 100vh;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
@@ -5,33 +5,36 @@ import { VitePWA } from 'vite-plugin-pwa';
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
server: {
|
||||
port: 2137,
|
||||
},
|
||||
plugins: [
|
||||
vue(),
|
||||
VitePWA({
|
||||
registerType: 'autoUpdate',
|
||||
|
||||
workbox: {
|
||||
globPatterns: ['**/*.{js,css,html,png,svg,img}'],
|
||||
// runtimeCaching: [
|
||||
// {
|
||||
// urlPattern: new RegExp(`^https://spythere.github.io/api\/.*`),
|
||||
// handler: 'NetworkFirst',
|
||||
// options: {
|
||||
// cacheName: 'github-api-cache',
|
||||
// expiration: {
|
||||
// maxEntries: 2,
|
||||
// maxAgeSeconds: 60 * 60 * 24 * 7, // <== 7 days
|
||||
// },
|
||||
// cacheableResponse: {
|
||||
// statuses: [0, 200],
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
},
|
||||
devOptions: {
|
||||
enabled: true,
|
||||
// globPatterns: ['**/*.{js,css,html,png,svg,img}'],
|
||||
|
||||
runtimeCaching: [
|
||||
{
|
||||
urlPattern: /^https:\/\/rj.td2.info.pl\/dist\/img\/thumbnails\/.*/i,
|
||||
handler: 'CacheFirst',
|
||||
options: {
|
||||
cacheName: 'swdr-images-cache',
|
||||
expiration: {
|
||||
maxEntries: 50,
|
||||
maxAgeSeconds: 60 * 60 * 24 * 7, // <== 7 days
|
||||
},
|
||||
cacheableResponse: {
|
||||
statuses: [404],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz"
|
||||
integrity sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==
|
||||
|
||||
"@babel/core@^7.11.1":
|
||||
"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.1", "@babel/core@^7.12.0", "@babel/core@^7.13.0", "@babel/core@^7.4.0-0":
|
||||
version "7.20.2"
|
||||
resolved "https://registry.npmjs.org/@babel/core/-/core-7.20.2.tgz"
|
||||
integrity sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==
|
||||
@@ -909,15 +909,48 @@
|
||||
"@babel/helper-validator-identifier" "^7.19.1"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@esbuild/android-arm@0.15.13":
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.13.tgz#ce11237a13ee76d5eae3908e47ba4ddd380af86a"
|
||||
integrity sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==
|
||||
"@esbuild/win32-x64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz"
|
||||
integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==
|
||||
|
||||
"@esbuild/linux-loong64@0.15.13":
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.13.tgz#64e8825bf0ce769dac94ee39d92ebe6272020dfc"
|
||||
integrity sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==
|
||||
"@intlify/core-base@9.2.2":
|
||||
version "9.2.2"
|
||||
resolved "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.2.2.tgz"
|
||||
integrity sha512-JjUpQtNfn+joMbrXvpR4hTF8iJQ2sEFzzK3KIESOx+f+uwIjgw20igOyaIdhfsVVBCds8ZM64MoeNSx+PHQMkA==
|
||||
dependencies:
|
||||
"@intlify/devtools-if" "9.2.2"
|
||||
"@intlify/message-compiler" "9.2.2"
|
||||
"@intlify/shared" "9.2.2"
|
||||
"@intlify/vue-devtools" "9.2.2"
|
||||
|
||||
"@intlify/devtools-if@9.2.2":
|
||||
version "9.2.2"
|
||||
resolved "https://registry.npmjs.org/@intlify/devtools-if/-/devtools-if-9.2.2.tgz"
|
||||
integrity sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg==
|
||||
dependencies:
|
||||
"@intlify/shared" "9.2.2"
|
||||
|
||||
"@intlify/message-compiler@9.2.2":
|
||||
version "9.2.2"
|
||||
resolved "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.2.2.tgz"
|
||||
integrity sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA==
|
||||
dependencies:
|
||||
"@intlify/shared" "9.2.2"
|
||||
source-map "0.6.1"
|
||||
|
||||
"@intlify/shared@9.2.2":
|
||||
version "9.2.2"
|
||||
resolved "https://registry.npmjs.org/@intlify/shared/-/shared-9.2.2.tgz"
|
||||
integrity sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==
|
||||
|
||||
"@intlify/vue-devtools@9.2.2":
|
||||
version "9.2.2"
|
||||
resolved "https://registry.npmjs.org/@intlify/vue-devtools/-/vue-devtools-9.2.2.tgz"
|
||||
integrity sha512-+dUyqyCHWHb/UcvY1MlIpO87munedm3Gn6E9WWYdWrMuYLcoIoOEVDWSS8xSwtlPU+kA+MEQTP6Q1iI/ocusJg==
|
||||
dependencies:
|
||||
"@intlify/core-base" "9.2.2"
|
||||
"@intlify/shared" "9.2.2"
|
||||
|
||||
"@jridgewell/gen-mapping@^0.1.0":
|
||||
version "0.1.1"
|
||||
@@ -954,7 +987,7 @@
|
||||
"@jridgewell/gen-mapping" "^0.3.0"
|
||||
"@jridgewell/trace-mapping" "^0.3.9"
|
||||
|
||||
"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10":
|
||||
"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@1.4.14":
|
||||
version "1.4.14"
|
||||
resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz"
|
||||
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
|
||||
@@ -975,7 +1008,7 @@
|
||||
"@nodelib/fs.stat" "2.0.5"
|
||||
run-parallel "^1.1.9"
|
||||
|
||||
"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
|
||||
"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5":
|
||||
version "2.0.5"
|
||||
resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
|
||||
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
|
||||
@@ -1016,13 +1049,13 @@
|
||||
"@rollup/pluginutils" "^3.1.0"
|
||||
magic-string "^0.25.7"
|
||||
|
||||
"@rollup/plugin-replace@^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-4.0.0.tgz"
|
||||
integrity sha512-+rumQFiaNac9y64OHtkHGmdjm7us9bo1PlbgQfdihQtuNxzjpaB064HbRnewUOggLQxVCCyINfStkgmBeQpv1g==
|
||||
"@rollup/plugin-replace@^5.0.1":
|
||||
version "5.0.2"
|
||||
resolved "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.2.tgz"
|
||||
integrity sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==
|
||||
dependencies:
|
||||
"@rollup/pluginutils" "^3.1.0"
|
||||
magic-string "^0.25.7"
|
||||
"@rollup/pluginutils" "^5.0.1"
|
||||
magic-string "^0.27.0"
|
||||
|
||||
"@rollup/pluginutils@^3.1.0":
|
||||
version "3.1.0"
|
||||
@@ -1033,6 +1066,15 @@
|
||||
estree-walker "^1.0.1"
|
||||
picomatch "^2.2.2"
|
||||
|
||||
"@rollup/pluginutils@^5.0.1":
|
||||
version "5.0.2"
|
||||
resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz"
|
||||
integrity sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==
|
||||
dependencies:
|
||||
"@types/estree" "^1.0.0"
|
||||
estree-walker "^2.0.2"
|
||||
picomatch "^2.3.1"
|
||||
|
||||
"@surma/rollup-plugin-off-main-thread@^2.2.3":
|
||||
version "2.2.3"
|
||||
resolved "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz"
|
||||
@@ -1043,12 +1085,17 @@
|
||||
magic-string "^0.25.0"
|
||||
string.prototype.matchall "^4.0.6"
|
||||
|
||||
"@types/estree@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz"
|
||||
integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==
|
||||
|
||||
"@types/estree@0.0.39":
|
||||
version "0.0.39"
|
||||
resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz"
|
||||
integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
|
||||
|
||||
"@types/node@*":
|
||||
"@types/node@*", "@types/node@>= 14":
|
||||
version "18.11.9"
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz"
|
||||
integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==
|
||||
@@ -1065,55 +1112,54 @@
|
||||
resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz"
|
||||
integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==
|
||||
|
||||
"@vitejs/plugin-vue@^3.2.0":
|
||||
version "3.2.0"
|
||||
resolved "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-3.2.0.tgz"
|
||||
integrity sha512-E0tnaL4fr+qkdCNxJ+Xd0yM31UwMkQje76fsDVBBUCoGOUPexu2VDUYHL8P4CwV+zMvWw6nlRw19OnRKmYAJpw==
|
||||
"@vitejs/plugin-vue@^4.1.0":
|
||||
version "4.1.0"
|
||||
resolved "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.1.0.tgz"
|
||||
integrity sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==
|
||||
|
||||
"@volar/language-core@1.0.9":
|
||||
version "1.0.9"
|
||||
resolved "https://registry.npmjs.org/@volar/language-core/-/language-core-1.0.9.tgz"
|
||||
integrity sha512-5Fty3slLet6svXiJw2YxhYeo6c7wFdtILrql5bZymYLM+HbiZtJbryW1YnUEKAP7MO9Mbeh+TNH4Z0HFxHgIqw==
|
||||
"@volar/language-core@1.3.0-alpha.0":
|
||||
version "1.3.0-alpha.0"
|
||||
resolved "https://registry.npmjs.org/@volar/language-core/-/language-core-1.3.0-alpha.0.tgz"
|
||||
integrity sha512-W3uMzecHPcbwddPu4SJpUcPakRBK/y/BP+U0U6NiPpUX1tONLC4yCawt+QBJqtgJ+sfD6ztf5PyvPL3hQRqfOA==
|
||||
dependencies:
|
||||
"@volar/source-map" "1.0.9"
|
||||
"@vue/reactivity" "^3.2.40"
|
||||
muggle-string "^0.1.0"
|
||||
"@volar/source-map" "1.3.0-alpha.0"
|
||||
|
||||
"@volar/source-map@1.0.9":
|
||||
version "1.0.9"
|
||||
resolved "https://registry.npmjs.org/@volar/source-map/-/source-map-1.0.9.tgz"
|
||||
integrity sha512-fazB/vy5ZEJ3yKx4fabJyGNI3CBkdLkfEIRVu6+1P3VixK0Mn+eqyUIkLBrzGYaeFM3GybhCLCvsVdNz0Fu/CQ==
|
||||
"@volar/source-map@1.3.0-alpha.0":
|
||||
version "1.3.0-alpha.0"
|
||||
resolved "https://registry.npmjs.org/@volar/source-map/-/source-map-1.3.0-alpha.0.tgz"
|
||||
integrity sha512-jSdizxWFvDTvkPYZnO6ew3sBZUnS0abKCbuopkc0JrIlFbznWC/fPH3iPFIMS8/IIkRxq1Jh9VVG60SmtsdaMQ==
|
||||
dependencies:
|
||||
muggle-string "^0.1.0"
|
||||
muggle-string "^0.2.2"
|
||||
|
||||
"@volar/typescript@1.0.9":
|
||||
version "1.0.9"
|
||||
resolved "https://registry.npmjs.org/@volar/typescript/-/typescript-1.0.9.tgz"
|
||||
integrity sha512-dVziu+ShQUWuMukM6bvK2v2O446/gG6l1XkTh2vfkccw1IzjfbiP1TWQoNo1ipTfZOtu5YJGYAx+o5HNrGXWfQ==
|
||||
"@volar/typescript@1.3.0-alpha.0":
|
||||
version "1.3.0-alpha.0"
|
||||
resolved "https://registry.npmjs.org/@volar/typescript/-/typescript-1.3.0-alpha.0.tgz"
|
||||
integrity sha512-5UItyW2cdH2mBLu4RrECRNJRgtvvzKrSCn2y3v/D61QwIDkGx4aeil6x8RFuUL5TFtV6QvVHXnsOHxNgd+sCow==
|
||||
dependencies:
|
||||
"@volar/language-core" "1.0.9"
|
||||
"@volar/language-core" "1.3.0-alpha.0"
|
||||
|
||||
"@volar/vue-language-core@1.0.9":
|
||||
version "1.0.9"
|
||||
resolved "https://registry.npmjs.org/@volar/vue-language-core/-/vue-language-core-1.0.9.tgz"
|
||||
integrity sha512-tofNoR8ShPFenHT1YVMuvoXtXWwoQE+fiXVqSmW0dSKZqEDjWQ3YeXSd0a6aqyKaIbvR7kWWGp34WbpQlwf9Ww==
|
||||
"@volar/vue-language-core@1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/@volar/vue-language-core/-/vue-language-core-1.2.0.tgz"
|
||||
integrity sha512-w7yEiaITh2WzKe6u8ZdeLKCUz43wdmY/OqAmsB/PGDvvhTcVhCJ6f0W/RprZL1IhqH8wALoWiwEh/Wer7ZviMQ==
|
||||
dependencies:
|
||||
"@volar/language-core" "1.0.9"
|
||||
"@volar/source-map" "1.0.9"
|
||||
"@vue/compiler-dom" "^3.2.40"
|
||||
"@vue/compiler-sfc" "^3.2.40"
|
||||
"@vue/reactivity" "^3.2.40"
|
||||
"@vue/shared" "^3.2.40"
|
||||
minimatch "^5.1.0"
|
||||
vue-template-compiler "^2.7.10"
|
||||
"@volar/language-core" "1.3.0-alpha.0"
|
||||
"@volar/source-map" "1.3.0-alpha.0"
|
||||
"@vue/compiler-dom" "^3.2.47"
|
||||
"@vue/compiler-sfc" "^3.2.47"
|
||||
"@vue/reactivity" "^3.2.47"
|
||||
"@vue/shared" "^3.2.47"
|
||||
minimatch "^6.1.6"
|
||||
muggle-string "^0.2.2"
|
||||
vue-template-compiler "^2.7.14"
|
||||
|
||||
"@volar/vue-typescript@1.0.9":
|
||||
version "1.0.9"
|
||||
resolved "https://registry.npmjs.org/@volar/vue-typescript/-/vue-typescript-1.0.9.tgz"
|
||||
integrity sha512-ZLe4y9YNbviACa7uAMCilzxA76gbbSlKfjspXBzk6fCobd8QCIig+VyDYcjANIlm2HhgSCX8jYTzhCKlegh4mw==
|
||||
"@volar/vue-typescript@1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/@volar/vue-typescript/-/vue-typescript-1.2.0.tgz"
|
||||
integrity sha512-zjmRi9y3J1EkG+pfuHp8IbHmibihrKK485cfzsHjiuvJMGrpkWvlO5WVEk8oslMxxeGC5XwBFE9AOlvh378EPA==
|
||||
dependencies:
|
||||
"@volar/typescript" "1.0.9"
|
||||
"@volar/vue-language-core" "1.0.9"
|
||||
"@volar/typescript" "1.3.0-alpha.0"
|
||||
"@volar/vue-language-core" "1.2.0"
|
||||
|
||||
"@vue/compiler-core@3.2.37":
|
||||
version "3.2.37"
|
||||
@@ -1125,16 +1171,24 @@
|
||||
estree-walker "^2.0.2"
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@vue/compiler-core@3.2.41":
|
||||
version "3.2.41"
|
||||
resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.41.tgz"
|
||||
integrity sha512-oA4mH6SA78DT+96/nsi4p9DX97PHcNROxs51lYk7gb9Z4BPKQ3Mh+BLn6CQZBw857Iuhu28BfMSRHAlPvD4vlw==
|
||||
"@vue/compiler-core@3.2.47":
|
||||
version "3.2.47"
|
||||
resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz"
|
||||
integrity sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.16.4"
|
||||
"@vue/shared" "3.2.41"
|
||||
"@vue/shared" "3.2.47"
|
||||
estree-walker "^2.0.2"
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@vue/compiler-dom@^3.2.47", "@vue/compiler-dom@3.2.47":
|
||||
version "3.2.47"
|
||||
resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz"
|
||||
integrity sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==
|
||||
dependencies:
|
||||
"@vue/compiler-core" "3.2.47"
|
||||
"@vue/shared" "3.2.47"
|
||||
|
||||
"@vue/compiler-dom@3.2.37":
|
||||
version "3.2.37"
|
||||
resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz"
|
||||
@@ -1143,13 +1197,21 @@
|
||||
"@vue/compiler-core" "3.2.37"
|
||||
"@vue/shared" "3.2.37"
|
||||
|
||||
"@vue/compiler-dom@3.2.41", "@vue/compiler-dom@^3.2.40":
|
||||
version "3.2.41"
|
||||
resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.41.tgz"
|
||||
integrity sha512-xe5TbbIsonjENxJsYRbDJvthzqxLNk+tb3d/c47zgREDa/PCp6/Y4gC/skM4H6PIuX5DAxm7fFJdbjjUH2QTMw==
|
||||
"@vue/compiler-sfc@^3.2.47":
|
||||
version "3.2.47"
|
||||
resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz"
|
||||
integrity sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==
|
||||
dependencies:
|
||||
"@vue/compiler-core" "3.2.41"
|
||||
"@vue/shared" "3.2.41"
|
||||
"@babel/parser" "^7.16.4"
|
||||
"@vue/compiler-core" "3.2.47"
|
||||
"@vue/compiler-dom" "3.2.47"
|
||||
"@vue/compiler-ssr" "3.2.47"
|
||||
"@vue/reactivity-transform" "3.2.47"
|
||||
"@vue/shared" "3.2.47"
|
||||
estree-walker "^2.0.2"
|
||||
magic-string "^0.25.7"
|
||||
postcss "^8.1.10"
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@vue/compiler-sfc@3.2.37":
|
||||
version "3.2.37"
|
||||
@@ -1167,22 +1229,6 @@
|
||||
postcss "^8.1.10"
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@vue/compiler-sfc@^3.2.40":
|
||||
version "3.2.41"
|
||||
resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.41.tgz"
|
||||
integrity sha512-+1P2m5kxOeaxVmJNXnBskAn3BenbTmbxBxWOtBq3mQTCokIreuMULFantBUclP0+KnzNCMOvcnKinqQZmiOF8w==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.16.4"
|
||||
"@vue/compiler-core" "3.2.41"
|
||||
"@vue/compiler-dom" "3.2.41"
|
||||
"@vue/compiler-ssr" "3.2.41"
|
||||
"@vue/reactivity-transform" "3.2.41"
|
||||
"@vue/shared" "3.2.41"
|
||||
estree-walker "^2.0.2"
|
||||
magic-string "^0.25.7"
|
||||
postcss "^8.1.10"
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@vue/compiler-ssr@3.2.37":
|
||||
version "3.2.37"
|
||||
resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz"
|
||||
@@ -1191,13 +1237,13 @@
|
||||
"@vue/compiler-dom" "3.2.37"
|
||||
"@vue/shared" "3.2.37"
|
||||
|
||||
"@vue/compiler-ssr@3.2.41":
|
||||
version "3.2.41"
|
||||
resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.41.tgz"
|
||||
integrity sha512-Y5wPiNIiaMz/sps8+DmhaKfDm1xgj6GrH99z4gq2LQenfVQcYXmHIOBcs5qPwl7jaW3SUQWjkAPKMfQemEQZwQ==
|
||||
"@vue/compiler-ssr@3.2.47":
|
||||
version "3.2.47"
|
||||
resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz"
|
||||
integrity sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==
|
||||
dependencies:
|
||||
"@vue/compiler-dom" "3.2.41"
|
||||
"@vue/shared" "3.2.41"
|
||||
"@vue/compiler-dom" "3.2.47"
|
||||
"@vue/shared" "3.2.47"
|
||||
|
||||
"@vue/devtools-api@^6.2.1":
|
||||
version "6.2.1"
|
||||
@@ -1215,17 +1261,24 @@
|
||||
estree-walker "^2.0.2"
|
||||
magic-string "^0.25.7"
|
||||
|
||||
"@vue/reactivity-transform@3.2.41":
|
||||
version "3.2.41"
|
||||
resolved "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.41.tgz"
|
||||
integrity sha512-mK5+BNMsL4hHi+IR3Ft/ho6Za+L3FA5j8WvreJ7XzHrqkPq8jtF/SMo7tuc9gHjLDwKZX1nP1JQOKo9IEAn54A==
|
||||
"@vue/reactivity-transform@3.2.47":
|
||||
version "3.2.47"
|
||||
resolved "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz"
|
||||
integrity sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.16.4"
|
||||
"@vue/compiler-core" "3.2.41"
|
||||
"@vue/shared" "3.2.41"
|
||||
"@vue/compiler-core" "3.2.47"
|
||||
"@vue/shared" "3.2.47"
|
||||
estree-walker "^2.0.2"
|
||||
magic-string "^0.25.7"
|
||||
|
||||
"@vue/reactivity@^3.2.47":
|
||||
version "3.2.47"
|
||||
resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.47.tgz"
|
||||
integrity sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==
|
||||
dependencies:
|
||||
"@vue/shared" "3.2.47"
|
||||
|
||||
"@vue/reactivity@3.2.37":
|
||||
version "3.2.37"
|
||||
resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.37.tgz"
|
||||
@@ -1233,13 +1286,6 @@
|
||||
dependencies:
|
||||
"@vue/shared" "3.2.37"
|
||||
|
||||
"@vue/reactivity@^3.2.40":
|
||||
version "3.2.41"
|
||||
resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.41.tgz"
|
||||
integrity sha512-9JvCnlj8uc5xRiQGZ28MKGjuCoPhhTwcoAdv3o31+cfGgonwdPNuvqAXLhlzu4zwqavFEG5tvaoINQEfxz+l6g==
|
||||
dependencies:
|
||||
"@vue/shared" "3.2.41"
|
||||
|
||||
"@vue/runtime-core@3.2.37":
|
||||
version "3.2.37"
|
||||
resolved "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.37.tgz"
|
||||
@@ -1265,22 +1311,22 @@
|
||||
"@vue/compiler-ssr" "3.2.37"
|
||||
"@vue/shared" "3.2.37"
|
||||
|
||||
"@vue/shared@^3.2.47", "@vue/shared@3.2.47":
|
||||
version "3.2.47"
|
||||
resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz"
|
||||
integrity sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==
|
||||
|
||||
"@vue/shared@3.2.37":
|
||||
version "3.2.37"
|
||||
resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.2.37.tgz"
|
||||
integrity sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==
|
||||
|
||||
"@vue/shared@3.2.41", "@vue/shared@^3.2.40":
|
||||
version "3.2.41"
|
||||
resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.2.41.tgz"
|
||||
integrity sha512-W9mfWLHmJhkfAmV+7gDjcHeAWALQtgGT3JErxULl0oz6R6+3ug91I7IErs93eCFhPCZPHBs4QJS7YWEV7A3sxw==
|
||||
|
||||
acorn@^8.5.0:
|
||||
version "8.8.1"
|
||||
resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz"
|
||||
integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==
|
||||
|
||||
ajv@^8.6.0:
|
||||
ajv@^8.6.0, ajv@>=8:
|
||||
version "8.11.0"
|
||||
resolved "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz"
|
||||
integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==
|
||||
@@ -1317,11 +1363,25 @@ async@^3.2.3:
|
||||
resolved "https://registry.npmjs.org/async/-/async-3.2.4.tgz"
|
||||
integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz"
|
||||
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
|
||||
|
||||
at-least-node@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz"
|
||||
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
|
||||
|
||||
axios@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz"
|
||||
integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==
|
||||
dependencies:
|
||||
follow-redirects "^1.15.0"
|
||||
form-data "^4.0.0"
|
||||
proxy-from-env "^1.1.0"
|
||||
|
||||
babel-plugin-polyfill-corejs2@^0.3.3:
|
||||
version "0.3.3"
|
||||
resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz"
|
||||
@@ -1378,7 +1438,7 @@ braces@^3.0.2, braces@~3.0.2:
|
||||
dependencies:
|
||||
fill-range "^7.0.1"
|
||||
|
||||
browserslist@^4.21.3, browserslist@^4.21.4:
|
||||
browserslist@^4.21.3, browserslist@^4.21.4, "browserslist@>= 4.21.0":
|
||||
version "4.21.4"
|
||||
resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz"
|
||||
integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==
|
||||
@@ -1457,15 +1517,22 @@ color-convert@^2.0.1:
|
||||
dependencies:
|
||||
color-name "~1.1.4"
|
||||
|
||||
color-name@~1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
color-name@1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
|
||||
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
|
||||
|
||||
color-name@~1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
combined-stream@^1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz"
|
||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
commander@^2.20.0:
|
||||
version "2.20.3"
|
||||
@@ -1529,6 +1596,11 @@ define-properties@^1.1.3, define-properties@^1.1.4:
|
||||
has-property-descriptors "^1.0.0"
|
||||
object-keys "^1.1.1"
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
|
||||
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
|
||||
|
||||
ejs@^3.1.6:
|
||||
version "3.1.8"
|
||||
resolved "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz"
|
||||
@@ -1580,133 +1652,33 @@ es-to-primitive@^1.2.1:
|
||||
is-date-object "^1.0.1"
|
||||
is-symbol "^1.0.2"
|
||||
|
||||
esbuild-android-64@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.15.13.tgz#5f25864055dbd62e250f360b38b4c382224063af"
|
||||
integrity sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==
|
||||
|
||||
esbuild-android-arm64@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.13.tgz#d8820f999314efbe8e0f050653a99ff2da632b0f"
|
||||
integrity sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==
|
||||
|
||||
esbuild-darwin-64@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.13.tgz#99ae7fdaa43947b06cd9d1a1c3c2c9f245d81fd0"
|
||||
integrity sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==
|
||||
|
||||
esbuild-darwin-arm64@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.13.tgz#bafa1814354ad1a47adcad73de416130ef7f55e3"
|
||||
integrity sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==
|
||||
|
||||
esbuild-freebsd-64@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.13.tgz#84ef85535c5cc38b627d1c5115623b088d1de161"
|
||||
integrity sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==
|
||||
|
||||
esbuild-freebsd-arm64@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.13.tgz#033f21de434ec8e0c478054b119af8056763c2d8"
|
||||
integrity sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==
|
||||
|
||||
esbuild-linux-32@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.15.13.tgz#54290ea8035cba0faf1791ce9ae6693005512535"
|
||||
integrity sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==
|
||||
|
||||
esbuild-linux-64@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.13.tgz"
|
||||
integrity sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==
|
||||
|
||||
esbuild-linux-arm64@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.13.tgz#9323c333924f97a02bdd2ae8912b36298acb312d"
|
||||
integrity sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==
|
||||
|
||||
esbuild-linux-arm@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.13.tgz#b407f47b3ae721fe4e00e19e9f19289bef87a111"
|
||||
integrity sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==
|
||||
|
||||
esbuild-linux-mips64le@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.13.tgz#bdf905aae5c0bcaa8f83567fe4c4c1bdc1f14447"
|
||||
integrity sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==
|
||||
|
||||
esbuild-linux-ppc64le@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.13.tgz#2911eae1c90ff58a3bd3259cb557235df25aa3b4"
|
||||
integrity sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==
|
||||
|
||||
esbuild-linux-riscv64@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.13.tgz#1837c660be12b1d20d2a29c7189ea703f93e9265"
|
||||
integrity sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==
|
||||
|
||||
esbuild-linux-s390x@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.13.tgz#d52880ece229d1bd10b2d936b792914ffb07c7fc"
|
||||
integrity sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==
|
||||
|
||||
esbuild-netbsd-64@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.13.tgz#de14da46f1d20352b43e15d97a80a8788275e6ed"
|
||||
integrity sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==
|
||||
|
||||
esbuild-openbsd-64@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.13.tgz#45e8a5fd74d92ad8f732c43582369c7990f5a0ac"
|
||||
integrity sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==
|
||||
|
||||
esbuild-sunos-64@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.13.tgz#f646ac3da7aac521ee0fdbc192750c87da697806"
|
||||
integrity sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==
|
||||
|
||||
esbuild-windows-32@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.15.13.tgz#fb4fe77c7591418880b3c9b5900adc4c094f2401"
|
||||
integrity sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==
|
||||
|
||||
esbuild-windows-64@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.15.13.tgz#1fca8c654392c0c31bdaaed168becfea80e20660"
|
||||
integrity sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==
|
||||
|
||||
esbuild-windows-arm64@0.15.13:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.13.tgz#4ffd01b6b2888603f1584a2fe96b1f6a6f2b3dd8"
|
||||
integrity sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==
|
||||
|
||||
esbuild@^0.15.9:
|
||||
version "0.15.13"
|
||||
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.15.13.tgz"
|
||||
integrity sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==
|
||||
esbuild@^0.18.10:
|
||||
version "0.18.20"
|
||||
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz"
|
||||
integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==
|
||||
optionalDependencies:
|
||||
"@esbuild/android-arm" "0.15.13"
|
||||
"@esbuild/linux-loong64" "0.15.13"
|
||||
esbuild-android-64 "0.15.13"
|
||||
esbuild-android-arm64 "0.15.13"
|
||||
esbuild-darwin-64 "0.15.13"
|
||||
esbuild-darwin-arm64 "0.15.13"
|
||||
esbuild-freebsd-64 "0.15.13"
|
||||
esbuild-freebsd-arm64 "0.15.13"
|
||||
esbuild-linux-32 "0.15.13"
|
||||
esbuild-linux-64 "0.15.13"
|
||||
esbuild-linux-arm "0.15.13"
|
||||
esbuild-linux-arm64 "0.15.13"
|
||||
esbuild-linux-mips64le "0.15.13"
|
||||
esbuild-linux-ppc64le "0.15.13"
|
||||
esbuild-linux-riscv64 "0.15.13"
|
||||
esbuild-linux-s390x "0.15.13"
|
||||
esbuild-netbsd-64 "0.15.13"
|
||||
esbuild-openbsd-64 "0.15.13"
|
||||
esbuild-sunos-64 "0.15.13"
|
||||
esbuild-windows-32 "0.15.13"
|
||||
esbuild-windows-64 "0.15.13"
|
||||
esbuild-windows-arm64 "0.15.13"
|
||||
"@esbuild/android-arm" "0.18.20"
|
||||
"@esbuild/android-arm64" "0.18.20"
|
||||
"@esbuild/android-x64" "0.18.20"
|
||||
"@esbuild/darwin-arm64" "0.18.20"
|
||||
"@esbuild/darwin-x64" "0.18.20"
|
||||
"@esbuild/freebsd-arm64" "0.18.20"
|
||||
"@esbuild/freebsd-x64" "0.18.20"
|
||||
"@esbuild/linux-arm" "0.18.20"
|
||||
"@esbuild/linux-arm64" "0.18.20"
|
||||
"@esbuild/linux-ia32" "0.18.20"
|
||||
"@esbuild/linux-loong64" "0.18.20"
|
||||
"@esbuild/linux-mips64el" "0.18.20"
|
||||
"@esbuild/linux-ppc64" "0.18.20"
|
||||
"@esbuild/linux-riscv64" "0.18.20"
|
||||
"@esbuild/linux-s390x" "0.18.20"
|
||||
"@esbuild/linux-x64" "0.18.20"
|
||||
"@esbuild/netbsd-x64" "0.18.20"
|
||||
"@esbuild/openbsd-x64" "0.18.20"
|
||||
"@esbuild/sunos-x64" "0.18.20"
|
||||
"@esbuild/win32-arm64" "0.18.20"
|
||||
"@esbuild/win32-ia32" "0.18.20"
|
||||
"@esbuild/win32-x64" "0.18.20"
|
||||
|
||||
escalade@^3.1.1:
|
||||
version "3.1.1"
|
||||
@@ -1738,7 +1710,7 @@ fast-deep-equal@^3.1.1:
|
||||
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
|
||||
fast-glob@^3.2.11:
|
||||
fast-glob@^3.2.12:
|
||||
version "3.2.12"
|
||||
resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz"
|
||||
integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==
|
||||
@@ -1775,6 +1747,20 @@ fill-range@^7.0.1:
|
||||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
follow-redirects@^1.15.0:
|
||||
version "1.15.2"
|
||||
resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz"
|
||||
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
|
||||
|
||||
form-data@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz"
|
||||
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.8"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
fs-extra@^9.0.1:
|
||||
version "9.1.0"
|
||||
resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz"
|
||||
@@ -1790,11 +1776,6 @@ fs.realpath@^1.0.0:
|
||||
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
|
||||
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
|
||||
|
||||
fsevents@~2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
||||
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
||||
|
||||
function-bind@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz"
|
||||
@@ -2120,9 +2101,9 @@ json-schema@^0.4.0:
|
||||
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
|
||||
|
||||
json5@^2.2.0, json5@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz"
|
||||
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
|
||||
version "2.2.3"
|
||||
resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz"
|
||||
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
|
||||
|
||||
jsonfile@^6.0.1:
|
||||
version "6.1.0"
|
||||
@@ -2165,6 +2146,13 @@ magic-string@^0.25.0, magic-string@^0.25.7:
|
||||
dependencies:
|
||||
sourcemap-codec "^1.4.8"
|
||||
|
||||
magic-string@^0.27.0:
|
||||
version "0.27.0"
|
||||
resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz"
|
||||
integrity sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==
|
||||
dependencies:
|
||||
"@jridgewell/sourcemap-codec" "^1.4.13"
|
||||
|
||||
merge-stream@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz"
|
||||
@@ -2183,6 +2171,18 @@ micromatch@^4.0.4:
|
||||
braces "^3.0.2"
|
||||
picomatch "^2.3.1"
|
||||
|
||||
mime-db@1.52.0:
|
||||
version "1.52.0"
|
||||
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz"
|
||||
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
|
||||
|
||||
mime-types@^2.1.12:
|
||||
version "2.1.35"
|
||||
resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz"
|
||||
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
|
||||
dependencies:
|
||||
mime-db "1.52.0"
|
||||
|
||||
minimatch@^3.0.4, minimatch@^3.1.1:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
|
||||
@@ -2190,27 +2190,34 @@ minimatch@^3.0.4, minimatch@^3.1.1:
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimatch@^5.0.1, minimatch@^5.1.0:
|
||||
minimatch@^5.0.1:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz"
|
||||
integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==
|
||||
dependencies:
|
||||
brace-expansion "^2.0.1"
|
||||
|
||||
minimatch@^6.1.6:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.npmjs.org/minimatch/-/minimatch-6.2.0.tgz"
|
||||
integrity sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==
|
||||
dependencies:
|
||||
brace-expansion "^2.0.1"
|
||||
|
||||
ms@2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
muggle-string@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.npmjs.org/muggle-string/-/muggle-string-0.1.0.tgz"
|
||||
integrity sha512-Tr1knR3d2mKvvWthlk7202rywKbiOm4rVFLsfAaSIhJ6dt9o47W4S+JMtWhd/PW9Wrdew2/S2fSvhz3E2gkfEg==
|
||||
muggle-string@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.npmjs.org/muggle-string/-/muggle-string-0.2.2.tgz"
|
||||
integrity sha512-YVE1mIJ4VpUMqZObFndk9CJu6DBJR/GB13p3tXuNbwD4XExaI5EOuRl6BHeIDxIqXZVxSfAC+y6U1Z/IxCfKUg==
|
||||
|
||||
nanoid@^3.3.4:
|
||||
version "3.3.4"
|
||||
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz"
|
||||
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
|
||||
nanoid@^3.3.6:
|
||||
version "3.3.6"
|
||||
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz"
|
||||
integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
|
||||
|
||||
node-releases@^2.0.6:
|
||||
version "2.0.6"
|
||||
@@ -2277,12 +2284,12 @@ pinia@^2.0.17:
|
||||
"@vue/devtools-api" "^6.2.1"
|
||||
vue-demi "*"
|
||||
|
||||
postcss@^8.1.10, postcss@^8.4.18:
|
||||
version "8.4.18"
|
||||
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz"
|
||||
integrity sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==
|
||||
postcss@^8.1.10, postcss@^8.4.27:
|
||||
version "8.4.28"
|
||||
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.28.tgz"
|
||||
integrity sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw==
|
||||
dependencies:
|
||||
nanoid "^3.3.4"
|
||||
nanoid "^3.3.6"
|
||||
picocolors "^1.0.0"
|
||||
source-map-js "^1.0.2"
|
||||
|
||||
@@ -2296,6 +2303,11 @@ pretty-bytes@^6.0.0:
|
||||
resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.0.0.tgz"
|
||||
integrity sha512-6UqkYefdogmzqAZWzJ7laYeJnaXDy2/J+ZqiiMtS7t7OfpXWTlaeGMwX8U6EFvPV/YWWEKRkS8hKS4k60WHTOg==
|
||||
|
||||
proxy-from-env@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz"
|
||||
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
|
||||
|
||||
punycode@^2.1.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz"
|
||||
@@ -2382,7 +2394,7 @@ require-from-string@^2.0.2:
|
||||
resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz"
|
||||
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
||||
|
||||
resolve@^1.14.2, resolve@^1.19.0, resolve@^1.22.1:
|
||||
resolve@^1.14.2, resolve@^1.19.0:
|
||||
version "1.22.1"
|
||||
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz"
|
||||
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
|
||||
@@ -2406,13 +2418,27 @@ rollup-plugin-terser@^7.0.0:
|
||||
serialize-javascript "^4.0.0"
|
||||
terser "^5.0.0"
|
||||
|
||||
rollup@^2.43.1, rollup@^2.79.0, rollup@^2.79.1:
|
||||
"rollup@^1.20.0 || ^2.0.0", rollup@^1.20.0||^2.0.0, rollup@^2.0.0, rollup@^2.43.1:
|
||||
version "2.79.1"
|
||||
resolved "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz"
|
||||
integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
rollup@^1.20.0||^2.0.0||^3.0.0, rollup@^3.7.2:
|
||||
version "3.20.2"
|
||||
resolved "https://registry.npmjs.org/rollup/-/rollup-3.20.2.tgz"
|
||||
integrity sha512-3zwkBQl7Ai7MFYQE0y1MeQ15+9jsi7XxfrqwTb/9EK8D9C9+//EBR4M+CuA1KODRaNbFez/lWxA5vhEGZp4MUg==
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
rollup@^3.27.1:
|
||||
version "3.28.0"
|
||||
resolved "https://registry.npmjs.org/rollup/-/rollup-3.28.0.tgz"
|
||||
integrity sha512-d7zhvo1OUY2SXSM6pfNjgD5+d0Nz87CUp4mt8l/GgVP3oBsPwzNvSzyu1me6BSG9JIgWNTVcafIXBIyM8yQ3yw==
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
run-parallel@^1.1.9:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz"
|
||||
@@ -2434,19 +2460,19 @@ safe-regex-test@^1.0.0:
|
||||
get-intrinsic "^1.1.3"
|
||||
is-regex "^1.1.4"
|
||||
|
||||
sass@^1.55.0:
|
||||
version "1.56.0"
|
||||
resolved "https://registry.npmjs.org/sass/-/sass-1.56.0.tgz"
|
||||
integrity sha512-WFJ9XrpkcnqZcYuLRJh5qiV6ibQOR4AezleeEjTjMsCocYW59dEG19U3fwTTXxzi2Ed3yjPBp727hbbj53pHFw==
|
||||
sass@*, sass@^1.59.3:
|
||||
version "1.61.0"
|
||||
resolved "https://registry.npmjs.org/sass/-/sass-1.61.0.tgz"
|
||||
integrity sha512-PDsN7BrVkNZK2+dj/dpKQAWZavbAQ87IXqVvw2+oEYI+GwlTWkvbQtL7F2cCNbMqJEYKPh1EcjSxsnqIb/kyaQ==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
immutable "^4.0.0"
|
||||
source-map-js ">=0.6.2 <2.0.0"
|
||||
|
||||
semver@^6.1.1, semver@^6.1.2, semver@^6.3.0:
|
||||
version "6.3.0"
|
||||
resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz"
|
||||
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
||||
version "6.3.1"
|
||||
resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
|
||||
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
|
||||
|
||||
serialize-javascript@^4.0.0:
|
||||
version "4.0.0"
|
||||
@@ -2464,7 +2490,7 @@ side-channel@^1.0.4:
|
||||
get-intrinsic "^1.0.2"
|
||||
object-inspect "^1.9.0"
|
||||
|
||||
"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2:
|
||||
source-map-js@^1.0.2, "source-map-js@>=0.6.2 <2.0.0":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz"
|
||||
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
||||
@@ -2477,7 +2503,7 @@ source-map-support@~0.5.20:
|
||||
buffer-from "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
source-map@^0.6.0, source-map@^0.6.1:
|
||||
source-map@^0.6.0, source-map@^0.6.1, source-map@0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
@@ -2574,7 +2600,7 @@ tempy@^0.6.0:
|
||||
type-fest "^0.16.0"
|
||||
unique-string "^2.0.0"
|
||||
|
||||
terser@^5.0.0:
|
||||
terser@^5.0.0, terser@^5.4.0:
|
||||
version "5.15.1"
|
||||
resolved "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz"
|
||||
integrity sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==
|
||||
@@ -2608,10 +2634,10 @@ type-fest@^0.16.0:
|
||||
resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz"
|
||||
integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==
|
||||
|
||||
typescript@^4.8.4:
|
||||
version "4.8.4"
|
||||
resolved "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz"
|
||||
integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==
|
||||
typescript@*, typescript@^5.0.2, typescript@>=4.4.4:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.npmjs.org/typescript/-/typescript-5.0.3.tgz"
|
||||
integrity sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==
|
||||
|
||||
unbox-primitive@^1.0.2:
|
||||
version "1.0.2"
|
||||
@@ -2678,28 +2704,27 @@ uri-js@^4.2.2:
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
vite-plugin-pwa@^0.13.3:
|
||||
version "0.13.3"
|
||||
resolved "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.13.3.tgz"
|
||||
integrity sha512-cjWXpZ7slAY14OKz7M8XdgTIi9wjf6OD6NkhiMAc+ogxnbUrecUwLdRtfGPCPsN2ftut5gaN1jTghb11p6IQAA==
|
||||
vite-plugin-pwa@^0.14.6:
|
||||
version "0.14.7"
|
||||
resolved "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.14.7.tgz"
|
||||
integrity sha512-dNJaf0fYOWncmjxv9HiSa2xrSjipjff7IkYE5oIUJ2x5HKu3cXgA8LRgzOwTc5MhwyFYRSU0xyN0Phbx3NsQYw==
|
||||
dependencies:
|
||||
"@rollup/plugin-replace" "^4.0.0"
|
||||
"@rollup/plugin-replace" "^5.0.1"
|
||||
debug "^4.3.4"
|
||||
fast-glob "^3.2.11"
|
||||
fast-glob "^3.2.12"
|
||||
pretty-bytes "^6.0.0"
|
||||
rollup "^2.79.0"
|
||||
rollup "^3.7.2"
|
||||
workbox-build "^6.5.4"
|
||||
workbox-window "^6.5.4"
|
||||
|
||||
vite@^3.2.1:
|
||||
version "3.2.3"
|
||||
resolved "https://registry.npmjs.org/vite/-/vite-3.2.3.tgz"
|
||||
integrity sha512-h8jl1TZ76eGs3o2dIBSsvXDLb1m/Ec1iej8ZMdz+PsaFUsftZeWe2CZOI3qogEsMNaywc17gu0q6cQDzh/weCQ==
|
||||
"vite@^3.1.0 || ^4.0.0", vite@^4.0.0, vite@^4.2.1:
|
||||
version "4.4.9"
|
||||
resolved "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz"
|
||||
integrity sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==
|
||||
dependencies:
|
||||
esbuild "^0.15.9"
|
||||
postcss "^8.4.18"
|
||||
resolve "^1.22.1"
|
||||
rollup "^2.79.1"
|
||||
esbuild "^0.18.10"
|
||||
postcss "^8.4.27"
|
||||
rollup "^3.27.1"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
@@ -2708,23 +2733,33 @@ vue-demi@*:
|
||||
resolved "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.5.tgz"
|
||||
integrity sha512-tO3K2bML3AwiHmVHeKCq6HLef2st4zBXIV5aEkoJl6HZ+gJWxWv2O8wLH8qrA3SX3lDoTDHNghLX1xZg83MXvw==
|
||||
|
||||
vue-template-compiler@^2.7.10:
|
||||
version "2.7.13"
|
||||
resolved "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.13.tgz"
|
||||
integrity sha512-jYM6TClwDS9YqP48gYrtAtaOhRKkbYmbzE+Q51gX5YDr777n7tNI/IZk4QV4l/PjQPNh/FVa/E92sh/RqKMrog==
|
||||
vue-i18n@9:
|
||||
version "9.2.2"
|
||||
resolved "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.2.2.tgz"
|
||||
integrity sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==
|
||||
dependencies:
|
||||
"@intlify/core-base" "9.2.2"
|
||||
"@intlify/shared" "9.2.2"
|
||||
"@intlify/vue-devtools" "9.2.2"
|
||||
"@vue/devtools-api" "^6.2.1"
|
||||
|
||||
vue-template-compiler@^2.7.14:
|
||||
version "2.7.14"
|
||||
resolved "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz"
|
||||
integrity sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==
|
||||
dependencies:
|
||||
de-indent "^1.0.2"
|
||||
he "^1.2.0"
|
||||
|
||||
vue-tsc@^1.0.9:
|
||||
version "1.0.9"
|
||||
resolved "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.0.9.tgz"
|
||||
integrity sha512-vRmHD1K6DmBymNhoHjQy/aYKTRQNLGOu2/ESasChG9Vy113K6CdP0NlhR0bzgFJfv2eFB9Ez/9L5kIciUajBxQ==
|
||||
vue-tsc@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.2.0.tgz"
|
||||
integrity sha512-rIlzqdrhyPYyLG9zxsVRa+JEseeS9s8F2BbVVVWRRsTZvJO2BbhLEb2HW3MY+DFma0378tnIqs+vfTzbcQtRFw==
|
||||
dependencies:
|
||||
"@volar/vue-language-core" "1.0.9"
|
||||
"@volar/vue-typescript" "1.0.9"
|
||||
"@volar/vue-language-core" "1.2.0"
|
||||
"@volar/vue-typescript" "1.2.0"
|
||||
|
||||
vue@^3.2.37:
|
||||
"vue@^2.6.14 || ^3.2.0", vue@^3.0.0, "vue@^3.0.0-0 || ^2.6.0", vue@^3.2.25, vue@^3.2.37, vue@3.2.37:
|
||||
version "3.2.37"
|
||||
resolved "https://registry.npmjs.org/vue/-/vue-3.2.37.tgz"
|
||||
integrity sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ==
|
||||
@@ -2910,7 +2945,7 @@ workbox-sw@6.5.4:
|
||||
resolved "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.5.4.tgz"
|
||||
integrity sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA==
|
||||
|
||||
workbox-window@6.5.4, workbox-window@^6.5.4:
|
||||
workbox-window@^6.5.4, workbox-window@6.5.4:
|
||||
version "6.5.4"
|
||||
resolved "https://registry.npmjs.org/workbox-window/-/workbox-window-6.5.4.tgz"
|
||||
integrity sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug==
|
||||
|
||||