Merge branch 'main' of github.com:jcalixte/tps
This commit is contained in:
5
core.css
5
core.css
@@ -9,6 +9,11 @@
|
|||||||
--gap: 1rem;
|
--gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
*:not(td):not(th) {
|
*:not(td):not(th) {
|
||||||
border-radius: 0.3rem;
|
border-radius: 0.3rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
<section class="just-in-time-pilar">
|
<section class="just-in-time-pilar">
|
||||||
<h3 class="just-in-time focusable">Just-in-time</h3>
|
<h3 class="just-in-time focusable">Just-in-time</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="takt-time focusable">Takt time</li>
|
<li class="takt-time takt focusable">Takt time</li>
|
||||||
<li class="one-piece-flow focusable">One piece flow</li>
|
<li class="one-piece-flow focusable">One piece flow</li>
|
||||||
<li class="pull-system focusable">
|
<li class="pull-system focusable">
|
||||||
<a href="/pull-system">Pull system</a>
|
<a href="/pull-system">Pull system</a>
|
||||||
|
|||||||
202
src/data/bird.ts
202
src/data/bird.ts
@@ -1,202 +0,0 @@
|
|||||||
export const birds = [
|
|
||||||
'Varied Thrush',
|
|
||||||
'Rock Dove',
|
|
||||||
'California Quail',
|
|
||||||
'Yellow-faced Grassquit',
|
|
||||||
'American Dipper',
|
|
||||||
'Tufted Puffin',
|
|
||||||
"Le Conte's Thrasher",
|
|
||||||
"Cassin's Vireo",
|
|
||||||
'Buff-bellied Hummingbird',
|
|
||||||
'Red Crossbill',
|
|
||||||
'Little Ringed Plover',
|
|
||||||
'American Avocet',
|
|
||||||
'Little Curlew',
|
|
||||||
'Tree Swallow',
|
|
||||||
'Three-toed Woodpecker',
|
|
||||||
'Bahama Mockingbird',
|
|
||||||
'Wandering Albatross',
|
|
||||||
'Hepatic Tanager',
|
|
||||||
'Ashy Storm-Petrel',
|
|
||||||
'Hoary Redpoll',
|
|
||||||
'Lazuli Bunting',
|
|
||||||
'Common House-Martin',
|
|
||||||
'Varied Bunting',
|
|
||||||
'Pygmy Nuthatch',
|
|
||||||
'American Coot',
|
|
||||||
'Shiny Cowbird',
|
|
||||||
'Rufous-capped Warbler',
|
|
||||||
'Eastern Wood-Pewee',
|
|
||||||
'Common Snipe',
|
|
||||||
'Northern Pygmy-Owl',
|
|
||||||
'Wood Stork',
|
|
||||||
'Gray-spotted Flycatcher',
|
|
||||||
'Bahama Woodstar',
|
|
||||||
'Black-backed Wagtail',
|
|
||||||
'Bean Goose',
|
|
||||||
'Buff-breasted Sandpiper',
|
|
||||||
'Northern Shoveler',
|
|
||||||
'Cinnamon Teal',
|
|
||||||
'Ruffed Grouse',
|
|
||||||
'Orchard Oriole',
|
|
||||||
'Black-footed Albatross',
|
|
||||||
'Mottled Duck',
|
|
||||||
'Red-headed Woodpecker',
|
|
||||||
'Double-crested Cormorant',
|
|
||||||
'Little Gull',
|
|
||||||
'Rufous Hummingbird',
|
|
||||||
'American Tree Sparrow',
|
|
||||||
'Black Swift',
|
|
||||||
'Fish Crow',
|
|
||||||
'Yellow-nosed Albatross',
|
|
||||||
'Ruddy Ground-Dove',
|
|
||||||
'White-winged Scoter',
|
|
||||||
'Black-capped Vireo',
|
|
||||||
'Chestnut-sided Warbler',
|
|
||||||
'Turkey Vulture',
|
|
||||||
'Mississippi Kite',
|
|
||||||
'Sage Thrasher',
|
|
||||||
'Whiskered Screech-Owl',
|
|
||||||
'Yucatan Vireo',
|
|
||||||
'Mountain Chickadee',
|
|
||||||
"Lewis's Woodpecker",
|
|
||||||
'Passenger Pigeon',
|
|
||||||
"Sabine's Gull",
|
|
||||||
'Black-billed Magpie',
|
|
||||||
'Florida Scrub-Jay',
|
|
||||||
'Plumbeous Vireo',
|
|
||||||
'Hoary Redpoll',
|
|
||||||
'Dusky Warbler',
|
|
||||||
"Couch's Kingbird",
|
|
||||||
'Double-striped Thick-knee',
|
|
||||||
'Canvasback',
|
|
||||||
'Warbling Vireo',
|
|
||||||
'Western Scrub-Jay',
|
|
||||||
'Green-winged Teal',
|
|
||||||
'Spot-breasted Oriole',
|
|
||||||
'American Bittern',
|
|
||||||
'White-winged Dove',
|
|
||||||
'Fieldfare',
|
|
||||||
'Barn Swallow',
|
|
||||||
'Golden-crowned Kinglet',
|
|
||||||
'Alder Flycatcher',
|
|
||||||
'Spotted Rail',
|
|
||||||
'Great Egret',
|
|
||||||
'Peregrine Falcon',
|
|
||||||
'Pacific-slope Flycatcher',
|
|
||||||
'Far Eastern Curlew',
|
|
||||||
'Whiskered Auklet',
|
|
||||||
'Yellow-billed Magpie',
|
|
||||||
'Eurasian Woodcock',
|
|
||||||
'Hepatic Tanager',
|
|
||||||
'Buff-bellied Hummingbird',
|
|
||||||
'Indigo Bunting',
|
|
||||||
"Gambel's Quail",
|
|
||||||
'Northern Waterthrush',
|
|
||||||
'Eurasian Wryneck',
|
|
||||||
"Audubon's Oriole",
|
|
||||||
'Gilded Flicker',
|
|
||||||
'Red-tailed Hawk',
|
|
||||||
'Zenaida Dove',
|
|
||||||
'Common Black-Hawk',
|
|
||||||
'Swamp Sparrow',
|
|
||||||
'Bahama Swallow',
|
|
||||||
'Jack Snipe',
|
|
||||||
"Le Conte's Thrasher",
|
|
||||||
'House Wren',
|
|
||||||
'Osprey',
|
|
||||||
'Savannah Sparrow',
|
|
||||||
'Eurasian Wigeon',
|
|
||||||
'Mexican Jay',
|
|
||||||
'Yellow Wagtail',
|
|
||||||
'Green Sandpiper',
|
|
||||||
'Greater Shearwater',
|
|
||||||
'Black-legged Kittiwake',
|
|
||||||
'Elegant Tern',
|
|
||||||
'Tufted Duck',
|
|
||||||
'Gray-headed Chickadee',
|
|
||||||
'Spotted Sandpiper',
|
|
||||||
'Barn Swallow',
|
|
||||||
'Bank Swallow',
|
|
||||||
'Scarlet Ibis',
|
|
||||||
'Spotted Redshank',
|
|
||||||
'Lark Bunting',
|
|
||||||
'American Golden-Plover',
|
|
||||||
'House Sparrow',
|
|
||||||
'Laysan Albatross',
|
|
||||||
'Whooper Swan',
|
|
||||||
'Marbled Murrelet',
|
|
||||||
"Townsend's Solitaire",
|
|
||||||
'Flesh-footed Shearwater',
|
|
||||||
'European Storm-Petrel',
|
|
||||||
'Manx Shearwater',
|
|
||||||
'Fieldfare',
|
|
||||||
'Least Bittern',
|
|
||||||
'Eskimo Curlew',
|
|
||||||
'Buff-collared Nightjar',
|
|
||||||
'White-breasted Nuthatch',
|
|
||||||
'Lanceolated Warbler',
|
|
||||||
'Bridled Tern',
|
|
||||||
'Yellow Wagtail',
|
|
||||||
'Jack Snipe',
|
|
||||||
'Western Tanager',
|
|
||||||
'Common Goldeneye',
|
|
||||||
'Greater Scaup',
|
|
||||||
'Belted Kingfisher',
|
|
||||||
'Rustic Bunting',
|
|
||||||
'Olive-sided Flycatcher',
|
|
||||||
'Bahama Mockingbird',
|
|
||||||
'White-tailed Ptarmigan',
|
|
||||||
'Lesser Scaup',
|
|
||||||
'Common Murre',
|
|
||||||
'Siberian Rubythroat',
|
|
||||||
'Siberian Rubythroat',
|
|
||||||
'Eared Trogon',
|
|
||||||
'Swallow-tailed Kite',
|
|
||||||
'Sulphur-bellied Flycatcher',
|
|
||||||
'Bohemian Waxwing',
|
|
||||||
'Common Sandpiper',
|
|
||||||
'Altamira Oriole',
|
|
||||||
'Mountain Plover',
|
|
||||||
'Common Ground-Dove',
|
|
||||||
'Great Gray Owl',
|
|
||||||
'Common Tern',
|
|
||||||
'Great Black-backed Gull',
|
|
||||||
'Horned Lark',
|
|
||||||
'Tricolored Heron',
|
|
||||||
'California Towhee',
|
|
||||||
'Fulvous Whistling-Duck',
|
|
||||||
'Hoary Redpoll',
|
|
||||||
'Plumbeous Vireo',
|
|
||||||
'Caribbean Elaenia',
|
|
||||||
'Purple Martin',
|
|
||||||
'American Crow',
|
|
||||||
'Key West Quail-Dove',
|
|
||||||
'Jungle Nightjar',
|
|
||||||
'Common Redpoll',
|
|
||||||
'Dusky Warbler',
|
|
||||||
'Neotropic Cormorant',
|
|
||||||
'Chestnut-backed Chickadee',
|
|
||||||
'Black Catbird',
|
|
||||||
'Redhead',
|
|
||||||
'American Tree Sparrow',
|
|
||||||
"Le Conte's Sparrow",
|
|
||||||
'Neotropic Cormorant',
|
|
||||||
'Wood Duck',
|
|
||||||
'Plumbeous Vireo',
|
|
||||||
'Bahama Mockingbird',
|
|
||||||
'Greater White-fronted Goose',
|
|
||||||
'Elegant Trogon',
|
|
||||||
'Jack Snipe',
|
|
||||||
'American Black Duck',
|
|
||||||
'Killdeer',
|
|
||||||
'Brown Jay',
|
|
||||||
'Pine Warbler',
|
|
||||||
'Nashville Warbler',
|
|
||||||
'Winter Wren',
|
|
||||||
'Blue Jay',
|
|
||||||
'Snowy Egret',
|
|
||||||
'Gray Bunting',
|
|
||||||
"Steller's Jay",
|
|
||||||
'Wood Warbler'
|
|
||||||
]
|
|
||||||
@@ -3,7 +3,6 @@ import { Chart as ChartJS, registerables } from 'chart.js'
|
|||||||
import { useBoardGameStore } from '@/modules/5s/board-game-store'
|
import { useBoardGameStore } from '@/modules/5s/board-game-store'
|
||||||
import { toDuration, toSeconds } from '@/modules/5s/utils'
|
import { toDuration, toSeconds } from '@/modules/5s/utils'
|
||||||
import { getNatural } from '@/utils'
|
import { getNatural } from '@/utils'
|
||||||
import { _ } from '@faker-js/faker/dist/airline-D6ksJFwG'
|
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { Bar } from 'vue-chartjs'
|
import { Bar } from 'vue-chartjs'
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { onMounted, ref, toValue } from 'vue'
|
|||||||
const userInput = ref('')
|
const userInput = ref('')
|
||||||
const mode = ref<_5S | null>(null)
|
const mode = ref<_5S | null>(null)
|
||||||
const boardGameStore = useBoardGameStore()
|
const boardGameStore = useBoardGameStore()
|
||||||
|
|
||||||
if (import.meta.env.DEV) {
|
if (import.meta.env.DEV) {
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
boardGameStore.initGame()
|
boardGameStore.initGame()
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ const createdAt = new Date('2025-01-08').toLocaleDateString(undefined, {
|
|||||||
Now we’re pretty confident! As quality issues increase in the
|
Now we’re pretty confident! As quality issues increase in the
|
||||||
<PushSystemIcon /> push system, defects and corrections accumulate,
|
<PushSystemIcon /> push system, defects and corrections accumulate,
|
||||||
leading to <span class="numeric">{{ meanLeadTimeDelta }}</span> days of
|
leading to <span class="numeric">{{ meanLeadTimeDelta }}</span> days of
|
||||||
delay<template v-if="meanLeadTimeDeltaFloat > 12">!!</template
|
delay<template v-if="meanLeadTimeDeltaFloat > 12">!</template
|
||||||
><template v-else>.</template>
|
><template v-else>.</template>
|
||||||
</p>
|
</p>
|
||||||
<p v-else class="waiting-simulations">
|
<p v-else class="waiting-simulations">
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const hasQualityIssues = computed(() => props.feature.qualityIssue > 0)
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="feature-item bin" :class="{ live: isLive }">
|
<div class="feature-item bin" :class="{ live: isLive }">
|
||||||
<div>
|
<div class="feature-name">
|
||||||
<!-- [complexity]
|
<!-- [complexity]
|
||||||
<span class="numeric">({{ feature.complexity }})</span> -->
|
<span class="numeric">({{ feature.complexity }})</span> -->
|
||||||
{{ feature.name }}
|
{{ feature.name }}
|
||||||
@@ -37,11 +37,15 @@ const hasQualityIssues = computed(() => props.feature.qualityIssue > 0)
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
justify-content: space-around;
|
justify-content: space-between;
|
||||||
|
|
||||||
&.live {
|
&.live {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.feature-name {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ defineProps<{ alias: string }>()
|
|||||||
|
|
||||||
const featureStore = useFeatureStore()
|
const featureStore = useFeatureStore()
|
||||||
|
|
||||||
onMounted(() => featureStore.initBoard('mobile-app', NUMBER_OF_FEATURES))
|
onMounted(() => featureStore.initBoard(NUMBER_OF_FEATURES))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const featureStore = useFeatureStore()
|
|||||||
|
|
||||||
const confirmReset = () => {
|
const confirmReset = () => {
|
||||||
if (confirm('Are you sure you want to reset the board?')) {
|
if (confirm('Are you sure you want to reset the board?')) {
|
||||||
featureStore.initBoard('mobile-app', NUMBER_OF_FEATURES)
|
featureStore.initBoard(NUMBER_OF_FEATURES)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
import { newsAppFeatures } from '@/data/app-feature'
|
|
||||||
import type {
|
import type {
|
||||||
Feature,
|
Feature,
|
||||||
FeatureStatus
|
FeatureStatus
|
||||||
} from '@/modules/pull-system/feature/feature'
|
} from '@/modules/pull-system/feature/feature'
|
||||||
import type { FeatureStep } from '@/modules/pull-system/feature/feature-steps'
|
import type { FeatureStep } from '@/modules/pull-system/feature/feature-steps'
|
||||||
import {
|
import { mobileAppFeatures } from '@/modules/pull-system/feature/feature.fixture'
|
||||||
birdFeatures,
|
|
||||||
mobileAppFeatures
|
|
||||||
} from '@/modules/pull-system/feature/feature.fixture'
|
|
||||||
import type { Strategy } from '@/modules/pull-system/lean/strategy'
|
import type { Strategy } from '@/modules/pull-system/lean/strategy'
|
||||||
import type { FeatureState } from '@/store-type'
|
import type { FeatureState } from '@/store-type'
|
||||||
import {
|
import {
|
||||||
@@ -74,9 +70,9 @@ const mayBeInProgress = ({
|
|||||||
return feature.status
|
return feature.status
|
||||||
}
|
}
|
||||||
|
|
||||||
export const newBacklog = (type: 'bird' | 'mobile-app', limit?: number) => {
|
export const newBacklog = (limit?: number) => {
|
||||||
const initialFeatures =
|
const initialFeatures = [...mobileAppFeatures]
|
||||||
type === 'bird' ? [...birdFeatures] : [...mobileAppFeatures]
|
|
||||||
return limit !== undefined
|
return limit !== undefined
|
||||||
? popNElement(shuffleArray(initialFeatures), limit)
|
? popNElement(shuffleArray(initialFeatures), limit)
|
||||||
: shuffleArray(initialFeatures)
|
: shuffleArray(initialFeatures)
|
||||||
@@ -254,8 +250,8 @@ export const nextDay = (
|
|||||||
strategy: Strategy | 'problem-solving'
|
strategy: Strategy | 'problem-solving'
|
||||||
): FeatureState => {
|
): FeatureState => {
|
||||||
state.meta.totalDays++
|
state.meta.totalDays++
|
||||||
// // each day, the teams know how to better work together
|
// each day, the teams know how to better work together
|
||||||
// state.meta.teamWorkExperience += 0.1
|
// state.meta.teamWorkExperience += 0.1 // Removed with a simplified version of pull system without the problem-solving strategy
|
||||||
|
|
||||||
if (strategy === 'problem-solving') {
|
if (strategy === 'problem-solving') {
|
||||||
const hasTeamLearned = randomFloat(0, 1) > 0.25
|
const hasTeamLearned = randomFloat(0, 1) > 0.25
|
||||||
@@ -306,7 +302,7 @@ export const simulate = (
|
|||||||
): FeatureState => {
|
): FeatureState => {
|
||||||
let i = 0
|
let i = 0
|
||||||
|
|
||||||
while (!isProjectFinished(state.features) && i++ < HARD_STOP) {
|
while (i++ < HARD_STOP && !isProjectFinished(state.features)) {
|
||||||
if (strategy.includes('dps')) {
|
if (strategy.includes('dps')) {
|
||||||
if (state.meta.totalDays % 5 === 0) {
|
if (state.meta.totalDays % 5 === 0) {
|
||||||
state = nextDay(state, 'problem-solving')
|
state = nextDay(state, 'problem-solving')
|
||||||
|
|||||||
@@ -34,9 +34,10 @@ export const useFeatureStore = defineStore('feature', {
|
|||||||
meta: resetMeta()
|
meta: resetMeta()
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
async initBoard(type: 'bird' | 'mobile-app', limit?: number) {
|
async initBoard(limit?: number) {
|
||||||
this.backlog = newBacklog(type, limit)
|
this.backlog = newBacklog(limit)
|
||||||
this.steps = featureSteps
|
this.steps = featureSteps
|
||||||
|
|
||||||
const initialSteps = featureSteps.filter(
|
const initialSteps = featureSteps.filter(
|
||||||
(step) => step.title !== 'Release' && step.title !== 'Development'
|
(step) => step.title !== 'Release' && step.title !== 'Development'
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,26 +1,7 @@
|
|||||||
import { newsAppFeatures } from '@/data/app-feature'
|
import { newsAppFeatures } from '@/data/app-feature'
|
||||||
import { birds } from '@/data/bird'
|
|
||||||
import { Feature } from '@/modules/pull-system/feature/feature'
|
import { Feature } from '@/modules/pull-system/feature/feature'
|
||||||
import { randomInteger } from '@/utils'
|
import { randomInteger } from '@/utils'
|
||||||
|
|
||||||
export const features: Feature[] = birds.map((name) => ({
|
|
||||||
name,
|
|
||||||
complexity: randomInteger(1, 5),
|
|
||||||
leadTime: 0,
|
|
||||||
status: 'doing',
|
|
||||||
step: Infinity,
|
|
||||||
qualityIssue: 0
|
|
||||||
}))
|
|
||||||
|
|
||||||
export const birdFeatures: readonly Feature[] = birds.map((name) => ({
|
|
||||||
name,
|
|
||||||
complexity: randomInteger(1, 5),
|
|
||||||
leadTime: 0,
|
|
||||||
status: 'doing',
|
|
||||||
step: Infinity,
|
|
||||||
qualityIssue: 0
|
|
||||||
}))
|
|
||||||
|
|
||||||
export const mobileAppFeatures: readonly Feature[] = newsAppFeatures.map(
|
export const mobileAppFeatures: readonly Feature[] = newsAppFeatures.map(
|
||||||
(name) => ({
|
(name) => ({
|
||||||
name,
|
name,
|
||||||
|
|||||||
@@ -45,12 +45,6 @@ const strategies: Strategy[] = ['push', 'pull']
|
|||||||
{{ simulationStore.meanTotalDays(strategy) }}
|
{{ simulationStore.meanTotalDays(strategy) }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td>Mean lead time</td>
|
|
||||||
<td class="numeric" v-for="strategy in strategies" :key="strategy">
|
|
||||||
{{ simulationStore.meanLeadTime(strategy) }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Min lead time</td>
|
<td>Min lead time</td>
|
||||||
<td class="numeric" v-for="strategy in strategies" :key="strategy">
|
<td class="numeric" v-for="strategy in strategies" :key="strategy">
|
||||||
@@ -71,6 +65,12 @@ const strategies: Strategy[] = ['push', 'pull']
|
|||||||
}}
|
}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Mean lead time</td>
|
||||||
|
<td class="numeric" v-for="strategy in strategies" :key="strategy">
|
||||||
|
{{ simulationStore.meanLeadTime(strategy) }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<!-- <tr>
|
<!-- <tr>
|
||||||
<td>Cycle time</td>
|
<td>Cycle time</td>
|
||||||
<td class="numeric" v-for="strategy in strategies" :key="strategy">
|
<td class="numeric" v-for="strategy in strategies" :key="strategy">
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export const useSimulationStore = defineStore('dashboard', {
|
|||||||
actions: {
|
actions: {
|
||||||
async simulate(strategy: Strategy) {
|
async simulate(strategy: Strategy) {
|
||||||
const steps = featureSteps
|
const steps = featureSteps
|
||||||
const backlog = await instance.newBacklog('mobile-app')
|
const backlog = await instance.newBacklog()
|
||||||
const features = await instance.initBoard(steps, backlog, true)
|
const features = await instance.initBoard(steps, backlog, true)
|
||||||
|
|
||||||
const newState = await instance.simulate(
|
const newState = await instance.simulate(
|
||||||
|
|||||||
5
src/shims-vue.d.ts
vendored
5
src/shims-vue.d.ts
vendored
@@ -1,6 +1 @@
|
|||||||
declare module '*.vue' {
|
|
||||||
import { defineComponent } from 'vue'
|
|
||||||
const component: ReturnType<typeof defineComponent>
|
|
||||||
export default component
|
|
||||||
}
|
|
||||||
declare module 'chart.xkcd'
|
declare module 'chart.xkcd'
|
||||||
|
|||||||
Reference in New Issue
Block a user