mirror of
https://github.com/GeorgeSG/v0.gar.dev
synced 2025-12-28 21:30:29 +00:00
Modernize
This commit is contained in:
45
.eslintrc.js
Normal file
45
.eslintrc.js
Normal file
@@ -0,0 +1,45 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es6: true
|
||||
},
|
||||
extends: [
|
||||
"eslint:recommended",
|
||||
"@nuxtjs/eslint-config-typescript",
|
||||
|
||||
// Uses the recommended rules from the @typescript-eslint/eslint-plugin
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
|
||||
// Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict
|
||||
// with prettier
|
||||
"prettier/@typescript-eslint",
|
||||
|
||||
// Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors.
|
||||
// Make sure this is always the last configuration in the extends array.
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
globals: {
|
||||
Atomics: "readonly",
|
||||
SharedArrayBuffer: "readonly"
|
||||
},
|
||||
plugins: ["vue", "@typescript-eslint"],
|
||||
rules: {
|
||||
camelcase: "off",
|
||||
"no-console": ["error", { allow: ["warn", "error"] }],
|
||||
|
||||
"no-useless-constructor": "off",
|
||||
"@typescript-eslint/no-useless-constructor": "error",
|
||||
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
vars: "all",
|
||||
args: "after-used",
|
||||
ignoreRestSiblings: false
|
||||
}
|
||||
],
|
||||
|
||||
"getter-return": "off"
|
||||
}
|
||||
};
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,3 @@
|
||||
.nuxt/
|
||||
dist/
|
||||
node_modules/
|
||||
static/ecmascript-explained-2019
|
||||
|
||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -1,6 +0,0 @@
|
||||
[submodule "sumbodules/ecmascript-explained-2019"]
|
||||
path = sumbodules/ecmascript-explained-2019
|
||||
url = git@github.com:GeorgeSG/ecmascript-explained-2019.git
|
||||
[submodule "submodules/ecmascript-explained-2019"]
|
||||
path = submodules/ecmascript-explained-2019
|
||||
url = git@github.com:GeorgeSG/ecmascript-explained-2019.git
|
||||
5
.prettierrc
Normal file
5
.prettierrc
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"printWidth": 100
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"printWidth": 120
|
||||
}
|
||||
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"files.exclude": {
|
||||
"**/.nuxt/": true,
|
||||
"**/dist/": true,
|
||||
"**/node_modules/": true,
|
||||
"submodules/": true
|
||||
}
|
||||
}
|
||||
8
Makefile
8
Makefile
@@ -1,8 +0,0 @@
|
||||
clean:
|
||||
rm -rf ./static/ecmascript-explained-2019
|
||||
|
||||
prod:
|
||||
mkdir -p ./static
|
||||
cd ./submodules/ecmascript-explained-2019 && make prod
|
||||
cp -r ./submodules/ecmascript-explained-2019/dist ./static/ecmascript-explained-2019
|
||||
yarn && yarn generate
|
||||
@@ -1,12 +1,3 @@
|
||||
/*
|
||||
Colors: ;
|
||||
Light Blue: #19C4FF
|
||||
Dark Blue: #0085B2
|
||||
Light Orange: #FF8F19
|
||||
Dark Orange: #B26009
|
||||
Light Gray: #f5f5f5
|
||||
*/
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
@@ -14,7 +5,7 @@ body {
|
||||
font-family: "Verdana", sans-serif;
|
||||
font-size: 100%;
|
||||
|
||||
background: #f5f5f5;
|
||||
background: $color-light-gray;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
@@ -29,7 +20,7 @@ h1 {
|
||||
margin-top: 3em;
|
||||
margin-bottom: 0;
|
||||
font-size: 2em;
|
||||
color: #0085b2;
|
||||
color: $color-dark-blue;
|
||||
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);
|
||||
}
|
||||
|
||||
|
||||
10
assets/styles/variables.scss
Normal file
10
assets/styles/variables.scss
Normal file
@@ -0,0 +1,10 @@
|
||||
$color-light-blue: #19C4FF;
|
||||
$color-dark-blue: #0085B2;
|
||||
$color-light-orange: #FF8F19;
|
||||
$color-dark-orange: #B26009;
|
||||
$color-gray: #bbb;
|
||||
$color-light-gray: #f5f5f5;
|
||||
$color-dark-gray: #666;
|
||||
|
||||
$color-white: #ffffff;
|
||||
|
||||
@@ -5,21 +5,22 @@
|
||||
:key="index"
|
||||
:state="cellState"
|
||||
:disabled="finished"
|
||||
@select="$emit('place', index)")
|
||||
@select="$emit('place', index)"
|
||||
)
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue, Prop } from "vue-property-decorator";
|
||||
import Cell from "./Cell/Cell.vue";
|
||||
import { CellState } from "~/plugins/tic-tac-toe/cell-state";
|
||||
import { Component, Vue, Prop } from 'vue-property-decorator';
|
||||
import Cell from './Cell/Cell.vue';
|
||||
import { CellState } from '~/lib/tic-tac-toe/cell-state';
|
||||
|
||||
@Component({ components: { Cell } })
|
||||
export default class Board extends Vue {
|
||||
@Prop({ required: true })
|
||||
cellStates: CellState[];
|
||||
readonly cellStates: CellState[];
|
||||
|
||||
@Prop({ required: false, default: false })
|
||||
finished: boolean;
|
||||
readonly finished: boolean;
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -30,8 +31,8 @@ export default class Board extends Vue {
|
||||
margin: 0 auto;
|
||||
width: 210px;
|
||||
height: 210px;
|
||||
background: #fff;
|
||||
border-left: 1px solid #ccc;
|
||||
border-top: 1px solid #ccc;
|
||||
background: $color-white;
|
||||
border-left: 1px solid $color-gray;
|
||||
border-top: 1px solid $color-gray;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,26 +1,30 @@
|
||||
<template lang="pug">
|
||||
input.cell(:disabled="disabled" type="button" @click="$emit('select')" :class="classNames")
|
||||
input.cell(:disabled="disabled" type="button" @click="onSelect" :class="classNames")
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue, Prop } from "vue-property-decorator";
|
||||
import { CellState } from "~/plugins/tic-tac-toe/cell-state";
|
||||
import { Component, Vue, Prop } from 'vue-property-decorator';
|
||||
import { CellState } from '~/lib/tic-tac-toe/cell-state';
|
||||
|
||||
@Component
|
||||
export default class Cell extends Vue {
|
||||
@Prop({ required: false, default: null })
|
||||
state: CellState;
|
||||
readonly state: CellState | null;
|
||||
|
||||
@Prop({ required: false, default: false })
|
||||
disabled: boolean;
|
||||
readonly disabled: boolean;
|
||||
|
||||
get classNames() {
|
||||
return {
|
||||
placed: this.state !== null,
|
||||
x: this.state === "x",
|
||||
o: this.state === "o"
|
||||
x: this.state === 'x',
|
||||
o: this.state === 'o'
|
||||
};
|
||||
}
|
||||
|
||||
onSelect() {
|
||||
this.$emit('select');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -28,15 +32,15 @@ export default class Cell extends Vue {
|
||||
.cell {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
background: #fff;
|
||||
background: $color-white;
|
||||
border-top: 0;
|
||||
border-left: 0;
|
||||
border-right: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-right: 1px solid $color-gray;
|
||||
border-bottom: 1px solid $color-gray;
|
||||
|
||||
&:not(.placed):not(:disabled):hover {
|
||||
cursor: pointer;
|
||||
background: #0085b2;
|
||||
background: $color-dark-blue;
|
||||
}
|
||||
|
||||
&:not(.placed):not(:disabled):active {
|
||||
|
||||
@@ -10,47 +10,49 @@
|
||||
label(:class="{ selected: difficulty === 'hard'}")
|
||||
input#hard(type="radio" v-model="difficulty" name="difficulty" value="hard")
|
||||
| hard
|
||||
|
||||
Board(:cellStates="cellStates" :finished="finished" @place="place")
|
||||
button.new-game(@click="newGame") new game
|
||||
p.result {{ lastResultString }}
|
||||
.stats
|
||||
h2 stats
|
||||
table
|
||||
tr
|
||||
td wins
|
||||
td.wins.count {{ wins }}
|
||||
tr
|
||||
td draws
|
||||
td.draws.count {{ draws }}
|
||||
tr
|
||||
td losses
|
||||
td.losses.count {{ losses }}
|
||||
tbody
|
||||
tr
|
||||
td wins
|
||||
td.wins.count {{ wins }}
|
||||
tr
|
||||
td draws
|
||||
td.draws.count {{ draws }}
|
||||
tr
|
||||
td losses
|
||||
td.losses.count {{ losses }}
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue, Watch } from "vue-property-decorator";
|
||||
import Board from "./Board/Board.vue";
|
||||
import Game from "~/plugins/tic-tac-toe/game";
|
||||
import { AI } from "~/plugins/tic-tac-toe/ai";
|
||||
import Player from "~/plugins/tic-tac-toe/player";
|
||||
import { CellState } from "~/plugins/tic-tac-toe/cell-state";
|
||||
import { Component, Vue, Watch } from 'vue-property-decorator';
|
||||
import Board from './Board/Board.vue';
|
||||
import { Game } from '~/lib/tic-tac-toe/game';
|
||||
import { AI } from '~/lib/tic-tac-toe/ai';
|
||||
import { Player } from '~/lib/tic-tac-toe/player';
|
||||
import { CellState } from '~/lib/tic-tac-toe/cell-state';
|
||||
|
||||
@Component({ components: { Board } })
|
||||
export default class TicTacToe extends Vue {
|
||||
wins: number = 0;
|
||||
draws: number = 0;
|
||||
losses: number = 0;
|
||||
lastResultString: string = "";
|
||||
private wins: number = 0;
|
||||
private draws: number = 0;
|
||||
private losses: number = 0;
|
||||
private lastResultString: string = '';
|
||||
|
||||
cellStates: CellState[] = [];
|
||||
finished: boolean = false;
|
||||
private cellStates: CellState[] = [];
|
||||
private finished: boolean = false;
|
||||
|
||||
difficulty: AI.Difficulty = "normal";
|
||||
private difficulty: AI.Difficulty = 'normal';
|
||||
|
||||
private game: Game;
|
||||
private ai: AI;
|
||||
|
||||
@Watch("difficulty", { immediate: true })
|
||||
@Watch('difficulty', { immediate: true })
|
||||
onDifficultyChange(newDifficulty: AI.Difficulty) {
|
||||
if (this.ai) {
|
||||
this.ai.difficulty = newDifficulty;
|
||||
@@ -66,7 +68,7 @@ export default class TicTacToe extends Vue {
|
||||
this.ai = new AI(this.game, this.difficulty);
|
||||
this.cellStates = this.game.copyBoard();
|
||||
this.finished = false;
|
||||
this.lastResultString = "";
|
||||
this.lastResultString = '';
|
||||
}
|
||||
|
||||
place(index: number) {
|
||||
@@ -94,10 +96,10 @@ export default class TicTacToe extends Vue {
|
||||
switch (this.game.winner) {
|
||||
case Player.HUMAN:
|
||||
this.wins++;
|
||||
this.lastResultString = "You win! Congratulations!";
|
||||
this.lastResultString = 'You win! Congratulations!';
|
||||
break;
|
||||
case Player.AI:
|
||||
this.lastResultString = "The AI won. Better luck next time!";
|
||||
this.lastResultString = 'The AI won. Better luck next time!';
|
||||
this.losses++;
|
||||
break;
|
||||
default:
|
||||
@@ -113,16 +115,16 @@ export default class TicTacToe extends Vue {
|
||||
cursor: pointer;
|
||||
padding: 10px 20px;
|
||||
margin-top: 10px;
|
||||
background: #fff;
|
||||
color: #0085b2;
|
||||
background: $color-white;
|
||||
color: $color-dark-blue;
|
||||
text-decoration: none;
|
||||
|
||||
border: 1px solid #0085b2;
|
||||
border: 1px solid $color-dark-blue;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
background: #0085b2;
|
||||
color: #fff;
|
||||
background: $color-dark-blue;
|
||||
color: $color-white;
|
||||
}
|
||||
|
||||
&:active {
|
||||
@@ -143,26 +145,26 @@ export default class TicTacToe extends Vue {
|
||||
text-align: center;
|
||||
font-size: 0.8em;
|
||||
cursor: pointer;
|
||||
background: #0085b2;
|
||||
color: #fff;
|
||||
border-bottom: 1px solid #00678a;
|
||||
border-top: 1px solid #00678a;
|
||||
background: $color-dark-blue;
|
||||
color: $color-white;
|
||||
border-bottom: 1px solid $color-dark-blue;
|
||||
border-top: 1px solid $color-dark-blue;
|
||||
|
||||
&:first-of-type {
|
||||
margin-left: 0;
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
border: 1px solid #00678a;
|
||||
border: 1px solid $color-dark-blue;
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border: 1px solid #00678a;
|
||||
border: 1px solid $color-dark-blue;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #00678a;
|
||||
background: $color-dark-blue;
|
||||
}
|
||||
|
||||
&:active {
|
||||
@@ -176,11 +178,11 @@ export default class TicTacToe extends Vue {
|
||||
|
||||
> .selected {
|
||||
cursor: default;
|
||||
background: #ff8f19;
|
||||
border-color: #b26009 !important;
|
||||
background: $color-light-orange;
|
||||
border-color: $color-dark-orange !important;
|
||||
|
||||
&:hover {
|
||||
background: #ff8f19;
|
||||
background: $color-light-orange;
|
||||
}
|
||||
|
||||
&:active {
|
||||
@@ -198,9 +200,9 @@ export default class TicTacToe extends Vue {
|
||||
> h2 {
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
color: #0085b2;
|
||||
color: $color-dark-blue;
|
||||
font-weight: normal;
|
||||
border-bottom: 1px solid #0085b2;
|
||||
border-bottom: 1px solid $color-dark-blue;
|
||||
}
|
||||
|
||||
table {
|
||||
@@ -217,21 +219,21 @@ export default class TicTacToe extends Vue {
|
||||
display: inline-block;
|
||||
min-width: 15px;
|
||||
padding: 2px 3px;
|
||||
color: #fff;
|
||||
color: $color-white;
|
||||
text-align: center;
|
||||
font-size: 0.8em;
|
||||
border-radius: 2px;
|
||||
|
||||
&.wins {
|
||||
background: #0085b2;
|
||||
background: $color-dark-blue;
|
||||
}
|
||||
|
||||
&.losses {
|
||||
background: #ff8f19;
|
||||
background: $color-light-orange;
|
||||
}
|
||||
|
||||
&.draws {
|
||||
background: #666;
|
||||
background: $color-dark-gray;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import Game from "./game";
|
||||
import { Game } from './game';
|
||||
|
||||
export class AI {
|
||||
class AI {
|
||||
private static readonly INFINITY = 9;
|
||||
|
||||
constructor(private game: Game, public difficulty: AI.Difficulty = "normal") {}
|
||||
constructor(private game: Game, public difficulty: AI.Difficulty = 'normal') {}
|
||||
|
||||
move() {
|
||||
const move = this.chooseMove();
|
||||
@@ -12,15 +12,15 @@ export class AI {
|
||||
|
||||
private chooseMove(): number[] {
|
||||
switch (this.difficulty) {
|
||||
case "easy":
|
||||
case 'easy':
|
||||
return this.randomChoice(this.game);
|
||||
case "normal":
|
||||
case 'normal':
|
||||
if (this.randomInt(0, 10) > 4) {
|
||||
return this.alphabetaChoice(this.game);
|
||||
} else {
|
||||
return this.randomChoice(this.game);
|
||||
}
|
||||
case "hard":
|
||||
case 'hard':
|
||||
return this.alphabetaChoice(this.game);
|
||||
}
|
||||
}
|
||||
@@ -134,6 +134,8 @@ export class AI {
|
||||
}
|
||||
}
|
||||
|
||||
export namespace AI {
|
||||
export type Difficulty = "easy" | "normal" | "hard";
|
||||
namespace AI {
|
||||
export type Difficulty = 'easy' | 'normal' | 'hard';
|
||||
}
|
||||
|
||||
export { AI };
|
||||
@@ -1,4 +1,4 @@
|
||||
type Token = "x" | "o";
|
||||
type Token = 'x' | 'o';
|
||||
type CellState = null | Token;
|
||||
|
||||
export { CellState, Token };
|
||||
3
lib/tic-tac-toe/difficulty.ts
Normal file
3
lib/tic-tac-toe/difficulty.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
type Difficulty = 'easy' | 'medium' | 'hard';
|
||||
|
||||
export { Difficulty };
|
||||
@@ -1,7 +1,7 @@
|
||||
import { CellState } from "./cell-state";
|
||||
import Player from "./player";
|
||||
import { CellState } from './cell-state';
|
||||
import { Player } from './player';
|
||||
|
||||
export default class Game {
|
||||
export class Game {
|
||||
private static readonly WINNING_STATES = [
|
||||
[0, 1, 2],
|
||||
[3, 4, 5],
|
||||
8
lib/tic-tac-toe/player.ts
Normal file
8
lib/tic-tac-toe/player.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { Token } from './cell-state';
|
||||
|
||||
export class Player {
|
||||
public static readonly HUMAN = new Player('x');
|
||||
public static readonly AI = new Player('o');
|
||||
|
||||
constructor(public token: Token) {}
|
||||
}
|
||||
@@ -1,40 +1,53 @@
|
||||
export default {
|
||||
buildModules: [
|
||||
'@nuxt/typescript-build',
|
||||
[
|
||||
'@nuxtjs/google-analytics',
|
||||
{
|
||||
id: 'UA-135058128-1'
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
head: {
|
||||
htmlAttrs: {
|
||||
lang: "en"
|
||||
lang: 'en'
|
||||
},
|
||||
title: "Georgi Gardev",
|
||||
title: 'Georgi Gardev',
|
||||
meta: [
|
||||
{ charset: "utf-8" },
|
||||
{ name: "author", content: "Georgi Gardev" },
|
||||
{ name: "owner", content: "Georgi Gardev" },
|
||||
{ name: "description", content: "Personal Homepage of Georgi Gardev" },
|
||||
{ name: "copyright", content: "Georgi Gardev 2014" },
|
||||
{ name: "robots", content: "index, follow" },
|
||||
{ name: "revisit-after", content: "2 days" },
|
||||
{ name: "GOOGLEBOT", content: "index, follow, all" },
|
||||
{ name: "audience", content: "all" },
|
||||
{ name: "viewport", content: "width=device-width, initial-scale=1" }
|
||||
{ charset: 'utf-8' },
|
||||
{ name: 'author', content: 'Georgi Gardev' },
|
||||
{ name: 'owner', content: 'Georgi Gardev' },
|
||||
{ name: 'description', content: 'Personal Homepage of Georgi Gardev' },
|
||||
{ name: 'copyright', content: 'Georgi Gardev 2014' },
|
||||
{ name: 'robots', content: 'index, follow' },
|
||||
{ name: 'revisit-after', content: '2 days' },
|
||||
{ name: 'GOOGLEBOT', content: 'index, follow, all' },
|
||||
{ name: 'audience', content: 'all' },
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
|
||||
]
|
||||
},
|
||||
css: [{ lang: "scss", src: "@/assets/styles/main.scss" }],
|
||||
css: ['~/assets/styles/main.scss'],
|
||||
modules: [
|
||||
'@nuxtjs/style-resources',
|
||||
[
|
||||
"nuxt-fontawesome",
|
||||
'nuxt-fontawesome',
|
||||
{
|
||||
component: "fa",
|
||||
component: 'fa',
|
||||
imports: [
|
||||
{
|
||||
set: "@fortawesome/free-solid-svg-icons",
|
||||
icons: ["fas"]
|
||||
set: '@fortawesome/free-solid-svg-icons',
|
||||
icons: ['fas']
|
||||
},
|
||||
{
|
||||
set: "@fortawesome/free-brands-svg-icons",
|
||||
icons: ["fab"]
|
||||
set: '@fortawesome/free-brands-svg-icons',
|
||||
icons: ['fab']
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
plugins: [{ src: "~/plugins/ga.js", ssr: false }]
|
||||
styleResources: {
|
||||
scss: ['assets/styles/variables.scss']
|
||||
}
|
||||
};
|
||||
|
||||
13252
package-lock.json
generated
Normal file
13252
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
51
package.json
51
package.json
@@ -2,33 +2,48 @@
|
||||
"name": "gardev.com",
|
||||
"description": "Georgi Gardev's personal website. Hosted at gardev.com",
|
||||
"version": "1.0.0",
|
||||
"license": "UNLICENSED",
|
||||
"private": true,
|
||||
"author": {
|
||||
"name": "Georgi Gardev",
|
||||
"email": "georgi@gardev.com",
|
||||
"url": "http://gardev.com"
|
||||
},
|
||||
"devDependencies": {
|
||||
"node-sass": "^4.11.0",
|
||||
"pug": "^2.0.3",
|
||||
"pug-plain-loader": "^1.0.0",
|
||||
"sass-loader": "^7.1.0",
|
||||
"tslint-config-prettier": "^1.18.0",
|
||||
"tslint-plugin-prettier": "^2.0.1"
|
||||
"engines": {
|
||||
"node": "12.15.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/free-brands-svg-icons": "^5.7.2",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.7.2",
|
||||
"nuxt-fontawesome": "^0.4.0",
|
||||
"nuxt-ts": "latest",
|
||||
"vue-property-decorator": "^7.3.0"
|
||||
},
|
||||
"license": "UNLICENSED",
|
||||
"scripts": {
|
||||
"dev": "nuxt-ts",
|
||||
"build": "nuxt-ts build",
|
||||
"start": "nuxt-ts start",
|
||||
"generate": "nuxt-ts generate",
|
||||
"lint": "prettier -c '**/*'",
|
||||
"format": "prettier --write '**/*'"
|
||||
"start": "nuxt-ts start",
|
||||
"test": "jest",
|
||||
"lint": "eslint --ext .ts,.js,.vue .",
|
||||
"lint-fix": "eslint --ext .ts,.js,.vue . --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/free-brands-svg-icons": "^5.12.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.12.1",
|
||||
"@nuxt/typescript-runtime": "^0.3.8",
|
||||
"@nuxtjs/style-resources": "^1.0.0",
|
||||
"nuxt": "^2.11.0",
|
||||
"nuxt-fontawesome": "^0.4.0",
|
||||
"vue-property-decorator": "^8.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxt/typescript-build": "^0.5.6",
|
||||
"@nuxtjs/eslint-config-typescript": "^1.0.2",
|
||||
"@nuxtjs/google-analytics": "^2.2.3",
|
||||
"@typescript-eslint/eslint-plugin": "^2.19.1",
|
||||
"@typescript-eslint/parser": "^2.19.1",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^6.10.0",
|
||||
"eslint-plugin-prettier": "^3.1.2",
|
||||
"node-sass": "^4.13.1",
|
||||
"prettier": "^1.19.1",
|
||||
"pug": "^2.0.4",
|
||||
"pug-plain-loader": "^1.0.0",
|
||||
"sass-loader": "^8.0.2",
|
||||
"tslint-config-prettier": "^1.18.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from "vue-property-decorator";
|
||||
import TicTacToe from "~/components/TicTacToe/TicTacToe.vue";
|
||||
import { Component, Vue } from 'vue-property-decorator';
|
||||
import TicTacToe from '~/components/TicTacToe/TicTacToe.vue';
|
||||
|
||||
@Component({ components: { TicTacToe } })
|
||||
export default class Home extends Vue {}
|
||||
@@ -34,17 +34,17 @@ export default class Home extends Vue {}
|
||||
|
||||
<style lang="scss">
|
||||
.social {
|
||||
color: #bbb;
|
||||
color: $color-gray;
|
||||
text-decoration: none;
|
||||
padding: 0 4px;
|
||||
border-radius: 5px;
|
||||
|
||||
&:hover {
|
||||
color: #0085b2;
|
||||
color: $color-dark-blue;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: #006385;
|
||||
color: $color-dark-blue;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
export default ({ app }) => {
|
||||
/*
|
||||
** Only run on client-side and only in production mode
|
||||
*/
|
||||
if (process.env.NODE_ENV !== 'production') return
|
||||
/*
|
||||
** Include Google Analytics Script
|
||||
*/
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
/*
|
||||
** Set the current page
|
||||
*/
|
||||
ga('create', 'UA-135058128-1', 'auto')
|
||||
/*
|
||||
** Every time the route changes (fired on initialization too)
|
||||
*/
|
||||
app.router.afterEach((to, from) => {
|
||||
/*
|
||||
** We tell Google Analytics to add a `pageview`
|
||||
*/
|
||||
ga('set', 'page', to.fullPath)
|
||||
ga('send', 'pageview')
|
||||
})
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
type Difficulty = "easy" | "medium" | "hard";
|
||||
|
||||
export default Difficulty;
|
||||
@@ -1,8 +0,0 @@
|
||||
import { Token } from "./cell-state";
|
||||
|
||||
export default class Player {
|
||||
public static readonly HUMAN = new Player("x");
|
||||
public static readonly AI = new Player("o");
|
||||
|
||||
constructor(public token: Token) {}
|
||||
}
|
||||
Submodule submodules/ecmascript-explained-2019 deleted from 0c5eca7037
@@ -1,16 +1,22 @@
|
||||
{
|
||||
"extends": "@nuxt/typescript",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"target": "es6",
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"lib": ["esnext", "esnext.asynciterable", "dom"],
|
||||
"esModuleInterop": true,
|
||||
"experimentalDecorators": true,
|
||||
"paths": {
|
||||
"~/plugins/*": ["./plugins/*"],
|
||||
"~/components/*": ["./components/*"],
|
||||
"~/pages/*": ["./pages/*"],
|
||||
"~/assets/*": ["./assets/*"]
|
||||
},
|
||||
"strictPropertyInitialization": false,
|
||||
"allowJs": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"types": ["@types/node", "@nuxt/vue-app"]
|
||||
}
|
||||
"noImplicitAny": false,
|
||||
"noEmit": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"~/*": ["./*"]
|
||||
},
|
||||
"types": ["@types/node", "@nuxt/types"]
|
||||
},
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
12
tslint.json
12
tslint.json
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"defaultSeverity": "warning",
|
||||
"extends": ["tslint:recommended", "tslint-config-prettier"],
|
||||
"rules": {
|
||||
"prettier": true,
|
||||
|
||||
"member-access": false,
|
||||
"no-namespace": false,
|
||||
"object-literal-sort-keys": false,
|
||||
"ordered-imports": false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user