Migracja store'a

This commit is contained in:
2022-07-25 23:00:05 +02:00
parent c46ddc8b0b
commit bea95f9cf3
12 changed files with 430 additions and 447 deletions
+3 -4
View File
@@ -8,15 +8,14 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"pinia": "^2.0.17",
"vue": "^3.2.37" "vue": "^3.2.37"
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^3.0.0", "@vitejs/plugin-vue": "^3.0.0",
"sass": "^1.26.5",
"typescript": "^4.6.4", "typescript": "^4.6.4",
"vite": "^3.0.0", "vite": "^3.0.0",
"vue-tsc": "^0.38.4", "vue-tsc": "^0.38.4"
"sass": "^1.26.5"
} }
} }
+2 -1
View File
@@ -32,6 +32,7 @@ import InputsSection from './components/InputsSection.vue';
import ListSection from './components/ListSection.vue'; import ListSection from './components/ListSection.vue';
import logoImage from './assets/logo.svg'; import logoImage from './assets/logo.svg';
import { useStore } from './store';
export default defineComponent({ export default defineComponent({
components: { components: {
@@ -46,7 +47,7 @@ export default defineComponent({
}), }),
setup() { setup() {
const store = inject('Store') as IStore; const store = useStore();
return { return {
store, store,
+17 -23
View File
@@ -38,8 +38,10 @@
import { defineComponent, inject, provide, ref } from 'vue'; import { defineComponent, inject, provide, ref } from 'vue';
import ReadyStockList from './ReadyStockList.vue'; import ReadyStockList from './ReadyStockList.vue';
import { IStore, ILocomotive, ICarWagon } from '../types'; import { IStore, ILocomotive, ICarWagon, IStock } from '../types';
import imageMixin from '../mixins/imageMixin'; import imageMixin from '../mixins/imageMixin';
import { useStore } from '../store';
import { isLocomotive } from '../utils/vehicleUtils';
export default defineComponent({ export default defineComponent({
components: { components: {
@@ -54,7 +56,7 @@ export default defineComponent({
}), }),
setup() { setup() {
const store = inject('Store') as IStore; const store = useStore();
const isReadyStockListOpen = ref(false); const isReadyStockListOpen = ref(false);
@@ -63,14 +65,6 @@ export default defineComponent({
return { return {
store, store,
isReadyStockListOpen, isReadyStockListOpen,
locoDataList: inject('locoDataList') as ILocomotive[],
carDataList: inject('carDataList') as ICarWagon[],
isTrainPassenger: inject('isTrainPassenger') as boolean,
totalLength: inject('totalLength') as number,
totalMass: inject('totalMass') as number,
maxStockSpeed: inject('maxStockSpeed') as number,
maxAllowedSpeed: inject('maxAllowedSpeed') as number,
isLocomotive: inject('isLocomotive') as (vehicle: ILocomotive | ICarWagon) => vehicle is ILocomotive,
}; };
}, },
@@ -95,11 +89,13 @@ export default defineComponent({
computed: { computed: {
locoOptions() { locoOptions() {
return this.locoDataList.sort((a, b) => (a.type > b.type ? 1 : -1)).sort((a) => (a.supportersOnly ? 1 : -1)); return this.store.locoDataList
.sort((a, b) => (a.type > b.type ? 1 : -1))
.sort((a) => (a.supportersOnly ? 1 : -1));
}, },
carOptions() { carOptions() {
return this.carDataList.sort((a, b) => (a.type > b.type ? 1 : -1)).sort((a) => (a.supportersOnly ? 1 : -1)); return this.store.carDataList.sort((a, b) => (a.type > b.type ? 1 : -1)).sort((a) => (a.supportersOnly ? 1 : -1));
}, },
}, },
@@ -117,32 +113,30 @@ export default defineComponent({
if (!vehicle) return; if (!vehicle) return;
const stockObj = { const stockObj: IStock = {
useType: isLocomotive(vehicle) ? vehicle.power : vehicle.useType,
type: vehicle.type, type: vehicle.type,
length: vehicle.length, length: vehicle.length,
mass: vehicle.mass, mass: vehicle.mass,
maxSpeed: vehicle.maxSpeed, maxSpeed: vehicle.maxSpeed,
isLoco: this.isLocomotive(vehicle), isLoco: isLocomotive(vehicle),
cargo: cargo:
!this.isLocomotive(vehicle) && vehicle.loadable && this.store.chosenCargo !isLocomotive(vehicle) && vehicle.loadable && this.store.chosenCargo ? this.store.chosenCargo : undefined,
? this.store.chosenCargo
: undefined,
count: 1, count: 1,
imgSrc: vehicle.imageSrc, imgSrc: vehicle.imageSrc,
useType: this.isLocomotive(vehicle) ? vehicle.power : vehicle.useType,
supportersOnly: vehicle.supportersOnly, supportersOnly: vehicle.supportersOnly,
}; };
if (this.store.chosenStockListIndex != -1) { if (this.store.chosenStockListIndex != -1) {
let currentStock = this.store.stockList[this.store.chosenStockListIndex]; let currentStock = this.store.stockList[this.store.chosenStockListIndex];
if (this.isLocomotive(vehicle) && currentStock && currentStock.type == vehicle.type) { if (isLocomotive(vehicle) && currentStock && currentStock.type == vehicle.type) {
this.store.stockList[this.store.chosenStockListIndex].count++; this.store.stockList[this.store.chosenStockListIndex].count++;
return; return;
} }
if ( if (
!this.isLocomotive(vehicle) && !isLocomotive(vehicle) &&
currentStock && currentStock &&
currentStock.type == vehicle.type && currentStock.type == vehicle.type &&
currentStock.cargo?.id == this.store.chosenCargo?.id currentStock.cargo?.id == this.store.chosenCargo?.id
@@ -159,13 +153,13 @@ export default defineComponent({
const previousStock = const previousStock =
this.store.stockList.length > 0 ? this.store.stockList[this.store.stockList.length - 1] : null; this.store.stockList.length > 0 ? this.store.stockList[this.store.stockList.length - 1] : null;
if (this.isLocomotive(vehicle) && previousStock && previousStock.type == vehicle.type) { if (isLocomotive(vehicle) && previousStock && previousStock.type == vehicle.type) {
this.store.stockList[this.store.stockList.length - 1].count++; this.store.stockList[this.store.stockList.length - 1].count++;
return; return;
} }
if ( if (
!this.isLocomotive(vehicle) && !isLocomotive(vehicle) &&
previousStock && previousStock &&
previousStock.type == vehicle.type && previousStock.type == vehicle.type &&
previousStock.cargo?.id == this.store.chosenCargo?.id previousStock.cargo?.id == this.store.chosenCargo?.id
@@ -175,7 +169,7 @@ export default defineComponent({
return; return;
} }
if (this.isLocomotive(vehicle) && this.store.stockList.length > 0 && !this.store.stockList[0].isLoco) if (isLocomotive(vehicle) && this.store.stockList.length > 0 && !this.store.stockList[0].isLoco)
this.store.stockList.unshift(stockObj); this.store.stockList.unshift(stockObj);
else this.store.stockList.push(stockObj); else this.store.stockList.push(stockObj);
}, },
+20 -50
View File
@@ -1,6 +1,6 @@
<template> <template>
<div class="bottom"> <div class="bottom">
<div class="bg-dimmer" v-if="isRandomizerCardOpen"></div> <div class="bg-dimmer" v-if="store.isRandomizerCardOpen"></div>
<train-image /> <train-image />
@@ -12,18 +12,18 @@
<button class="btn" @click="resetStock">ZRESETUJ LISTĘ</button> <button class="btn" @click="resetStock">ZRESETUJ LISTĘ</button>
<span></span> <span></span>
<button class="btn" @click="shuffleCars">TASUJ WAGONY</button> <button class="btn" @click="shuffleCars">TASUJ WAGONY</button>
<button class="btn" @click="openRandomizerCard">LOSUJ SKŁAD</button> <button class="btn" @click="store.isRandomizerCardOpen = true">LOSUJ SKŁAD</button>
<transition name="card-anim"> <transition name="card-anim">
<randomizer-card v-if="isRandomizerCardOpen" /> <randomizer-card v-if="store.isRandomizerCardOpen" />
</transition> </transition>
</div> </div>
<div class="stock-list_specs"> <div class="stock-list_specs">
<div> <div>
Masa: <span class="text--accent">{{ totalMass }}t</span> | Długość: Masa: <span class="text--accent">{{ store.totalMass }}t</span> | Długość:
<span class="text--accent">{{ totalLength }}m</span> <span class="text--accent">{{ store.totalLength }}m</span>
| Vmax pociągu: <span class="text--accent">{{ maxStockSpeed }} km/h</span> | Vmax pociągu: <span class="text--accent">{{ store.maxStockSpeed }} km/h</span>
</div> </div>
<!-- <div v-if="store.chosenRealStockName" style="margin-top: 0.25rem"> <!-- <div v-if="store.chosenRealStockName" style="margin-top: 0.25rem">
@@ -37,7 +37,7 @@
</button> </button>
</div> </div>
<div class="warnings"> <!-- <div class="warnings">
<div class="warning" v-if="warnings.locoNotSuitable.value"> <div class="warning" v-if="warnings.locoNotSuitable.value">
Lokomotywy EP07 i EP08 przeznaczone jedynie do ruchu pasażerskiego! Lokomotywy EP07 i EP08 przeznaczone jedynie do ruchu pasażerskiego!
</div> </div>
@@ -57,7 +57,7 @@
</div> </div>
<div class="warning" v-if="warnings.tooManyLocos.value">Ten skład posiada za dużo pojazdów trakcyjnych!</div> <div class="warning" v-if="warnings.tooManyLocos.value">Ten skład posiada za dużo pojazdów trakcyjnych!</div>
</div> </div> -->
<ul ref="list" data-ignore-outside="1"> <ul ref="list" data-ignore-outside="1">
<li v-if="store.stockList.length == 0" class="list-empty"> <li v-if="store.stockList.length == 0" class="list-empty">
@@ -131,42 +131,16 @@ import subIcon from '../assets/sub-icon.svg';
import removeIcon from '../assets/remove-icon.svg'; import removeIcon from '../assets/remove-icon.svg';
import lowerIcon from '../assets/lower-icon.svg'; import lowerIcon from '../assets/lower-icon.svg';
import higherIcon from '../assets/higher-icon.svg'; import higherIcon from '../assets/higher-icon.svg';
import { useStore } from '../store';
export default defineComponent({ export default defineComponent({
components: { RandomizerCard, TrainImage }, components: { RandomizerCard, TrainImage },
setup() { setup() {
const store = inject('Store') as IStore; const store = useStore();
const isRandomizerCardOpen = ref(false);
provide('isCardOpen', isRandomizerCardOpen);
provide('chosenLength', ref(350));
provide('chosenMass', ref(1000));
provide('chosenLocoType', ref('loco-e'));
provide('chosenCarTypes', reactive([]));
provide('includeSupporterVehicles', ref(false));
return { return {
store, store,
locoDataList: inject('locoDataList') as ILocomotive[],
carDataList: inject('carDataList') as ICarWagon[],
isTrainPassenger: inject('isTrainPassenger') as boolean,
totalLength: inject('totalLength') as number,
totalMass: inject('totalMass') as number,
maxStockSpeed: inject('maxStockSpeed') as number,
maxAllowedSpeed: inject('maxAllowedSpeed') as number,
warnings: inject('warnings') as {
locoNotSuitable: ComputedRef<boolean>;
trainTooLong: ComputedRef<boolean>;
trainTooHeavy: ComputedRef<boolean>;
tooManyLocos: ComputedRef<boolean>;
},
isRandomizerCardOpen,
hasSupporterOnlyVehicle: computed(() => store.stockList.some((stock) => stock.supportersOnly)),
}; };
}, },
@@ -221,10 +195,10 @@ export default defineComponent({
methods: { methods: {
copyToClipboard() { copyToClipboard() {
if (Object.values(this.warnings).some((v) => v.value == true)) { // if (Object.values(this.warnings).some((v) => v.value == true)) {
alert('Jazda tym pociągiem jest niezgodna z regulaminem symulatora! Zmień parametry zestawienia!'); // alert('Jazda tym pociągiem jest niezgodna z regulaminem symulatora! Zmień parametry zestawienia!');
return; // return;
} // }
navigator.clipboard.writeText(this.stockString); navigator.clipboard.writeText(this.stockString);
@@ -247,7 +221,7 @@ export default defineComponent({
if (vehicle.isLoco) { if (vehicle.isLoco) {
this.store.chosenLocoPower = vehicle.useType; this.store.chosenLocoPower = vehicle.useType;
this.store.chosenLoco = this.locoDataList.find((v) => v.type == vehicle.type) || null; this.store.chosenLoco = this.store.locoDataList.find((v) => v.type == vehicle.type) || null;
this.store.chosenCar = null; this.store.chosenCar = null;
this.store.chosenCargo = null; this.store.chosenCargo = null;
@@ -255,7 +229,7 @@ export default defineComponent({
this.store.chosenCarUseType = vehicle.useType; this.store.chosenCarUseType = vehicle.useType;
this.store.chosenLoco = null; this.store.chosenLoco = null;
this.store.chosenCar = this.carDataList.find((v) => v.type == vehicle.type) || null; this.store.chosenCar = this.store.carDataList.find((v) => v.type == vehicle.type) || null;
this.store.chosenCargo = vehicle.cargo || null; this.store.chosenCargo = vehicle.cargo || null;
} }
@@ -333,15 +307,11 @@ export default defineComponent({
} }
}, },
openRandomizerCard() {
this.isRandomizerCardOpen = true;
},
downloadStock() { downloadStock() {
if (Object.values(this.warnings).some((v) => v.value == true)) { // if (Object.values(this.warnings).some((v) => v.value == true)) {
alert('Jazda tym pociągiem może być niezgodna z regulaminem symulatora! Zmień parametry zestawienia!'); // alert('Jazda tym pociągiem może być niezgodna z regulaminem symulatora! Zmień parametry zestawienia!');
return; // return;
} // }
const fileName = prompt('Nazwij plik:', 'pociag'); const fileName = prompt('Nazwij plik:', 'pociag');
+26 -33
View File
@@ -57,7 +57,7 @@
<p>Wybierz preferowaną długość składu (m) i (opcjonalnie) max. masę (t)</p> <p>Wybierz preferowaną długość składu (m) i (opcjonalnie) max. masę (t)</p>
<input <input
type="number" type="number"
v-model="chosenLength" v-model="randomStockLength"
name="length" name="length"
max="650" max="650"
min="20" min="20"
@@ -66,8 +66,8 @@
/> />
<input <input
type="number" type="number"
v-model="chosenMass" v-model="randomStockMass"
name="length" name="mass"
max="4000" max="4000"
min="100" min="100"
step="100" step="100"
@@ -82,34 +82,30 @@
</div> </div>
<button class="btn" style="font-size: 1.15em; margin-top: 2em" @click="randomize">LOSUJ SKŁAD!</button> <button class="btn" style="font-size: 1.15em; margin-top: 2em" @click="randomize">LOSUJ SKŁAD!</button>
<button class="btn" style="font-size: 1.15em; margin-top: 2em" @click="closeCard">ZAMKNIJ</button> <button class="btn" style="font-size: 1.15em; margin-top: 2em" @click="store.isRandomizerCardOpen = false">
ZAMKNIJ
</button>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { ComputedRef, defineComponent, inject } from 'vue'; import { defineComponent, inject } from 'vue';
import carUsage from '../data/carUsage.json'; import carUsage from '../data/carUsage.json';
import { IStore, ICarWagon, ILocomotive, ICargo } from '../types'; import { ICarWagon, ILocomotive, ICargo } from '../types';
import randomizeIcon from '../assets/randomize-icon.svg'; import randomizeIcon from '../assets/randomize-icon.svg';
import { useStore } from '../store';
export default defineComponent({ export default defineComponent({
setup() { setup() {
const isCardOpen = inject('isCardOpen') as boolean; const store = useStore();
const store = inject('Store') as IStore;
const carDataList = inject('carDataList') as ComputedRef<ICarWagon[]>;
return { return {
isCardOpen,
store, store,
locoDataList: inject('locoDataList') as ILocomotive[],
chosenLength: inject('chosenLength') as number, carTypeList: store.carDataList.reduce((list, car) => {
chosenMass: inject('chosenMass') as number,
carDataList,
carTypeList: carDataList.value.reduce((list, car) => {
const type = car.type.split('_')[0]; const type = car.type.split('_')[0];
if (list.includes(type)) return list; if (list.includes(type)) return list;
@@ -119,14 +115,15 @@ export default defineComponent({
return list; return list;
}, [] as string[]), }, [] as string[]),
chosenLocoType: inject('chosenLocoType') as string,
chosenCarTypes: inject('chosenCarTypes') as string[],
includeSupporterVehicles: inject('includeSupporterVehicles') as boolean, includeSupporterVehicles: inject('includeSupporterVehicles') as boolean,
}; };
}, },
data: () => ({ data: () => ({
randomStockMass: 1500,
randomStockLength: 650,
chosenCarTypes: [] as string[],
icons: { icons: {
randomize: randomizeIcon, randomize: randomizeIcon,
}, },
@@ -160,12 +157,8 @@ export default defineComponent({
}), }),
methods: { methods: {
closeCard() {
this.isCardOpen = false;
},
displayPreview(carType: string) { displayPreview(carType: string) {
const list = this.carDataList.filter((car) => car.type.includes(carType)); const list = this.store.carDataList.filter((car) => car.type.includes(carType));
const randIndex = Math.floor(Math.random() * list.length); const randIndex = Math.floor(Math.random() * list.length);
if (this.focusedCar?.type == list[randIndex].type) return; if (this.focusedCar?.type == list[randIndex].type) return;
@@ -188,17 +181,17 @@ export default defineComponent({
return; return;
} }
if (this.chosenLength <= 20) { if (this.randomStockLength <= 20) {
alert('Długość składu musi być większa niż 20m!'); alert('Długość składu musi być większa niż 20m!');
return; return;
} }
if (this.chosenMass <= 100) { if (this.randomStockMass <= 100) {
alert('Masa składu musi być większa niż 100t!'); alert('Masa składu musi być większa niż 100t!');
return; return;
} }
if (this.chosenLength > 650) { if (this.randomStockLength > 650) {
alert('Długość składu nie może przekraczać 650m dla pociągów towarowych!'); alert('Długość składu nie może przekraczać 650m dla pociągów towarowych!');
return; return;
} }
@@ -209,7 +202,7 @@ export default defineComponent({
if (this.store.stockList.length == 0 || !this.store.stockList[0].isLoco) { if (this.store.stockList.length == 0 || !this.store.stockList[0].isLoco) {
this.store.stockList.length = 0; this.store.stockList.length = 0;
let locoSet = this.locoDataList let locoSet = this.store.locoDataList
.filter((loco) => loco.power == 'loco-e' || loco.power == 'loco-s') .filter((loco) => loco.power == 'loco-e' || loco.power == 'loco-s')
.filter((loco) => (!this.includeSupporterVehicles && loco.supportersOnly ? false : true)); .filter((loco) => (!this.includeSupporterVehicles && loco.supportersOnly ? false : true));
@@ -224,7 +217,7 @@ export default defineComponent({
totalStockLength += this.store.stockList[0].length; totalStockLength += this.store.stockList[0].length;
totalStockMass += this.store.stockList[0].mass; totalStockMass += this.store.stockList[0].mass;
let availableCarsSet = this.carDataList.filter((cargoCar) => { let availableCarsSet = this.store.carDataList.filter((cargoCar) => {
if (!this.includeSupporterVehicles && cargoCar.supportersOnly) return false; if (!this.includeSupporterVehicles && cargoCar.supportersOnly) return false;
if (this.chosenCarTypes.find((carType) => cargoCar.type.includes(carType))) return true; if (this.chosenCarTypes.find((carType) => cargoCar.type.includes(carType))) return true;
@@ -232,7 +225,7 @@ export default defineComponent({
return false; return false;
}); });
while (totalStockLength < this.chosenLength && totalStockMass < this.chosenMass) { while (totalStockLength < this.randomStockLength && totalStockMass < this.randomStockMass) {
const randCarIndex = Math.floor(Math.random() * availableCarsSet.length); const randCarIndex = Math.floor(Math.random() * availableCarsSet.length);
const randCar = availableCarsSet[randCarIndex]; const randCar = availableCarsSet[randCarIndex];
@@ -240,14 +233,14 @@ export default defineComponent({
// const count = Math.random() < 0.25 ? Math.floor(Math.random() * 2) + 1 : 1; // const count = Math.random() < 0.25 ? Math.floor(Math.random() * 2) + 1 : 1;
const count = 1; const count = 1;
if (randCar.length * count + totalStockLength >= this.chosenLength) break; if (randCar.length * count + totalStockLength >= this.randomStockLength) break;
let randCargo = undefined; let randCargo = undefined;
let randNum = this.loadableByDefault ? 1 : Math.random(); let randNum = this.loadableByDefault ? 1 : Math.random();
if (randCar.cargoList.length != 0 && randNum >= 0.6) if (randCar.cargoList.length != 0 && randNum >= 0.6)
randCargo = randCar.cargoList[Math.floor(Math.random() * randCar.cargoList.length)]; randCargo = randCar.cargoList[Math.floor(Math.random() * randCar.cargoList.length)];
if ((randCargo?.totalMass || randCar.mass) * count + totalStockMass >= this.chosenMass) break; if ((randCargo?.totalMass || randCar.mass) * count + totalStockMass >= this.randomStockMass) break;
for (let i = 0; i < count; i++) this.addCar(randCar, randCargo); for (let i = 0; i < count; i++) this.addCar(randCar, randCargo);
@@ -255,7 +248,7 @@ export default defineComponent({
totalStockMass += randCargo?.totalMass || randCar.mass; totalStockMass += randCargo?.totalMass || randCar.mass;
} }
this.isCardOpen = false; this.store.isRandomizerCardOpen = false;
}, },
toggleCarType(carType: string) { toggleCarType(carType: string) {
+8 -9
View File
@@ -44,6 +44,8 @@ import { IStore, ILocomotive, ICarWagon } from '../types';
import iconEIC from '../assets/EIC.png'; import iconEIC from '../assets/EIC.png';
import iconIC from '../assets/IC.svg'; import iconIC from '../assets/IC.svg';
import iconTLK from '../assets/TLK.png'; import iconTLK from '../assets/TLK.png';
import { useStore } from '../store';
import { isLocomotive } from '../utils/vehicleUtils';
interface ReadyStockList { interface ReadyStockList {
[key: string]: { stockString: string; type: string; number: string; name: string }; [key: string]: { stockString: string; type: string; number: string; name: string };
@@ -56,17 +58,14 @@ interface ResponseJSONData {
export default defineComponent({ export default defineComponent({
setup() { setup() {
return { return {
isOpen: inject('isReadyStockListOpen'), store: useStore(),
store: inject('Store') as IStore,
locoDataList: inject('locoDataList') as ILocomotive[],
carDataList: inject('carDataList') as ICarWagon[],
isLocomotive: inject('isLocomotive') as (vehicle: ILocomotive | ICarWagon) => vehicle is ILocomotive,
}; };
}, },
data: () => ({ data: () => ({
responseStatus: 'loading', responseStatus: 'loading',
isMobile: 'ontouchstart' in document.documentElement && navigator.userAgent.match(/Mobi/) ? true : false, isMobile: 'ontouchstart' in document.documentElement && navigator.userAgent.match(/Mobi/) ? true : false,
isOpen: false,
readyStockList: {} as ReadyStockList, readyStockList: {} as ReadyStockList,
searchedReadyStockName: '', searchedReadyStockName: '',
@@ -129,8 +128,8 @@ export default defineComponent({
stockArray.forEach((type, i) => { stockArray.forEach((type, i) => {
let vehicle; let vehicle;
if (i == 0) vehicle = this.locoDataList.find((loco) => loco.type == stockArray[0]); if (i == 0) vehicle = this.store.locoDataList.find((loco) => loco.type == stockArray[0]);
else vehicle = this.carDataList.find((car) => car.type == type); else vehicle = this.store.carDataList.find((car) => car.type == type);
this.addVehicle(vehicle); this.addVehicle(vehicle);
}); });
@@ -146,11 +145,11 @@ export default defineComponent({
length: vehicle.length, length: vehicle.length,
mass: vehicle.mass, mass: vehicle.mass,
maxSpeed: vehicle.maxSpeed, maxSpeed: vehicle.maxSpeed,
isLoco: this.isLocomotive(vehicle), isLoco: isLocomotive(vehicle),
cargo: undefined, cargo: undefined,
count: 1, count: 1,
imgSrc: vehicle.imageSrc, imgSrc: vehicle.imageSrc,
useType: this.isLocomotive(vehicle) ? vehicle.power : vehicle.useType, useType: isLocomotive(vehicle) ? vehicle.power : vehicle.useType,
supportersOnly: vehicle.supportersOnly, supportersOnly: vehicle.supportersOnly,
}; };
+5 -4
View File
@@ -24,7 +24,7 @@
<div style="color: #ccc"> <div style="color: #ccc">
<b>{{ vehicleTypes[store.chosenLoco?.power || store.chosenCar?.useType || 'loco-e'] }}</b> <b>{{ vehicleTypes[store.chosenLoco?.power || store.chosenCar?.useType || 'loco-e'] }}</b>
<div> <div>
{{ (store.chosenCar || store.chosenLoco)?.length }}m | {{ (store.chosenCar || store.chosenLoco)?.mass }}t | {{ (store.chosenCar || store.chosenLoco)?.length }}m | {{ (store.chosenCar || store.chosenLoco)?.mass }}t |
{{ (store.chosenCar || store.chosenLoco)?.maxSpeed }} km/h {{ (store.chosenCar || store.chosenLoco)?.maxSpeed }} km/h
@@ -48,12 +48,12 @@
<script lang="ts"> <script lang="ts">
import carUsage from '../data/carUsage.json'; import carUsage from '../data/carUsage.json';
import { defineComponent, inject } from 'vue'; import { defineComponent } from 'vue';
import { IStore } from '../types'; import { useStore } from '../store';
export default defineComponent({ export default defineComponent({
setup() { setup() {
const store = inject('Store') as IStore; const store = useStore();
return { return {
store, store,
@@ -161,3 +161,4 @@ export default defineComponent({
} }
} }
</style> </style>
+39 -25
View File
@@ -1,32 +1,46 @@
import { createApp, Directive } from "vue"; import { createApp, Directive } from 'vue';
import App from "./App.vue"; import { createPinia } from 'pinia';
import App from './App.vue';
import { Store, isLocomotive, locoDataList, carDataList, totalLength, totalMass, maxAllowedSpeed, maxStockSpeed, isTrainPassenger, warnings } from "./store"; import {
Store,
isLocomotive,
locoDataList,
carDataList,
totalLength,
totalMass,
maxAllowedSpeed,
maxStockSpeed,
isTrainPassenger,
warnings,
} from './store';
const clickOutsideDirective: Directive = { const clickOutsideDirective: Directive = {
beforeMount(el, binding) { beforeMount(el, binding) {
el.clickOutsideEvent = (event: Event) => {
if (!(el == event.target || el.contains(event.target))) {
binding.value();
}
};
el.clickOutsideEvent = (event: Event) => { document.addEventListener('click', el.clickOutsideEvent);
if (!(el == event.target || el.contains(event.target))) { },
binding.value(); };
}
};
document.addEventListener("click", el.clickOutsideEvent); const pinia = createPinia();
},
}
createApp(App) createApp(App)
.provide('Store', Store) .use(pinia)
.provide('isLocomotive', isLocomotive) // .provide('Store', Store)
.provide('locoDataList', locoDataList) // .provide('isLocomotive', isLocomotive)
.provide('carDataList', carDataList) // .provide('locoDataList', locoDataList)
.provide('totalMass', totalMass) // .provide('carDataList', carDataList)
.provide('totalLength', totalLength) // .provide('totalMass', totalMass)
.provide('maxStockSpeed', maxStockSpeed) // .provide('totalLength', totalLength)
.provide('maxAllowedSpeed', maxAllowedSpeed) // .provide('maxStockSpeed', maxStockSpeed)
.provide('isTrainPassenger', isTrainPassenger) // .provide('maxAllowedSpeed', maxAllowedSpeed)
.provide('warnings', warnings) // .provide('isTrainPassenger', isTrainPassenger)
.directive('click-outside', clickOutsideDirective) // .provide('warnings', warnings)
.mount("#app"); // .directive('click-outside', clickOutsideDirective)
.mount('#app');
+30 -297
View File
@@ -1,311 +1,44 @@
import { IStore } from './types';
import { defineStore } from 'pinia';
import { carDataList, isTrainPassenger, locoDataList, maxStockSpeed, totalLength, totalMass } from './utils/vehicleUtils';
import { ICargo, ICarWagon, ILocomotive, IStock, IStore, IVehicleData } from "./types"; export const useStore = defineStore({
import { reactive } from "@vue/reactivity"; id: 'store',
state: () =>
({
chosenCar: null,
chosenLoco: null,
chosenCargo: null,
import vehicleDataJSON from "./data/vehicleData.json"; showSupporter: false,
import vehiclePropsJSON from "./data/vehicleProps.json"; imageLoading: false,
import { EVehicleUseType } from "./enums/EVehicleUseType";
import { computed } from "vue";
export const Store: IStore = reactive({ chosenLocoPower: 'loco-e',
chosenCar: null as ICarWagon | null, chosenCarUseType: 'car-passenger',
chosenLoco: null as ILocomotive | null,
chosenCargo: null as ICargo | null,
showSupporter: false, stockList: [],
imageLoading: false, cargoOptions: [],
chosenLocoPower: "loco-e", swapVehicles: false,
chosenCarUseType: "car-passenger",
stockList: [] as IStock[], chosenStockListIndex: -1,
cargoOptions: [] as any[][], chosenRealStockName: null,
swapVehicles: false, vehiclePreviewSrc: '',
chosenStockListIndex: -1, isRandomizerCardOpen: false,
chosenRealStockName: null,
// locoOptions: [] as ILocomotive[],
// carOptions: [] as ICarWagon[],
vehiclePreviewSrc: ""
})
export function isLocomotive(vehicle: ILocomotive | ICarWagon): vehicle is ILocomotive {
return (vehicle as ILocomotive).power !== undefined;
}
export const locoDataList = computed(() => Object.keys(vehicleDataJSON).reduce(
(acc, vehicleTypeKey) => {
if (!vehicleTypeKey.startsWith("loco")) return acc;
const locoVehiclesData = (vehicleDataJSON as IVehicleData)[
vehicleTypeKey
];
locoVehiclesData.forEach((loco) => {
if (Store.showSupporter && !loco[4]) return;
const locoType = loco[0] as string;
let length = 0,
mass = 0;
// Elektrowozy
if (vehicleTypeKey.startsWith("loco-e")) {
// 32m dla ET41, reszta 16
length = locoType.startsWith("ET") ? 32 : 16;
// 80t dla wszystkich EU06, EP08
mass = 80;
// 83t dla: EU07 o nr większych niż 300 & dla wszystkich EP07 oprócz nr 135,242,1002,1048
const locoNumber = Number(locoType.split("-")[1]);
if (
(locoType.startsWith("EU") && locoNumber > 300) ||
(locoType.startsWith("EP") &&
![242, 135, 1002, 1048].includes(locoNumber))
) {
mass = 83;
}
}
// Spalinowozy
if (vehicleTypeKey.startsWith("loco-s")) {
length = 14;
mass = 74;
}
// EZT
if (vehicleTypeKey.startsWith("loco-ezt")) {
// EN57
length = 65;
mass = 126;
// EN71
if (locoType.startsWith("EN71")) {
length = 86;
mass = 182;
}
// 2xEN57
if (locoType.startsWith("2EN57")) {
length = 130;
mass = 253;
}
}
// SZT
if (vehicleTypeKey.startsWith("loco-szt")) {
length = 14;
mass = 23;
}
acc.push({
power: vehicleTypeKey,
type: loco[0] as string,
constructionType: loco[1] as string,
cabinType: loco[2] as string,
maxSpeed: Number(loco[3] as string),
supportersOnly: loco[4] as boolean,
imageSrc: loco[5] as string,
length,
mass,
});
});
return acc;
},
[] as ILocomotive[]
));
export const carDataList = computed(() => Object.keys(vehicleDataJSON).reduce(
(acc, vehicleTypeKey) => {
if (!vehicleTypeKey.startsWith("car")) return acc;
const carVehiclesData = (vehicleDataJSON as IVehicleData)[
vehicleTypeKey
];
carVehiclesData.forEach((car) => {
if (Store.showSupporter && !car[3]) return;
const carPropsData = vehiclePropsJSON.find((v) => } as IStore),
car[0].toString().includes(v.type)
);
acc.push({ getters: {
useType: vehicleTypeKey, locoDataList: (state) => locoDataList(state),
type: car[0] as string, carDataList: (state) => carDataList(state),
constructionType: car[1] as string, totalMass: (state) => totalMass(state),
loadable: car[2] as boolean, totalLength: (state) => totalLength(state),
supportersOnly: car[3] as boolean, maxStockSpeed: (state) => maxStockSpeed(state),
maxSpeed: Number(car[4] as string), isTrainPassenger: (state) => isTrainPassenger(state),
imageSrc: car[5] as string, },
cargoList:
carPropsData?.cargo.includes(";") ? carPropsData.cargo.split(";").map((cargo) => ({
id: cargo.split(":")[0],
totalMass: Number(cargo.split(":")[1]),
})) : [],
mass: carPropsData?.mass || 0,
length: carPropsData?.length || 0,
});
});
return acc;
},
[] as ICarWagon[]
));
export const totalMass = computed(() => {
return Store.stockList.reduce(
(acc, stock) =>
acc +
(stock.cargo ? stock.cargo.totalMass : stock.mass) * stock.count,
0
)
}); });
export const totalLength = computed(() => {
return Store.stockList.reduce(
(acc, stock) => acc + stock.length * stock.count,
0
)
});
export const maxStockSpeed = computed(() => {
return Store.stockList.reduce(
(acc, stock) =>
stock.maxSpeed < acc || acc == 0 ? stock.maxSpeed : acc,
0
)
});
export const isTrainPassenger = computed(() => {
if (Store.stockList.length == 0) return false;
if (Store.stockList.every(stock => stock.isLoco)) return false;
return Store.stockList
.filter((stock) => !stock.isLoco)
.every((stock) => stock.useType === EVehicleUseType.CAR_PASSENGER);
})
export const maxAllowedSpeed = computed(() => {
if (Store.stockList.length < 1) return -1;
if (!Store.stockList[0].isLoco) return -1;
const headingLoco = Store.stockList[0];
if (headingLoco.type.startsWith("EU07")) {
if (isTrainPassenger.value && totalMass.value <= 650) return 125;
if (!isTrainPassenger.value && totalMass.value <= 2000) return 70;
return -1;
}
if (headingLoco.type.startsWith("EP07")) {
if (isTrainPassenger.value && totalMass.value <= 650) return 125;
if (!isTrainPassenger.value) return -1;
return -1;
}
if (headingLoco.type.startsWith("EP08")) {
if (isTrainPassenger.value && totalMass.value <= 650) return 140;
if (!isTrainPassenger.value) return -1;
return -1;
}
if (headingLoco.type.startsWith("ET41")) {
if (isTrainPassenger.value && totalMass.value <= 700) return 125;
if (!isTrainPassenger.value && totalMass.value <= 4000) return 70;
return -1;
}
if (headingLoco.type.startsWith("SM42")) {
if (totalMass.value <= 95) return 90;
if (totalMass.value <= 200) return 80;
if (totalMass.value <= 300) return 70;
if (totalMass.value <= 450) return 60;
if (totalMass.value <= 750) return 50;
if (totalMass.value <= 1130) return 40;
if (totalMass.value <= 1720) return 30;
if (totalMass.value <= 2400) return 20;
return -1;
}
return Store.stockList.reduce(
(acc, stock) =>
stock.maxSpeed < acc || acc == 0 ? stock.maxSpeed : acc,
0
);
})
export const warnings = {
trainTooLong: computed(() => {
if (isTrainPassenger.value && totalLength.value > 350) return true;
if (!isTrainPassenger.value && totalLength.value > 650) return true;
return false;
}),
locoNotSuitable: computed(() => {
if (!isTrainPassenger.value
&& Store.stockList.length > 1
&& !Store.stockList.every(stock => stock.isLoco)
&& Store.stockList.find(stock => stock.isLoco && stock.type.startsWith("EP"))) return true;
return false;
}),
trainTooHeavy: computed(() => {
if (Store.stockList.length == 0 || !Store.stockList[0].isLoco) return false;
const headingLoco = Store.stockList[0];
if (isTrainPassenger.value && (headingLoco.type.startsWith("EU") || headingLoco.type.startsWith("EP")) && totalMass.value > 650) return true;
if (isTrainPassenger.value && headingLoco.type.startsWith("ET") && totalMass.value > 700) return true;
if (!isTrainPassenger.value && headingLoco.type.startsWith("EU") && totalMass.value > 2000) return true;
if (!isTrainPassenger.value && headingLoco.type.startsWith("ET") && totalMass.value > 4000) return true;
if (headingLoco.type.startsWith("SM") && totalMass.value > 2400) return true;
return false;
}),
tooManyLocos: computed(() => {
if (Store.stockList.reduce((acc, stock) => {
if (!stock.isLoco) return acc;
acc += stock.count;
return acc;
}, 0) > 2) return true;
return false;
})
}
// export const trainTooLong = computed(() => {
// if (isTrainPassenger.value && totalLength.value > 350) return true;
// if (!isTrainPassenger.value && totalLength.value > 650) return true;
// return false;
// })
// export const locoNotSuitable = computed(() => {
// if (!isTrainPassenger.value && Store.stockList.length > 1 && Store.stockList.find(stock => stock.isLoco && stock.type.startsWith("EP"))) return true;
// return false;
// })
+3 -1
View File
@@ -17,6 +17,8 @@ export interface IStore {
swapVehicles: boolean; swapVehicles: boolean;
vehiclePreviewSrc: string; vehiclePreviewSrc: string;
isRandomizerCardOpen: boolean;
} }
export interface IVehicleData { export interface IVehicleData {
@@ -67,4 +69,4 @@ export interface IStock {
supportersOnly: boolean; supportersOnly: boolean;
count: number; count: number;
imgSrc: string; imgSrc: string;
} }
+259
View File
@@ -0,0 +1,259 @@
import { computed } from "vue";
import { EVehicleUseType } from "../enums/EVehicleUseType";
import { ICarWagon, ILocomotive, IStore, IVehicleData } from "../types";
import vehicleDataJSON from '../data/vehicleData.json';
import vehiclePropsJSON from '../data/vehicleProps.json';
export function isLocomotive(vehicle: ILocomotive | ICarWagon): vehicle is ILocomotive {
return (vehicle as ILocomotive).power !== undefined;
}
export function locoDataList(state: IStore) {
return Object.keys(vehicleDataJSON).reduce((acc, vehicleTypeKey) => {
if (!vehicleTypeKey.startsWith('loco')) return acc;
const locoVehiclesData = (vehicleDataJSON as IVehicleData)[vehicleTypeKey];
locoVehiclesData.forEach((loco) => {
if (state.showSupporter && !loco[4]) return;
const locoType = loco[0] as string;
let length = 0,
mass = 0;
// Elektrowozy
if (vehicleTypeKey.startsWith('loco-e')) {
// 32m dla ET41, reszta 16
length = locoType.startsWith('ET') ? 32 : 16;
// 80t dla wszystkich EU06, EP08
mass = 80;
// 83t dla: EU07 o nr większych niż 300 & dla wszystkich EP07 oprócz nr 135,242,1002,1048
const locoNumber = Number(locoType.split('-')[1]);
if (
(locoType.startsWith('EU') && locoNumber > 300) ||
(locoType.startsWith('EP') && ![242, 135, 1002, 1048].includes(locoNumber))
) {
mass = 83;
}
}
// Spalinowozy
if (vehicleTypeKey.startsWith('loco-s')) {
length = 14;
mass = 74;
}
// EZT
if (vehicleTypeKey.startsWith('loco-ezt')) {
// EN57
length = 65;
mass = 126;
// EN71
if (locoType.startsWith('EN71')) {
length = 86;
mass = 182;
}
// 2xEN57
if (locoType.startsWith('2EN57')) {
length = 130;
mass = 253;
}
}
// SZT
if (vehicleTypeKey.startsWith('loco-szt')) {
length = 14;
mass = 23;
}
acc.push({
power: vehicleTypeKey,
type: loco[0] as string,
constructionType: loco[1] as string,
cabinType: loco[2] as string,
maxSpeed: Number(loco[3] as string),
supportersOnly: loco[4] as boolean,
imageSrc: loco[5] as string,
length,
mass,
});
});
return acc;
}, [] as ILocomotive[])
}
export function carDataList(state: IStore) {
return Object.keys(vehicleDataJSON).reduce((acc, vehicleTypeKey) => {
if (!vehicleTypeKey.startsWith('car')) return acc;
const carVehiclesData = (vehicleDataJSON as IVehicleData)[vehicleTypeKey];
carVehiclesData.forEach((car) => {
if (state.showSupporter && !car[3]) return;
const carPropsData = vehiclePropsJSON.find((v) => car[0].toString().includes(v.type));
acc.push({
useType: vehicleTypeKey,
type: car[0] as string,
constructionType: car[1] as string,
loadable: car[2] as boolean,
supportersOnly: car[3] as boolean,
maxSpeed: Number(car[4] as string),
imageSrc: car[5] as string,
cargoList: carPropsData?.cargo.includes(';')
? carPropsData.cargo.split(';').map((cargo) => ({
id: cargo.split(':')[0],
totalMass: Number(cargo.split(':')[1]),
}))
: [],
mass: carPropsData?.mass || 0,
length: carPropsData?.length || 0,
});
});
return acc;
}, [] as ICarWagon[])
}
export function totalMass(state: IStore) {
return state.stockList.reduce(
(acc, stock) => acc + (stock.cargo ? stock.cargo.totalMass : stock.mass) * stock.count,
0
);
};
export function totalLength(state: IStore) {
return state.stockList.reduce((acc, stock) => acc + stock.length * stock.count, 0);
};
export function maxStockSpeed(state: IStore) {
return state.stockList.reduce((acc, stock) => (stock.maxSpeed < acc || acc == 0 ? stock.maxSpeed : acc), 0);
};
export function isTrainPassenger(state: IStore) {
if (state.stockList.length == 0) return false;
if (state.stockList.every((stock) => stock.isLoco)) return false;
return state.stockList
.filter((stock) => !stock.isLoco)
.every((stock) => stock.useType === EVehicleUseType.CAR_PASSENGER);
};
// export function maxAllowedSpeed(state: IStore) {
// if (state.stockList.length < 1) return -1;
// if (!state.stockList[0].isLoco) return -1;
// const headingLoco = state.stockList[0];
// const isPassenger = isTrainPassenger(state);
// if (headingLoco.type.startsWith('EU07')) {
// if (isPassenger && totalMass.value <= 650) return 125;
// if (!isPassenger && totalMass.value <= 2000) return 70;
// return -1;
// }
// if (headingLoco.type.startsWith('EP07')) {
// if (isPassenger && totalMass.value <= 650) return 125;
// if (!isPassenger) return -1;
// return -1;
// }
// if (headingLoco.type.startsWith('EP08')) {
// if (isPassenger && totalMass.value <= 650) return 140;
// if (!isPassenger) return -1;
// return -1;
// }
// if (headingLoco.type.startsWith('ET41')) {
// if (isPassenger && totalMass.value <= 700) return 125;
// if (!isPassenger && totalMass.value <= 4000) return 70;
// return -1;
// }
// if (headingLoco.type.startsWith('SM42')) {
// if (totalMass.value <= 95) return 90;
// if (totalMass.value <= 200) return 80;
// if (totalMass.value <= 300) return 70;
// if (totalMass.value <= 450) return 60;
// if (totalMass.value <= 750) return 50;
// if (totalMass.value <= 1130) return 40;
// if (totalMass.value <= 1720) return 30;
// if (totalMass.value <= 2400) return 20;
// return -1;
// }
// return Store.stockList.reduce((acc, stock) => (stock.maxSpeed < acc || acc == 0 ? stock.maxSpeed : acc), 0);
// });
// export const warnings = {
// trainTooLong: computed(() => {
// if (isTrainPassenger.value && totalLength.value > 350) return true;
// if (!isTrainPassenger.value && totalLength.value > 650) return true;
// return false;
// }),
// locoNotSuitable: computed(() => {
// if (
// !isTrainPassenger.value &&
// Store.stockList.length > 1 &&
// !Store.stockList.every((stock) => stock.isLoco) &&
// Store.stockList.find((stock) => stock.isLoco && stock.type.startsWith('EP'))
// )
// return true;
// return false;
// }),
// trainTooHeavy: computed(() => {
// if (Store.stockList.length == 0 || !Store.stockList[0].isLoco) return false;
// const headingLoco = Store.stockList[0];
// if (
// isTrainPassenger.value &&
// (headingLoco.type.startsWith('EU') || headingLoco.type.startsWith('EP')) &&
// totalMass.value > 650
// )
// return true;
// if (isTrainPassenger.value && headingLoco.type.startsWith('ET') && totalMass.value > 700) return true;
// if (!isTrainPassenger.value && headingLoco.type.startsWith('EU') && totalMass.value > 2000) return true;
// if (!isTrainPassenger.value && headingLoco.type.startsWith('ET') && totalMass.value > 4000) return true;
// if (headingLoco.type.startsWith('SM') && totalMass.value > 2400) return true;
// return false;
// }),
// tooManyLocos: computed(() => {
// if (
// Store.stockList.reduce((acc, stock) => {
// if (!stock.isLoco) return acc;
// acc += stock.count;
// return acc;
// }, 0) > 2
// )
// return true;
// return false;
// }),
// };
+18
View File
@@ -88,6 +88,11 @@
"@vue/compiler-dom" "3.2.37" "@vue/compiler-dom" "3.2.37"
"@vue/shared" "3.2.37" "@vue/shared" "3.2.37"
"@vue/devtools-api@^6.2.1":
version "6.2.1"
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.2.1.tgz#6f2948ff002ec46df01420dfeff91de16c5b4092"
integrity sha512-OEgAMeQXvCoJ+1x8WyQuVZzFo0wcyCmUR3baRVLmKBo1LmYZWMlRiXlux5jd0fqVJu6PfDbOrZItVqUEzLobeQ==
"@vue/reactivity-transform@3.2.37": "@vue/reactivity-transform@3.2.37":
version "3.2.37" version "3.2.37"
resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.2.37.tgz#0caa47c4344df4ae59f5a05dde2a8758829f8eca" resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.2.37.tgz#0caa47c4344df4ae59f5a05dde2a8758829f8eca"
@@ -406,6 +411,14 @@ picomatch@^2.0.4, picomatch@^2.2.1:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
pinia@^2.0.17:
version "2.0.17"
resolved "https://registry.yarnpkg.com/pinia/-/pinia-2.0.17.tgz#f925e5e4f73c15e16dfb4838176a9ca50752f26b"
integrity sha512-AtwLwEWQgIjofjgeFT+nxbnK5lT2QwQjaHNEDqpsi2AiCwf/NY78uWTeHUyEhiiJy8+sBmw0ujgQMoQbWiZDfA==
dependencies:
"@vue/devtools-api" "^6.2.1"
vue-demi "*"
postcss@^8.1.10, postcss@^8.4.14: postcss@^8.1.10, postcss@^8.4.14:
version "8.4.14" version "8.4.14"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf"
@@ -491,6 +504,11 @@ vite@^3.0.0:
optionalDependencies: optionalDependencies:
fsevents "~2.3.2" fsevents "~2.3.2"
vue-demi@*:
version "0.13.5"
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.5.tgz#d5eddbc9eaefb89ce5995269d1fa6b0486312092"
integrity sha512-tO3K2bML3AwiHmVHeKCq6HLef2st4zBXIV5aEkoJl6HZ+gJWxWv2O8wLH8qrA3SX3lDoTDHNghLX1xZg83MXvw==
vue-tsc@^0.38.4: vue-tsc@^0.38.4:
version "0.38.9" version "0.38.9"
resolved "https://registry.yarnpkg.com/vue-tsc/-/vue-tsc-0.38.9.tgz#9e945937667f704325328db8af1cc6bc7314b85e" resolved "https://registry.yarnpkg.com/vue-tsc/-/vue-tsc-0.38.9.tgz#9e945937667f704325328db8af1cc6bc7314b85e"