This commit is contained in:
louiscklaw
2025-01-31 19:30:10 +08:00
parent abff74fd77
commit d8e1289123
168 changed files with 91704 additions and 0 deletions

BIN
chris0243/2023-11-18_21-04.png (Stored with Git LFS) Normal file

Binary file not shown.

7
chris0243/gitUpdate.bat Normal file
View File

@@ -0,0 +1,7 @@
git status .
@pause
git add .
git commit -m"update chris0243,"
start git push

32
chris20202020/.prettierrc Normal file
View File

@@ -0,0 +1,32 @@
{
"arrowParens": "avoid",
"bracketSpacing": true,
"htmlWhitespaceSensitivity": "strict",
"insertPragma": false,
"jsxBracketSameLine": false,
"jsxSingleQuote": false,
"printWidth": 120,
"proseWrap": "preserve",
"quoteProps": "as-needed",
"requirePragma": false,
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all",
"useTabs": false,
"overrides": [
{
"files": [
"*.html"
],
"options": {}
},
{
"files": [
"*.{j,t}sx",
"*.{j,t}s"
],
"options": {}
}
]
}

15
chris20202020/README.md Normal file
View File

@@ -0,0 +1,15 @@
### to start
1. $ yarn start
1. then browse http://localhost:9080
- game-of-life speed
- [https://youtu.be/dvosJUDJJ-w](https://youtu.be/dvosJUDJJ-w)
- game-of-life start-stop
- [https://youtu.be/3CaQbHuAlqU](https://youtu.be/3CaQbHuAlqU)
- game-of-life resize
- [https://youtu.be/Klzl3StsqFo](https://youtu.be/Klzl3StsqFo)
- self-introduction
- [https://youtu.be/dvoLUdEwzJY](https://youtu.be/dvoLUdEwzJY)

BIN
chris20202020/_ref/1.docx Normal file

Binary file not shown.

BIN
chris20202020/_ref/1.pdf Normal file

Binary file not shown.

BIN
chris20202020/_ref/2.docx Normal file

Binary file not shown.

BIN
chris20202020/_ref/2.pdf Normal file

Binary file not shown.

BIN
chris20202020/_ref/3.pdf Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
A JavaScript implementation of [Conway's Game of Life](http://web.stanford.edu/%7Ecdebs/GameOfLife/).
- represents the board as 2D array of cells
- creates a second representation of board as 2D array of number of live neighbors
- uses map, filter, and reduce for calculation/iteration
`index.html` displays a canvas version of the program, with play/pause and reload buttons. (Play/pause can be triggered with the `Space` or `Enter` keys. Reloading can be triggered with the `r` key.)
Also, can run on the terminal or in the browser console.

View File

@@ -0,0 +1,135 @@
console.log('Loading Game of Life');
const {
newBoard,
neighborCoordinatesForBoard,
boardAsNumberOfNeighbors,
isLive,
isUnderPopulated,
isOverPopulated,
willContinue,
canReproduce,
SIZE
} = life;
const playPause = document.querySelector('[data-play-pause]');
const reload = document.querySelector('[data-reload]');
const startClass = 'fa-play';
const pauseClass = 'fa-pause';
const canvas = document.querySelector('#life');
const ctx = canvas.getContext('2d');
const {height, width} = canvas;
const UPDATE_FREQUENCY = 30;
const GRID_COUNT = SIZE;
const CELL_SIZE = width/GRID_COUNT;
const COLORS = {
// live: 'rgba(200, 0, 0, 1)',
live: 'rgba(40, 169, 255, 0.75)',
dead: 'rgba(255, 255, 255, 0.5)'
};
// Uses function declaration for binding `this`
// to the canvas context.
function _renderBox (isLive, xGrid, yGrid) {
this.lineWidth = 0.8;
this.strokeStyle = isLive ? COLORS.live : COLORS.dead;
this.strokeRect(xGrid*CELL_SIZE,
yGrid*CELL_SIZE,
CELL_SIZE,
CELL_SIZE);
}
//
const liveAt = _renderBox.bind(ctx, true);
const deadAt = _renderBox.bind(ctx, false);
const numberToIsLive = (number, cell) => {
if (isLive(cell)) {
if (isUnderPopulated(number)) {
// return DEAD;
return false;
} else if (isOverPopulated(number)) {
// return DEAD;
return false
} else if (willContinue(number)) {
// return LIVE;
return true;
}
} else if (canReproduce(number)){
// return LIVE;
return true;
} else {
// return DEAD;
return false;
}
};
// Given rows or boards of cells and neighbor counts, calculate next states.
const numberRowAsLiveDeadCells = (rowOfNumbers, rowOfCells) => rowOfNumbers.map((n, i) => numberToIsLive(n, rowOfCells[i]));
const numberBoardAsLiveDeadCells = (boardOfNumbers, boardOfCells) => boardOfNumbers.map((r, i) => numberRowAsLiveDeadCells(r, boardOfCells[i]));
const renderRow = (r, y) => r.map((c, i) => (c ? liveAt(i, y) : deadAt(i, y)) && c);
const renderBoard = b => b.map(renderRow);
let rafID;
let board = newBoard(true);
const coords = neighborCoordinatesForBoard(board);
let neighbors; // The game board as number of live neighbors per cell.
let isRunning = false;
const main = () => {
if (isRunning) {
// Given a board, calculate all the valid neighbor coordinates.
neighbors = boardAsNumberOfNeighbors(board, coords); // Calculate live neighbor counts.
board = numberBoardAsLiveDeadCells(neighbors, board); // Calculate next state of board.
renderBoard(board);
setTimeout(() => {
rafID = requestAnimationFrame(main);
}, UPDATE_FREQUENCY);
}
}
const togglePlaying = () => {
if (isRunning) {
cancelAnimationFrame(rafID);
playPause.querySelector('i').classList.add(startClass);
playPause.querySelector('i').classList.remove(pauseClass);
} else {
rafID = requestAnimationFrame(main);
playPause.querySelector('i').classList.remove(startClass);
playPause.querySelector('i').classList.add(pauseClass);
}
isRunning = !isRunning;
};
const reloadBoard = () => board = newBoard(true);
playPause.addEventListener('click', togglePlaying);
reload.addEventListener('click', reloadBoard);
document.addEventListener('keydown', (e) => {
console.log(e.keyCode);
if (e.getModifierState('Control')) {
return;
}
switch (e.keyCode) {
case 32:
case 13:
e.preventDefault();
togglePlaying()
break;
case 82:
e.preventDefault();
reloadBoard();
break;
}
})

View File

@@ -0,0 +1,48 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Document</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<style>
html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
justify-content: space-around;
align-items: center;
flex-direction: column;
background-color: rgba(40, 169, 255, 0.25);
}
canvas {
border: 1px solid rgba(0, 0, 0, 0.7);
background-color: #fff;
}
button {
width: 80px;
}
</style>
</head>
<body>
<canvas id="life"
width="420"
height="420">
Loading...
</canvas>
<div>
<button data-play-pause>
<i class="fa fa-play"></i>
</button>
<button data-reload>
<i class="fa fa-refresh"></i>
</button>
</div>
<script src="life.js"></script>
<script src="canvas.js"></script>
</body>
</html>

View File

@@ -0,0 +1,2 @@
const life = require('./life');
life();

View File

@@ -0,0 +1,172 @@
const life = (() => {
const SIZE = 42; // Size of (square) board
const INTERVAL = 300; // Frequency of screen updates
const THRESHOLD = 33; // % chance a cell will be seeded with life
// Printable representations of cells
let LIVE = "L";
let DEAD = " ";
// ---------------------------------------------------------------------
// The rules
/*
- Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.
- Any live cell with two or three live neighbours lives on to the next generation.
- Any live cell with more than three live neighbours dies, as if by overpopulation.
- Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
*/
const FEW = 2;
const MANY = 3;
const PLENTY = 3;
const isLive = c => c === LIVE;
const isUnderPopulated = n => n < FEW;
const isOverPopulated = n => n > MANY;
const canReproduce = n => n === PLENTY;
const willContinue = n => !(isUnderPopulated(n)) && !(isOverPopulated(n));
// ---------------------------------------------------------------------
const getRandomInt = (max, min=0) => {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive
}
// New boards are rows of DEAD cells, optionally seeded with LIVE cells.
const newRow = () => Array(SIZE).fill(DEAD);
const newBoard = shouldSeed => {
let board = newRow().map(newRow);
if (shouldSeed) {
board = board.map(row => row.map(_ => getRandomInt(100) < THRESHOLD ? LIVE : DEAD))
}
return board;
}
// When counting live neighbors, make sure to stay within array bounds.
const isWithinBounds = v => v >= 0 && v < SIZE;
const areWithinBounds = (x, y) => isWithinBounds(x) && isWithinBounds(y);
// Given a coordinate pair, return an array of valid neighbor coordinate pairs.
const neighborCoordinates = (x, y) => [
[x-1, y-1], [x, y-1], [x+1, y-1],
[x-1, y], [x+1, y],
[x-1, y+1], [x, y+1], [x+1, y+1],
].filter(xyArr => areWithinBounds(...xyArr));
// Functions to produce board containing coordinate pairs for each cell.
const coordsForRow = (r, x=0) => r.map((_, y) => [x, y]);
const coordsForBoard = b => b.map(coordsForRow);
// Functions to produce board containing array of valid neighbor coordinate pairs.
const neighborCoordinatesForRow = (r, x=0) => coordsForRow(r, x).map(xyArr => neighborCoordinates(...xyArr));
const neighborCoordinatesForBoard = b => b.map(neighborCoordinatesForRow);
// Retrieve value of cell at specified coordinates.
const cellAtCoorinate = (board, x, y) => board[x][y];
// Given a board and an array of neighbor coordinates, retrieve the neighbor cells.
const neighborCellsForCoordinateArray = (board, arrayOfNeighborCoors) => {
return arrayOfNeighborCoors.map(neighborCoordsForCell => {
return neighborCoordsForCell.map(coordsArray => {
return coordsArray.map(xyArray => cellAtCoorinate(board, ...xyArray))
})
})
};
// Given a board and an array of neighbor coordinates, return a board with the live neighbor count
// for each cell.
const boardAsNumberOfNeighbors = (board, arrayOfNeighborCoords) => {
return neighborCellsForCoordinateArray(board, arrayOfNeighborCoords).map(neighborCellsForRow => {
return neighborCellsForRow.map(neighborCellsForCell => {
return neighborCellsForCell
.filter(isLive)
.reduce((total, _) => total + 1, 0)
});
});
};
// Given a live neighbor count and a cell, calculate the cell's next state.
const numberToLiveDead = (number, cell) => {
if (isLive(cell)) {
if (isUnderPopulated(number)) {
return DEAD;
} else if (isOverPopulated(number)) {
return DEAD;
} else if (willContinue(number)) {
return LIVE;
}
} else if (canReproduce(number)){
return LIVE;
} else {
return DEAD;
}
};
// Given rows or boards of cells and neighbor counts, calculate next states.
const numberRowAsLiveDeadCells = (rowOfNumbers, rowOfCells) => rowOfNumbers.map((n, i) => numberToLiveDead(n, rowOfCells[i]));
const numberBoardAsLiveDeadCells = (boardOfNumbers, boardOfCells) => boardOfNumbers.map((r, i) => numberRowAsLiveDeadCells(r, boardOfCells[i]));
// Functions for printing to the console.
const printRow = r => r.join(' '); // A little horizontal space looks better
const printBoard = b => {
const boardAsString = b.map(printRow).join('\n');
console.log(boardAsString);
return boardAsString;
};
// The game loop!
const main = board => {
// Given a board, calculate all the valid neighbor coordinates.
const coords = neighborCoordinatesForBoard(board);
let neighbors; // The game board as number of live neighbors per cell.
let generation = 0; // What generation we're on.
let curr = ''; // Current generation as a string.
let prev = ''; // For checking if this generation is same as current - 1.
let prevMinusOne = ''; // For checking if this generation is same as current - 2.
let tick = setInterval(() => {
neighbors = boardAsNumberOfNeighbors(board, coords); // Calculate live neighbor counts.
board = numberBoardAsLiveDeadCells(neighbors, board); // Calculate next state of board.
console.clear();
prevMinusOne = prev.slice(); // Copy string representation of current - 2.
prev = curr.slice(); // Copy string representation of current - 1.
curr = printBoard(board); // Print board, saving string representation.
console.log(`Generation ${generation}`);
generation++;
// If the current generation is identical to one of the previous two,
// then we've reached the end of the simulation.
if (curr === prev || curr === prevMinusOne) {
clearInterval(tick);
}
}, INTERVAL);
};
if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
// This must be node!
module.exports = () => {
main(newBoard(true)); // Start game with new board, seeded with some live cells.
}
} else {
LIVE = true;
DEAD = false;
return {
newBoard,
neighborCoordinatesForBoard,
boardAsNumberOfNeighbors,
isLive,
isUnderPopulated,
isOverPopulated,
willContinue,
canReproduce,
SIZE
}
}
})();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
{
"name": "js-game-of-life",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"nodemon": "^1.17.1"
}
}

16
chris20202020/build.sh Normal file
View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
rm -rf _temp/*
rm -rf delivery.zip
mkdir -p _temp
set -ex
cp -r ./src/step2/* _temp/
pushd _temp
7za a -tzip ../delivery.zip *
popd
rm -rf _temp

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,7 @@
git status .
@pause
git add .
git commit -m"update chris20202020,"
start git push

0
chris20202020/index.css Normal file
View File

45
chris20202020/index.html Normal file
View File

@@ -0,0 +1,45 @@
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- public resources -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous" />
<!-- local resources -->
<link rel="stylesheet" href="/index.css"/>
</head>
<body>
<label class="form-label" for="customRange1">Example range</label>
<div id='canvas'></div>
<button id="reset-game">reset-game</button>
<button id="pause-game">pause-game</button>
<div id="game_status"></div>
<div>
<label for="volume">framerate</label>
<input type="range" id="frame-rate-range" name="frame-rate-range" min="10" max="100" step="10" />
<div id="frame-rate-value"></div>
</div>
<!-- public resources -->
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.2.0/p5.js"></script>
<!-- local resources -->
<script src="/index.js"></script>
</body>
</html>

250
chris20202020/index.js Normal file
View File

@@ -0,0 +1,250 @@
const unitLength = 20;
let boxColor = 150;
const strokeColor = 50;
let columns; /* To be determined by window width */
let rows; /* To be determined by window height */
let currentBoard;
let nextBoard;
let o_currentBoard;
let o_nextBoard;
let color_white = 255;
let paused_game = false;
let color_dice;
let color_dice_darken;
function getRandomInt(max) {
return Math.floor(Math.random() * max);
}
/**
* Initialize/reset the board state
*/
function init(fr) {
console.debug({ init: { fr } });
frameRate(fr || 10); // Attempt to refresh at starting FPS
for (let i = 0; i < columns; i++) {
for (let j = 0; j < rows; j++) {
currentBoard[i][j] = 0;
nextBoard[i][j] = 0;
o_currentBoard[i][j] = { alive: 0 };
o_nextBoard[i][j] = { alive: 0 };
}
}
}
function generate() {
//Loop over every single box on the board
for (let x = 0; x < columns; x++) {
for (let y = 0; y < rows; y++) {
// Count all living members in the Moore neighborhood(8 boxes surrounding)
let neighbors = 0;
let o_neighbors = 0;
for (let i of [-1, 0, 1]) {
for (let j of [-1, 0, 1]) {
if (i == 0 && j == 0) {
// the cell itself is not its own neighbor
continue;
}
// The modulo operator is crucial for wrapping on the edge
// neighbors += currentBoard[(x + i + columns) % columns][(y + j + rows) % rows];
o_neighbors += parseInt(o_currentBoard[(x + i + columns) % columns][(y + j + rows) % rows].alive);
// Rules of Life
if (o_currentBoard[x][y].alive == 1 && o_neighbors < 2) {
// Die of Loneliness
o_nextBoard[x][y] = { alive: 0 };
} else if (o_currentBoard[x][y].alive == 1 && o_neighbors > 3) {
// Die of Overpopulation
o_nextBoard[x][y] = { alive: 0 };
} else if (o_currentBoard[x][y].alive == 0 && o_neighbors == 3) {
// New life due to Reproduction
let color_idx = getRandomInt(color_dice_length);
o_nextBoard[x][y] = { alive: 1, color: color_dice[color_idx], color_idx };
} else {
// Stasis
o_nextBoard[x][y] = o_currentBoard[x][y];
o_nextBoard[x][y].color = color(64, 64, 64);
}
}
}
}
}
// Swap the nextBoard to be the current Board
[currentBoard, nextBoard] = [nextBoard, currentBoard];
[o_currentBoard, o_nextBoard] = [o_nextBoard, o_currentBoard];
}
function setup() {
console.log('setup');
// Setup logic here
boxColor = color(255, 204, 0);
color_dice = [
color(250, 211, 144),
color(106, 137, 204),
color(184, 233, 148),
color(248, 194, 145),
color(130, 204, 221),
];
color_dice_length = color_dice.length;
/* Set the canvas to be under the element #canvas*/
// NOTES:
// Let's look at some of the magic variables here. The magic variables include windowWidth, windowHeight, width and height. They are all provided by p5.js to make our life easier.
// windowWidth and windowHeight are the width and height of the viewport.
// width and height are the width and height of the canvas element.
const canvas = createCanvas(windowWidth, windowHeight - 100);
canvas.parent(document.querySelector('#canvas'));
/*Calculate the number of columns and rows */
// NOTES:
// We are calling createCanvas() with windowWidth and windowHeight - 100 to make a canvas that is as wide as the screen but 100 px shorter than the height.
// We then use .parent() to insert our canvas element to the element with id canvas.
columns = floor(width / unitLength);
rows = floor(height / unitLength);
/*Making both currentBoard and nextBoard 2-dimensional matrix that has (columns * rows) boxes. */
currentBoard = [];
nextBoard = [];
o_currentBoard = [];
o_nextBoard = [];
for (let i = 0; i < columns; i++) {
currentBoard[i] = [];
nextBoard[i] = [];
o_currentBoard[i] = [];
o_nextBoard[i] = [];
}
// Now both currentBoard and nextBoard are array of array of undefined values.
init(); // Set the initial values of the currentBoard and nextBoard
}
function draw() {
// draw logic here
background(255);
if (paused_game) {
//
} else {
generate();
}
for (let i = 0; i < columns; i++) {
for (let j = 0; j < rows; j++) {
if (o_currentBoard[i][j].alive == 1) {
// let idx = getRandomInt(color_dice_length);
// fill(color_dice[idx]);
fill(o_currentBoard[i][j].color);
} else {
fill(color_white);
}
stroke(strokeColor);
rect(i * unitLength, j * unitLength, unitLength, unitLength);
}
}
}
/**
* When mouse is dragged
*/
function mouseDragged() {
/**
* If the mouse coordinate is outside the board
*/
if (mouseX > unitLength * columns || mouseY > unitLength * rows) {
return;
}
const x = Math.floor(mouseX / unitLength);
const y = Math.floor(mouseY / unitLength);
currentBoard[x][y] = 1;
o_currentBoard[x][y] = { alive: 1, color: boxColor };
fill(boxColor);
stroke(strokeColor);
rect(x * unitLength, y * unitLength, unitLength, unitLength);
}
/**
* When mouse is pressed
*/
function mousePressed() {
noLoop();
mouseDragged();
}
/**
* When mouse is released
*/
function mouseReleased() {
loop();
}
function windowResized() {
resizeCanvas(window.innerWidth, window.innerHeight);
setup();
}
document.addEventListener('DOMContentLoaded', () => {
document.querySelector('#frame-rate-value').innerHTML = 10;
document.querySelector('#frame-rate-range').value = 10;
document.querySelector('#reset-game').addEventListener('click', function () {
init(10);
document.querySelector('#frame-rate-value').innerHTML = 10;
});
document.querySelector('#pause-game').addEventListener('click', function () {
paused_game = !paused_game;
if (paused_game) {
document.querySelector('#game_status').innerHTML = 'paused';
} else {
document.querySelector('#game_status').innerHTML = 'running';
}
});
document.querySelector('#frame-rate-range').addEventListener('change', function () {
let ele = document.querySelector('#frame-rate-range');
let framerate_value = ele.value;
document.querySelector('#frame-rate-value').innerHTML = framerate_value;
init(parseInt(framerate_value));
});
});
// Control speed of the Game of Life.
// (Checkout framerate, you can use slider to control the framerate )
// Allow users to change the rules of survival.
// Allow users to change the rules of reproduction.
// Start/Stop the Game of life
// Multiple colors of life on the same board.
// Darken colors for stable life.
// Random initial states
// Well-known patterns of Game of Life to select from (Examples: Gosper Glider Gun, Glider, Lightweight train).
// Use Keyboard to control the cursor to place the life
// Resize board on windows resize (Check out windowsResized)
// Switching between different styles.
// Anything else that you could think of.

View File

@@ -0,0 +1,14 @@
{
"name": "chris20202020",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"gitUpdate": "git add . && git commit -m \"update chris20202020,\" && git push",
"test": "echo \"Error: no test specified\" && exit 1",
"start": "npx static-server src/step2"
},
"keywords": [],
"author": "",
"license": "ISC"
}

View File

@@ -0,0 +1,29 @@
### Personal Project: Game of Life Enhanced
Now that you have finished our code along. It is time for you to unleash your creativity to continue on this project.
Here are some of the topics that you to work on:
- Landing Page for your Game of Life project.
- It should be a different html file from the Game of life page.
- A simple page to introduce yourself
Here are some of the topics that you to work on:
- Control speed of the Game of Life. (Checkout framerate, you can use slider tocontrol the framerate)
- Allow users to change the rules of survival.
- Allow users to change the rules of reproduction.
- Start/Stop the Game of life
- Multiple colors of life on the same board.
- Darken colors for stable life.
- Random initial states
- Well-known patterns of Game of Life to select from
- (Examples: Gosper Glider Gun, Glider, Lightweight train).
- Use Keyboard to control the cursor to place the life
- Resize board on windows resize (Check out windowsResized)
- Switching between different styles.
- Anything else that you could think of.
Let's build your own 2-D lives!

View File

@@ -0,0 +1 @@
1

View File

View File

@@ -0,0 +1,30 @@
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- public resources -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous" />
<!-- local resources -->
<link rel="stylesheet" href="index.css"/>
</head>
<body>
<div id='canvas'></div>
<!-- public resources -->
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.2.0/p5.js"></script>
<!-- local resources -->
<script src="index.js"></script>
</body>
</html>

View File

@@ -0,0 +1,9 @@
function setup() {
// Setup logic here
}
function draw() {
// draw logic here
console.log("helloworld");
}

View File

@@ -0,0 +1 @@
1

View File

View File

@@ -0,0 +1,34 @@
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- public resources -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous" />
<!-- local resources -->
<link rel="stylesheet" href="index.css"/>
</head>
<body>
<div id='canvas'></div>
<button id="reset-game">reset-game</button>
helloworld
<!-- public resources -->
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.2.0/p5.js"></script>
<!-- local resources -->
<script src="index.js"></script>
</body>
</html>

View File

@@ -0,0 +1,173 @@
const unitLength = 20;
const boxColor = 150;
const strokeColor = 50;
let columns; /* To be determined by window width */
let rows; /* To be determined by window height */
let currentBoard;
let nextBoard;
/**
* Initialize/reset the board state
*/
function init() {
console.log('init');
for (let i = 0; i < columns; i++) {
for (let j = 0; j < rows; j++) {
currentBoard[i][j] = 0;
nextBoard[i][j] = 0;
}
}
}
function generate() {
console.log('generate');
//Loop over every single box on the board
for (let x = 0; x < columns; x++) {
for (let y = 0; y < rows; y++) {
// Count all living members in the Moore neighborhood(8 boxes surrounding)
let neighbors = 0;
for (let i of [-1, 0, 1]) {
for (let j of [-1, 0, 1]) {
if (i == 0 && j == 0) {
// the cell itself is not its own neighbor
continue;
}
// The modulo operator is crucial for wrapping on the edge
neighbors += currentBoard[(x + i + columns) % columns][(y + j + rows) % rows];
}
}
// Rules of Life
if (currentBoard[x][y] == 1 && neighbors < 2) {
// Die of Loneliness
nextBoard[x][y] = 0;
} else if (currentBoard[x][y] == 1 && neighbors > 3) {
// Die of Overpopulation
nextBoard[x][y] = 0;
} else if (currentBoard[x][y] == 0 && neighbors == 3) {
// New life due to Reproduction
nextBoard[x][y] = 1;
} else {
// Stasis
nextBoard[x][y] = currentBoard[x][y];
}
}
}
// Swap the nextBoard to be the current Board
[currentBoard, nextBoard] = [nextBoard, currentBoard];
}
function setup() {
console.log('setup');
// Setup logic here
/* Set the canvas to be under the element #canvas*/
// NOTES:
// Let's look at some of the magic variables here. The magic variables include windowWidth, windowHeight, width and height. They are all provided by p5.js to make our life easier.
// windowWidth and windowHeight are the width and height of the viewport.
// width and height are the width and height of the canvas element.
const canvas = createCanvas(windowWidth, windowHeight - 100);
canvas.parent(document.querySelector('#canvas'));
/*Calculate the number of columns and rows */
// NOTES:
// We are calling createCanvas() with windowWidth and windowHeight - 100 to make a canvas that is as wide as the screen but 100 px shorter than the height.
// We then use .parent() to insert our canvas element to the element with id canvas.
columns = floor(width / unitLength);
rows = floor(height / unitLength);
/*Making both currentBoard and nextBoard 2-dimensional matrix that has (columns * rows) boxes. */
currentBoard = [];
nextBoard = [];
for (let i = 0; i < columns; i++) {
currentBoard[i] = [];
nextBoard[i] = [];
}
// Now both currentBoard and nextBoard are array of array of undefined values.
init(); // Set the initial values of the currentBoard and nextBoard
}
function draw() {
// draw logic here
console.log('draw');
background(255);
generate();
for (let i = 0; i < columns; i++) {
for (let j = 0; j < rows; j++) {
if (currentBoard[i][j] == 1) {
fill(boxColor);
} else {
fill(255);
}
stroke(strokeColor);
rect(i * unitLength, j * unitLength, unitLength, unitLength);
}
}
}
/**
* When mouse is dragged
*/
function mouseDragged() {
/**
* If the mouse coordinate is outside the board
*/
if (mouseX > unitLength * columns || mouseY > unitLength * rows) {
return;
}
const x = Math.floor(mouseX / unitLength);
const y = Math.floor(mouseY / unitLength);
currentBoard[x][y] = 1;
fill(boxColor);
stroke(strokeColor);
rect(x * unitLength, y * unitLength, unitLength, unitLength);
}
/**
* When mouse is pressed
*/
function mousePressed() {
noLoop();
mouseDragged();
}
/**
* When mouse is released
*/
function mouseReleased() {
loop();
}
document.querySelector('#reset-game').addEventListener('click', function () {
init();
});
// Control speed of the Game of Life.
// (Checkout framerate, you can use slider to control the framerate )
// Allow users to change the rules of survival.
// Allow users to change the rules of reproduction.
// Start/Stop the Game of life
// Multiple colors of life on the same board.
// Darken colors for stable life.
// Random initial states
// Well-known patterns of Game of Life to select from (Examples: Gosper Glider Gun, Glider, Lightweight train).
// Use Keyboard to control the cursor to place the life
// Resize board on windows resize (Check out windowsResized)
// Switching between different styles.
// Anything else that you could think of.

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
A simple page to introduce yourself
</body>
</html>

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
Landing Page for your Game of Life project. It should be a different html file from the Game of life page.
</body>
</html>

File diff suppressed because it is too large Load Diff

BIN
chris20202020/src/step2/assets/img/apple-touch-icon.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
chris20202020/src/step2/assets/img/favicon.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
chris20202020/src/step2/assets/img/hero-bg.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
chris20202020/src/step2/assets/img/portfolio/portfolio-1.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
chris20202020/src/step2/assets/img/portfolio/portfolio-2.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
chris20202020/src/step2/assets/img/portfolio/portfolio-3.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
chris20202020/src/step2/assets/img/portfolio/portfolio-4.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
chris20202020/src/step2/assets/img/portfolio/portfolio-5.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
chris20202020/src/step2/assets/img/portfolio/portfolio-6.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
chris20202020/src/step2/assets/img/portfolio/portfolio-7.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
chris20202020/src/step2/assets/img/portfolio/portfolio-8.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
chris20202020/src/step2/assets/img/portfolio/portfolio-9.jpg (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
chris20202020/src/step2/assets/img/profile-img.jpg (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,261 @@
/**
* Template Name: iPortfolio - v3.10.0
* Template URL: https://bootstrapmade.com/iportfolio-bootstrap-portfolio-websites-template/
* Author: BootstrapMade.com
* License: https://bootstrapmade.com/license/
*/
(function() {
"use strict";
/**
* Easy selector helper function
*/
const select = (el, all = false) => {
el = el.trim()
if (all) {
return [...document.querySelectorAll(el)]
} else {
return document.querySelector(el)
}
}
/**
* Easy event listener function
*/
const on = (type, el, listener, all = false) => {
let selectEl = select(el, all)
if (selectEl) {
if (all) {
selectEl.forEach(e => e.addEventListener(type, listener))
} else {
selectEl.addEventListener(type, listener)
}
}
}
/**
* Easy on scroll event listener
*/
const onscroll = (el, listener) => {
el.addEventListener('scroll', listener)
}
/**
* Navbar links active state on scroll
*/
let navbarlinks = select('#navbar .scrollto', true)
const navbarlinksActive = () => {
let position = window.scrollY + 200
navbarlinks.forEach(navbarlink => {
if (!navbarlink.hash) return
let section = select(navbarlink.hash)
if (!section) return
if (position >= section.offsetTop && position <= (section.offsetTop + section.offsetHeight)) {
navbarlink.classList.add('active')
} else {
navbarlink.classList.remove('active')
}
})
}
window.addEventListener('load', navbarlinksActive)
onscroll(document, navbarlinksActive)
/**
* Scrolls to an element with header offset
*/
const scrollto = (el) => {
let elementPos = select(el).offsetTop
window.scrollTo({
top: elementPos,
behavior: 'smooth'
})
}
/**
* Back to top button
*/
let backtotop = select('.back-to-top')
if (backtotop) {
const toggleBacktotop = () => {
if (window.scrollY > 100) {
backtotop.classList.add('active')
} else {
backtotop.classList.remove('active')
}
}
window.addEventListener('load', toggleBacktotop)
onscroll(document, toggleBacktotop)
}
/**
* Mobile nav toggle
*/
on('click', '.mobile-nav-toggle', function(e) {
select('body').classList.toggle('mobile-nav-active')
this.classList.toggle('bi-list')
this.classList.toggle('bi-x')
})
/**
* Scrool with ofset on links with a class name .scrollto
*/
on('click', '.scrollto', function(e) {
if (select(this.hash)) {
e.preventDefault()
let body = select('body')
if (body.classList.contains('mobile-nav-active')) {
body.classList.remove('mobile-nav-active')
let navbarToggle = select('.mobile-nav-toggle')
navbarToggle.classList.toggle('bi-list')
navbarToggle.classList.toggle('bi-x')
}
scrollto(this.hash)
}
}, true)
/**
* Scroll with ofset on page load with hash links in the url
*/
window.addEventListener('load', () => {
if (window.location.hash) {
if (select(window.location.hash)) {
scrollto(window.location.hash)
}
}
});
/**
* Hero type effect
*/
const typed = select('.typed')
if (typed) {
let typed_strings = typed.getAttribute('data-typed-items')
typed_strings = typed_strings.split(',')
new Typed('.typed', {
strings: typed_strings,
loop: true,
typeSpeed: 100,
backSpeed: 50,
backDelay: 2000
});
}
/**
* Skills animation
*/
let skilsContent = select('.skills-content');
if (skilsContent) {
new Waypoint({
element: skilsContent,
offset: '80%',
handler: function(direction) {
let progress = select('.progress .progress-bar', true);
progress.forEach((el) => {
el.style.width = el.getAttribute('aria-valuenow') + '%'
});
}
})
}
/**
* Porfolio isotope and filter
*/
window.addEventListener('load', () => {
let portfolioContainer = select('.portfolio-container');
if (portfolioContainer) {
let portfolioIsotope = new Isotope(portfolioContainer, {
itemSelector: '.portfolio-item'
});
let portfolioFilters = select('#portfolio-flters li', true);
on('click', '#portfolio-flters li', function(e) {
e.preventDefault();
portfolioFilters.forEach(function(el) {
el.classList.remove('filter-active');
});
this.classList.add('filter-active');
portfolioIsotope.arrange({
filter: this.getAttribute('data-filter')
});
portfolioIsotope.on('arrangeComplete', function() {
AOS.refresh()
});
}, true);
}
});
/**
* Initiate portfolio lightbox
*/
const portfolioLightbox = GLightbox({
selector: '.portfolio-lightbox'
});
/**
* Portfolio details slider
*/
new Swiper('.portfolio-details-slider', {
speed: 400,
loop: true,
autoplay: {
delay: 5000,
disableOnInteraction: false
},
pagination: {
el: '.swiper-pagination',
type: 'bullets',
clickable: true
}
});
/**
* Testimonials slider
*/
new Swiper('.testimonials-slider', {
speed: 600,
loop: true,
autoplay: {
delay: 5000,
disableOnInteraction: false
},
slidesPerView: 'auto',
pagination: {
el: '.swiper-pagination',
type: 'bullets',
clickable: true
},
breakpoints: {
320: {
slidesPerView: 1,
spaceBetween: 20
},
1200: {
slidesPerView: 3,
spaceBetween: 20
}
}
});
/**
* Animation on scroll
*/
window.addEventListener('load', () => {
AOS.init({
duration: 1000,
easing: 'ease-in-out',
once: true,
mirror: false
})
});
/**
* Initiate Pure Counter
*/
new PureCounter();
})()

View File

@@ -0,0 +1 @@
The .scss (Sass) files are only avilable in the pro version. You can buy it from: https://bootstrapmade.com/iportfolio-bootstrap-portfolio-websites-template/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,488 @@
/*!
* Bootstrap Reboot v5.2.3 (https://getbootstrap.com/)
* Copyright 2011-2022 The Bootstrap Authors
* Copyright 2011-2022 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
:root {
--bs-blue: #0d6efd;
--bs-indigo: #6610f2;
--bs-purple: #6f42c1;
--bs-pink: #d63384;
--bs-red: #dc3545;
--bs-orange: #fd7e14;
--bs-yellow: #ffc107;
--bs-green: #198754;
--bs-teal: #20c997;
--bs-cyan: #0dcaf0;
--bs-black: #000;
--bs-white: #fff;
--bs-gray: #6c757d;
--bs-gray-dark: #343a40;
--bs-gray-100: #f8f9fa;
--bs-gray-200: #e9ecef;
--bs-gray-300: #dee2e6;
--bs-gray-400: #ced4da;
--bs-gray-500: #adb5bd;
--bs-gray-600: #6c757d;
--bs-gray-700: #495057;
--bs-gray-800: #343a40;
--bs-gray-900: #212529;
--bs-primary: #0d6efd;
--bs-secondary: #6c757d;
--bs-success: #198754;
--bs-info: #0dcaf0;
--bs-warning: #ffc107;
--bs-danger: #dc3545;
--bs-light: #f8f9fa;
--bs-dark: #212529;
--bs-primary-rgb: 13, 110, 253;
--bs-secondary-rgb: 108, 117, 125;
--bs-success-rgb: 25, 135, 84;
--bs-info-rgb: 13, 202, 240;
--bs-warning-rgb: 255, 193, 7;
--bs-danger-rgb: 220, 53, 69;
--bs-light-rgb: 248, 249, 250;
--bs-dark-rgb: 33, 37, 41;
--bs-white-rgb: 255, 255, 255;
--bs-black-rgb: 0, 0, 0;
--bs-body-color-rgb: 33, 37, 41;
--bs-body-bg-rgb: 255, 255, 255;
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
--bs-body-font-family: var(--bs-font-sans-serif);
--bs-body-font-size: 1rem;
--bs-body-font-weight: 400;
--bs-body-line-height: 1.5;
--bs-body-color: #212529;
--bs-body-bg: #fff;
--bs-border-width: 1px;
--bs-border-style: solid;
--bs-border-color: #dee2e6;
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
--bs-border-radius: 0.375rem;
--bs-border-radius-sm: 0.25rem;
--bs-border-radius-lg: 0.5rem;
--bs-border-radius-xl: 1rem;
--bs-border-radius-2xl: 2rem;
--bs-border-radius-pill: 50rem;
--bs-link-color: #0d6efd;
--bs-link-hover-color: #0a58ca;
--bs-code-color: #d63384;
--bs-highlight-bg: #fff3cd;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
@media (prefers-reduced-motion: no-preference) {
:root {
scroll-behavior: smooth;
}
}
body {
margin: 0;
font-family: var(--bs-body-font-family);
font-size: var(--bs-body-font-size);
font-weight: var(--bs-body-font-weight);
line-height: var(--bs-body-line-height);
color: var(--bs-body-color);
text-align: var(--bs-body-text-align);
background-color: var(--bs-body-bg);
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
hr {
margin: 1rem 0;
color: inherit;
border: 0;
border-top: 1px solid;
opacity: 0.25;
}
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
font-weight: 500;
line-height: 1.2;
}
h1 {
font-size: calc(1.375rem + 1.5vw);
}
@media (min-width: 1200px) {
h1 {
font-size: 2.5rem;
}
}
h2 {
font-size: calc(1.325rem + 0.9vw);
}
@media (min-width: 1200px) {
h2 {
font-size: 2rem;
}
}
h3 {
font-size: calc(1.3rem + 0.6vw);
}
@media (min-width: 1200px) {
h3 {
font-size: 1.75rem;
}
}
h4 {
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
h4 {
font-size: 1.5rem;
}
}
h5 {
font-size: 1.25rem;
}
h6 {
font-size: 1rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul {
padding-left: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: 0.5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 0.875em;
}
mark {
padding: 0.1875em;
background-color: var(--bs-highlight-bg);
}
sub,
sup {
position: relative;
font-size: 0.75em;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
a {
color: var(--bs-link-color);
text-decoration: underline;
}
a:hover {
color: var(--bs-link-hover-color);
}
a:not([href]):not([class]), a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: var(--bs-font-monospace);
font-size: 1em;
}
pre {
display: block;
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
font-size: 0.875em;
}
pre code {
font-size: inherit;
color: inherit;
word-break: normal;
}
code {
font-size: 0.875em;
color: var(--bs-code-color);
word-wrap: break-word;
}
a > code {
color: inherit;
}
kbd {
padding: 0.1875rem 0.375rem;
font-size: 0.875em;
color: var(--bs-body-bg);
background-color: var(--bs-body-color);
border-radius: 0.25rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
}
figure {
margin: 0 0 1rem;
}
img,
svg {
vertical-align: middle;
}
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
color: #6c757d;
text-align: left;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
label {
display: inline-block;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
select {
text-transform: none;
}
[role=button] {
cursor: pointer;
}
select {
word-wrap: normal;
}
select:disabled {
opacity: 1;
}
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
display: none !important;
}
button,
[type=button],
[type=reset],
[type=submit] {
-webkit-appearance: button;
}
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
cursor: pointer;
}
::-moz-focus-inner {
padding: 0;
border-style: none;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
float: left;
width: 100%;
padding: 0;
margin-bottom: 0.5rem;
font-size: calc(1.275rem + 0.3vw);
line-height: inherit;
}
@media (min-width: 1200px) {
legend {
font-size: 1.5rem;
}
}
legend + * {
clear: left;
}
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
[type=search] {
outline-offset: -2px;
-webkit-appearance: textfield;
}
/* rtl:raw:
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
*/
::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-color-swatch-wrapper {
padding: 0;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
::file-selector-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
iframe {
border: 0;
}
summary {
display: list-item;
cursor: pointer;
}
progress {
vertical-align: baseline;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,485 @@
/*!
* Bootstrap Reboot v5.2.3 (https://getbootstrap.com/)
* Copyright 2011-2022 The Bootstrap Authors
* Copyright 2011-2022 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
:root {
--bs-blue: #0d6efd;
--bs-indigo: #6610f2;
--bs-purple: #6f42c1;
--bs-pink: #d63384;
--bs-red: #dc3545;
--bs-orange: #fd7e14;
--bs-yellow: #ffc107;
--bs-green: #198754;
--bs-teal: #20c997;
--bs-cyan: #0dcaf0;
--bs-black: #000;
--bs-white: #fff;
--bs-gray: #6c757d;
--bs-gray-dark: #343a40;
--bs-gray-100: #f8f9fa;
--bs-gray-200: #e9ecef;
--bs-gray-300: #dee2e6;
--bs-gray-400: #ced4da;
--bs-gray-500: #adb5bd;
--bs-gray-600: #6c757d;
--bs-gray-700: #495057;
--bs-gray-800: #343a40;
--bs-gray-900: #212529;
--bs-primary: #0d6efd;
--bs-secondary: #6c757d;
--bs-success: #198754;
--bs-info: #0dcaf0;
--bs-warning: #ffc107;
--bs-danger: #dc3545;
--bs-light: #f8f9fa;
--bs-dark: #212529;
--bs-primary-rgb: 13, 110, 253;
--bs-secondary-rgb: 108, 117, 125;
--bs-success-rgb: 25, 135, 84;
--bs-info-rgb: 13, 202, 240;
--bs-warning-rgb: 255, 193, 7;
--bs-danger-rgb: 220, 53, 69;
--bs-light-rgb: 248, 249, 250;
--bs-dark-rgb: 33, 37, 41;
--bs-white-rgb: 255, 255, 255;
--bs-black-rgb: 0, 0, 0;
--bs-body-color-rgb: 33, 37, 41;
--bs-body-bg-rgb: 255, 255, 255;
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
--bs-body-font-family: var(--bs-font-sans-serif);
--bs-body-font-size: 1rem;
--bs-body-font-weight: 400;
--bs-body-line-height: 1.5;
--bs-body-color: #212529;
--bs-body-bg: #fff;
--bs-border-width: 1px;
--bs-border-style: solid;
--bs-border-color: #dee2e6;
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
--bs-border-radius: 0.375rem;
--bs-border-radius-sm: 0.25rem;
--bs-border-radius-lg: 0.5rem;
--bs-border-radius-xl: 1rem;
--bs-border-radius-2xl: 2rem;
--bs-border-radius-pill: 50rem;
--bs-link-color: #0d6efd;
--bs-link-hover-color: #0a58ca;
--bs-code-color: #d63384;
--bs-highlight-bg: #fff3cd;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
@media (prefers-reduced-motion: no-preference) {
:root {
scroll-behavior: smooth;
}
}
body {
margin: 0;
font-family: var(--bs-body-font-family);
font-size: var(--bs-body-font-size);
font-weight: var(--bs-body-font-weight);
line-height: var(--bs-body-line-height);
color: var(--bs-body-color);
text-align: var(--bs-body-text-align);
background-color: var(--bs-body-bg);
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
hr {
margin: 1rem 0;
color: inherit;
border: 0;
border-top: 1px solid;
opacity: 0.25;
}
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
font-weight: 500;
line-height: 1.2;
}
h1 {
font-size: calc(1.375rem + 1.5vw);
}
@media (min-width: 1200px) {
h1 {
font-size: 2.5rem;
}
}
h2 {
font-size: calc(1.325rem + 0.9vw);
}
@media (min-width: 1200px) {
h2 {
font-size: 2rem;
}
}
h3 {
font-size: calc(1.3rem + 0.6vw);
}
@media (min-width: 1200px) {
h3 {
font-size: 1.75rem;
}
}
h4 {
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
h4 {
font-size: 1.5rem;
}
}
h5 {
font-size: 1.25rem;
}
h6 {
font-size: 1rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul {
padding-right: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: 0.5rem;
margin-right: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 0.875em;
}
mark {
padding: 0.1875em;
background-color: var(--bs-highlight-bg);
}
sub,
sup {
position: relative;
font-size: 0.75em;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
a {
color: var(--bs-link-color);
text-decoration: underline;
}
a:hover {
color: var(--bs-link-hover-color);
}
a:not([href]):not([class]), a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: var(--bs-font-monospace);
font-size: 1em;
}
pre {
display: block;
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
font-size: 0.875em;
}
pre code {
font-size: inherit;
color: inherit;
word-break: normal;
}
code {
font-size: 0.875em;
color: var(--bs-code-color);
word-wrap: break-word;
}
a > code {
color: inherit;
}
kbd {
padding: 0.1875rem 0.375rem;
font-size: 0.875em;
color: var(--bs-body-bg);
background-color: var(--bs-body-color);
border-radius: 0.25rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
}
figure {
margin: 0 0 1rem;
}
img,
svg {
vertical-align: middle;
}
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
color: #6c757d;
text-align: right;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
label {
display: inline-block;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
select {
text-transform: none;
}
[role=button] {
cursor: pointer;
}
select {
word-wrap: normal;
}
select:disabled {
opacity: 1;
}
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
display: none !important;
}
button,
[type=button],
[type=reset],
[type=submit] {
-webkit-appearance: button;
}
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
cursor: pointer;
}
::-moz-focus-inner {
padding: 0;
border-style: none;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
float: right;
width: 100%;
padding: 0;
margin-bottom: 0.5rem;
font-size: calc(1.275rem + 0.3vw);
line-height: inherit;
}
@media (min-width: 1200px) {
legend {
font-size: 1.5rem;
}
}
legend + * {
clear: right;
}
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
[type=search] {
outline-offset: -2px;
-webkit-appearance: textfield;
}
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-color-swatch-wrapper {
padding: 0;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
::file-selector-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
iframe {
border: 0;
}
summary {
display: list-item;
cursor: pointer;
}
progress {
vertical-align: baseline;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More