🎉 First commit 1.0
This commit is contained in:
160
client/app.css
Normal file
160
client/app.css
Normal file
@@ -0,0 +1,160 @@
|
||||
*::before,
|
||||
*,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
font-family: "Open Sans", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background-color: #333;
|
||||
color: #ddd;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.alert p {
|
||||
text-align: center;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.alert img {
|
||||
display: block;
|
||||
max-height: 200px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
* Karaoke time
|
||||
*/
|
||||
|
||||
.light {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
height: 140vh;
|
||||
width: 40%;
|
||||
margin-left: 30%;
|
||||
margin-top: -1rem;
|
||||
clip-path: polygon(
|
||||
45% 0,
|
||||
55% 0,
|
||||
100% 100%,
|
||||
0% 100%
|
||||
);
|
||||
|
||||
transform-origin: top center;
|
||||
}
|
||||
|
||||
.light-left {
|
||||
animation:
|
||||
rotateLights 1.75s infinite ease-in-out alternate,
|
||||
lightsColor .75s infinite linear alternate;
|
||||
}
|
||||
|
||||
.light-right {
|
||||
animation:
|
||||
rotateLights 1.75s infinite ease-in-out alternate-reverse,
|
||||
lightsColor .75s infinite linear alternate-reverse;
|
||||
}
|
||||
|
||||
@keyframes rotateLights {
|
||||
from {
|
||||
transform: rotateZ(-30deg);
|
||||
}
|
||||
to {
|
||||
transform: rotateZ(30deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes lightsColor {
|
||||
from {
|
||||
background-color: var(--light-color-left);
|
||||
}
|
||||
|
||||
to {
|
||||
background-color: var(--light-color-right);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Russian roulette
|
||||
*/
|
||||
|
||||
.shoot {
|
||||
transform-origin: center;
|
||||
animation: shoot .3s ease-in-out -.05s alternate;
|
||||
}
|
||||
|
||||
@keyframes shoot {
|
||||
from {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: rotateZ(4deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Card
|
||||
*/
|
||||
.card {
|
||||
position: absolute;
|
||||
left: calc(50% - 25rem / 2);
|
||||
top: .5rem;
|
||||
width: 25rem;
|
||||
height: 6.25rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 1px solid var(--card-border-color);
|
||||
border-radius: .5rem;
|
||||
background-color: var(--card-background-color);
|
||||
}
|
||||
|
||||
.card.open {
|
||||
animation: cardAnimation .75s cubic-bezier(0.18, 0.89, 0.32, 1.28) forwards;
|
||||
}
|
||||
|
||||
.card.close {
|
||||
animation: cardAnimation .75s cubic-bezier(0.18, 0.89, 0.32, 1.28) reverse;
|
||||
}
|
||||
|
||||
@keyframes cardAnimation {
|
||||
from {
|
||||
top: -6.25rem;
|
||||
}
|
||||
to {
|
||||
top: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.card-light {
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.card .card-image {
|
||||
height: 3.5rem;
|
||||
margin: .5rem;
|
||||
}
|
||||
|
||||
.card .card-body {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card .card-body .title,
|
||||
.card .card-body .message {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.card .card-body .title {
|
||||
font-size: 1.25rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card .card-body .message {
|
||||
font-size: 1rem;
|
||||
margin: 0 .5rem;
|
||||
}
|
438
client/app.js
Normal file
438
client/app.js
Normal file
@@ -0,0 +1,438 @@
|
||||
document.addEventListener("DOMContentLoaded", init);
|
||||
|
||||
let ws;
|
||||
let env;
|
||||
|
||||
function init() {
|
||||
ws = new WebSocket(`${location.protocol === "https:" ? "wss" : "ws"}://${location.host}`);
|
||||
|
||||
ws.onopen = () => {
|
||||
console.log("Connected");
|
||||
|
||||
ws.onmessage = checkEvent;
|
||||
}
|
||||
ws.onclose = reconnect;
|
||||
}
|
||||
|
||||
function reconnect() {
|
||||
// !TEMP: only for development mode
|
||||
if (env === "dev") {
|
||||
location.reload();
|
||||
}
|
||||
console.log("Reconnecting in 5 seconds...");
|
||||
setTimeout(init, 5000);
|
||||
}
|
||||
|
||||
const events = [];
|
||||
let handlingEvents = false;
|
||||
|
||||
async function checkEvent(e) {
|
||||
if (!env) {
|
||||
env = JSON.parse(e.data).env.toLowerCase();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const message = JSON.parse(e.data);
|
||||
|
||||
if (message.song) {
|
||||
updateSong(message.song)
|
||||
return;
|
||||
}
|
||||
|
||||
events.push(message);
|
||||
|
||||
if (events.length === 1) {
|
||||
do {
|
||||
const data = events[0];
|
||||
|
||||
if (data.channelId) {
|
||||
switch (data.rewardId) {
|
||||
// karaoke time
|
||||
case "27faa7e4-f496-4e91-92ae-a51f99b9e854":
|
||||
await karaokeTime(data.userDisplayName, data.message);
|
||||
break;
|
||||
// ruleta rusa
|
||||
case "a73247ee-e33e-4e9b-9105-bd9d11e111fc":
|
||||
await russianRoulette(data.userDisplayName);
|
||||
break;
|
||||
// timeout a un amigo
|
||||
case "638c642d-23d8-4264-9702-e77eeba134de":
|
||||
await timeoutFriend(data);
|
||||
break;
|
||||
// highlight message
|
||||
case "a26c0d9e-fd2c-4943-bc94-c5c2f2c974e4":
|
||||
await highlightMessage(data);
|
||||
break;
|
||||
case "a215d6a0-2c11-4503-bb29-1ca98ef046ac":
|
||||
await giveTempVip(data);
|
||||
data.message = `@${data.userDisplayName} ha encontrado diamantes!`;
|
||||
await createCard(data.rewardName, data.message, data.backgroundColor, data.rewardImage);
|
||||
break;
|
||||
// robar el vip
|
||||
case "ac750bd6-fb4c-4259-b06d-56953601243b":
|
||||
await createCard(data.rewardName, data.message, data.backgroundColor, data.rewardImage);
|
||||
break;
|
||||
// hidratate
|
||||
case "232e951f-93d1-4138-a0e3-9e822b4852e0":
|
||||
data.message = `@${data.userDisplayName} ha invitado a una ronda.`;
|
||||
sendWsActions({
|
||||
action: "say",
|
||||
message: "FunnyCatTastingTHEWATER FunnyCatTastingTHEWATER FunnyCatTastingTHEWATER"
|
||||
});
|
||||
await createCard(data.rewardName, data.message, data.backgroundColor, data.rewardImage);
|
||||
break;
|
||||
default:
|
||||
await createCard(data.rewardName, data.message ? data.message : "", data.backgroundColor, data.rewardImage);
|
||||
}
|
||||
}
|
||||
|
||||
events.shift();
|
||||
await waitTime();
|
||||
|
||||
} while (events.length > 0);
|
||||
}
|
||||
|
||||
console.log(e.data);
|
||||
}
|
||||
|
||||
function waitTime() {
|
||||
const WAIT_TIME_MS = 500;
|
||||
|
||||
return new Promise(res => {
|
||||
setTimeout(res, WAIT_TIME_MS);
|
||||
});
|
||||
}
|
||||
|
||||
function karaokeTime(username, message) {
|
||||
return new Promise(res => {
|
||||
console.log(username, message);
|
||||
|
||||
const div = document.createElement("div");
|
||||
div.classList.add("alert");
|
||||
|
||||
const lightLeft = document.createElement("div");
|
||||
lightLeft.classList.add("light", "light-left");
|
||||
div.appendChild(lightLeft);
|
||||
|
||||
const lightRight = document.createElement("div");
|
||||
lightRight.classList.add("light", "light-right");
|
||||
div.appendChild(lightRight);
|
||||
|
||||
const randomLeft = tinycolor.random().setAlpha(.45).saturate(100).toRgbString();
|
||||
const randomRight = tinycolor(randomLeft).spin(Math.floor(Math.random() * 90) + 90).toRgbString();
|
||||
|
||||
insertCssVariables({
|
||||
"--light-color-left": randomLeft,
|
||||
"--light-color-right": randomRight
|
||||
});
|
||||
|
||||
const img = createImg("/img/karaoke-time.png");
|
||||
const p = createText(`${username} ha sugerido cantar un tema`);
|
||||
|
||||
div.appendChild(img);
|
||||
div.appendChild(p);
|
||||
img.onload = () => {
|
||||
const audio = createAudio("/sfx/karaoke-time.mp3");
|
||||
|
||||
audio.onended = function() {
|
||||
div.remove();
|
||||
res();
|
||||
}
|
||||
|
||||
document.body.appendChild(div);
|
||||
audio.play();
|
||||
};
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
let rrAttemps = 0;
|
||||
function russianRoulette(username) {
|
||||
return new Promise(res => {
|
||||
const win = rando(5 - rrAttemps) !== 0;
|
||||
|
||||
const div = document.createElement("div");
|
||||
div.classList.add("alert");
|
||||
div.style.margin = ".5rem";
|
||||
|
||||
const img = createImg("/img/toy-gun.png");
|
||||
|
||||
const p = createText();
|
||||
|
||||
if (win) {
|
||||
p.innerText = `${username} ha sido afortunado y aún sigue entre nosotros`;
|
||||
rrAttemps = 0;
|
||||
} else {
|
||||
p.innerText = `${username} se ha ido a un mundo mejor, siempre te recordaremos`;
|
||||
rrAttemps++;
|
||||
}
|
||||
|
||||
div.appendChild(img);
|
||||
div.appendChild(p);
|
||||
|
||||
img.onload = () => {
|
||||
const audio = createAudio(`/sfx/toy-gun/${win ? 'stuck' : 'shot'}.mp3`);
|
||||
|
||||
document.body.appendChild(div);
|
||||
|
||||
const actions = [];
|
||||
if (!win) {
|
||||
img.classList.add("shoot");
|
||||
|
||||
actions.push({
|
||||
action: "timeout",
|
||||
username: username,
|
||||
time: "60",
|
||||
reason: "F en la ruleta."
|
||||
});
|
||||
|
||||
actions.push({
|
||||
action: "say",
|
||||
message: `PepeHands ${username} no ha sobrevivido para contarlo.`
|
||||
});
|
||||
|
||||
} else {
|
||||
actions.push({
|
||||
action: "say",
|
||||
message: `rdCool Clap ${username}`
|
||||
});
|
||||
}
|
||||
|
||||
if (actions.length > 0) {
|
||||
sendWsActions(actions);
|
||||
}
|
||||
|
||||
audio.onended = () => {
|
||||
setTimeout(() => {
|
||||
div.remove();
|
||||
res();
|
||||
}, 1250);
|
||||
}
|
||||
|
||||
audio.play();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function timeoutFriend(data) {
|
||||
const senderUser = data.userDisplayName;
|
||||
const receptorUser = data.message.split(" ")[0];
|
||||
|
||||
sendWsActions({
|
||||
action: "timeout",
|
||||
username: receptorUser,
|
||||
time: "60",
|
||||
reason: `Timeout dado por @${senderUser} con puntos del canal.`
|
||||
});
|
||||
|
||||
const cardMessage = `@${senderUser} ha expulsado a @${receptorUser} por 60 segundos.`;
|
||||
await createCard(data.rewardName, cardMessage, data.backgroundColor, data.rewardImage);
|
||||
}
|
||||
|
||||
async function highlightMessage(data) {
|
||||
const urlRegex = /(https?:\/\/)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/;
|
||||
|
||||
if (urlRegex.test(data.message)) {
|
||||
sendWsActions({
|
||||
action: "timeout",
|
||||
username: data.userDisplayName,
|
||||
time: "10",
|
||||
reason: "No esta permitido enviar enlaces en mensajes destacados."
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await createCard(data.rewardName, data.message, data.backgroundColor, data.rewardImage);
|
||||
}
|
||||
|
||||
async function giveTempVip(data) {
|
||||
const username = data.userDisplayName;
|
||||
const channel = data.channelId;
|
||||
|
||||
sendWsActions([{
|
||||
action: "addVip",
|
||||
channel,
|
||||
username
|
||||
}, {
|
||||
scheduledAt: Date.now() + 1000 * 60 * 60 * 24 * 7,
|
||||
action: "removeVip",
|
||||
channel,
|
||||
username
|
||||
}]);
|
||||
}
|
||||
|
||||
// send actions to be performed by the server
|
||||
function sendWsActions(actions) {
|
||||
if (!Array.isArray(actions)) {
|
||||
actions = [actions];
|
||||
}
|
||||
|
||||
if (env === "dev") {
|
||||
console.log("Dev mode, actions not sent: ", actions);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ws.readyState === WebSocket.OPEN) {
|
||||
|
||||
if (actions.length > 0) {
|
||||
ws.send(JSON.stringify({
|
||||
actions: actions
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function createCard(title, message, color, image) {
|
||||
const maxMessageLength = 120;
|
||||
const darkenLighten = 10;
|
||||
|
||||
return new Promise(res => {
|
||||
const card = document.createElement("div");
|
||||
card.classList.add("card", "open");
|
||||
|
||||
const img = createImg(image);
|
||||
img.classList.add("card-image");
|
||||
card.appendChild(img);
|
||||
|
||||
const body = document.createElement("div");
|
||||
body.classList.add("card-body");
|
||||
card.appendChild(body);
|
||||
|
||||
const titl = document.createElement("h1");
|
||||
titl.classList.add("title");
|
||||
titl.innerText = title;
|
||||
body.appendChild(titl);
|
||||
|
||||
if (message.length > maxMessageLength) {
|
||||
while (message.length > maxMessageLength) {
|
||||
message = message.split(" ").slice(0, -1).join(" ");
|
||||
}
|
||||
message += "...";
|
||||
}
|
||||
|
||||
const msg = createText(message);
|
||||
msg.classList.add("message");
|
||||
body.appendChild(msg);
|
||||
|
||||
color = tinycolor(color);
|
||||
|
||||
if (!color.isValid()) {
|
||||
color = tinycolor("#2EC90C");
|
||||
}
|
||||
|
||||
let backgroundColor = color;
|
||||
let borderColor = new tinycolor(backgroundColor.toHexString());
|
||||
|
||||
if (backgroundColor.isLight()) {
|
||||
card.classList.add("card-light");
|
||||
borderColor.darken(darkenLighten).toHexString();
|
||||
|
||||
} else {
|
||||
borderColor.lighten(darkenLighten).toHexString();
|
||||
}
|
||||
|
||||
insertCssVariables({
|
||||
"--card-background-color": backgroundColor.toHexString(),
|
||||
"--card-border-color": borderColor.toHexString()
|
||||
});
|
||||
|
||||
card.addEventListener("animationend", () => {
|
||||
if (card.classList.contains("open")) {
|
||||
card.classList.remove("open");
|
||||
|
||||
const fairTime = message.split(" ").length / 5;
|
||||
const timeOpen = Math.min(Math.max(fairTime, 4), 8);
|
||||
|
||||
setTimeout(() => {
|
||||
card.classList.add("close");
|
||||
}, timeOpen * 1000);
|
||||
|
||||
} else {
|
||||
card.remove();
|
||||
res();
|
||||
}
|
||||
});
|
||||
|
||||
img.onload = () => {
|
||||
document.body.appendChild(card);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// creates a img and sets its src
|
||||
function createImg(path) {
|
||||
const img = document.createElement("img");
|
||||
img.src = path;
|
||||
return img;
|
||||
}
|
||||
|
||||
// creates a paragraph and sets a text inside
|
||||
function createText(txt) {
|
||||
const p = document.createElement("p");
|
||||
|
||||
if (txt) {
|
||||
p.innerText = txt;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
// creates and initializes an audio element with given audio src
|
||||
function createAudio(path) {
|
||||
const audio = new Audio(path);
|
||||
audio.volume = .025;
|
||||
|
||||
return audio;
|
||||
}
|
||||
|
||||
// get a internal style sheet or create it if it does not exist, used to set css variables on :root
|
||||
function cssSheet() {
|
||||
const targetValue = "cssVariables";
|
||||
let style = document.querySelector(`style[data-target="${targetValue}"]`);
|
||||
|
||||
if (style) {
|
||||
return style.sheet;
|
||||
}
|
||||
|
||||
style = document.createElement("style");
|
||||
style.setAttribute("data-target", targetValue);
|
||||
document.head.appendChild(style);
|
||||
|
||||
return style.sheet;
|
||||
}
|
||||
|
||||
// add css rules to :root element
|
||||
function insertCssVariables(rules) {
|
||||
const sheet = cssSheet();
|
||||
|
||||
while (sheet.rules.length > 0) {
|
||||
sheet.deleteRule(0);
|
||||
}
|
||||
|
||||
let rulesTxt = ":root {";
|
||||
for (const name in rules) {
|
||||
rulesTxt += `${name}: ${rules[name]};`;
|
||||
}
|
||||
rulesTxt += "}";
|
||||
|
||||
sheet.insertRule(rulesTxt);
|
||||
}
|
||||
|
||||
// playing song overlay
|
||||
function updateSong({ title, artist, coverArt}) {
|
||||
const playing = document.getElementById("playing");
|
||||
if (
|
||||
!title &&
|
||||
!artist
|
||||
) {
|
||||
playing.style.display = "none";
|
||||
return;
|
||||
}
|
||||
|
||||
playing.style.display = null;
|
||||
playing.querySelector(".coverArt").src = coverArt;
|
||||
playing.querySelector(".trackName").innerText = title;
|
||||
playing.querySelector(".trackArtist").innerText = artist;
|
||||
}
|
BIN
client/img/karaoke-time.png
Normal file
BIN
client/img/karaoke-time.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 132 KiB |
BIN
client/img/toy-gun.png
Normal file
BIN
client/img/toy-gun.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 216 KiB |
116
client/index.html
Normal file
116
client/index.html
Normal file
@@ -0,0 +1,116 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Websocket</title>
|
||||
|
||||
<script src="/libs/js/tinycolor-min.js" defer></script>
|
||||
<script src="/libs/js/randojs.js" defer></script>
|
||||
|
||||
<script src="app.js" defer></script>
|
||||
<link rel="stylesheet" href="app.css">
|
||||
<style>
|
||||
:root {
|
||||
--playerWidth: 20rem;
|
||||
--imgSize: 5rem;
|
||||
}
|
||||
|
||||
#playing {
|
||||
position: absolute;
|
||||
bottom: .5rem;
|
||||
left: .5rem;
|
||||
width: var(--playerWidth);
|
||||
padding: .5rem;
|
||||
background-color: rgba(0, 0, 0, .5);
|
||||
border-radius: .5rem;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#playing > div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#playing .previous {
|
||||
animation: 1s translateLeft forwards;
|
||||
}
|
||||
|
||||
#playing .next {
|
||||
animation: 1s translateRight forwards;
|
||||
}
|
||||
|
||||
@keyframes translateLeft {
|
||||
from {
|
||||
transform: translate3d(0, 0, 0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
80%,
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translate3d(-100%, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes translateRight {
|
||||
from {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
0%,
|
||||
10% {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translate3d(-100%, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#playing img {
|
||||
display: block;
|
||||
width: var(--imgSize);
|
||||
height: var(--imgSize);
|
||||
margin-right: calc(var(--imgSize) / 5)
|
||||
}
|
||||
|
||||
#playing h1,
|
||||
#playing h2 {
|
||||
width: calc(var(--playerWidth) - var(--imgSize) * 1.2 - 1em * 1.5);
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="playing" style="display: none !important">
|
||||
<div>
|
||||
<img class="coverArt" src="https://picsum.photos/id/248/300/300.jpg">
|
||||
<div>
|
||||
<h1 class="trackName">Track Name</h1>
|
||||
<h2 class="trackArtist">Track Artist</h2>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="previous">
|
||||
<img class="coverArt" src="https://picsum.photos/id/141/300/300.jpg">
|
||||
<div>
|
||||
<h1 class="trackName">Name previous</h1>
|
||||
<h2 class="trackArtist">Artist previous</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="next">
|
||||
<img class="coverArt" src="https://picsum.photos/id/415/300/300.jpg">
|
||||
<div>
|
||||
<h1 class="trackName">Name next</h1>
|
||||
<h2 class="trackArtist">Artist next</h2>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
5
client/libs/js/randojs.js
Normal file
5
client/libs/js/randojs.js
Normal file
@@ -0,0 +1,5 @@
|
||||
function rando(a,b,e){var g=function(f){return"undefined"===typeof f},k=function(f){return"number"===typeof f&&!isNaN(f)},d=function(f){return!g(f)&&null!==f&&f.constructor===Array},c=function(){try{for(var f,q=[],r;30>(r="."+q.join("")).length;){f=(window.crypto||window.msCrypto).getRandomValues(new Uint32Array(5));for(var p=0;p<f.length;p++){var t=4E9>f[p]?f[p].toString().slice(1):"";0<t.length&&(q[q.length]=t)}}return Number(r)}catch(v){return Math.random()}};try{if(null!==a&&null!==b&&null!==
|
||||
e){if(g(a))return c();if(window.jQuery&&a instanceof jQuery&&g(b)){if(0==a.length)return!1;var n=rando(0,a.length-1);return{index:n,value:a.eq(n)}}if(k(a)&&k(b)&&"string"===typeof e&&"float"==e.toLowerCase().trim()){if(a>b){var m=b;b=a;a=m}return c()*(b-a)+a}if(d(a)&&0<a.length&&g(b)){var l=c()*a.length<<0;return{index:l,value:a[l]}}if("object"===typeof a&&g(b)){l=a;var h=Object.keys(l);if(0<h.length){var u=h[h.length*c()<<0];return{key:u,value:l[u]}}}if((!0===a&&!1===b||!1===a&&!0===b)&&g(e))return.5>
|
||||
rando();if(k(a)&&g(b))return 0<=a?rando(0,a):rando(a,0);if(k(a)&&"string"===typeof b&&"float"==b.toLowerCase().trim()&&g(e))return 0<=a?rando(0,a,"float"):rando(a,0,"float");if(k(a)&&k(b)&&g(e))return a>b&&(m=b,b=a,a=m),a=Math.floor(a),b=Math.floor(b),Math.floor(c()*(b-a+1)+a);if("string"===typeof a&&0<a.length&&g(b))return a.charAt(rando(0,a.length-1))}return!1}catch(f){return!1}}
|
||||
function randoSequence(a,b){var e=function(h){return"undefined"===typeof h},g=function(h){return"number"===typeof h&&!isNaN(h)},k=function(h){return!e(h)&&null!==h&&h.constructor===Array};try{if(e(a)||null===a||null===b)return!1;var d=[];if(window.jQuery&&a instanceof jQuery&&e(b)){if(0<a.length){d=randoSequence(0,a.length-1);for(var c=0;c<d.length;c++)d[c]={index:d[c],value:a.eq(d[c])}}return d}if(e(b))if(k(a)&&e(b))for(c=0;c<a.length;c++)d[d.length]={index:c,value:a[c]};else if("object"===typeof a&&
|
||||
e(b))for(var n in a)Object.prototype.hasOwnProperty.call(a,n)&&(d[d.length]={key:n,value:a[n]});else if("string"===typeof a&&e(b))for(c=0;c<a.length;c++)d[d.length]=a.charAt(c);else return g(a)&&e(b)?0<=a?randoSequence(0,a):randoSequence(a,0):!1;else{if(!g(a)||!g(b)||0<a%1||0<b%1)return!1;if(a>b){var m=b;b=a;a=m}for(c=a;c<=b;c++)d[d.length]=c}for(c=d.length-1;0<c;c--){var l=rando(c);m=d[c];d[c]=d[l];d[l]=m}return d}catch(h){return!1}};
|
4
client/libs/js/tinycolor-min.js
vendored
Normal file
4
client/libs/js/tinycolor-min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
client/sfx/karaoke-time.mp3
Normal file
BIN
client/sfx/karaoke-time.mp3
Normal file
Binary file not shown.
BIN
client/sfx/toy-gun/shot.mp3
Normal file
BIN
client/sfx/toy-gun/shot.mp3
Normal file
Binary file not shown.
BIN
client/sfx/toy-gun/stuck.mp3
Normal file
BIN
client/sfx/toy-gun/stuck.mp3
Normal file
Binary file not shown.
Reference in New Issue
Block a user