mirror of
https://github.com/codeninjasgg/roblox-royale-camp.git
synced 2024-11-24 08:17:52 -05:00
Deploying to gh-pages from @ 3074536999
🚀
This commit is contained in:
parent
31240fd084
commit
4eb5c7c8cc
7 changed files with 109 additions and 98 deletions
|
@ -47,7 +47,7 @@
|
|||
</a>
|
||||
<header class="px-4 pt-3 sm:px-6 sm:pt-4">
|
||||
<div class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Last published 12/12/2020,<br> 8:02:40 PM PST.
|
||||
Last published 2/8/2021,<br> 2:16:02 PM PST.
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
@ -109,7 +109,7 @@
|
|||
</a>
|
||||
<header class="px-4 pt-3 sm:px-6 sm:pt-4">
|
||||
<div class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Last published 12/12/2020,<br> 8:02:40 PM PST.
|
||||
Last published 2/8/2021,<br> 2:16:02 PM PST.
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
</a>
|
||||
<header class="px-4 pt-3 sm:px-6 sm:pt-4">
|
||||
<div class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Last published 12/12/2020,<br> 8:02:40 PM PST.
|
||||
Last published 2/8/2021,<br> 2:16:02 PM PST.
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
@ -109,7 +109,7 @@
|
|||
</a>
|
||||
<header class="px-4 pt-3 sm:px-6 sm:pt-4">
|
||||
<div class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Last published 12/12/2020,<br> 8:02:40 PM PST.
|
||||
Last published 2/8/2021,<br> 2:16:02 PM PST.
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
@ -207,32 +207,34 @@
|
|||
<p>When we are done, our scripts should resemble the following samples:</p>
|
||||
<h3 id="serverstorage--modulescripts--gamesettings"><code>ServerStorage > ModuleScripts > GameSettings</code></h3>
|
||||
<pre><code class="language-lua">local GameSettings = {}
|
||||
|
||||
|
||||
-- Game Variables
|
||||
GameSettings.intermissionDuration = 5
|
||||
GameSettings.matchDuration = 10
|
||||
GameSettings.minimumPlayers = 2
|
||||
GameSettings.transitionTime = 5
|
||||
|
||||
return GameSettings</code></pre>
|
||||
|
||||
return GameSettings
|
||||
</code></pre>
|
||||
<h3 id="serverstorage--modulescripts--matchmanager"><code>ServerStorage > ModuleScripts > MatchManager</code></h3>
|
||||
<pre><code class="language-lua">local MatchManager = {}
|
||||
|
||||
|
||||
function MatchManager.preparePlayers()
|
||||
print("Game starting!")
|
||||
end
|
||||
|
||||
return MatchManager</code></pre>
|
||||
|
||||
return MatchManager
|
||||
</code></pre>
|
||||
<h3 id="serverscriptservice--gamemanager"><code>ServerScriptService > GameManager</code></h3>
|
||||
<pre><code class="language-lua">-- Services
|
||||
local ServerStorage = game:GetService("ServerStorage")
|
||||
local Players = game:GetService("Players")
|
||||
|
||||
|
||||
-- Module Scripts
|
||||
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
|
||||
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
|
||||
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
|
||||
|
||||
|
||||
while true do
|
||||
repeat
|
||||
wait(gameSettings.intermissionDuration)
|
||||
|
@ -241,7 +243,8 @@ while true do
|
|||
print("Intermission over")
|
||||
wait(gameSettings.transitionTime)
|
||||
matchManager.prepareGame()
|
||||
end</code></pre>
|
||||
end
|
||||
</code></pre>
|
||||
<hr>
|
||||
<p>A complete example project of the scripting we have done in class today can be found <a href="https://education.roblox.com/assets/blt7fffb3d25cb1a1dd/battleroyale_lesson2_final.rbxl?disposition=inline">here</a>.</p>
|
||||
<h2 id="optional-homework-📄">Optional Homework 📄</h2>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
</a>
|
||||
<header class="px-4 pt-3 sm:px-6 sm:pt-4">
|
||||
<div class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Last published 12/12/2020,<br> 8:02:40 PM PST.
|
||||
Last published 2/8/2021,<br> 2:16:02 PM PST.
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
@ -109,7 +109,7 @@
|
|||
</a>
|
||||
<header class="px-4 pt-3 sm:px-6 sm:pt-4">
|
||||
<div class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Last published 12/12/2020,<br> 8:02:40 PM PST.
|
||||
Last published 2/8/2021,<br> 2:16:02 PM PST.
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
@ -207,87 +207,89 @@
|
|||
<pre><code class="language-lua">-- Services
|
||||
local ServerStorage = game:GetService("ServerStorage")
|
||||
local Players = game:GetService("Players")
|
||||
|
||||
|
||||
-- Module Scripts
|
||||
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
|
||||
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
|
||||
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
|
||||
|
||||
|
||||
-- Events
|
||||
local events = ServerStorage:WaitForChild("Events")
|
||||
local matchEnd = events:WaitForChild("MatchEnd")
|
||||
|
||||
|
||||
while true do
|
||||
repeat
|
||||
wait(gameSettings.intermissionDuration)
|
||||
print("Restarting intermission")
|
||||
until Players.NumPlayers >= gameSettings.minimumPlayers
|
||||
|
||||
|
||||
print("Intermission over")
|
||||
wait(gameSettings.transitionTime)
|
||||
|
||||
|
||||
matchManager.prepareGame()
|
||||
-- Placeholder wait for the length of the game.
|
||||
matchEnd.Event:Wait()
|
||||
|
||||
end</code></pre>
|
||||
|
||||
end
|
||||
</code></pre>
|
||||
<h3 id="serverstorage--modulescripts--matchmanager"><code>ServerStorage > ModuleScripts > MatchManager</code></h3>
|
||||
<pre><code class="language-lua">local MatchManager = {}
|
||||
|
||||
|
||||
-- Services
|
||||
local ServerStorage = game:GetService("ServerStorage")
|
||||
|
||||
|
||||
-- Module Scripts
|
||||
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
|
||||
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
|
||||
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
|
||||
local timer = require(moduleScripts:WaitForChild("Timer"))
|
||||
|
||||
|
||||
-- Events
|
||||
local events = ServerStorage:WaitForChild("Events")
|
||||
local matchStart = events:WaitForChild("MatchStart")
|
||||
local matchEnd = events:WaitForChild("MatchEnd")
|
||||
|
||||
|
||||
-- Creates a new timer object to be used to keep track of match time.
|
||||
local myTimer = timer.new()
|
||||
|
||||
|
||||
-- Local Functions
|
||||
local function timeUp()
|
||||
print("Time is up!")
|
||||
end
|
||||
|
||||
|
||||
local function startTimer()
|
||||
print("Timer started")
|
||||
myTimer:start(gameSettings.matchDuration)
|
||||
myTimer.finished:Connect(timeUp)
|
||||
end
|
||||
|
||||
|
||||
-- Module Functions
|
||||
function MatchManager.prepareGame()
|
||||
playerManager.sendPlayersToMatch()
|
||||
matchStart:Fire()
|
||||
end
|
||||
|
||||
|
||||
matchStart.Event:Connect(startTimer)
|
||||
|
||||
return MatchManager</code></pre>
|
||||
|
||||
return MatchManager
|
||||
</code></pre>
|
||||
<h3 id="serverstorage--modulescripts--timer"><code>ServerStorage > ModuleScripts > Timer</code></h3>
|
||||
<pre><code class="language-lua">local Timer = {}
|
||||
Timer.__index = Timer
|
||||
|
||||
|
||||
function Timer.new()
|
||||
local self = setmetatable({}, Timer)
|
||||
|
||||
|
||||
self._finishedEvent = Instance.new("BindableEvent")
|
||||
self.finished = self._finishedEvent.Event
|
||||
|
||||
|
||||
self._running = false
|
||||
self._startTime = nil
|
||||
self._duration = nil
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
function Timer:start(duration)
|
||||
if not self._running then
|
||||
local timerThread = coroutine.wrap(function()
|
||||
|
@ -308,7 +310,7 @@ function Timer:start(duration)
|
|||
warn("Warning: timer could not start again as it is already running.")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Timer:getTimeLeft()
|
||||
if self._running then
|
||||
local now = tick()
|
||||
|
@ -321,16 +323,17 @@ function Timer:getTimeLeft()
|
|||
warn("Warning: could not get remaining time, timer is not running.")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Timer:isRunning()
|
||||
return self._running
|
||||
end
|
||||
|
||||
|
||||
function Timer:stop()
|
||||
self._running = false
|
||||
end
|
||||
|
||||
return Timer</code></pre>
|
||||
|
||||
return Timer
|
||||
</code></pre>
|
||||
<hr>
|
||||
<p>A complete example project of the scripting we have done in class today can be found <a href="https://education.roblox.com/assets/blt03dc7fe967c0c5f3/battleroyale_lesson4_final.rbxl?disposition=inline">here</a>.</p>
|
||||
<h2 id="optional-homework-📄">Optional Homework 📄</h2>
|
||||
|
|
102
Day 4/index.html
102
Day 4/index.html
|
@ -47,7 +47,7 @@
|
|||
</a>
|
||||
<header class="px-4 pt-3 sm:px-6 sm:pt-4">
|
||||
<div class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Last published 12/12/2020,<br> 8:02:40 PM PST.
|
||||
Last published 2/8/2021,<br> 2:16:02 PM PST.
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
@ -109,7 +109,7 @@
|
|||
</a>
|
||||
<header class="px-4 pt-3 sm:px-6 sm:pt-4">
|
||||
<div class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Last published 12/12/2020,<br> 8:02:40 PM PST.
|
||||
Last published 2/8/2021,<br> 2:16:02 PM PST.
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
@ -207,141 +207,144 @@
|
|||
<pre><code class="language-lua">-- Services
|
||||
local ServerStorage = game:GetService("ServerStorage")
|
||||
local Players = game:GetService("Players")
|
||||
|
||||
|
||||
-- Module Scripts
|
||||
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
|
||||
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
|
||||
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
|
||||
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
|
||||
|
||||
|
||||
-- Events
|
||||
local events = ServerStorage:WaitForChild("Events")
|
||||
local matchEnd = events:WaitForChild("MatchEnd")
|
||||
|
||||
|
||||
while true do
|
||||
displayManager.updateStatus("Waiting for Players")
|
||||
|
||||
|
||||
repeat
|
||||
wait(gameSettings.intermissionDuration)
|
||||
until Players.NumPlayers >= gameSettings.minimumPlayers
|
||||
|
||||
|
||||
displayManager.updateStatus("Get ready!")
|
||||
wait(gameSettings.transitionTime)
|
||||
|
||||
|
||||
matchManager.prepareGame()
|
||||
local endState = matchEnd.Event:Wait()
|
||||
print("Game ended with: " .. endState)
|
||||
end</code></pre>
|
||||
end
|
||||
</code></pre>
|
||||
<h3 id="serverstorage--modulescripts--matchmanager"><code>ServerStorage > ModuleScripts > MatchManager</code></h3>
|
||||
<pre><code class="language-lua">local MatchManager = {}
|
||||
|
||||
|
||||
-- Services
|
||||
local ServerStorage = game:GetService("ServerStorage")
|
||||
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||
|
||||
|
||||
-- Module Scripts
|
||||
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
|
||||
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
|
||||
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
|
||||
local timer = require(moduleScripts:WaitForChild("Timer"))
|
||||
|
||||
|
||||
-- Events
|
||||
local events = ServerStorage:WaitForChild("Events")
|
||||
local matchStart = events:WaitForChild("MatchStart")
|
||||
local matchEnd = events:WaitForChild("MatchEnd")
|
||||
|
||||
|
||||
-- Values
|
||||
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
|
||||
local timeLeft = displayValues:WaitForChild("TimeLeft")
|
||||
|
||||
|
||||
-- Creates a new timer object to be used to keep track of match time.
|
||||
local myTimer = timer.new()
|
||||
|
||||
|
||||
-- Local Functions
|
||||
local function stopTimer()
|
||||
myTimer:stop()
|
||||
end
|
||||
|
||||
|
||||
local function timeUp()
|
||||
matchEnd:Fire(gameSettings.endStates.TimerUp)
|
||||
end
|
||||
|
||||
|
||||
local function startTimer()
|
||||
print("Timer started")
|
||||
myTimer:start(gameSettings.matchDuration)
|
||||
myTimer.finished:Connect(timeUp)
|
||||
|
||||
|
||||
while myTimer:isRunning() do
|
||||
-- Adding +1 makes sure the timer display ends at 1 instead of 0.
|
||||
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
|
||||
-- By not setting the time for wait, it offers more accurate looping
|
||||
wait()
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- Module Functions
|
||||
function MatchManager.prepareGame()
|
||||
playerManager.sendPlayersToMatch()
|
||||
matchStart:Fire()
|
||||
end
|
||||
|
||||
|
||||
matchStart.Event:Connect(startTimer)
|
||||
matchEnd.Event:Connect(stopTimer)
|
||||
|
||||
return MatchManager</code></pre>
|
||||
|
||||
return MatchManager
|
||||
</code></pre>
|
||||
<h3 id="serverstorage--modulescripts--gamesettings"><code>ServerStorage > ModuleScripts > GameSettings</code></h3>
|
||||
<pre><code class="language-lua">local GameSettings = {}
|
||||
|
||||
|
||||
-- Game Variables
|
||||
GameSettings.intermissionDuration = 5
|
||||
GameSettings.matchDuration = 10
|
||||
GameSettings.minimumPlayers = 2
|
||||
GameSettings.transitionTime = 5
|
||||
|
||||
|
||||
-- Possible ways that the game can end.
|
||||
GameSettings.endStates = {
|
||||
TimerUp = "TimerUp",
|
||||
FoundWinner = "FoundWinner"
|
||||
}
|
||||
|
||||
return GameSettings</code></pre>
|
||||
|
||||
return GameSettings
|
||||
</code></pre>
|
||||
<h3 id="serverstorage--modulescripts--playermanager"><code>ServerStorage > ModuleScripts > PlayerManager</code></h3>
|
||||
<pre><code class="language-lua">local PlayerManager = {}
|
||||
|
||||
|
||||
-- Services
|
||||
local Players = game:GetService("Players")
|
||||
local ServerStorage = game:GetService("ServerStorage")
|
||||
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||
|
||||
|
||||
-- Modules
|
||||
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
|
||||
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
|
||||
|
||||
|
||||
-- Events
|
||||
local events = ServerStorage:WaitForChild("Events")
|
||||
local matchEnd = events:WaitForChild("MatchEnd")
|
||||
|
||||
|
||||
-- Map Variables
|
||||
local lobbySpawn = workspace.Lobby.StartSpawn
|
||||
local arenaMap = workspace.Arena
|
||||
local spawnLocations = arenaMap.SpawnLocations
|
||||
|
||||
|
||||
-- Values
|
||||
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
|
||||
local playersLeft = displayValues:WaitForChild("PlayersLeft")
|
||||
|
||||
|
||||
-- Player Variables
|
||||
local activePlayers = {}
|
||||
local playerWeapon = ServerStorage.Weapon
|
||||
|
||||
|
||||
-- Local Functions
|
||||
local function checkPlayerCount()
|
||||
if #activePlayers == 1 then
|
||||
matchEnd:Fire(gameSettings.endStates.FoundWinner)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function removeActivePlayer(player)
|
||||
for playerKey, whichPlayer in pairs(activePlayers) do
|
||||
if whichPlayer == player then
|
||||
|
@ -351,52 +354,53 @@ local function removeActivePlayer(player)
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function respawnPlayerInLobby(player)
|
||||
player.RespawnLocation = lobbySpawn
|
||||
player:LoadCharacter()
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
local function onPlayerJoin(player)
|
||||
player.RespawnLocation = lobbySpawn
|
||||
end
|
||||
|
||||
|
||||
local function preparePlayer(player, whichSpawn)
|
||||
player.RespawnLocation = whichSpawn
|
||||
player:LoadCharacter()
|
||||
|
||||
|
||||
local character = player.Character or player.CharacterAdded:Wait()
|
||||
local sword = playerWeapon:Clone()
|
||||
sword.Parent = character
|
||||
|
||||
|
||||
local humanoid = character:WaitForChild("Humanoid")
|
||||
|
||||
|
||||
humanoid.Died:Connect(function()
|
||||
respawnPlayerInLobby(player)
|
||||
removeActivePlayer(player)
|
||||
end)
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- Module Functions
|
||||
function PlayerManager.sendPlayersToMatch()
|
||||
local arenaSpawns = spawnLocations:GetChildren()
|
||||
|
||||
|
||||
for playerKey, whichPlayer in pairs(Players:GetPlayers()) do
|
||||
table.insert(activePlayers,whichPlayer)
|
||||
local spawnLocation = arenaSpawns[1]
|
||||
preparePlayer(whichPlayer, spawnLocation)
|
||||
table.remove(arenaSpawns, 1)
|
||||
end
|
||||
|
||||
|
||||
playersLeft.Value = #activePlayers
|
||||
end
|
||||
|
||||
|
||||
-- Events
|
||||
Players.PlayerAdded:Connect(onPlayerJoin)
|
||||
|
||||
return PlayerManager</code></pre>
|
||||
|
||||
return PlayerManager
|
||||
</code></pre>
|
||||
<hr>
|
||||
<p>A complete example project of the scripting we have done in class today can be found <a href="https://education.roblox.com/assets/blt03dc7fe967c0c5f3/battleroyale_lesson4_final.rbxl?disposition=inline">here</a>.</p>
|
||||
<h2 id="optional-homework-📄">Optional Homework 📄</h2>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
</a>
|
||||
<header class="px-4 pt-3 sm:px-6 sm:pt-4">
|
||||
<div class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Last published 12/12/2020,<br> 8:02:40 PM PST.
|
||||
Last published 2/8/2021,<br> 2:16:02 PM PST.
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
@ -109,7 +109,7 @@
|
|||
</a>
|
||||
<header class="px-4 pt-3 sm:px-6 sm:pt-4">
|
||||
<div class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Last published 12/12/2020,<br> 8:02:40 PM PST.
|
||||
Last published 2/8/2021,<br> 2:16:02 PM PST.
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
@ -184,7 +184,8 @@
|
|||
<p>Download <a href="https://education.roblox.com/assets/bltb5d7401ffa20b600/battleroyale_lesson6_final.rbxl?disposition=inline">this</a> file and open it in Roblox Studio. Publish it to Roblox (<code>Alt+P</code>) as your final Roblox Royale game, so name it something cool! Change the way that the arena looks by changing the colors, materials, and shapes of existing parts and by adding new parts from the toolbox.</p>
|
||||
<h3 id="second-half">Second Half</h3>
|
||||
<p>Let's open the <code>GameSettings</code> script (<code>ServerStorage > ModuleScripts > GameSettings</code>) and update a configuration variable:</p>
|
||||
<pre><code class="language-lua">GameSettings.matchDuration = 180</code></pre>
|
||||
<pre><code class="language-lua">GameSettings.matchDuration = 180
|
||||
</code></pre>
|
||||
<blockquote>
|
||||
<p>💡 Note: We are changing the match duration variable from 10 seconds to 180 seconds. 180 seconds was calculated by taking the amount of seconds in one minute (60) and multiplying it by 3 to get the amount of seconds there are in 3 minutes.</p>
|
||||
</blockquote>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
</a>
|
||||
<header class="px-4 pt-3 sm:px-6 sm:pt-4">
|
||||
<div class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Last published 12/12/2020,<br> 8:02:40 PM PST.
|
||||
Last published 2/8/2021,<br> 2:16:02 PM PST.
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
@ -109,7 +109,7 @@
|
|||
</a>
|
||||
<header class="px-4 pt-3 sm:px-6 sm:pt-4">
|
||||
<div class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Last published 12/12/2020,<br> 8:02:40 PM PST.
|
||||
Last published 2/8/2021,<br> 2:16:02 PM PST.
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
</a>
|
||||
<header class="px-4 pt-3 sm:px-6 sm:pt-4">
|
||||
<div class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Last published 12/12/2020,<br> 8:02:40 PM PST.
|
||||
Last published 2/8/2021,<br> 2:16:02 PM PST.
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
@ -109,7 +109,7 @@
|
|||
</a>
|
||||
<header class="px-4 pt-3 sm:px-6 sm:pt-4">
|
||||
<div class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Last published 12/12/2020,<br> 8:02:40 PM PST.
|
||||
Last published 2/8/2021,<br> 2:16:02 PM PST.
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue