Compare commits
No commits in common. "main" and "2.6.0" have entirely different histories.
1
.gitignore
vendored
|
|
@ -110,4 +110,3 @@ src/config/twitch-emotes.json
|
||||||
dist/*
|
dist/*
|
||||||
src/config/betterttv-emotes.json
|
src/config/betterttv-emotes.json
|
||||||
test.py
|
test.py
|
||||||
src/config/settings.json
|
|
||||||
|
|
|
||||||
|
|
@ -34,22 +34,17 @@ from vosk import Model, KaldiRecognizer, SetLogLevel
|
||||||
|
|
||||||
SetLogLevel(-1)
|
SetLogLevel(-1)
|
||||||
|
|
||||||
settings = None;
|
settings = configparser.ConfigParser()
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
settingsPath = os.path.normpath(sys.argv[1])
|
settingsPath = os.path.normpath(sys.argv[1])
|
||||||
|
|
||||||
environment = sys.argv[2]
|
environment = sys.argv[2]
|
||||||
|
|
||||||
q = queue.Queue()
|
q = queue.Queue()
|
||||||
|
|
||||||
# gobal functions
|
# gobal functions
|
||||||
|
|
||||||
def loadSettings():
|
|
||||||
with open(settingsPath, 'r') as file:
|
|
||||||
global settings
|
|
||||||
settings = json.load(file)
|
|
||||||
|
|
||||||
# classes
|
# classes
|
||||||
class LanguageDetection:
|
class LanguageDetection:
|
||||||
|
|
@ -140,8 +135,8 @@ class STT:
|
||||||
def stop_recognition(self):
|
def stop_recognition(self):
|
||||||
self.is_running = False
|
self.is_running = False
|
||||||
|
|
||||||
loadSettings()
|
settings.read(settingsPath)
|
||||||
if settings["STT"]["USE_STT"] and settings["STT"]["LANGUAGE"] != '':
|
if settings["STT"]["USE_STT"] and bool(settings["STT"]["LANGUAGE"]):
|
||||||
speech_recognition_service = STT()
|
speech_recognition_service = STT()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -184,7 +179,7 @@ class TTS:
|
||||||
|
|
||||||
return [voice.name for voice in voices]
|
return [voice.name for voice in voices]
|
||||||
|
|
||||||
loadSettings()
|
settings.read(settingsPath)
|
||||||
if settings["TTS"]["USE_TTS"]:
|
if settings["TTS"]["USE_TTS"]:
|
||||||
text_to_speech_service = TTS()
|
text_to_speech_service = TTS()
|
||||||
|
|
||||||
|
|
@ -236,17 +231,17 @@ def get_language():
|
||||||
|
|
||||||
@app.route("/translate", methods=["POST"])
|
@app.route("/translate", methods=["POST"])
|
||||||
def get_translation():
|
def get_translation():
|
||||||
loadSettings()
|
try:
|
||||||
|
settings.read(settingsPath)
|
||||||
request_data = request.json
|
request_data = request.json
|
||||||
message = request_data.get("message", "")
|
message = request_data.get("message", "")
|
||||||
detectedLanguage = request_data.get("language", "")
|
detectedLanguage = request_data.get("language", "")
|
||||||
try:
|
try:
|
||||||
# try:
|
|
||||||
translated = MyMemoryTranslator(
|
translated = MyMemoryTranslator(
|
||||||
source=detectedLanguage, target=settings["LANGUAGE"]["TRANSLATE_TO"]
|
source=detectedLanguage, target=settings["LANGUAGE"]["TRANSLATE_TO"]
|
||||||
).translate(message)
|
).translate(message)
|
||||||
# except Exception as e:
|
except Exception as e:
|
||||||
# return jsonify({"error": str(e), "code":429 }), 429
|
return jsonify({"error": str(e), "code":429 }), 429
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({"error": str(e), "code":500 }), 500
|
return jsonify({"error": str(e), "code":500 }), 500
|
||||||
return jsonify({"translation": translated}), 200
|
return jsonify({"translation": translated}), 200
|
||||||
|
|
@ -281,7 +276,7 @@ def get_voices():
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
loadSettings()
|
settings.read(settingsPath)
|
||||||
port = int(settings["GENERAL"]["PORT"])
|
port = int(settings["GENERAL"]["PORT"])
|
||||||
else:
|
else:
|
||||||
environment = "dev"
|
environment = "dev"
|
||||||
|
|
|
||||||
|
|
@ -40,16 +40,13 @@
|
||||||
},
|
},
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mediapipe/tasks-vision": "^0.10.12",
|
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"dlivetv-api": "^1.0.10",
|
|
||||||
"emoji-picker-element": "^1.21.0",
|
"emoji-picker-element": "^1.21.0",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"flag-icons": "^7.1.0",
|
"flag-icons": "^7.1.0",
|
||||||
"ini": "^2.0.0",
|
"ini": "^2.0.0",
|
||||||
"kill-process-by-name": "^1.0.5",
|
"kill-process-by-name": "^1.0.5",
|
||||||
"node-google-tts-api": "^1.1.1",
|
"node-google-tts-api": "^1.1.1",
|
||||||
"p5": "^1.9.2",
|
|
||||||
"querystring": "^0.2.1",
|
"querystring": "^0.2.1",
|
||||||
"socket.io": "^4.7.1",
|
"socket.io": "^4.7.1",
|
||||||
"socket.io-client": "^4.7.1",
|
"socket.io-client": "^4.7.1",
|
||||||
|
|
@ -57,8 +54,7 @@
|
||||||
"tmi.js": "^1.8.5",
|
"tmi.js": "^1.8.5",
|
||||||
"url": "^0.11.1",
|
"url": "^0.11.1",
|
||||||
"winston": "^3.10.0",
|
"winston": "^3.10.0",
|
||||||
"write-ini-file": "^4.0.1",
|
"write-ini-file": "^4.0.1"
|
||||||
"youtube-chat": "^2.2.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@electron-forge/cli": "^6.2.1",
|
"@electron-forge/cli": "^6.2.1",
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,5 @@ After getting your credentials you can set it in <img src="https://raw.githubuse
|
||||||
* [Speech2Go](https://harposoftware.com/en/spanish-spain-/340-S2G-Jorge-Nuance-Voice.html).
|
* [Speech2Go](https://harposoftware.com/en/spanish-spain-/340-S2G-Jorge-Nuance-Voice.html).
|
||||||
### Linux
|
### Linux
|
||||||
* WIP
|
* WIP
|
||||||
|
|
||||||
### Mac
|
### Mac
|
||||||
* WIP
|
* WIP
|
||||||
|
|
@ -297,12 +297,12 @@ h1 {
|
||||||
align-self: start;
|
align-self: start;
|
||||||
}
|
}
|
||||||
.post-time.sender {
|
.post-time.sender {
|
||||||
padding: 5px 5px 5px 15px;
|
padding: 5px 5px 0px 15px;
|
||||||
margin: 0px 0px 0px 50px;
|
margin: 0px 0px 0px 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-time.user {
|
.post-time.user {
|
||||||
padding: 5px 15px 5px 5px;
|
padding: 5px 15px 0px 5px;
|
||||||
margin: 0px 50px 0px 0px;
|
margin: 0px 50px 0px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -573,8 +573,3 @@ h1 {
|
||||||
right: 18px;
|
right: 18px;
|
||||||
top: -65px;
|
top: -65px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.emote {
|
|
||||||
width: 28px;
|
|
||||||
height: 28px;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -260,15 +260,3 @@ body {
|
||||||
unicode-range: U+1F1E6-1F1FF;
|
unicode-range: U+1F1E6-1F1FF;
|
||||||
src: url(https://raw.githack.com/googlefonts/noto-emoji/main/fonts/NotoColorEmoji.ttf);
|
src: url(https://raw.githack.com/googlefonts/noto-emoji/main/fonts/NotoColorEmoji.ttf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#drop-zone {
|
|
||||||
width: 300px;
|
|
||||||
height: 200px;
|
|
||||||
border: 2px dashed #ccc;
|
|
||||||
text-align: center;
|
|
||||||
padding: 20px;
|
|
||||||
margin: 20px auto;
|
|
||||||
}
|
|
||||||
#dropped-file {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -267,37 +267,7 @@ pop-content div {
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(3, 1fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
.network-select {
|
|
||||||
position: relative;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.send-to-channel {
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
background-color: var(--main-color3);
|
|
||||||
top: calc(-50% - 3px);
|
|
||||||
border: 1px solid #444;
|
|
||||||
z-index: 1;
|
|
||||||
width: 107px;
|
|
||||||
}
|
|
||||||
|
|
||||||
send-to-channel div {
|
|
||||||
color: white;
|
|
||||||
text-decoration: none;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
send-to-channel div:hover {
|
|
||||||
backdrop-filter: invert(50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.network-select:hover .send-to-channel {
|
|
||||||
display: block;
|
|
||||||
backdrop-filter: invert(50%);
|
|
||||||
grid-template-columns: repeat(3, 1fr);
|
|
||||||
}
|
|
||||||
|
|
||||||
.language-select {
|
.language-select {
|
||||||
|
padding: 5px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
.token-autocomplete-container {
|
|
||||||
display: inline-flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
width: 300px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token-autocomplete-container,
|
|
||||||
.token-autocomplete-container * {
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token-autocomplete-container .token-autocomplete-input {
|
|
||||||
color: var(--main-color2);
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 32px;
|
|
||||||
margin: 4px 2px;
|
|
||||||
padding: 0px 8px;
|
|
||||||
height: 40px;
|
|
||||||
width: 300px;
|
|
||||||
background-color: var(--main-color3);
|
|
||||||
border-radius: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token-autocomplete-container .token-autocomplete-input:empty::before {
|
|
||||||
content: attr(data-placeholder);
|
|
||||||
color: gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token-autocomplete-container .token-autocomplete-token {
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 32px;
|
|
||||||
background-color: var(--main-color3);
|
|
||||||
margin: 4px 2px;
|
|
||||||
border-radius: 32px;
|
|
||||||
padding: 0px 8px;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token-autocomplete-container .token-autocomplete-token:hover {
|
|
||||||
background-color: #ef9a9a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token-autocomplete-container .token-autocomplete-token .token-autocomplete-token-delete {
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 16px;
|
|
||||||
margin-left: 4px;
|
|
||||||
pointer-events: auto;
|
|
||||||
border-radius: 50%;
|
|
||||||
height: 24px;
|
|
||||||
width: 24px;
|
|
||||||
display: inline-block;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token-autocomplete-container .token-autocomplete-token .token-autocomplete-token-delete:hover {
|
|
||||||
background-color: #e55858;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token-autocomplete-container .token-autocomplete-suggestions {
|
|
||||||
display: none;
|
|
||||||
width: 100%;
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token-autocomplete-container .token-autocomplete-suggestions li {
|
|
||||||
width: 100%;
|
|
||||||
padding: 8px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token-autocomplete-container .token-autocomplete-suggestions li.token-autocomplete-suggestion-active {
|
|
||||||
color: #747474;
|
|
||||||
background-color: #fdfdfd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token-autocomplete-container .token-autocomplete-suggestions li.token-autocomplete-suggestion-highlighted {
|
|
||||||
background-color: #95caec;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token-autocomplete-container .token-autocomplete-suggestions li .token-autocomplete-suggestion-description {
|
|
||||||
display: block;
|
|
||||||
font-size: 0.7em;
|
|
||||||
color: #808080;
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 242 B |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 175 B |
236
src/index.html
|
|
@ -17,8 +17,6 @@
|
||||||
<link rel="stylesheet" href="./css/tts-menu.css" />
|
<link rel="stylesheet" href="./css/tts-menu.css" />
|
||||||
<link rel="stylesheet" href="./css/volume-slider.css" />
|
<link rel="stylesheet" href="./css/volume-slider.css" />
|
||||||
<link rel="stylesheet" href="./css/sliders.css" />
|
<link rel="stylesheet" href="./css/sliders.css" />
|
||||||
<link rel="stylesheet" href="./css/token-autocomplete.css" />
|
|
||||||
|
|
||||||
<link
|
<link
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"
|
||||||
|
|
@ -78,21 +76,15 @@
|
||||||
<li class="item" tip="Chat Creator" id="btnChatCreator">
|
<li class="item" tip="Chat Creator" id="btnChatCreator">
|
||||||
<i class="fa-solid fa-spray-can"></i>
|
<i class="fa-solid fa-spray-can"></i>
|
||||||
</li>
|
</li>
|
||||||
<li class="item" tip="BrowserSource ChatBubble" id="btnBrowsersourceChatBubble">
|
<li class="item" tip="BrowserSource ChatBubble" id="btnBrowsersourceChat">
|
||||||
<i class="fa fa-history menu-icon"></i>
|
<i class="fa fa-history menu-icon"></i>
|
||||||
</li>
|
</li>
|
||||||
<li class="item" tip="BrowserSource Vtuber" id="btnBrowsersourceVtuber">
|
<li class="item" tip="BrowserSource Vtuber" id="btnBrowsersourceVtuber">
|
||||||
<i class="fa-solid fa-address-card menu-icon"></i>
|
<i class="fa fa-user menu-icon"></i>
|
||||||
</li>
|
|
||||||
<li class="item" tip="BrowserSource PNGTuber" id="btnBrowsersourcePNGTuber">
|
|
||||||
<i class="fa-solid fa-image-portrait menu-icon"></i>
|
|
||||||
</li>
|
</li>
|
||||||
<li class="item" tip="Logs" id="btnLogs">
|
<li class="item" tip="Logs" id="btnLogs">
|
||||||
<i class="fa fa-clipboard menu-icon"></i>
|
<i class="fa fa-clipboard menu-icon"></i>
|
||||||
</li>
|
</li>
|
||||||
<li class="item" tip="FaceMask" id="btnFaceMask">
|
|
||||||
<i class="fa-solid fa-masks-theater"></i>
|
|
||||||
</li>
|
|
||||||
<li class="item active-mic" tip="Info" id="btnConfiguration">
|
<li class="item active-mic" tip="Info" id="btnConfiguration">
|
||||||
<i class="fa-solid fa-microphone-lines"></i>
|
<i class="fa-solid fa-microphone-lines"></i>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -124,42 +116,14 @@
|
||||||
</div>
|
</div>
|
||||||
<!--#endregion -->
|
<!--#endregion -->
|
||||||
|
|
||||||
<!-- #region Chat-->
|
<!-- #region Commands Screen-->
|
||||||
<div class="OptionPanel" id="BrowsersourceChatWindow"></div>
|
<div class="OptionPanel" id="BrowsersourceChat"></div>
|
||||||
<!--#endregion -->
|
<!--#endregion -->
|
||||||
|
|
||||||
<!-- #region ChatBubble-->
|
<!-- #region Commands Screen-->
|
||||||
<div class="OptionPanel" id="BrowsersourceChatBubble"></div>
|
|
||||||
<!--#endregion -->
|
|
||||||
|
|
||||||
<!-- #region Vtuber-->
|
|
||||||
<div class="OptionPanel" id="BrowsersourceVtuber"></div>
|
<div class="OptionPanel" id="BrowsersourceVtuber"></div>
|
||||||
<!--#endregion -->
|
<!--#endregion -->
|
||||||
|
|
||||||
<!-- #region Vtuber-->
|
|
||||||
<div class="OptionPanel" id="BrowsersourcePNGTuber"></div>
|
|
||||||
<!--#endregion -->
|
|
||||||
|
|
||||||
<!-- #region FaceMask-->
|
|
||||||
<div class="OptionPanel" id="FaceMask">
|
|
||||||
<!-- <div class="select">
|
|
||||||
<label for="audioSource">Audio source: </label
|
|
||||||
><select id="audioSource"></select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="select">
|
|
||||||
<label for="videoSource">Video source: </label
|
|
||||||
><select id="videoSource"></select>
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
<!-- <video id="video" autoplay></video> -->
|
|
||||||
<div id="drop-zone">
|
|
||||||
<p>Drag a file here</p>
|
|
||||||
<p id="dropped-file"></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--#endregion -->
|
|
||||||
|
|
||||||
<!-- #region Configuration Screen-->
|
<!-- #region Configuration Screen-->
|
||||||
<div class="OptionPanel" id="Configuration">
|
<div class="OptionPanel" id="Configuration">
|
||||||
<div id="tstx">
|
<div id="tstx">
|
||||||
|
|
@ -397,7 +361,7 @@
|
||||||
<button class="password-toggle-btn password-toggle-btn1">
|
<button class="password-toggle-btn password-toggle-btn1">
|
||||||
<span class="password-toggle-icon"><i class="fa-regular fa-eye-slash"></i></span>
|
<span class="password-toggle-icon"><i class="fa-regular fa-eye-slash"></i></span>
|
||||||
</button>
|
</button>
|
||||||
<i class="fa-solid fa-key fa-2x SmallButton option-icon-container" id="Info_TWITCH_USERNAME" tip="Get OAuth Token"></i>
|
<i class="fa-solid fa-key fa-2x SmallButton option-icon-container" id="Info_USERNAME" tip="Get OAuth Token"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="AdvancedMenuRow inputTwitch">
|
<div class="AdvancedMenuRow inputTwitch">
|
||||||
<div class="AdvancedMenuLabel">Channel Name</div>
|
<div class="AdvancedMenuLabel">Channel Name</div>
|
||||||
|
|
@ -417,15 +381,6 @@
|
||||||
tip="Test Twitch credentials"
|
tip="Test Twitch credentials"
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="AdvancedMenuRow inputTwitch">
|
|
||||||
<div class="AdvancedMenuLabel">BetterTTV Channels</div>
|
|
||||||
<div id="sample"></div>
|
|
||||||
<i
|
|
||||||
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
|
||||||
id="Info_BETTERTTV_CHANNELS"
|
|
||||||
tip="Insert the channel names of the betterTTV emotes you want"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
<div class="AdvancedMenuRow inputTwitch">
|
<div class="AdvancedMenuRow inputTwitch">
|
||||||
<div class="AdvancedMenuLabel">Get BetterTTV emotes</div>
|
<div class="AdvancedMenuLabel">Get BetterTTV emotes</div>
|
||||||
<button type="text" class="AdvancedMenuButton" id="GetBetterTtvEmotes">
|
<button type="text" class="AdvancedMenuButton" id="GetBetterTtvEmotes">
|
||||||
|
|
@ -439,147 +394,6 @@
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset id="YoutubeMenu" class="AdvancedMenu">
|
|
||||||
<legend class="legendStyle" tip="Enable/Disable Youtube">
|
|
||||||
<img class="AdvancedMenuIcon" src="./images/youtube.png" alt=" " />
|
|
||||||
<input type="checkbox" id="USE_YOUTUBE" class="checkbox" />
|
|
||||||
<label for="USE_YOUTUBE" class="toggle-small"></label>
|
|
||||||
<div class="AdvancedMenuLabel3">Enable Youtube</div>
|
|
||||||
</legend>
|
|
||||||
<!-- <div class="AdvancedMenuRow inputYoutube">
|
|
||||||
<div class="AdvancedMenuLabel">API Key</div>
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
type2="text"
|
|
||||||
class="fname inputYoutube"
|
|
||||||
id="YOUTUBE_OAUTH_TOKEN"
|
|
||||||
placeholder="click the key icon to get the OAuth token"
|
|
||||||
/>
|
|
||||||
<button class="password-toggle-btn password-toggle-btn2">
|
|
||||||
<span class="password-toggle-icon"><i class="fa-regular fa-eye-slash"></i></span>
|
|
||||||
</button>
|
|
||||||
<i class="fa-solid fa-key fa-2x SmallButton option-icon-container" id="Info_YOUTUBE_USERNAME" tip="Get OAuth Token"></i>
|
|
||||||
</div> -->
|
|
||||||
<div class="AdvancedMenuRow inputYoutube">
|
|
||||||
<div class="AdvancedMenuLabel">Channel Handle</div>
|
|
||||||
<input type="text" class="fname inputYoutube" id="YOUTUBE_CHANNEL_HANDLE" />
|
|
||||||
<i
|
|
||||||
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
|
||||||
id="Info_YOUTUBE_CHANNEL_HANDLE"
|
|
||||||
tip="The channel you want to connect to"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
<div class="AdvancedMenuRow inputYoutube">
|
|
||||||
<div class="AdvancedMenuLabel">Channel ID</div>
|
|
||||||
<input type="text" class="fname inputYoutube" id="YOUTUBE_CHANNEL_ID" />
|
|
||||||
<i
|
|
||||||
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
|
||||||
id="Info_YOUTUBE_CHANNEL_ID"
|
|
||||||
tip="The channel you want to connect to"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
<div class="AdvancedMenuRow inputYoutube">
|
|
||||||
<div class="AdvancedMenuLabel">Live ID</div>
|
|
||||||
<input type="text" class="fname inputYoutube" id="YOUTUBE_LIVE_ID" />
|
|
||||||
<i
|
|
||||||
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
|
||||||
id="Info_YOUTUBE_LIVE_ID"
|
|
||||||
tip="The channel you want to connect to"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
<div class="AdvancedMenuRow inputYoutube">
|
|
||||||
<div class="AdvancedMenuLabel">Test credentials</div>
|
|
||||||
<button type="text" class="AdvancedMenuButton" id="TestYoutubeCredentials">Test</button>
|
|
||||||
<i
|
|
||||||
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
|
||||||
id="Info_YOUTUBE_TEST_CREDENTIALS"
|
|
||||||
tip="Test Youtube credentials"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<fieldset id="TrovoMenu" class="AdvancedMenu">
|
|
||||||
<legend class="legendStyle" tip="Enable/Disable Trovo">
|
|
||||||
<img class="AdvancedMenuIcon" src="./images/trovo.png" alt=" " />
|
|
||||||
<input type="checkbox" id="USE_TROVO" class="checkbox" />
|
|
||||||
<label for="USE_TROVO" class="toggle-small"></label>
|
|
||||||
<div class="AdvancedMenuLabel3">Enable Trovo</div>
|
|
||||||
</legend>
|
|
||||||
<div class="AdvancedMenuRow inputTrovo">
|
|
||||||
<div class="AdvancedMenuLabel">Oauth Token</div>
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
type2="text"
|
|
||||||
class="fname inputTrovo"
|
|
||||||
id="TROVO_OAUTH_TOKEN"
|
|
||||||
placeholder="click the key icon to get the OAuth token"
|
|
||||||
/>
|
|
||||||
<button class="password-toggle-btn password-toggle-btn2">
|
|
||||||
<span class="password-toggle-icon"><i class="fa-regular fa-eye-slash"></i></span>
|
|
||||||
</button>
|
|
||||||
<i class="fa-solid fa-key fa-2x SmallButton option-icon-container" id="Info_TROVO_USERNAME" tip="Get OAuth Token"></i>
|
|
||||||
</div>
|
|
||||||
<div class="AdvancedMenuRow inputTrovo">
|
|
||||||
<div class="AdvancedMenuLabel">Channel Name</div>
|
|
||||||
<input type="text" class="fname inputTrovo" id="TROVO_CHANNEL_NAME" />
|
|
||||||
<i
|
|
||||||
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
|
||||||
id="Info_TROVO_CHANNEL_NAME"
|
|
||||||
tip="The channel you want to connect to"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
<div class="AdvancedMenuRow inputTrovo">
|
|
||||||
<div class="AdvancedMenuLabel">Test credentials</div>
|
|
||||||
<button type="text" class="AdvancedMenuButton" id="TestTrovoCredentials">Test</button>
|
|
||||||
<i
|
|
||||||
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
|
||||||
id="Info_TROVO_TEST_CREDENTIALS"
|
|
||||||
tip="Test Trovo credentials"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<fieldset id="DLiveMenu" class="AdvancedMenu">
|
|
||||||
<legend class="legendStyle" tip="Enable/Disable DLive">
|
|
||||||
<img class="AdvancedMenuIcon" src="./images/dlive.png" alt=" " />
|
|
||||||
<input type="checkbox" id="USE_DLIVE" class="checkbox" />
|
|
||||||
<label for="USE_DLIVE" class="toggle-small"></label>
|
|
||||||
<div class="AdvancedMenuLabel3">Enable DLive</div>
|
|
||||||
</legend>
|
|
||||||
<div class="AdvancedMenuRow inputDLive">
|
|
||||||
<div class="AdvancedMenuLabel">API Key</div>
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
type2="text"
|
|
||||||
class="fname inputDLive"
|
|
||||||
id="DLIVE_OAUTH_TOKEN"
|
|
||||||
placeholder="click the key icon to get the OAuth token"
|
|
||||||
/>
|
|
||||||
<button class="password-toggle-btn password-toggle-btn2">
|
|
||||||
<span class="password-toggle-icon"><i class="fa-regular fa-eye-slash"></i></span>
|
|
||||||
</button>
|
|
||||||
<i class="fa-solid fa-key fa-2x SmallButton option-icon-container" id="Info_DLIVE_USERNAME" tip="Get OAuth Token"></i>
|
|
||||||
</div>
|
|
||||||
<div class="AdvancedMenuRow inputDLive">
|
|
||||||
<div class="AdvancedMenuLabel">Channel Name</div>
|
|
||||||
<input type="text" class="fname inputDLive" id="DLIVE_CHANNEL_NAME" />
|
|
||||||
<i
|
|
||||||
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
|
||||||
id="Info_DLIVE_CHANNEL_NAME"
|
|
||||||
tip="The channel you want to connect to"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
<div class="AdvancedMenuRow inputDLive">
|
|
||||||
<div class="AdvancedMenuLabel">Test credentials</div>
|
|
||||||
<button type="text" class="AdvancedMenuButton" id="TestDLiveCredentials">Test</button>
|
|
||||||
<i
|
|
||||||
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
|
||||||
id="Info_DLIVE_TEST_CREDENTIALS"
|
|
||||||
tip="Test DLive credentials"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<fieldset id="AdvancedMenuServer" class="AdvancedMenu">
|
<fieldset id="AdvancedMenuServer" class="AdvancedMenu">
|
||||||
<legend class="legendStyle" tip="Enable/Disable Server">
|
<legend class="legendStyle" tip="Enable/Disable Server">
|
||||||
<img class="AdvancedMenuIcon" src="./images/server.png" alt />
|
<img class="AdvancedMenuIcon" src="./images/server.png" alt />
|
||||||
|
|
@ -587,8 +401,8 @@
|
||||||
<label for="USE_MODULES" class="toggle-small"></label>
|
<label for="USE_MODULES" class="toggle-small"></label>
|
||||||
<div class="AdvancedMenuLabel3">Enable Modules</div>
|
<div class="AdvancedMenuLabel3">Enable Modules</div>
|
||||||
</legend>
|
</legend>
|
||||||
<div class="AdvancedMenuRow inputServer">
|
<div class="AdvancedMenuRow inputServer" style="height: 0; visibility: hidden">
|
||||||
<div class="AdvancedMenuLabel">PNGtuber</div>
|
<div class="AdvancedMenuLabel">Use PNGtuber</div>
|
||||||
<input type="checkbox" id="USE_PNGTUBER" class="checkbox" />
|
<input type="checkbox" id="USE_PNGTUBER" class="checkbox" />
|
||||||
<label for="USE_PNGTUBER" class="toggle-small"></label>
|
<label for="USE_PNGTUBER" class="toggle-small"></label>
|
||||||
<input type="url" type2="text" class="fname inputServer" id="PNGTUBER_URL" />
|
<input type="url" type2="text" class="fname inputServer" id="PNGTUBER_URL" />
|
||||||
|
|
@ -599,7 +413,7 @@
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="AdvancedMenuRow inputServer">
|
<div class="AdvancedMenuRow inputServer">
|
||||||
<div class="AdvancedMenuLabel">Vtuber</div>
|
<div class="AdvancedMenuLabel">Use Vtuber</div>
|
||||||
<input type="checkbox" id="USE_VTUBER" class="checkbox" />
|
<input type="checkbox" id="USE_VTUBER" class="checkbox" />
|
||||||
<label for="USE_VTUBER" class="toggle-small"></label>
|
<label for="USE_VTUBER" class="toggle-small"></label>
|
||||||
<input type="url" type2="text" class="fname inputServer" id="VTUBER_URL" />
|
<input type="url" type2="text" class="fname inputServer" id="VTUBER_URL" />
|
||||||
|
|
@ -610,35 +424,17 @@
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="AdvancedMenuRow inputServer">
|
<div class="AdvancedMenuRow inputServer">
|
||||||
<div class="AdvancedMenuLabel">external Chat window</div>
|
<div class="AdvancedMenuLabel">Use ChatBubble</div>
|
||||||
<input type="checkbox" id="USE_CHATWINDOW" class="checkbox" />
|
|
||||||
<label for="USE_CHATWINDOW" class="toggle-small"></label>
|
|
||||||
<input type="url" type2="text" class="fname inputServer" id="CHATWINDOW_URL" />
|
|
||||||
<i
|
|
||||||
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
|
||||||
id="Info_CHATWINDOW"
|
|
||||||
tip="You can use it as a browsersource on http://localhost:PORT/chat"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
<div class="AdvancedMenuRow inputServer">
|
|
||||||
<div class="AdvancedMenuLabel">ChatBubble</div>
|
|
||||||
<input type="checkbox" id="USE_CHATBUBBLE" class="checkbox" />
|
<input type="checkbox" id="USE_CHATBUBBLE" class="checkbox" />
|
||||||
<label for="USE_CHATBUBBLE" class="toggle-small"></label>
|
<label for="USE_CHATBUBBLE" class="toggle-small"></label>
|
||||||
<input type="url" type2="text" class="fname inputServer" id="CHATBUBBLE_URL" />
|
<input type="url" type2="text" class="fname inputServer" id="CHATBUBBLE_URL" />
|
||||||
<i
|
<i
|
||||||
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
||||||
id="Info_CHATBUBBLE"
|
id="Info_CHATBUBBLE"
|
||||||
tip="You can use it as a browsersource on http://localhost:PORT/chatbubble"
|
tip="You can use it as a browsersource on http://localhost:PORT/chat"
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="AdvancedMenuRow inputServer">
|
<div class="AdvancedMenuRow inputServer" style="height: 0; visibility: hidden">
|
||||||
<div class="AdvancedMenuLabel">FaceMask</div>
|
|
||||||
<input type="checkbox" id="USE_FACEMASK" class="checkbox" />
|
|
||||||
<label for="USE_FACEMASK" class="toggle-small"></label>
|
|
||||||
<input type="url" type2="text" class="fname inputServer" id="FACEMASK_URL" />
|
|
||||||
<i class="fa fa-question-circle fa-2x SmallButton option-icon-container" id="Info_FACEMASK" tip="WIP"></i>
|
|
||||||
</div>
|
|
||||||
<!-- <div class="AdvancedMenuRow inputServer" style="height: 0; visibility: hidden">
|
|
||||||
<div class="AdvancedMenuLabel">Use Finger</div>
|
<div class="AdvancedMenuLabel">Use Finger</div>
|
||||||
<input type="checkbox" id="USE_CHATBUBBLE" class="checkbox" />
|
<input type="checkbox" id="USE_CHATBUBBLE" class="checkbox" />
|
||||||
<label for="USE_CHATBUBBLE" class="toggle-small"></label>
|
<label for="USE_CHATBUBBLE" class="toggle-small"></label>
|
||||||
|
|
@ -648,7 +444,7 @@
|
||||||
id="Info_CHATBUBBLE"
|
id="Info_CHATBUBBLE"
|
||||||
tip="You can use it as a browsersource on http://localhost:PORT/chat"
|
tip="You can use it as a browsersource on http://localhost:PORT/chat"
|
||||||
></i>
|
></i>
|
||||||
</div> -->
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset id="AdvancedMenuAmazon" class="AdvancedMenu" style="height: 0; visibility: hidden">
|
<fieldset id="AdvancedMenuAmazon" class="AdvancedMenu" style="height: 0; visibility: hidden">
|
||||||
|
|
@ -826,12 +622,6 @@
|
||||||
<input id="textInput" class="input-box" type="text" name="msg" placeholder="Tap 'Enter' to send a message" />
|
<input id="textInput" class="input-box" type="text" name="msg" placeholder="Tap 'Enter' to send a message" />
|
||||||
|
|
||||||
<!-- Send button-->
|
<!-- Send button-->
|
||||||
<div class="network-select">
|
|
||||||
<button class="SmallButton">
|
|
||||||
<i class="fa-brands fa-stack-exchange fa-2x" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
<div class="send-to-channel" id="SEND_TO_CHANNELS"></div>
|
|
||||||
</div>
|
|
||||||
<button class="SmallButton" id="SendButton">
|
<button class="SmallButton" id="SendButton">
|
||||||
<i class="fa fa-play-circle fa-2x" aria-hidden="true"></i>
|
<i class="fa fa-play-circle fa-2x" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
/* global settings,twitch,trovo, fs, settingsPath, ini, shell, options, axios */
|
/* global settings,twitch, fs, settingsPath, ini, shell, options, axios */
|
||||||
|
|
||||||
const twitchAuthentication = () =>
|
const twitchAuthentication = () =>
|
||||||
new Promise(resolve => {
|
new Promise(resolve => {
|
||||||
const http = require('http');
|
const http = require('http');
|
||||||
const redirectUri = 'http://localhost:1989/auth';
|
const redirectUri = 'http://localhost:1989/auth';
|
||||||
const scopes = ['chat:edit', 'chat:read', 'user:read:follows', 'user:read:subscriptions', 'channel:read:redemptions'];
|
const scopes = ['chat:edit', 'chat:read', 'user:read:follows', 'user:read:subscriptions'];
|
||||||
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const tempAuthServer = express();
|
const tempAuthServer = express();
|
||||||
|
|
@ -13,25 +13,20 @@ const twitchAuthentication = () =>
|
||||||
const { parse: parseQueryString } = require('querystring');
|
const { parse: parseQueryString } = require('querystring');
|
||||||
|
|
||||||
tempAuthServer.use(function (req, res, next) {
|
tempAuthServer.use(function (req, res, next) {
|
||||||
console.log('1');
|
|
||||||
if (req.url !== '/auth') {
|
if (req.url !== '/auth') {
|
||||||
console.log(req.url);
|
|
||||||
const token = parseQueryString(req.query.auth);
|
const token = parseQueryString(req.query.auth);
|
||||||
console.log(req);
|
|
||||||
console.log(token);
|
|
||||||
settings.TWITCH.OAUTH_TOKEN = token['#access_token'];
|
settings.TWITCH.OAUTH_TOKEN = token['#access_token'];
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
|
|
||||||
resolve(token['#access_token']);
|
resolve(token['#access_token']);
|
||||||
stopServer();
|
stopServer();
|
||||||
} else {
|
|
||||||
res.send(htmlString);
|
|
||||||
}
|
}
|
||||||
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
const htmlString = `
|
const htmlString = `
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Authentication</title>
|
<title>Authentication</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
@ -41,6 +36,7 @@ const twitchAuthentication = () =>
|
||||||
<input type="text" id="auth" name="auth"/>
|
<input type="text" id="auth" name="auth"/>
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
|
</html>
|
||||||
<script>
|
<script>
|
||||||
function onSubmitComplete() {
|
function onSubmitComplete() {
|
||||||
close();
|
close();
|
||||||
|
|
@ -50,16 +46,22 @@ const twitchAuthentication = () =>
|
||||||
document.auth.submit();
|
document.auth.submit();
|
||||||
setTimeout(onSubmitComplete, 500);
|
setTimeout(onSubmitComplete, 500);
|
||||||
</script>
|
</script>
|
||||||
</html>
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
console.log('-1');
|
tempAuthServer.get('/auth', (req, res) => {
|
||||||
|
res.send(htmlString);
|
||||||
|
});
|
||||||
|
|
||||||
|
tempAuthServer.post('/auth', (req, res) => {
|
||||||
|
res.render('authentication', { name: req.body.name });
|
||||||
|
});
|
||||||
|
|
||||||
const server = http.createServer(tempAuthServer);
|
const server = http.createServer(tempAuthServer);
|
||||||
|
|
||||||
server.listen(port, () => {
|
server.listen(port, () => {
|
||||||
const authURL = `https://id.twitch.tv/oauth2/authorize?client_id=${settings.TWITCH.CLIENT_ID}&redirect_uri=${encodeURIComponent(
|
const authURL = `https://id.twitch.tv/oauth2/authorize?client_id=${settings.TWITCH.CLIENT_ID}&redirect_uri=${encodeURIComponent(
|
||||||
redirectUri
|
redirectUri
|
||||||
)}&response_type=token&scope=${scopes.join('+')}`;
|
)}&response_type=token&scope=${scopes.join(' ')}`;
|
||||||
shell.openExternal(authURL);
|
shell.openExternal(authURL);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -71,60 +73,9 @@ const twitchAuthentication = () =>
|
||||||
function getTwitchOauthToken() {
|
function getTwitchOauthToken() {
|
||||||
return twitchAuthentication().then(res => {
|
return twitchAuthentication().then(res => {
|
||||||
twitch.getTwitchUserId();
|
twitch.getTwitchUserId();
|
||||||
|
// twitch.getTwitchChannelId();
|
||||||
return res;
|
return res;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const trovoAuthentication = () =>
|
module.exports = { getTwitchOauthToken };
|
||||||
new Promise(resolve => {
|
|
||||||
const http = require('http');
|
|
||||||
const redirectUri = 'http://localhost:1989/auth';
|
|
||||||
const scopes = ['user_details_self', 'chat_send_self', 'send_to_my_channel', 'manage_messages'];
|
|
||||||
|
|
||||||
const express = require('express');
|
|
||||||
const tempAuthServer = express();
|
|
||||||
const port = 1989;
|
|
||||||
|
|
||||||
tempAuthServer.use(function (req, res) {
|
|
||||||
res.send(htmlString);
|
|
||||||
const token = req.query.access_token;
|
|
||||||
settings.TROVO.OAUTH_TOKEN = token;
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
|
||||||
resolve(token);
|
|
||||||
stopServer();
|
|
||||||
});
|
|
||||||
|
|
||||||
const htmlString = `
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Authentication</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Authentication successful! You can close this window now.</h1>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`;
|
|
||||||
|
|
||||||
const server = http.createServer(tempAuthServer);
|
|
||||||
|
|
||||||
server.listen(port, () => {
|
|
||||||
const authURL = `https://open.trovo.live/page/login.html?client_id=${
|
|
||||||
settings.TROVO.CLIENT_ID
|
|
||||||
}&response_type=token&scope=${scopes.join('+')}&redirect_uri=${encodeURIComponent(redirectUri)}`;
|
|
||||||
const lol = shell.openExternal(authURL);
|
|
||||||
});
|
|
||||||
|
|
||||||
function stopServer() {
|
|
||||||
server.close(() => {});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function getTrovoOAuthToken() {
|
|
||||||
return trovoAuthentication().then(res => {
|
|
||||||
trovo.getTrovoUserId();
|
|
||||||
return res;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { getTwitchOauthToken, getTrovoOAuthToken };
|
|
||||||
|
|
|
||||||
|
|
@ -75,12 +75,12 @@ function setTranslatedUserMessage(message) {
|
||||||
function setTranslatedMessage(message) {
|
function setTranslatedMessage(message) {
|
||||||
// this determines if it is a message that is send by a user
|
// this determines if it is a message that is send by a user
|
||||||
const languageBox = document.getElementById(message.messageId).getElementsByClassName('language-icon flag-icon')[0];
|
const languageBox = document.getElementById(message.messageId).getElementsByClassName('language-icon flag-icon')[0];
|
||||||
// if (false) {
|
if (!languageBox) {
|
||||||
// twitch.sendMessage(
|
twitch.sendMessage(
|
||||||
// `[${message.language.detectedLanguage.name} ${message.language.detectedLanguage.ISO639} > ${message.language.selectedLanguage.name} ${message.language.selectedLanguage.ISO639}] @${settings.TWITCH.USERNAME}: ${message.translation}`
|
`[${message.language.detectedLanguage.name} ${message.language.detectedLanguage.ISO639} > ${message.language.selectedLanguage.name} ${message.language.selectedLanguage.ISO639}] @${message.username}: ${message.translation}`
|
||||||
// );
|
);
|
||||||
// return setTranslatedUserMessage(message);
|
return setTranslatedUserMessage(message);
|
||||||
// }
|
}
|
||||||
|
|
||||||
if (message.language.selectedLanguage.ISO639 !== message.language.detectedLanguage.ISO639) {
|
if (message.language.selectedLanguage.ISO639 !== message.language.detectedLanguage.ISO639) {
|
||||||
const messageBox = document.getElementById(message.messageId).getElementsByClassName('msg-box')[0];
|
const messageBox = document.getElementById(message.messageId).getElementsByClassName('msg-box')[0];
|
||||||
|
|
@ -106,14 +106,9 @@ function setTranslatedMessage(message) {
|
||||||
translationMessage.className = 'translation-message';
|
translationMessage.className = 'translation-message';
|
||||||
translationMessage.innerText = message.translation;
|
translationMessage.innerText = message.translation;
|
||||||
messageBox.appendChild(translationMessage);
|
messageBox.appendChild(translationMessage);
|
||||||
// showChatMessage();
|
showChatMessage();
|
||||||
const messages = document.body.querySelectorAll('.msg-container');
|
|
||||||
|
|
||||||
const lastMessage = messages[messages.length - 1];
|
|
||||||
lastMessage.scrollIntoView({ block: 'end', behavior: 'smooth' });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(message);
|
|
||||||
if (settings.LANGUAGE.OUTPUT_TO_TTS) {
|
if (settings.LANGUAGE.OUTPUT_TO_TTS) {
|
||||||
sound.playVoice({
|
sound.playVoice({
|
||||||
originalMessage: message.originalMessage,
|
originalMessage: message.originalMessage,
|
||||||
|
|
@ -128,9 +123,6 @@ function setTranslatedMessage(message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getTranslatedMessage(message) {
|
async function getTranslatedMessage(message) {
|
||||||
// TODO: translate primary language to
|
|
||||||
console.log(message);
|
|
||||||
console.log(message.isPrimaryLanguage ? message.language.selectedLanguage.IETF : message.language.detectedLanguage.IETF);
|
|
||||||
const requestOptions = {
|
const requestOptions = {
|
||||||
method: 'POST', // HTTP method
|
method: 'POST', // HTTP method
|
||||||
headers: {
|
headers: {
|
||||||
|
|
@ -138,7 +130,7 @@ async function getTranslatedMessage(message) {
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
message: message.message,
|
message: message.message,
|
||||||
language: message.isPrimaryLanguage ? message.language.selectedLanguage.IETF : message.language.detectedLanguage.IETF
|
language: message.language.detectedLanguage.IETF
|
||||||
}) // Convert the data to JSON and include it in the request body
|
}) // Convert the data to JSON and include it in the request body
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -234,15 +226,11 @@ async function filterLanguage(message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const language = selectedPrimaryLanguageIndex < selectedSecondaryLanguageIndex ? selectedPrimaryLanguage : detectedLanguage;
|
const language = selectedPrimaryLanguageIndex < selectedSecondaryLanguageIndex ? selectedPrimaryLanguage : detectedLanguage;
|
||||||
|
if (settings.LANGUAGE.TRANSLATE_TO !== 'none' && selectedPrimaryLanguage.ISO639 !== detectedLanguage.ISO639) {
|
||||||
if (settings.LANGUAGE.TRANSLATE_TO !== 'none' && selectedPrimaryLanguage.ISO639 !== language.ISO639) {
|
|
||||||
// console.log('1');
|
|
||||||
console.log('hola');
|
|
||||||
getTranslatedMessage({
|
getTranslatedMessage({
|
||||||
message: message.message,
|
message: message.message,
|
||||||
messageId: message.messageId,
|
messageId: message.messageId,
|
||||||
remainingDetectedLanguages,
|
remainingDetectedLanguages,
|
||||||
isPrimaryLanguage: false,
|
|
||||||
language: {
|
language: {
|
||||||
selectedLanguage: selectedPrimaryLanguage,
|
selectedLanguage: selectedPrimaryLanguage,
|
||||||
detectedLanguage: detectedLanguage
|
detectedLanguage: detectedLanguage
|
||||||
|
|
@ -252,8 +240,6 @@ async function filterLanguage(message) {
|
||||||
logoUrl: message.logoUrl
|
logoUrl: message.logoUrl
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log('adios');
|
|
||||||
// console.log('2');
|
|
||||||
setTranslatedMessage({
|
setTranslatedMessage({
|
||||||
originalMessage: message.message,
|
originalMessage: message.message,
|
||||||
translation: message.message,
|
translation: message.message,
|
||||||
|
|
@ -266,19 +252,6 @@ async function filterLanguage(message) {
|
||||||
username: message.username,
|
username: message.username,
|
||||||
logoUrl: message.logoUrl
|
logoUrl: message.logoUrl
|
||||||
});
|
});
|
||||||
// getTranslatedMessage({
|
|
||||||
// message: message.message,
|
|
||||||
// messageId: message.messageId,
|
|
||||||
// remainingDetectedLanguages: [],
|
|
||||||
// isPrimaryLanguage: true,
|
|
||||||
// language: {
|
|
||||||
// selectedLanguage: selectedSecondaryLanguage,
|
|
||||||
// detectedLanguage: selectedPrimaryLanguage
|
|
||||||
// },
|
|
||||||
// username: message.username,
|
|
||||||
// formattedMessage: message.formattedMessage,
|
|
||||||
// logoUrl: message.logoUrl
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return language;
|
return language;
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ const replaceChatMessageWithCustomEmojis = message =>
|
||||||
if (word !== '') {
|
if (word !== '') {
|
||||||
await emojiPicker.database.getEmojiByUnicodeOrName(word).then(data => {
|
await emojiPicker.database.getEmojiByUnicodeOrName(word).then(data => {
|
||||||
if (data && data.name === word) {
|
if (data && data.name === word) {
|
||||||
const url = `<img class="emote" src="${data.url}" >`;
|
const url = `<img src="${data.url}">`;
|
||||||
message = message.replace(word, url);
|
message = message.replace(word, url);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -144,10 +144,8 @@ const displayPanel = (panelSelectorClass, panelSelectorID, btnSelectorID) => {
|
||||||
|
|
||||||
displayPanel('.OptionPanel', '#Configuration', '#btnConfiguration');
|
displayPanel('.OptionPanel', '#Configuration', '#btnConfiguration');
|
||||||
displayPanel('.OptionPanel', '#Logs', '#btnLogs');
|
displayPanel('.OptionPanel', '#Logs', '#btnLogs');
|
||||||
displayPanel('.OptionPanel', '#BrowsersourceChatBubble', '#btnBrowsersourceChatBubble');
|
displayPanel('.OptionPanel', '#BrowsersourceChat', '#btnBrowsersourceChat');
|
||||||
displayPanel('.OptionPanel', '#BrowsersourceVtuber', '#btnBrowsersourceVtuber');
|
displayPanel('.OptionPanel', '#BrowsersourceVtuber', '#btnBrowsersourceVtuber');
|
||||||
displayPanel('.OptionPanel', '#BrowsersourcePNGTuber', '#btnBrowsersourcePNGTuber');
|
|
||||||
displayPanel('.OptionPanel', '#FaceMask', '#btnFaceMask');
|
|
||||||
displayPanel('.OptionPanel', '#Chat', '#btnChat');
|
displayPanel('.OptionPanel', '#Chat', '#btnChat');
|
||||||
displayPanel('.OptionPanel', '#ThemeCreator', '#btnThemeCreator');
|
displayPanel('.OptionPanel', '#ThemeCreator', '#btnThemeCreator');
|
||||||
displayPanel('.OptionPanel', '#ChatCreator', '#btnChatCreator');
|
displayPanel('.OptionPanel', '#ChatCreator', '#btnChatCreator');
|
||||||
|
|
@ -177,10 +175,8 @@ const displayPanelX = (panelSelectorClass, panelSelectorID, btnSelectorID) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
displayPanelX('.item', '#btnChat', '#btnChat');
|
displayPanelX('.item', '#btnChat', '#btnChat');
|
||||||
displayPanelX('.item', '#btnBrowsersourceChatBubble', '#btnBrowsersourceChatBubble');
|
displayPanelX('.item', '#btnBrowsersourceChat', '#btnBrowsersourceChat');
|
||||||
displayPanelX('.item', '#btnBrowsersourceVtuber', '#btnBrowsersourceVtuber');
|
displayPanelX('.item', '#btnBrowsersourceVtuber', '#btnBrowsersourceVtuber');
|
||||||
displayPanelX('.item', '#btnBrowsersourcePNGTuber', '#btnBrowsersourcePNGTuber');
|
|
||||||
displayPanelX('.item', '#btnFaceMask', '#btnFaceMask');
|
|
||||||
displayPanelX('.item', '#btnLogs', '#btnLogs');
|
displayPanelX('.item', '#btnLogs', '#btnLogs');
|
||||||
displayPanelX('.item', '#btnConfiguration', '#btnConfiguration');
|
displayPanelX('.item', '#btnConfiguration', '#btnConfiguration');
|
||||||
displayPanelX('.item', '#btnThemeCreator', '#btnThemeCreator');
|
displayPanelX('.item', '#btnThemeCreator', '#btnThemeCreator');
|
||||||
|
|
|
||||||
102
src/js/dlive.js
|
|
@ -1,102 +0,0 @@
|
||||||
/* global settings, bot,settingsPath, fs, ini, messageId, showChatMessage, messageTemplates, chat, addSingleTooltip,getPostTime */
|
|
||||||
|
|
||||||
const Dlive = require('dlivetv-api');
|
|
||||||
|
|
||||||
const bot = new Dlive(settings.DLIVE.API_KEY);
|
|
||||||
|
|
||||||
function setTrovoSendButton() {
|
|
||||||
const languageSelectContent = document.querySelector('.send-to-channel');
|
|
||||||
|
|
||||||
const option = document.createElement('div');
|
|
||||||
option.classList = 'language-select';
|
|
||||||
|
|
||||||
const checkbox = document.createElement('input');
|
|
||||||
checkbox.classList = 'checkbox';
|
|
||||||
checkbox.type = 'checkbox';
|
|
||||||
checkbox.id = 'SEND_CHAT_DLIVE';
|
|
||||||
option.appendChild(checkbox);
|
|
||||||
|
|
||||||
const label = document.createElement('label');
|
|
||||||
label.classList = 'toggle-small';
|
|
||||||
option.setAttribute('for', 'SEND_CHAT_DLIVE');
|
|
||||||
checkbox.checked = settings.TROVO.SEND_CHAT;
|
|
||||||
option.appendChild(label);
|
|
||||||
|
|
||||||
const network = document.createElement('img');
|
|
||||||
network.src = './images/dlive.png';
|
|
||||||
network.classList = 'emote';
|
|
||||||
option.appendChild(network);
|
|
||||||
|
|
||||||
option.addEventListener('click', () => {
|
|
||||||
checkbox.checked = !checkbox.checked;
|
|
||||||
settings.TROVO.SEND_CHAT = checkbox.checked;
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
|
||||||
});
|
|
||||||
|
|
||||||
languageSelectContent.appendChild(option);
|
|
||||||
}
|
|
||||||
setTrovoSendButton();
|
|
||||||
|
|
||||||
bot.on('ChatText', message => {
|
|
||||||
// console.log(`[${msg.sender.displayname}]: ${msg.content}`);
|
|
||||||
displayDLiveMessage(message);
|
|
||||||
});
|
|
||||||
|
|
||||||
// bot.sendMessage('test').then(console.log).catch(console.log);
|
|
||||||
|
|
||||||
bot.on('ChatGift', msg => {
|
|
||||||
console.log(`${msg.sender.displayname} donated ${msg.amount} ${msg.gift}'s`);
|
|
||||||
});
|
|
||||||
|
|
||||||
bot.on('ChatHost', msg => {
|
|
||||||
console.log(`${msg.sender.displayname} coming in with that ${msg.viewer} viewer host!`);
|
|
||||||
});
|
|
||||||
|
|
||||||
bot.on('ChatFollow', msg => {
|
|
||||||
console.log(`New follower! ${msg.sender.displayname} has joined the party!`);
|
|
||||||
});
|
|
||||||
|
|
||||||
async function displayDLiveMessage(message) {
|
|
||||||
messageId++;
|
|
||||||
const article = document.createElement('article');
|
|
||||||
article.className = 'msg-container sender';
|
|
||||||
article.setAttribute('id', messageId);
|
|
||||||
|
|
||||||
article.innerHTML = messageTemplates.dliveTemplate;
|
|
||||||
const userImg = article.querySelector('.user-img');
|
|
||||||
if (userImg) {
|
|
||||||
userImg.src = message.sender.avatar;
|
|
||||||
userImg.setAttribute('tip', '');
|
|
||||||
}
|
|
||||||
addSingleTooltip(userImg);
|
|
||||||
|
|
||||||
const usernameHtml = article.querySelector('.username');
|
|
||||||
if (usernameHtml) {
|
|
||||||
usernameHtml.innerText = message.sender.displayname;
|
|
||||||
}
|
|
||||||
|
|
||||||
const postTime = article.querySelector('.post-time');
|
|
||||||
|
|
||||||
if (postTime) {
|
|
||||||
postTime.innerText = getPostTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
article.appendChild(postTime);
|
|
||||||
|
|
||||||
const formattedMessage = article.querySelector('.msg-box');
|
|
||||||
if (formattedMessage) {
|
|
||||||
formattedMessage.innerHTML = message.content;
|
|
||||||
// message.message.forEach(entry => {
|
|
||||||
// if (entry.text) {
|
|
||||||
// formattedMessage.innerHTML += entry.text;
|
|
||||||
// } else {
|
|
||||||
// formattedMessage.innerHTML += `<img src="${entry.url}"/>`;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
|
|
||||||
await chat.replaceChatMessageWithCustomEmojis(formattedMessage.innerHTML).then(data => {
|
|
||||||
formattedMessage.innerHTML = data;
|
|
||||||
showChatMessage(article);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +1,6 @@
|
||||||
const twitchTemplate = `
|
const twitchTemplate = `
|
||||||
<img class="user-img" src="" />
|
<img class="user-img" src="" />
|
||||||
<img class="status-circle sender" src="./images/twitch-icon.png" tip="Twitch" />
|
<img class="status-circle sender" src="./images/twitch-icon.png" tip="twitch" />
|
||||||
<span class="post-time sender"></span>
|
|
||||||
<span class="username sender"></span>
|
|
||||||
<div class="msg-box sender"></div>
|
|
||||||
`.trim();
|
|
||||||
|
|
||||||
const trovoTemplate = `
|
|
||||||
<img class="user-img" src="" />
|
|
||||||
<img class="status-circle sender" src="./images/trovo-icon.jpg" tip="Trovo" />
|
|
||||||
<span class="post-time sender"></span>
|
|
||||||
<span class="username sender"></span>
|
|
||||||
<div class="msg-box sender"></div>
|
|
||||||
`.trim();
|
|
||||||
|
|
||||||
const youtubeTemplate = `
|
|
||||||
<img class="user-img" src="" />
|
|
||||||
<img class="status-circle sender" src="./images/youtube-icon.png" tip="Youtube" />
|
|
||||||
<span class="post-time sender"></span>
|
|
||||||
<span class="username sender"></span>
|
|
||||||
<div class="msg-box sender"></div>
|
|
||||||
`.trim();
|
|
||||||
|
|
||||||
const dliveTemplate = `
|
|
||||||
<img class="user-img" src="" />
|
|
||||||
<img class="status-circle sender" src="./images/dlive-icon.png" tip="DLive" />
|
|
||||||
<span class="post-time sender"></span>
|
<span class="post-time sender"></span>
|
||||||
<span class="username sender"></span>
|
<span class="username sender"></span>
|
||||||
<div class="msg-box sender"></div>
|
<div class="msg-box sender"></div>
|
||||||
|
|
@ -48,4 +24,4 @@ const messageTemplate = `
|
||||||
</article>
|
</article>
|
||||||
`.trim();
|
`.trim();
|
||||||
|
|
||||||
module.exports = { twitchTemplate, dliveTemplate, youtubeTemplate, userTemplate, messageTemplate, trovoTemplate };
|
module.exports = { twitchTemplate, userTemplate, messageTemplate };
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
/* eslint-disable no-unused-vars */
|
/* eslint-disable no-unused-vars */
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const ini = require('ini');
|
||||||
|
const path = require('path'); // get directory path
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
const Sockette = require('sockette');
|
|
||||||
|
|
||||||
const { webFrame, ipcRenderer, shell } = require('electron');
|
const { webFrame, ipcRenderer, shell } = require('electron'); // necessary electron libraries to send data to the app
|
||||||
const io = require('socket.io-client');
|
const io = require('socket.io-client');
|
||||||
|
|
||||||
const GoogleTTS = require('node-google-tts-api');
|
const GoogleTTS = require('node-google-tts-api');
|
||||||
|
|
@ -23,8 +23,12 @@ const settings = main.settings;
|
||||||
const googleVoices = fs.readFileSync(path.join(__dirname, './config/googleVoices.txt')).toString().split('\r\n');
|
const googleVoices = fs.readFileSync(path.join(__dirname, './config/googleVoices.txt')).toString().split('\r\n');
|
||||||
// TODO: remove amazon voices txt and use api instead (sakura project has it)
|
// TODO: remove amazon voices txt and use api instead (sakura project has it)
|
||||||
const amazonVoices = fs.readFileSync(path.join(__dirname, './config/amazonVoices.txt')).toString().split('\r\n');
|
const amazonVoices = fs.readFileSync(path.join(__dirname, './config/amazonVoices.txt')).toString().split('\r\n');
|
||||||
const customEmotesListSavePath =
|
const twitchEmoteListSavePath =
|
||||||
main.isPackaged === true ? path.join(resourcesPath, './custom-emotes.json') : path.join(resourcesPath, './config/custom-emotes.json');
|
main.isPackaged === true ? path.join(resourcesPath, './twitch-emotes.json') : path.join(resourcesPath, './config/twitch-emotes.json');
|
||||||
|
const betterTtvEmoteListSavePath =
|
||||||
|
main.isPackaged === true
|
||||||
|
? path.join(resourcesPath, './betterttv-emotes.json')
|
||||||
|
: path.join(resourcesPath, './config/betterttv-emotes.json');
|
||||||
|
|
||||||
// html elements
|
// html elements
|
||||||
const root = document.documentElement;
|
const root = document.documentElement;
|
||||||
|
|
@ -47,17 +51,6 @@ const languageObject = require(path.join(__dirname, './js/languages'));
|
||||||
const logger = require(path.join(__dirname, './js/logger'));
|
const logger = require(path.join(__dirname, './js/logger'));
|
||||||
const sound = require(path.join(__dirname, './js/sound'));
|
const sound = require(path.join(__dirname, './js/sound'));
|
||||||
const config = require(path.join(__dirname, './js/settings'));
|
const config = require(path.join(__dirname, './js/settings'));
|
||||||
const { TokenAutocomplete } = require(path.join(__dirname, './js/token-autocomplete'));
|
|
||||||
|
|
||||||
const betterTTVAutocomplete = new TokenAutocomplete({
|
|
||||||
name: 'sample',
|
|
||||||
selector: '#sample',
|
|
||||||
noMatchesText: 'No matching results...',
|
|
||||||
initialTokens: [...settings.TWITCH.BETTERTTV_CHANNELS]
|
|
||||||
});
|
|
||||||
|
|
||||||
const test = settings.TWITCH.BETTERTTV_CHANNELS;
|
|
||||||
console.log(test);
|
|
||||||
|
|
||||||
const mediaDevices = require(path.join(__dirname, './js/mediaDevices'));
|
const mediaDevices = require(path.join(__dirname, './js/mediaDevices'));
|
||||||
|
|
||||||
|
|
@ -74,16 +67,6 @@ const socket = io(`http://localhost:${settings.GENERAL.PORT}`); // Connect to yo
|
||||||
|
|
||||||
let twitch = null;
|
let twitch = null;
|
||||||
twitch = settings.TWITCH.USE_TWITCH ? require(path.join(__dirname, './js/twitch')) : '';
|
twitch = settings.TWITCH.USE_TWITCH ? require(path.join(__dirname, './js/twitch')) : '';
|
||||||
|
|
||||||
let dlive = null;
|
|
||||||
dlive = settings.DLIVE.USE_DLIVE ? require(path.join(__dirname, './js/dlive')) : '';
|
|
||||||
|
|
||||||
let youtube = null;
|
|
||||||
youtube = settings.YOUTUBE.USE_YOUTUBE ? require(path.join(__dirname, './js/youtube')) : '';
|
|
||||||
|
|
||||||
let trovo = null;
|
|
||||||
trovo = settings.TROVO.USE_TROVO ? require(path.join(__dirname, './js/trovo')) : '';
|
|
||||||
|
|
||||||
const Polly = settings.AMAZON.USE_AMAZON ? require(path.join(__dirname, './js/amazon')) : '';
|
const Polly = settings.AMAZON.USE_AMAZON ? require(path.join(__dirname, './js/amazon')) : '';
|
||||||
const google = settings.GOOGLE.USE_GOOGLE ? require(path.join(__dirname, './js/google')) : '';
|
const google = settings.GOOGLE.USE_GOOGLE ? require(path.join(__dirname, './js/google')) : '';
|
||||||
|
|
||||||
|
|
@ -96,7 +79,6 @@ let customEmojis = [];
|
||||||
customEmojis = [];
|
customEmojis = [];
|
||||||
let messageId = 0;
|
let messageId = 0;
|
||||||
messageId = 0;
|
messageId = 0;
|
||||||
let customEmojiList = [];
|
|
||||||
|
|
||||||
// initialize values
|
// initialize values
|
||||||
config.getGeneralSettings();
|
config.getGeneralSettings();
|
||||||
|
|
@ -209,7 +191,7 @@ function setLanguagesinSelectx(languageSelector, language) {
|
||||||
settings.LANGUAGE.SEND_TRANSLATION_OUT = language.IETF;
|
settings.LANGUAGE.SEND_TRANSLATION_OUT = language.IETF;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
setSelectedLanguageinSelect(languageSelect, language);
|
setSelectedLanguageinSelect(languageSelect, language);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -345,27 +327,14 @@ Array.from(document.body.querySelectorAll('[tip]')).forEach(el => {
|
||||||
});
|
});
|
||||||
|
|
||||||
function showChatMessage(article) {
|
function showChatMessage(article) {
|
||||||
let body = null;
|
|
||||||
if (article !== undefined) {
|
if (article !== undefined) {
|
||||||
body = document.getElementById('chatBox');
|
document.querySelector('#chatBox').appendChild(article);
|
||||||
body.appendChild(article);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const messages = document.body.querySelectorAll('.msg-container');
|
const messages = document.body.querySelectorAll('.msg-container');
|
||||||
|
|
||||||
const lastMessage = messages[messages.length - 1];
|
const lastMessage = messages[messages.length - 1];
|
||||||
lastMessage.scrollIntoView({ block: 'end', behavior: 'smooth' });
|
lastMessage.scrollIntoView({ block: 'end', behavior: 'smooth' });
|
||||||
|
|
||||||
// const messageId = article.id;
|
|
||||||
// languageElement.setAttribute('id', article.id);
|
|
||||||
|
|
||||||
// console.log(article);
|
|
||||||
const username = article.querySelector('.username').innerHTML;
|
|
||||||
const image = article.querySelector('.user-img').src;
|
|
||||||
const statusCircle = article.querySelector('.status-circle').src;
|
|
||||||
const message = article.querySelector('.msg-box').innerHTML;
|
|
||||||
const postTime = article.querySelector('.post-time').innerHTML;
|
|
||||||
socket.emit('chat-out', { messageId, username, image, statusCircle, message, postTime });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPostTime() {
|
function getPostTime() {
|
||||||
|
|
@ -401,7 +370,6 @@ function hideText(button, field) {
|
||||||
}
|
}
|
||||||
|
|
||||||
hideText('.password-toggle-btn1', '#TWITCH_OAUTH_TOKEN');
|
hideText('.password-toggle-btn1', '#TWITCH_OAUTH_TOKEN');
|
||||||
hideText('.password-toggle-btn2', '#TROVO_OAUTH_TOKEN');
|
|
||||||
hideText('.password-toggle-btn4', '#AMAZON_ACCESS_KEY');
|
hideText('.password-toggle-btn4', '#AMAZON_ACCESS_KEY');
|
||||||
hideText('.password-toggle-btn5', '#AMAZON_ACCESS_SECRET');
|
hideText('.password-toggle-btn5', '#AMAZON_ACCESS_SECRET');
|
||||||
hideText('.password-toggle-btn6', '#GOOGLE_API_KEY');
|
hideText('.password-toggle-btn6', '#GOOGLE_API_KEY');
|
||||||
|
|
@ -418,10 +386,28 @@ function setZoomLevel(currentZoom, zoomIn) {
|
||||||
|
|
||||||
webFrame.setZoomFactor(parseFloat(newZoom));
|
webFrame.setZoomFactor(parseFloat(newZoom));
|
||||||
settings.GENERAL.ZOOMLEVEL = newZoom;
|
settings.GENERAL.ZOOMLEVEL = newZoom;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
document.body.querySelector('#ZOOMLEVEL').value = (settings.GENERAL.ZOOMLEVEL * 100).toFixed(0);
|
document.body.querySelector('#ZOOMLEVEL').value = (settings.GENERAL.ZOOMLEVEL * 100).toFixed(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: refactor
|
||||||
|
let twitchEmotes = null;
|
||||||
|
if (fs.existsSync(twitchEmoteListSavePath)) {
|
||||||
|
const xxx = fs.readFileSync(twitchEmoteListSavePath);
|
||||||
|
twitchEmotes = JSON.parse(xxx);
|
||||||
|
emojiPicker.customEmoji = [...twitchEmotes];
|
||||||
|
}
|
||||||
|
let betterTtvEmotes = null;
|
||||||
|
if (fs.existsSync(betterTtvEmoteListSavePath)) {
|
||||||
|
const xxx = fs.readFileSync(betterTtvEmoteListSavePath);
|
||||||
|
betterTtvEmotes = JSON.parse(xxx);
|
||||||
|
emojiPicker.customEmoji = [...betterTtvEmotes];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (twitchEmotes && betterTtvEmotes) {
|
||||||
|
emojiPicker.customEmoji = [...twitchEmotes, ...betterTtvEmotes];
|
||||||
|
}
|
||||||
|
|
||||||
function getLanguageProperties(languageToDetect) {
|
function getLanguageProperties(languageToDetect) {
|
||||||
try {
|
try {
|
||||||
const filteredLanguage = Object.keys(languageObject.languages).reduce(function (accumulator, currentValue) {
|
const filteredLanguage = Object.keys(languageObject.languages).reduce(function (accumulator, currentValue) {
|
||||||
|
|
@ -448,132 +434,3 @@ function getLanguageProperties(languageToDetect) {
|
||||||
return 'error';
|
return 'error';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let customEmotes = null;
|
|
||||||
if (fs.existsSync(customEmotesListSavePath)) {
|
|
||||||
const file = fs.readFileSync(customEmotesListSavePath);
|
|
||||||
customEmotes = JSON.parse(file);
|
|
||||||
customEmojiList = [...customEmojiList, ...customEmotes];
|
|
||||||
}
|
|
||||||
|
|
||||||
emojiPicker.customEmoji = customEmojiList;
|
|
||||||
|
|
||||||
function saveCustomEmotesToFile(emotes) {
|
|
||||||
const data = JSON.stringify(emotes);
|
|
||||||
customEmojiList = [...customEmojiList, data];
|
|
||||||
const savePath =
|
|
||||||
main.isPackaged === true ? path.join(resourcesPath, './custom-emotes.json') : path.join(resourcesPath, './config/custom-emotes.json');
|
|
||||||
|
|
||||||
fs.writeFile(savePath, data, error => {
|
|
||||||
if (error) {
|
|
||||||
console.error(error);
|
|
||||||
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function countWords(str) {
|
|
||||||
return str.trim().split(/\s+/).length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// function saveSettingsToFile(settings) {
|
|
||||||
// const data = JSON.stringify(settings);
|
|
||||||
// const savePath =
|
|
||||||
// main.isPackaged === true ? path.join(resourcesPath, './settings.json') : path.join(resourcesPath, './config/settings.json');
|
|
||||||
|
|
||||||
// fs.writeFile(savePath, data, error => {
|
|
||||||
// if (error) {
|
|
||||||
// console.error(error);
|
|
||||||
// throw error;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2017 Google Inc.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// var videoElement = document.querySelector('video');
|
|
||||||
// var audioSelect = document.querySelector('select#audioSource');
|
|
||||||
// var videoSelect = document.querySelector('select#videoSource');
|
|
||||||
|
|
||||||
// audioSelect.onchange = getStream;
|
|
||||||
// videoSelect.onchange = getStream;
|
|
||||||
|
|
||||||
// getStream().then(getDevices).then(gotDevices);
|
|
||||||
|
|
||||||
// function getDevices() {
|
|
||||||
// // AFAICT in Safari this only gets default devices until gUM is called :/
|
|
||||||
// return navigator.mediaDevices.enumerateDevices();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function gotDevices(deviceInfos) {
|
|
||||||
// window.deviceInfos = deviceInfos; // make available to console
|
|
||||||
// console.log('Available input and output devices:', deviceInfos);
|
|
||||||
// for (const deviceInfo of deviceInfos) {
|
|
||||||
// const option = document.createElement('option');
|
|
||||||
// option.value = deviceInfo.deviceId;
|
|
||||||
// if (deviceInfo.kind === 'audioinput') {
|
|
||||||
// option.text = deviceInfo.label || `Microphone ${audioSelect.length + 1}`;
|
|
||||||
// audioSelect.appendChild(option);
|
|
||||||
// } else if (deviceInfo.kind === 'videoinput') {
|
|
||||||
// option.text = deviceInfo.label || `Camera ${videoSelect.length + 1}`;
|
|
||||||
// videoSelect.appendChild(option);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function getStream() {
|
|
||||||
// if (window.stream) {
|
|
||||||
// window.stream.getTracks().forEach(track => {
|
|
||||||
// track.stop();
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// const audioSource = audioSelect.value;
|
|
||||||
// const videoSource = videoSelect.value;
|
|
||||||
// const constraints = {
|
|
||||||
// audio: { deviceId: audioSource ? { exact: audioSource } : undefined },
|
|
||||||
// video: { deviceId: videoSource ? { exact: videoSource } : undefined }
|
|
||||||
// };
|
|
||||||
// return navigator.mediaDevices.getUserMedia(constraints).then(gotStream).catch(handleError);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function gotStream(stream) {
|
|
||||||
// window.stream = stream; // make stream available to console
|
|
||||||
// audioSelect.selectedIndex = [...audioSelect.options].findIndex(option => option.text === stream.getAudioTracks()[0].label);
|
|
||||||
// videoSelect.selectedIndex = [...videoSelect.options].findIndex(option => option.text === stream.getVideoTracks()[0].label);
|
|
||||||
// videoElement.srcObject = stream;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function handleError(error) {
|
|
||||||
// console.error('Error: ', error);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const settingxs = {
|
|
||||||
// video: true
|
|
||||||
// };
|
|
||||||
|
|
||||||
// navigator.mediaDevices
|
|
||||||
// .getUserMedia(settingxs)
|
|
||||||
// .then(stream => {
|
|
||||||
// const video = document.getElementById('video');
|
|
||||||
// video.srcObject = stream;
|
|
||||||
// video.play();
|
|
||||||
// })
|
|
||||||
// .catch(err => {
|
|
||||||
// console.log(err);
|
|
||||||
// alert('Não há permissões para acessar a webcam.');
|
|
||||||
// });
|
|
||||||
|
|
|
||||||
|
|
@ -28,33 +28,14 @@ function startVtuberModule() {
|
||||||
|
|
||||||
startVtuberModule();
|
startVtuberModule();
|
||||||
|
|
||||||
function startPNGtuberModule() {
|
function startChatBubbleModule() {
|
||||||
if (!settings.MODULES.USE_PNGTUBER) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
app.use('/pngtuber', express.static(path.join(__dirname, '../modules/pngtuber/')));
|
|
||||||
|
|
||||||
const pngtuber = document.body.querySelector('#BrowsersourcePNGTuber');
|
|
||||||
const pngtuberframe = document.createElement('iframe');
|
|
||||||
pngtuberframe.class = 'frame';
|
|
||||||
pngtuberframe.src = `http://localhost:${settings.GENERAL.PORT}/pngtuber`;
|
|
||||||
pngtuberframe.style.width = '100%';
|
|
||||||
pngtuberframe.style.height = '100%';
|
|
||||||
pngtuberframe.frameBorder = 0;
|
|
||||||
pngtuber.appendChild(pngtuberframe);
|
|
||||||
}
|
|
||||||
|
|
||||||
startPNGtuberModule();
|
|
||||||
|
|
||||||
function startChatWindowModule() {
|
|
||||||
if (!settings.MODULES.USE_CHATBUBBLE) {
|
if (!settings.MODULES.USE_CHATBUBBLE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
app.use('/chat', express.static(path.join(__dirname, '../modules/chat')));
|
app.use('/chat', express.static(path.join(__dirname, '../modules/chat')));
|
||||||
|
|
||||||
const chat = document.body.querySelector('#BrowsersourceChatWindow');
|
const chat = document.body.querySelector('#BrowsersourceChat');
|
||||||
const chatframe = document.createElement('iframe');
|
const chatframe = document.createElement('iframe');
|
||||||
chatframe.class = 'frame';
|
chatframe.class = 'frame';
|
||||||
chatframe.src = `http://localhost:${settings.GENERAL.PORT}/chat`;
|
chatframe.src = `http://localhost:${settings.GENERAL.PORT}/chat`;
|
||||||
|
|
@ -64,27 +45,10 @@ function startChatWindowModule() {
|
||||||
chat.appendChild(chatframe);
|
chat.appendChild(chatframe);
|
||||||
}
|
}
|
||||||
|
|
||||||
startChatWindowModule();
|
|
||||||
|
|
||||||
function startChatBubbleModule() {
|
|
||||||
if (!settings.MODULES.USE_CHATBUBBLE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
app.use('/chatbubble', express.static(path.join(__dirname, '../modules/chatbubble')));
|
|
||||||
|
|
||||||
const chatBubble = document.body.querySelector('#BrowsersourceChatBubble');
|
|
||||||
const chatBubbleFrame = document.createElement('iframe');
|
|
||||||
chatBubbleFrame.class = 'frame';
|
|
||||||
chatBubbleFrame.src = `http://localhost:${settings.GENERAL.PORT}/chatbubble`;
|
|
||||||
chatBubbleFrame.style.width = '100%';
|
|
||||||
chatBubbleFrame.style.height = '100%';
|
|
||||||
chatBubbleFrame.frameBorder = 0;
|
|
||||||
chatBubble.appendChild(chatBubbleFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
startChatBubbleModule();
|
startChatBubbleModule();
|
||||||
|
|
||||||
|
function startSTT() {}
|
||||||
|
|
||||||
// Middleware to conditionally serve routes
|
// Middleware to conditionally serve routes
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
if (!settings.MODULES.USE_VTUBER && req.path === '/vtuber') {
|
if (!settings.MODULES.USE_VTUBER && req.path === '/vtuber') {
|
||||||
|
|
@ -98,7 +62,6 @@ app.use((req, res, next) => {
|
||||||
|
|
||||||
localServer.listen(settings.GENERAL.PORT, () => {
|
localServer.listen(settings.GENERAL.PORT, () => {
|
||||||
startVtuberModule();
|
startVtuberModule();
|
||||||
startChatWindowModule();
|
|
||||||
startChatBubbleModule();
|
startChatBubbleModule();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -106,9 +69,6 @@ localServer.listen(settings.GENERAL.PORT, () => {
|
||||||
io.on('connection', socket => {
|
io.on('connection', socket => {
|
||||||
// Receive data from the client
|
// Receive data from the client
|
||||||
socket.on('message', data => {});
|
socket.on('message', data => {});
|
||||||
socket.on('chat-out', message => {
|
|
||||||
socket.broadcast.emit('chat-in', message);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Receive data from the client
|
// Receive data from the client
|
||||||
socket.on('xxx', (logoUrl, username, message) => {
|
socket.on('xxx', (logoUrl, username, message) => {
|
||||||
|
|
@ -118,4 +78,4 @@ io.on('connection', socket => {
|
||||||
socket.on('disconnect', () => {});
|
socket.on('disconnect', () => {});
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = { startVtuberModule, startChatBubbleModule, startChatWindowModule };
|
module.exports = { startVtuberModule, startChatBubbleModule };
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* global settings,main, betterTTVAutocomplete sttModels, trovo, setZoomLevel, webFrame, theme, fs, settingsPath, ini, startVoiceRecognition,notificationSoundAudioDevices, ttsAudioDevices, notificationSound, path, resourcesPath, ipcRenderer, auth, shell, sound, twitch, server, backend */
|
/* global settings,main sttModels, setZoomLevel, webFrame, theme, fs, settingsPath, ini, startVoiceRecognition,notificationSoundAudioDevices, ttsAudioDevices, notificationSound, path, resourcesPath, ipcRenderer, auth, shell, sound, twitch, server, backend */
|
||||||
|
|
||||||
function getGeneralSettings() {
|
function getGeneralSettings() {
|
||||||
// General
|
// General
|
||||||
|
|
@ -30,26 +30,14 @@ function getGeneralSettings() {
|
||||||
document.body.querySelector('#TWITCH_CHANNEL_NAME').value = settings.TWITCH.CHANNEL_NAME;
|
document.body.querySelector('#TWITCH_CHANNEL_NAME').value = settings.TWITCH.CHANNEL_NAME;
|
||||||
document.body.querySelector('#TWITCH_OAUTH_TOKEN').value = settings.TWITCH.OAUTH_TOKEN;
|
document.body.querySelector('#TWITCH_OAUTH_TOKEN').value = settings.TWITCH.OAUTH_TOKEN;
|
||||||
|
|
||||||
// Trovo
|
|
||||||
document.body.querySelector('#USE_TROVO').checked = settings.TROVO.USE_TWITCH;
|
|
||||||
document.body.querySelector('#TROVO_CHANNEL_NAME').value = settings.TROVO.CHANNEL_NAME;
|
|
||||||
document.body.querySelector('#TROVO_OAUTH_TOKEN').value = settings.TROVO.OAUTH_TOKEN;
|
|
||||||
|
|
||||||
// Modules
|
// Modules
|
||||||
document.body.querySelector('#USE_MODULES').checked = settings.MODULES.USE_MODULES;
|
document.body.querySelector('#USE_MODULES').checked = settings.MODULES.USE_MODULES;
|
||||||
document.body.querySelector('#USE_VTUBER').checked = settings.MODULES.USE_VTUBER;
|
document.body.querySelector('#USE_VTUBER').checked = settings.MODULES.USE_VTUBER;
|
||||||
document.body.querySelector('#VTUBER_URL').value = `http://localhost:${settings.GENERAL.PORT}/vtuber`;
|
document.body.querySelector('#VTUBER_URL').value = `http://localhost:${settings.GENERAL.PORT}/vtuber/`;
|
||||||
showMenuButton('#btnBrowsersourceVtuber', settings.MODULES.USE_VTUBER);
|
showMenuButton('#btnBrowsersourceVtuber', settings.MODULES.USE_VTUBER);
|
||||||
document.body.querySelector('#USE_PNGTUBER').checked = settings.MODULES.USE_PNGTUBER;
|
|
||||||
document.body.querySelector('#PNGTUBER_URL').value = `http://localhost:${settings.GENERAL.PORT}/pngtuber`;
|
|
||||||
showMenuButton('#btnBrowsersourcePNGTuber', settings.MODULES.USE_PNGTUBER);
|
|
||||||
document.body.querySelector('#USE_CHATBUBBLE').checked = settings.MODULES.USE_CHATBUBBLE;
|
document.body.querySelector('#USE_CHATBUBBLE').checked = settings.MODULES.USE_CHATBUBBLE;
|
||||||
document.body.querySelector('#CHATBUBBLE_URL').value = `http://localhost:${settings.GENERAL.PORT}/chatbubble`;
|
document.body.querySelector('#CHATBUBBLE_URL').value = `http://localhost:${settings.GENERAL.PORT}/chat/`;
|
||||||
document.body.querySelector('#USE_CHATWINDOW').checked = settings.MODULES.USE_CHATWINDOW;
|
showMenuButton('#btnBrowsersourceChat', settings.GENERAL.USE_CHATBUBBLE);
|
||||||
document.body.querySelector('#CHATWINDOW_URL').value = `http://localhost:${settings.GENERAL.PORT}/chat`;
|
|
||||||
document.body.querySelector('#USE_FACEMASK').checked = settings.MODULES.USE_FACEMASK;
|
|
||||||
showMenuButton('#btnBrowsersourceChatBubble', settings.GENERAL.USE_CHATWINDOW);
|
|
||||||
showMenuButton('#btnFaceMask', settings.MODULES.USE_FACEMASK);
|
|
||||||
|
|
||||||
// Amazon
|
// Amazon
|
||||||
document.body.querySelector('#USE_AMAZON').checked = settings.AMAZON.USE_AMAZON;
|
document.body.querySelector('#USE_AMAZON').checked = settings.AMAZON.USE_AMAZON;
|
||||||
|
|
@ -64,35 +52,35 @@ function getGeneralSettings() {
|
||||||
document.body.querySelector('#primaryAmazonVoice').addEventListener('change', () => {
|
document.body.querySelector('#primaryAmazonVoice').addEventListener('change', () => {
|
||||||
const select = document.querySelector('#primaryAmazonVoice');
|
const select = document.querySelector('#primaryAmazonVoice');
|
||||||
settings.AMAZON.PRIMARY_VOICE = select.value;
|
settings.AMAZON.PRIMARY_VOICE = select.value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved Amazon primary voice!', 'success');
|
createNotification('Saved Amazon primary voice!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#secondaryAmazonVoice').addEventListener('change', () => {
|
document.body.querySelector('#secondaryAmazonVoice').addEventListener('change', () => {
|
||||||
const select = document.querySelector('#secondaryAmazonVoice');
|
const select = document.querySelector('#secondaryAmazonVoice');
|
||||||
settings.AMAZON.SECONDARY_VOICE = select.value;
|
settings.AMAZON.SECONDARY_VOICE = select.value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved Amazon secondary voice!', 'success');
|
createNotification('Saved Amazon secondary voice!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#primaryGoogleVoice').addEventListener('change', () => {
|
document.body.querySelector('#primaryGoogleVoice').addEventListener('change', () => {
|
||||||
const select = document.querySelector('#primaryGoogleVoice');
|
const select = document.querySelector('#primaryGoogleVoice');
|
||||||
settings.GOOGLE.PRIMARY_VOICE = select.value;
|
settings.GOOGLE.PRIMARY_VOICE = select.value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved Google primary voice!', 'success');
|
createNotification('Saved Google primary voice!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#secondaryGoogleVoice').addEventListener('change', () => {
|
document.body.querySelector('#secondaryGoogleVoice').addEventListener('change', () => {
|
||||||
const select = document.querySelector('#secondaryGoogleVoice');
|
const select = document.querySelector('#secondaryGoogleVoice');
|
||||||
settings.GOOGLE.SECONDARY_VOICE = select.value;
|
settings.GOOGLE.SECONDARY_VOICE = select.value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved Google secondary voice!', 'success');
|
createNotification('Saved Google secondary voice!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#primaryVoice').addEventListener('change', () => {
|
document.body.querySelector('#primaryVoice').addEventListener('change', () => {
|
||||||
const select = document.querySelector('#primaryVoice');
|
const select = document.querySelector('#primaryVoice');
|
||||||
settings.TTS.PRIMARY_VOICE = select.value;
|
settings.TTS.PRIMARY_VOICE = select.value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved primary voice!', 'success');
|
createNotification('Saved primary voice!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -100,7 +88,7 @@ document.body.querySelector('#microphone').addEventListener('change', () => {
|
||||||
const select = document.querySelector('#microphone');
|
const select = document.querySelector('#microphone');
|
||||||
settings.STT.MICROPHONE = select.value;
|
settings.STT.MICROPHONE = select.value;
|
||||||
settings.STT.MICROPHONE_ID = select.options[select.selectedIndex].text;
|
settings.STT.MICROPHONE_ID = select.options[select.selectedIndex].text;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved microphone!', 'success');
|
createNotification('Saved microphone!', 'success');
|
||||||
startVoiceRecognition();
|
startVoiceRecognition();
|
||||||
});
|
});
|
||||||
|
|
@ -108,7 +96,7 @@ document.body.querySelector('#microphone').addEventListener('change', () => {
|
||||||
document.body.querySelector('#sttModel').addEventListener('change', () => {
|
document.body.querySelector('#sttModel').addEventListener('change', () => {
|
||||||
const select = document.querySelector('#sttModel');
|
const select = document.querySelector('#sttModel');
|
||||||
settings.STT.LANGUAGE = select.value;
|
settings.STT.LANGUAGE = select.value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved voice detection language!', 'success');
|
createNotification('Saved voice detection language!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -116,14 +104,14 @@ document.body.querySelector('#defaultLanguage').addEventListener('change', () =>
|
||||||
const select = document.querySelector('#defaultLanguage');
|
const select = document.querySelector('#defaultLanguage');
|
||||||
settings.TTS.PRIMARY_TTS_LANGUAGE_INDEX = select.selectedIndex;
|
settings.TTS.PRIMARY_TTS_LANGUAGE_INDEX = select.selectedIndex;
|
||||||
settings.TTS.PRIMARY_TTS_LANGUAGE = select.options[select.selectedIndex].value;
|
settings.TTS.PRIMARY_TTS_LANGUAGE = select.options[select.selectedIndex].value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved default language!', 'success');
|
createNotification('Saved default language!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#secondaryVoice').addEventListener('change', () => {
|
document.body.querySelector('#secondaryVoice').addEventListener('change', () => {
|
||||||
const select = document.querySelector('#secondaryVoice');
|
const select = document.querySelector('#secondaryVoice');
|
||||||
settings.TTS.SECONDARY_VOICE = select.value;
|
settings.TTS.SECONDARY_VOICE = select.value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved secondary voice!', 'success');
|
createNotification('Saved secondary voice!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -131,7 +119,7 @@ document.body.querySelector('#secondaryLanguage').addEventListener('change', ()
|
||||||
const select = document.querySelector('#secondaryLanguage');
|
const select = document.querySelector('#secondaryLanguage');
|
||||||
settings.TTS.SECONDARY_TTS_LANGUAGE_INDEX = select.selectedIndex;
|
settings.TTS.SECONDARY_TTS_LANGUAGE_INDEX = select.selectedIndex;
|
||||||
settings.TTS.SECONDARY_TTS_LANGUAGE = select.options[select.selectedIndex].value;
|
settings.TTS.SECONDARY_TTS_LANGUAGE = select.options[select.selectedIndex].value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved secondary language!', 'success');
|
createNotification('Saved secondary language!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -139,7 +127,7 @@ document.body.querySelector('#language').addEventListener('change', () => {
|
||||||
const select = document.querySelector('#language');
|
const select = document.querySelector('#language');
|
||||||
settings.GENERAL.LANGUAGE_INDEX = select.selectedIndex;
|
settings.GENERAL.LANGUAGE_INDEX = select.selectedIndex;
|
||||||
settings.GENERAL.LANGUAGE = select.options[select.selectedIndex].value;
|
settings.GENERAL.LANGUAGE = select.options[select.selectedIndex].value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved language!', 'success');
|
createNotification('Saved language!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -171,56 +159,34 @@ document.body.querySelector('#TRANSLATE_TO').addEventListener('change', () => {
|
||||||
settings.LANGUAGE.TRANSLATE_TO = select.options[select.selectedIndex].value;
|
settings.LANGUAGE.TRANSLATE_TO = select.options[select.selectedIndex].value;
|
||||||
setTranslateToOptions();
|
setTranslateToOptions();
|
||||||
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved primary voice!', 'success');
|
createNotification('Saved primary voice!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#ttsAudioDevice').addEventListener('change', () => {
|
document.body.querySelector('#ttsAudioDevice').addEventListener('change', () => {
|
||||||
settings.AUDIO.TTS_AUDIO_DEVICE = ttsAudioDevices.value;
|
settings.AUDIO.TTS_AUDIO_DEVICE = ttsAudioDevices.value;
|
||||||
settings.AUDIO.SELECTED_TTS_AUDIO_DEVICE = ttsAudioDevices.selectedIndex;
|
settings.AUDIO.SELECTED_TTS_AUDIO_DEVICE = ttsAudioDevices.selectedIndex;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved audio device!', 'success');
|
createNotification('Saved audio device!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#notificationSoundAudioDevice').addEventListener('change', () => {
|
document.body.querySelector('#notificationSoundAudioDevice').addEventListener('change', () => {
|
||||||
settings.AUDIO.SELECTED_NOTIFICATION_AUDIO_DEVICE = notificationSoundAudioDevices.value;
|
settings.AUDIO.SELECTED_NOTIFICATION_AUDIO_DEVICE = notificationSoundAudioDevices.value;
|
||||||
settings.AUDIO.NOTIFICATION_AUDIO_DEVICE = notificationSoundAudioDevices.selectedIndex;
|
settings.AUDIO.NOTIFICATION_AUDIO_DEVICE = notificationSoundAudioDevices.selectedIndex;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved audio device!', 'success');
|
createNotification('Saved audio device!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#TWITCH_CHANNEL_NAME').addEventListener('change', () => {
|
document.body.querySelector('#TWITCH_CHANNEL_NAME').addEventListener('change', () => {
|
||||||
settings.TWITCH.CHANNEL_NAME = document.body.querySelector('#TWITCH_CHANNEL_NAME').value;
|
settings.TWITCH.CHANNEL_NAME = document.body.querySelector('#TWITCH_CHANNEL_NAME').value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved Channel name, please restart the application to reset twitch service', 'warning');
|
createNotification('Saved Channel name, please restart the application to reset twitch service', 'warning');
|
||||||
if (settings.TWITCH.CHANNEL_NAME !== '') {
|
twitch.getTwitchChannelId();
|
||||||
twitch.getTwitchChannelId(settings.TWITCH.CHANNEL_NAME).then(data => {
|
|
||||||
settings.TWITCH.CHANNEL_USER_ID = data;
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
|
||||||
createNotification('Obtained channel info succesfully', 'success');
|
|
||||||
twitch.getUserAvailableTwitchEmotes();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#TROVO_CHANNEL_NAME').addEventListener('change', () => {
|
|
||||||
settings.TROVO.CHANNEL_NAME = document.body.querySelector('#TROVO_CHANNEL_NAME').value;
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
|
||||||
createNotification('Saved Channel name, please restart the application to reset twitch service', 'warning');
|
|
||||||
if (settings.TROVO.CHANNEL_NAME !== '') {
|
|
||||||
trovo.getTrovoChannelId();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#TWITCH_OAUTH_TOKEN').addEventListener('change', () => {
|
document.body.querySelector('#TWITCH_OAUTH_TOKEN').addEventListener('change', () => {
|
||||||
settings.TWITCH.OAUTH_TOKEN = document.body.querySelector('#TWITCH_OAUTH_TOKEN').value;
|
settings.TWITCH.OAUTH_TOKEN = document.body.querySelector('#TWITCH_OAUTH_TOKEN').value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved OAuth token, please restart the application to reset twitch service', 'warning');
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#TROVO_OAUTH_TOKEN').addEventListener('change', () => {
|
|
||||||
settings.TROVO.OAUTH_TOKEN = document.body.querySelector('#TROVO_OAUTH_TOKEN').value;
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
|
||||||
createNotification('Saved OAuth token, please restart the application to reset twitch service', 'warning');
|
createNotification('Saved OAuth token, please restart the application to reset twitch service', 'warning');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -234,31 +200,31 @@ setInputFilter(
|
||||||
|
|
||||||
document.body.querySelector('#PORT').addEventListener('change', () => {
|
document.body.querySelector('#PORT').addEventListener('change', () => {
|
||||||
settings.GENERAL.PORT = document.body.querySelector('#PORT').value;
|
settings.GENERAL.PORT = document.body.querySelector('#PORT').value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved port, please restart the application to reset the port', 'warning');
|
createNotification('Saved port, please restart the application to reset the port', 'warning');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#AMAZON_ACCESS_KEY').addEventListener('change', () => {
|
document.body.querySelector('#AMAZON_ACCESS_KEY').addEventListener('change', () => {
|
||||||
settings.AMAZON.ACCESS_KEY = document.body.querySelector('#AMAZON_ACCESS_KEY').value;
|
settings.AMAZON.ACCESS_KEY = document.body.querySelector('#AMAZON_ACCESS_KEY').value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved Amazon access key!', 'success');
|
createNotification('Saved Amazon access key!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#AMAZON_ACCESS_SECRET').addEventListener('change', () => {
|
document.body.querySelector('#AMAZON_ACCESS_SECRET').addEventListener('change', () => {
|
||||||
settings.AMAZON.ACCESS_SECRET = document.body.querySelector('#AMAZON_ACCESS_SECRET').value;
|
settings.AMAZON.ACCESS_SECRET = document.body.querySelector('#AMAZON_ACCESS_SECRET').value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved Amazon access secret!', 'success');
|
createNotification('Saved Amazon access secret!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#GOOGLE_API_KEY').addEventListener('change', () => {
|
document.body.querySelector('#GOOGLE_API_KEY').addEventListener('change', () => {
|
||||||
settings.GOOGLE.API_KEY = document.body.querySelector('#GOOGLE_API_KEY').value;
|
settings.GOOGLE.API_KEY = document.body.querySelector('#GOOGLE_API_KEY').value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved Google api key!', 'success');
|
createNotification('Saved Google api key!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#notification').addEventListener('change', () => {
|
document.body.querySelector('#notification').addEventListener('change', () => {
|
||||||
settings.AUDIO.NOTIFICATION_SOUND = notificationSound.selectedIndex;
|
settings.AUDIO.NOTIFICATION_SOUND = notificationSound.selectedIndex;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved notification sound!', 'success');
|
createNotification('Saved notification sound!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -340,7 +306,7 @@ document.body.querySelector('#USE_CUSTOM_THEME').addEventListener('click', () =>
|
||||||
toggleRadio(toggle, inputs);
|
toggleRadio(toggle, inputs);
|
||||||
|
|
||||||
settings.THEME.USE_CUSTOM_THEME = toggle;
|
settings.THEME.USE_CUSTOM_THEME = toggle;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
theme.setTheme();
|
theme.setTheme();
|
||||||
createNotification(`${toggle ? 'Enabled' : 'Disabled'} custom theme!`, 'success');
|
createNotification(`${toggle ? 'Enabled' : 'Disabled'} custom theme!`, 'success');
|
||||||
});
|
});
|
||||||
|
|
@ -351,27 +317,15 @@ document.body.querySelector('#min-button').addEventListener('click', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// #region Top bar buttons
|
// #region Top bar buttons
|
||||||
document.body.querySelector('#Info_TWITCH_USERNAME').addEventListener('click', async () => {
|
document.body.querySelector('#Info_USERNAME').addEventListener('click', async () => {
|
||||||
const element = document.body.querySelector('#TWITCH_OAUTH_TOKEN');
|
const element = document.body.querySelector('#TWITCH_OAUTH_TOKEN');
|
||||||
element.value = await auth.getTwitchOauthToken();
|
element.value = await auth.getTwitchOauthToken();
|
||||||
twitch.checkIfTokenIsValid();
|
twitch.checkIfTokenIsValid();
|
||||||
createNotification('Saved OAuth token!', 'success');
|
createNotification('Saved OAuth token!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#Info_TROVO_USERNAME').addEventListener('click', async () => {
|
|
||||||
const element = document.body.querySelector('#TROVO_OAUTH_TOKEN');
|
|
||||||
element.value = await auth.getTrovoOAuthToken();
|
|
||||||
console.log(element.value);
|
|
||||||
// trovo.checkIfTokenIsValid();
|
|
||||||
createNotification('Saved OAuth token!', 'success');
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#GetBetterTtvEmotes').addEventListener('click', async () => {
|
document.body.querySelector('#GetBetterTtvEmotes').addEventListener('click', async () => {
|
||||||
twitch.getBetterTtvGLobalEmotes();
|
twitch.getBetterTtvGLobalEmotes();
|
||||||
if (betterTTVAutocomplete.tokens.length !== 0) {
|
|
||||||
twitch.getBetterTtvChannelsEmotes();
|
|
||||||
}
|
|
||||||
|
|
||||||
createNotification('Saved BetterTTV emotes!', 'success');
|
createNotification('Saved BetterTTV emotes!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -399,7 +353,7 @@ function hideOrShowViewerPanel() {
|
||||||
menu.classList.remove('collapse-menu-right');
|
menu.classList.remove('collapse-menu-right');
|
||||||
leftCircle.classList.remove('collapse-circle-right');
|
leftCircle.classList.remove('collapse-circle-right');
|
||||||
}
|
}
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
hideOrShowViewerPanel();
|
hideOrShowViewerPanel();
|
||||||
|
|
@ -414,19 +368,11 @@ document.body.querySelector('#VIEWERS_PANEL').addEventListener('click', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#Info_VTUBER').addEventListener('click', () => {
|
document.body.querySelector('#Info_VTUBER').addEventListener('click', () => {
|
||||||
shell.openExternal(`http://localhost:${settings.GENERAL.PORT}/vtuber`);
|
shell.openExternal(`http://localhost:${settings.GENERAL.PORT}/vtuber/`);
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#Info_PNGTUBER').addEventListener('click', () => {
|
|
||||||
shell.openExternal(`http://localhost:${settings.GENERAL.PORT}/pngtuber`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#Info_CHATBUBBLE').addEventListener('click', () => {
|
document.body.querySelector('#Info_CHATBUBBLE').addEventListener('click', () => {
|
||||||
shell.openExternal(`http://localhost:${settings.GENERAL.PORT}/chatbubble`);
|
shell.openExternal(`http://localhost:${settings.GENERAL.PORT}/chat/`);
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#Info_CHATWINDOW').addEventListener('click', () => {
|
|
||||||
shell.openExternal(`http://localhost:${settings.GENERAL.PORT}/chat`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#max-button').addEventListener('click', () => {
|
document.body.querySelector('#max-button').addEventListener('click', () => {
|
||||||
|
|
@ -460,7 +406,7 @@ toggleTwitch();
|
||||||
document.body.querySelector('#USE_TWITCH').addEventListener('click', () => {
|
document.body.querySelector('#USE_TWITCH').addEventListener('click', () => {
|
||||||
const toggle = document.getElementById('USE_TWITCH').checked;
|
const toggle = document.getElementById('USE_TWITCH').checked;
|
||||||
settings.TWITCH.USE_TWITCH = toggle;
|
settings.TWITCH.USE_TWITCH = toggle;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
const inputs = document.getElementsByClassName('inputTwitch');
|
const inputs = document.getElementsByClassName('inputTwitch');
|
||||||
toggleRadio(toggle, inputs);
|
toggleRadio(toggle, inputs);
|
||||||
twitch = settings.TWITCH.USE_TWITCH ? require(path.join(__dirname, './twitch')) : null;
|
twitch = settings.TWITCH.USE_TWITCH ? require(path.join(__dirname, './twitch')) : null;
|
||||||
|
|
@ -478,7 +424,7 @@ toggleGoogle();
|
||||||
document.body.querySelector('#USE_GOOGLE').addEventListener('click', () => {
|
document.body.querySelector('#USE_GOOGLE').addEventListener('click', () => {
|
||||||
const toggle = document.getElementById('USE_GOOGLE').checked;
|
const toggle = document.getElementById('USE_GOOGLE').checked;
|
||||||
settings.GOOGLE.USE_GOOGLE = toggle;
|
settings.GOOGLE.USE_GOOGLE = toggle;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
const inputs = document.getElementsByClassName('inputGoogle');
|
const inputs = document.getElementsByClassName('inputGoogle');
|
||||||
toggleRadio(toggle, inputs);
|
toggleRadio(toggle, inputs);
|
||||||
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Google settings!`, 'success');
|
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Google settings!`, 'success');
|
||||||
|
|
@ -495,7 +441,7 @@ toggleAmazon();
|
||||||
document.body.querySelector('#USE_AMAZON').addEventListener('click', () => {
|
document.body.querySelector('#USE_AMAZON').addEventListener('click', () => {
|
||||||
const toggle = document.getElementById('USE_AMAZON').checked;
|
const toggle = document.getElementById('USE_AMAZON').checked;
|
||||||
settings.AMAZON.USE_AMAZON = toggle;
|
settings.AMAZON.USE_AMAZON = toggle;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
const inputs = document.getElementsByClassName('inputAmazon');
|
const inputs = document.getElementsByClassName('inputAmazon');
|
||||||
toggleRadio(toggle, inputs);
|
toggleRadio(toggle, inputs);
|
||||||
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Amazon settings!`, 'success');
|
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Amazon settings!`, 'success');
|
||||||
|
|
@ -512,7 +458,7 @@ toggleServer();
|
||||||
document.body.querySelector('#USE_MODULES').addEventListener('click', () => {
|
document.body.querySelector('#USE_MODULES').addEventListener('click', () => {
|
||||||
const toggle = document.getElementById('USE_MODULES').checked;
|
const toggle = document.getElementById('USE_MODULES').checked;
|
||||||
settings.MODULES.USE_MODULES = toggle;
|
settings.MODULES.USE_MODULES = toggle;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
const inputs = document.getElementsByClassName('inputServer');
|
const inputs = document.getElementsByClassName('inputServer');
|
||||||
toggleRadio(toggle, inputs);
|
toggleRadio(toggle, inputs);
|
||||||
createNotification(
|
createNotification(
|
||||||
|
|
@ -525,7 +471,7 @@ document.body.querySelector('#USE_MODULES').addEventListener('click', () => {
|
||||||
document.body.querySelector('#USE_VTUBER').addEventListener('change', () => {
|
document.body.querySelector('#USE_VTUBER').addEventListener('change', () => {
|
||||||
const toggle = document.getElementById('USE_VTUBER').checked;
|
const toggle = document.getElementById('USE_VTUBER').checked;
|
||||||
settings.MODULES.USE_VTUBER = toggle;
|
settings.MODULES.USE_VTUBER = toggle;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
showMenuButton('#btnBrowsersourceVtuber', toggle);
|
showMenuButton('#btnBrowsersourceVtuber', toggle);
|
||||||
createNotification(
|
createNotification(
|
||||||
`${toggle ? 'Enabled' : 'Disabled'} Vtuber setting!
|
`${toggle ? 'Enabled' : 'Disabled'} Vtuber setting!
|
||||||
|
|
@ -535,45 +481,11 @@ document.body.querySelector('#USE_VTUBER').addEventListener('change', () => {
|
||||||
server.startVtuberModule();
|
server.startVtuberModule();
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#USE_PNGTUBER').addEventListener('change', () => {
|
|
||||||
const toggle = document.getElementById('USE_PNGTUBER').checked;
|
|
||||||
settings.MODULES.USE_PNGTUBER = toggle;
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
|
||||||
showMenuButton('#btnBrowsersourcePNGTuber', toggle);
|
|
||||||
createNotification(
|
|
||||||
`${toggle ? 'Enabled' : 'Disabled'} PNGtuber setting!
|
|
||||||
${toggle ? '' : ', the service will stop working after restarting the application'}`,
|
|
||||||
'success'
|
|
||||||
);
|
|
||||||
server.startVtuberModule();
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#USE_FACEMASK').addEventListener('change', () => {
|
|
||||||
const toggle = document.getElementById('USE_FACEMASK').checked;
|
|
||||||
settings.MODULES.USE_FACEMASK = toggle;
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
|
||||||
showMenuButton('#btnFaceMask', toggle);
|
|
||||||
createNotification(
|
|
||||||
`${toggle ? 'Enabled' : 'Disabled'} FaceMask setting!
|
|
||||||
${toggle ? '' : ', the service will stop working after restarting the application'}`,
|
|
||||||
'success'
|
|
||||||
);
|
|
||||||
// server.startVtuberModule();
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#USE_CHATWINDOW').addEventListener('change', () => {
|
|
||||||
const toggle = document.getElementById('USE_CHATWINDOW').checked;
|
|
||||||
settings.MODULES.USE_CHATWINDOW = toggle;
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
|
||||||
createNotification(`${toggle ? 'Enabled' : 'Disabled'} chat window setting!`, 'success');
|
|
||||||
server.startChatWindowModule();
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#USE_CHATBUBBLE').addEventListener('change', () => {
|
document.body.querySelector('#USE_CHATBUBBLE').addEventListener('change', () => {
|
||||||
const toggle = document.getElementById('USE_CHATBUBBLE').checked;
|
const toggle = document.getElementById('USE_CHATBUBBLE').checked;
|
||||||
settings.MODULES.USE_CHATBUBBLE = toggle;
|
settings.MODULES.USE_CHATBUBBLE = toggle;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
showMenuButton('#btnBrowsersourceChatBubble', toggle);
|
showMenuButton('#btnBrowsersourceChat', toggle);
|
||||||
createNotification(`${toggle ? 'Enabled' : 'Disabled'} chatbubble setting!`, 'success');
|
createNotification(`${toggle ? 'Enabled' : 'Disabled'} chatbubble setting!`, 'success');
|
||||||
server.startChatBubbleModule();
|
server.startChatBubbleModule();
|
||||||
});
|
});
|
||||||
|
|
@ -589,7 +501,7 @@ toggleTTS();
|
||||||
document.body.querySelector('#USE_TTS').addEventListener('change', () => {
|
document.body.querySelector('#USE_TTS').addEventListener('change', () => {
|
||||||
const toggle = document.getElementById('USE_TTS').checked;
|
const toggle = document.getElementById('USE_TTS').checked;
|
||||||
settings.TTS.USE_TTS = toggle;
|
settings.TTS.USE_TTS = toggle;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
const inputs = document.getElementsByClassName('inputTTS');
|
const inputs = document.getElementsByClassName('inputTTS');
|
||||||
toggleRadio(toggle, inputs);
|
toggleRadio(toggle, inputs);
|
||||||
createNotification(`${toggle ? 'Enabled' : 'Disabled'} text to speech!`, 'success');
|
createNotification(`${toggle ? 'Enabled' : 'Disabled'} text to speech!`, 'success');
|
||||||
|
|
@ -606,7 +518,7 @@ toggleSTT();
|
||||||
document.body.querySelector('#USE_STT').addEventListener('change', () => {
|
document.body.querySelector('#USE_STT').addEventListener('change', () => {
|
||||||
const toggle = document.getElementById('USE_STT').checked;
|
const toggle = document.getElementById('USE_STT').checked;
|
||||||
settings.STT.USE_STT = toggle;
|
settings.STT.USE_STT = toggle;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
const inputs = document.getElementsByClassName('inputSTT');
|
const inputs = document.getElementsByClassName('inputSTT');
|
||||||
toggleRadio(toggle, inputs);
|
toggleRadio(toggle, inputs);
|
||||||
createNotification(`${toggle ? 'Enabled' : 'Disabled'} speech to text!`, 'success');
|
createNotification(`${toggle ? 'Enabled' : 'Disabled'} speech to text!`, 'success');
|
||||||
|
|
@ -623,7 +535,7 @@ toggleSendTranslation();
|
||||||
document.body.querySelector('#SEND_TRANSLATION').addEventListener('change', () => {
|
document.body.querySelector('#SEND_TRANSLATION').addEventListener('change', () => {
|
||||||
const toggle = document.getElementById('SEND_TRANSLATION').checked;
|
const toggle = document.getElementById('SEND_TRANSLATION').checked;
|
||||||
settings.LANGUAGE.SEND_TRANSLATION = toggle;
|
settings.LANGUAGE.SEND_TRANSLATION = toggle;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
const inputs = document.getElementsByClassName('send-translation');
|
const inputs = document.getElementsByClassName('send-translation');
|
||||||
toggleRadio(toggle, inputs);
|
toggleRadio(toggle, inputs);
|
||||||
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Sending translations!`, 'success');
|
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Sending translations!`, 'success');
|
||||||
|
|
@ -638,14 +550,14 @@ document.body.querySelector('#OUTPUT_TO_TTS').addEventListener('change', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.LANGUAGE.OUTPUT_TO_TTS = toggle;
|
settings.LANGUAGE.OUTPUT_TO_TTS = toggle;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Outputting translations to TTS!`, 'success');
|
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Outputting translations to TTS!`, 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.querySelector('#BROADCAST_TRANSLATION').addEventListener('change', () => {
|
document.body.querySelector('#BROADCAST_TRANSLATION').addEventListener('change', () => {
|
||||||
const toggle = document.getElementById('BROADCAST_TRANSLATION').checked;
|
const toggle = document.getElementById('BROADCAST_TRANSLATION').checked;
|
||||||
settings.LANGUAGE.BROADCAST_TRANSLATION = toggle;
|
settings.LANGUAGE.BROADCAST_TRANSLATION = toggle;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Language detection!`, 'success');
|
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Language detection!`, 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -668,7 +580,7 @@ document.body.querySelector('#USE_DETECTION').addEventListener('change', () => {
|
||||||
document.body.querySelector('#OUTPUT_TO_TTS').checked = false;
|
document.body.querySelector('#OUTPUT_TO_TTS').checked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
const inputs = document.getElementsByClassName('languageDetectionInput');
|
const inputs = document.getElementsByClassName('languageDetectionInput');
|
||||||
toggleRadio(toggle, inputs);
|
toggleRadio(toggle, inputs);
|
||||||
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Language detection!`, 'success');
|
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Language detection!`, 'success');
|
||||||
|
|
@ -685,7 +597,7 @@ toggleNotificationSounds();
|
||||||
document.body.querySelector('#USE_NOTIFICATION_SOUNDS').addEventListener('change', () => {
|
document.body.querySelector('#USE_NOTIFICATION_SOUNDS').addEventListener('change', () => {
|
||||||
const toggle = document.getElementById('USE_NOTIFICATION_SOUNDS').checked;
|
const toggle = document.getElementById('USE_NOTIFICATION_SOUNDS').checked;
|
||||||
settings.AUDIO.USE_NOTIFICATION_SOUNDS = toggle;
|
settings.AUDIO.USE_NOTIFICATION_SOUNDS = toggle;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
const inputs = document.getElementsByClassName('inputNotificationSound');
|
const inputs = document.getElementsByClassName('inputNotificationSound');
|
||||||
toggleRadio(toggle, inputs);
|
toggleRadio(toggle, inputs);
|
||||||
createNotification(`${toggle ? 'Enabled' : 'Disabled'} notification sounds!`, 'success');
|
createNotification(`${toggle ? 'Enabled' : 'Disabled'} notification sounds!`, 'success');
|
||||||
|
|
@ -694,7 +606,7 @@ document.body.querySelector('#USE_NOTIFICATION_SOUNDS').addEventListener('change
|
||||||
document.body.querySelector('#notificationVolume').addEventListener('change', () => {
|
document.body.querySelector('#notificationVolume').addEventListener('change', () => {
|
||||||
const element = document.body.querySelector('#notificationVolume');
|
const element = document.body.querySelector('#notificationVolume');
|
||||||
settings.AUDIO.NOTIFICATION_VOLUME = element.value;
|
settings.AUDIO.NOTIFICATION_VOLUME = element.value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
|
|
||||||
const slider = document.querySelector('#notificationVolumeSlider');
|
const slider = document.querySelector('#notificationVolumeSlider');
|
||||||
slider.value = settings.AUDIO.NOTIFICATION_VOLUME;
|
slider.value = settings.AUDIO.NOTIFICATION_VOLUME;
|
||||||
|
|
@ -714,7 +626,7 @@ document.body.querySelector('#notificationVolumeSlider').addEventListener('chang
|
||||||
e.style.setProperty('--tiempotemporal', e.value);
|
e.style.setProperty('--tiempotemporal', e.value);
|
||||||
document.querySelector('#notificationVolume').value = e.value;
|
document.querySelector('#notificationVolume').value = e.value;
|
||||||
settings.AUDIO.NOTIFICATION_VOLUME = e.value;
|
settings.AUDIO.NOTIFICATION_VOLUME = e.value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -732,7 +644,7 @@ if (settings.AUDIO.NOTIFICATION_VOLUME) {
|
||||||
document.body.querySelector('#ttsVolume').addEventListener('change', () => {
|
document.body.querySelector('#ttsVolume').addEventListener('change', () => {
|
||||||
const element = document.body.querySelector('#ttsVolume');
|
const element = document.body.querySelector('#ttsVolume');
|
||||||
settings.AUDIO.TTS_VOLUME = element.value;
|
settings.AUDIO.TTS_VOLUME = element.value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
|
|
||||||
const slider = document.querySelector('#ttsVolumeSlider');
|
const slider = document.querySelector('#ttsVolumeSlider');
|
||||||
slider.value = settings.AUDIO.TTS_VOLUME;
|
slider.value = settings.AUDIO.TTS_VOLUME;
|
||||||
|
|
@ -752,7 +664,7 @@ document.body.querySelector('#ttsVolumeSlider').addEventListener('change', () =>
|
||||||
e.style.setProperty('--tiempotemporal', e.value);
|
e.style.setProperty('--tiempotemporal', e.value);
|
||||||
document.querySelector('#ttsVolume').value = e.value;
|
document.querySelector('#ttsVolume').value = e.value;
|
||||||
settings.AUDIO.TTS_VOLUME = e.value;
|
settings.AUDIO.TTS_VOLUME = e.value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -770,7 +682,7 @@ if (settings.AUDIO.TTS_VOLUME) {
|
||||||
document.body.querySelector('#ttsVolume').addEventListener('change', () => {
|
document.body.querySelector('#ttsVolume').addEventListener('change', () => {
|
||||||
const element = document.body.querySelector('#ttsVolume');
|
const element = document.body.querySelector('#ttsVolume');
|
||||||
settings.AUDIO.TTS_VOLUME = element.value;
|
settings.AUDIO.TTS_VOLUME = element.value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
|
|
||||||
const slider = document.querySelector('#ttsVolumeSlider');
|
const slider = document.querySelector('#ttsVolumeSlider');
|
||||||
slider.value = settings.AUDIO.TTS_VOLUME;
|
slider.value = settings.AUDIO.TTS_VOLUME;
|
||||||
|
|
@ -857,7 +769,7 @@ setInputFilter(
|
||||||
document.body.querySelector('#ZOOMLEVEL').addEventListener('change', () => {
|
document.body.querySelector('#ZOOMLEVEL').addEventListener('change', () => {
|
||||||
const newZoom = parseInt(document.body.querySelector('#ZOOMLEVEL').value) / 100;
|
const newZoom = parseInt(document.body.querySelector('#ZOOMLEVEL').value) / 100;
|
||||||
settings.GENERAL.ZOOMLEVEL = newZoom;
|
settings.GENERAL.ZOOMLEVEL = newZoom;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
setZoomLevel(newZoom, null);
|
setZoomLevel(newZoom, null);
|
||||||
createNotification('Saved zoom new level', 'warning');
|
createNotification('Saved zoom new level', 'warning');
|
||||||
});
|
});
|
||||||
|
|
@ -873,6 +785,7 @@ document.body.querySelector('emoji-picker').addEventListener('emoji-click', e =>
|
||||||
|
|
||||||
div.focus();
|
div.focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getGeneralSettings,
|
getGeneralSettings,
|
||||||
createNotification
|
createNotification
|
||||||
|
|
|
||||||
|
|
@ -101,12 +101,7 @@ async function playVoice(message) {
|
||||||
let voice = settings.TTS.PRIMARY_VOICE;
|
let voice = settings.TTS.PRIMARY_VOICE;
|
||||||
textObject.filtered = `${message.username}: ${message.filteredMessage}`;
|
textObject.filtered = `${message.username}: ${message.filteredMessage}`;
|
||||||
|
|
||||||
if (
|
if (settings.LANGUAGE.USE_DETECTION && settings.TTS.SECONDARY_VOICE) {
|
||||||
settings.LANGUAGE.USE_DETECTION &&
|
|
||||||
settings.TTS.SECONDARY_VOICE &&
|
|
||||||
message.filteredMessage.length > 20 &&
|
|
||||||
countWords(message.filteredMessage) > 4
|
|
||||||
) {
|
|
||||||
const secondaryTTSLanguage = getLanguageProperties(settings.TTS.SECONDARY_TTS_LANGUAGE);
|
const secondaryTTSLanguage = getLanguageProperties(settings.TTS.SECONDARY_TTS_LANGUAGE);
|
||||||
if (message.language.detectedLanguage === null || message.language.detectedLanguage.ISO639 === secondaryTTSLanguage.ISO639) {
|
if (message.language.detectedLanguage === null || message.language.detectedLanguage.ISO639 === secondaryTTSLanguage.ISO639) {
|
||||||
voice = settings.TTS.SECONDARY_VOICE;
|
voice = settings.TTS.SECONDARY_VOICE;
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ document.body.querySelector('#MAIN_COLOR_1').addEventListener('input', () => {
|
||||||
|
|
||||||
document.body.querySelector('#MAIN_COLOR_1').addEventListener('change', () => {
|
document.body.querySelector('#MAIN_COLOR_1').addEventListener('change', () => {
|
||||||
settings.THEME.MAIN_COLOR_1 = document.getElementById('MAIN_COLOR_1').value;
|
settings.THEME.MAIN_COLOR_1 = document.getElementById('MAIN_COLOR_1').value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
changeColor('#MAIN_COLOR_1', settings.THEME.MAIN_COLOR_1, '--main-color1');
|
changeColor('#MAIN_COLOR_1', settings.THEME.MAIN_COLOR_1, '--main-color1');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -59,7 +59,7 @@ document.body.querySelector('#MAIN_COLOR_2').addEventListener('input', () => {
|
||||||
|
|
||||||
document.body.querySelector('#MAIN_COLOR_2').addEventListener('change', () => {
|
document.body.querySelector('#MAIN_COLOR_2').addEventListener('change', () => {
|
||||||
settings.THEME.MAIN_COLOR_2 = document.getElementById('MAIN_COLOR_2').value;
|
settings.THEME.MAIN_COLOR_2 = document.getElementById('MAIN_COLOR_2').value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
changeColor('#MAIN_COLOR_2', settings.THEME.MAIN_COLOR_2, '--main-color2');
|
changeColor('#MAIN_COLOR_2', settings.THEME.MAIN_COLOR_2, '--main-color2');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@ document.body.querySelector('#MAIN_COLOR_3').addEventListener('input', () => {
|
||||||
|
|
||||||
document.body.querySelector('#MAIN_COLOR_3').addEventListener('change', () => {
|
document.body.querySelector('#MAIN_COLOR_3').addEventListener('change', () => {
|
||||||
settings.THEME.MAIN_COLOR_3 = document.getElementById('MAIN_COLOR_3').value;
|
settings.THEME.MAIN_COLOR_3 = document.getElementById('MAIN_COLOR_3').value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
changeColor('#MAIN_COLOR_3', settings.THEME.MAIN_COLOR_3, '--main-color3');
|
changeColor('#MAIN_COLOR_3', settings.THEME.MAIN_COLOR_3, '--main-color3');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -81,7 +81,7 @@ document.body.querySelector('#MAIN_COLOR_4').addEventListener('input', () => {
|
||||||
|
|
||||||
document.body.querySelector('#MAIN_COLOR_4').addEventListener('change', () => {
|
document.body.querySelector('#MAIN_COLOR_4').addEventListener('change', () => {
|
||||||
settings.THEME.MAIN_COLOR_4 = document.getElementById('MAIN_COLOR_4').value;
|
settings.THEME.MAIN_COLOR_4 = document.getElementById('MAIN_COLOR_4').value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
changeColor('#MAIN_COLOR_4', settings.THEME.MAIN_COLOR_4, '--main-color4');
|
changeColor('#MAIN_COLOR_4', settings.THEME.MAIN_COLOR_4, '--main-color4');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -92,7 +92,7 @@ document.body.querySelector('#TOP_BAR').addEventListener('input', () => {
|
||||||
|
|
||||||
document.body.querySelector('#TOP_BAR').addEventListener('change', () => {
|
document.body.querySelector('#TOP_BAR').addEventListener('change', () => {
|
||||||
settings.THEME.TOP_BAR = document.getElementById('TOP_BAR').value;
|
settings.THEME.TOP_BAR = document.getElementById('TOP_BAR').value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
changeColor('#TOP_BAR', settings.THEME.TOP_BAR, '--top-bar');
|
changeColor('#TOP_BAR', settings.THEME.TOP_BAR, '--top-bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -103,7 +103,7 @@ document.body.querySelector('#MID_SECTION').addEventListener('input', () => {
|
||||||
|
|
||||||
document.body.querySelector('#MID_SECTION').addEventListener('change', () => {
|
document.body.querySelector('#MID_SECTION').addEventListener('change', () => {
|
||||||
settings.THEME.MID_SECTION = document.getElementById('MID_SECTION').value;
|
settings.THEME.MID_SECTION = document.getElementById('MID_SECTION').value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
changeColor('#MID_SECTION', settings.THEME.MID_SECTION, '--mid-section');
|
changeColor('#MID_SECTION', settings.THEME.MID_SECTION, '--mid-section');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -114,7 +114,7 @@ document.body.querySelector('#CHAT_BUBBLE_BG').addEventListener('input', () => {
|
||||||
|
|
||||||
document.body.querySelector('#CHAT_BUBBLE_BG').addEventListener('change', () => {
|
document.body.querySelector('#CHAT_BUBBLE_BG').addEventListener('change', () => {
|
||||||
settings.THEME.CHAT_BUBBLE_BG = document.getElementById('CHAT_BUBBLE_BG').value;
|
settings.THEME.CHAT_BUBBLE_BG = document.getElementById('CHAT_BUBBLE_BG').value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
changeColor('#CHAT_BUBBLE_BG', settings.THEME.CHAT_BUBBLE_BG, '--chat-bubble');
|
changeColor('#CHAT_BUBBLE_BG', settings.THEME.CHAT_BUBBLE_BG, '--chat-bubble');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -125,7 +125,7 @@ document.body.querySelector('#CHAT_BUBBLE_HEADER').addEventListener('input', ()
|
||||||
|
|
||||||
document.body.querySelector('#CHAT_BUBBLE_HEADER').addEventListener('change', () => {
|
document.body.querySelector('#CHAT_BUBBLE_HEADER').addEventListener('change', () => {
|
||||||
settings.THEME.CHAT_BUBBLE_HEADER = document.getElementById('CHAT_BUBBLE_HEADER').value;
|
settings.THEME.CHAT_BUBBLE_HEADER = document.getElementById('CHAT_BUBBLE_HEADER').value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
changeColor('#CHAT_BUBBLE_HEADER', settings.THEME.CHAT_BUBBLE_HEADER, '--chat-bubble-header');
|
changeColor('#CHAT_BUBBLE_HEADER', settings.THEME.CHAT_BUBBLE_HEADER, '--chat-bubble-header');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -136,7 +136,7 @@ document.body.querySelector('#CHAT_BUBBLE_MESSAGE').addEventListener('input', ()
|
||||||
|
|
||||||
document.body.querySelector('#CHAT_BUBBLE_MESSAGE').addEventListener('change', () => {
|
document.body.querySelector('#CHAT_BUBBLE_MESSAGE').addEventListener('change', () => {
|
||||||
settings.THEME.CHAT_BUBBLE_MESSAGE = document.getElementById('CHAT_BUBBLE_MESSAGE').value;
|
settings.THEME.CHAT_BUBBLE_MESSAGE = document.getElementById('CHAT_BUBBLE_MESSAGE').value;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
changeColor('#CHAT_BUBBLE_MESSAGE', settings.THEME.CHAT_BUBBLE_MESSAGE, '--chat-bubble-message');
|
changeColor('#CHAT_BUBBLE_MESSAGE', settings.THEME.CHAT_BUBBLE_MESSAGE, '--chat-bubble-message');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,392 +0,0 @@
|
||||||
let __assign =
|
|
||||||
(this && this.__assign) ||
|
|
||||||
function () {
|
|
||||||
__assign =
|
|
||||||
Object.assign ||
|
|
||||||
function (t) {
|
|
||||||
for (let s, i = 1, n = arguments.length; i < n; i++) {
|
|
||||||
s = arguments[i];
|
|
||||||
for (const p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
};
|
|
||||||
return __assign.apply(this, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
let tokens = [];
|
|
||||||
|
|
||||||
const TokenAutocomplete = /** @class */ (function () {
|
|
||||||
function TokenAutocomplete(options) {
|
|
||||||
this.KEY_BACKSPACE = 8;
|
|
||||||
this.KEY_ENTER = 13;
|
|
||||||
this.KEY_UP = 38;
|
|
||||||
this.KEY_DOWN = 40;
|
|
||||||
this.tokens = tokens;
|
|
||||||
this.defaults = {
|
|
||||||
name: '',
|
|
||||||
selector: '',
|
|
||||||
noMatchesText: null,
|
|
||||||
initialTokens: null,
|
|
||||||
initialSuggestions: null,
|
|
||||||
suggestionsUri: '',
|
|
||||||
suggestionRenderer: TokenAutocomplete.Autocomplete.defaultRenderer,
|
|
||||||
minCharactersForSuggestion: 1
|
|
||||||
};
|
|
||||||
this.options = __assign(__assign({}, this.defaults), options);
|
|
||||||
const passedContainer = document.querySelector(this.options.selector);
|
|
||||||
if (!passedContainer) {
|
|
||||||
throw new Error('passed selector does not point to a DOM element.');
|
|
||||||
}
|
|
||||||
this.container = passedContainer;
|
|
||||||
this.container.classList.add('token-autocomplete-container');
|
|
||||||
if (!Array.isArray(this.options.initialTokens) && !Array.isArray(this.options.initialSuggestions)) {
|
|
||||||
this.parseTokensAndSuggestions();
|
|
||||||
}
|
|
||||||
this.hiddenSelect = document.createElement('select');
|
|
||||||
this.hiddenSelect.id = this.container.id + '-select';
|
|
||||||
this.hiddenSelect.name = this.options.name;
|
|
||||||
this.hiddenSelect.setAttribute('multiple', 'true');
|
|
||||||
this.hiddenSelect.style.display = 'none';
|
|
||||||
this.textInput = document.createElement('span');
|
|
||||||
this.textInput.id = this.container.id + '-input';
|
|
||||||
this.textInput.classList.add('token-autocomplete-input');
|
|
||||||
this.textInput.setAttribute('data-placeholder', 'Enter BetterTTV channel');
|
|
||||||
this.textInput.contentEditable = 'true';
|
|
||||||
this.container.appendChild(this.textInput);
|
|
||||||
this.container.appendChild(this.hiddenSelect);
|
|
||||||
this.select = new TokenAutocomplete.MultiSelect(this);
|
|
||||||
this.autocomplete = new TokenAutocomplete.Autocomplete(this);
|
|
||||||
this.debug(false);
|
|
||||||
const me = this;
|
|
||||||
if (Array.isArray(this.options.initialTokens)) {
|
|
||||||
this.options.initialTokens.forEach(function (token) {
|
|
||||||
if (typeof token === 'object') {
|
|
||||||
me.select.addToken(token.value, token.text);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.textInput.addEventListener('keydown', function (event) {
|
|
||||||
if (event.which === me.KEY_ENTER || event.key === me.KEY_ENTER) {
|
|
||||||
event.preventDefault();
|
|
||||||
const highlightedSuggestion = me.autocomplete.suggestions.querySelector('.token-autocomplete-suggestion-highlighted');
|
|
||||||
if (highlightedSuggestion !== null) {
|
|
||||||
if (highlightedSuggestion.classList.contains('token-autocomplete-suggestion-active')) {
|
|
||||||
me.select.removeTokenWithText(highlightedSuggestion.textContent);
|
|
||||||
} else {
|
|
||||||
me.select.addToken(highlightedSuggestion.getAttribute('data-value'), highlightedSuggestion.textContent);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
me.select.addToken(me.textInput.textContent, me.textInput.textContent);
|
|
||||||
}
|
|
||||||
me.clearCurrentInput();
|
|
||||||
} else if (me.textInput.textContent === '' && (event.which === me.KEY_BACKSPACE || event.key === me.KEY_BACKSPACE)) {
|
|
||||||
event.preventDefault();
|
|
||||||
// me.select.removeLastToken();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.textInput.addEventListener('keyup', function (event) {
|
|
||||||
let _a, _b;
|
|
||||||
if ((event.which === me.KEY_UP || event.key === me.KEY_UP) && me.autocomplete.suggestions.childNodes.length > 0) {
|
|
||||||
const highlightedSuggestion = me.autocomplete.suggestions.querySelector('.token-autocomplete-suggestion-highlighted');
|
|
||||||
const aboveSuggestion = (_a = highlightedSuggestion) === null || _a === void 0 ? void 0 : _a.previousSibling;
|
|
||||||
if (aboveSuggestion != null) {
|
|
||||||
me.autocomplete.highlightSuggestion(aboveSuggestion);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((event.which === me.KEY_DOWN || event.key === me.KEY_DOWN) && me.autocomplete.suggestions.childNodes.length > 0) {
|
|
||||||
const highlightedSuggestion = me.autocomplete.suggestions.querySelector('.token-autocomplete-suggestion-highlighted');
|
|
||||||
const belowSuggestion = (_b = highlightedSuggestion) === null || _b === void 0 ? void 0 : _b.nextSibling;
|
|
||||||
if (belowSuggestion != null) {
|
|
||||||
me.autocomplete.highlightSuggestion(belowSuggestion);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
me.autocomplete.hideSuggestions();
|
|
||||||
me.autocomplete.clearSuggestions();
|
|
||||||
const value = me.textInput.textContent || '';
|
|
||||||
if (value.length >= me.options.minCharactersForSuggestion) {
|
|
||||||
if (Array.isArray(me.options.initialSuggestions)) {
|
|
||||||
me.options.initialSuggestions.forEach(function (suggestion) {
|
|
||||||
if (typeof suggestion !== 'object') {
|
|
||||||
// the suggestion is of wrong type and therefore ignored
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (value.localeCompare(suggestion.text.slice(0, value.length), undefined, { sensitivity: 'base' }) === 0) {
|
|
||||||
// The suggestion starts with the query text the user entered and will be displayed
|
|
||||||
me.autocomplete.addSuggestion(suggestion);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (me.autocomplete.suggestions.childNodes.length > 0) {
|
|
||||||
me.autocomplete.highlightSuggestionAtPosition(0);
|
|
||||||
} else if (me.options.noMatchesText) {
|
|
||||||
me.autocomplete.addSuggestion({ value: '_no_match_', text: me.options.noMatchesText, description: null });
|
|
||||||
}
|
|
||||||
} else if (me.options.suggestionsUri.length > 0) {
|
|
||||||
me.autocomplete.requestSuggestions(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.container.tokenAutocomplete = this;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Searches the element given as a container for option elements and creates active tokens (when the option is marked selected)
|
|
||||||
* and suggestions (all options found) from these. During this all found options are removed from the DOM.
|
|
||||||
*/
|
|
||||||
TokenAutocomplete.prototype.parseTokensAndSuggestions = function () {
|
|
||||||
const initialTokens = [];
|
|
||||||
const initialSuggestions = [];
|
|
||||||
const options = this.container.querySelectorAll('option');
|
|
||||||
const me = this;
|
|
||||||
options.forEach(function (option) {
|
|
||||||
if (option.text != null) {
|
|
||||||
if (option.hasAttribute('selected')) {
|
|
||||||
initialTokens.push({ value: option.value, text: option.text });
|
|
||||||
}
|
|
||||||
initialSuggestions.push({ value: option.value, text: option.text, description: null });
|
|
||||||
}
|
|
||||||
me.container.removeChild(option);
|
|
||||||
});
|
|
||||||
if (initialTokens.length > 0) {
|
|
||||||
this.options.initialTokens = initialTokens;
|
|
||||||
}
|
|
||||||
if (initialSuggestions.length > 0) {
|
|
||||||
this.options.initialSuggestions = initialSuggestions;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Clears the currently present tokens and creates new ones from the given input value.
|
|
||||||
*
|
|
||||||
* @param {(Array\|string)} value - either the name of a single token or a list of tokens to create
|
|
||||||
*/
|
|
||||||
TokenAutocomplete.prototype.val = function (value) {
|
|
||||||
this.select.clear();
|
|
||||||
if (Array.isArray(value)) {
|
|
||||||
const me1 = this;
|
|
||||||
value.forEach(function (token) {
|
|
||||||
if (typeof token === 'object') {
|
|
||||||
me1.select.addToken(token.value, token.text);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.select.addToken(value.value, value.text);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
TokenAutocomplete.prototype.clearCurrentInput = function () {
|
|
||||||
this.textInput.textContent = '';
|
|
||||||
};
|
|
||||||
TokenAutocomplete.prototype.debug = function (state) {
|
|
||||||
if (state) {
|
|
||||||
this.log = console.log.bind(window.console);
|
|
||||||
} else {
|
|
||||||
this.log = function () {};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let _a;
|
|
||||||
TokenAutocomplete.MultiSelect = /** @class */ (function () {
|
|
||||||
function saveTokens() {
|
|
||||||
settings.TWITCH.BETTERTTV_CHANNELS = tokens;
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
|
||||||
}
|
|
||||||
|
|
||||||
function class1(parent) {
|
|
||||||
this.parent = parent;
|
|
||||||
this.container = parent.container;
|
|
||||||
this.options = parent.options;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Adds a token with the specified name to the list of currently prensent tokens displayed to the user and the hidden select.
|
|
||||||
*
|
|
||||||
* @param {string} tokenText - the name of the token to create
|
|
||||||
*/
|
|
||||||
class1.prototype.addToken = function (tokenValue, tokenText) {
|
|
||||||
if (tokenValue === null || tokenText === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
tokens.push({ value: tokenValue, text: tokenText });
|
|
||||||
saveTokens();
|
|
||||||
const option = document.createElement('option');
|
|
||||||
option.text = tokenText;
|
|
||||||
option.value = tokenValue;
|
|
||||||
option.setAttribute('selected', 'true');
|
|
||||||
option.setAttribute('data-text', tokenText);
|
|
||||||
option.setAttribute('data-value', tokenValue);
|
|
||||||
this.parent.hiddenSelect.add(option);
|
|
||||||
const token = document.createElement('span');
|
|
||||||
token.classList.add('token-autocomplete-token');
|
|
||||||
token.setAttribute('data-text', tokenText);
|
|
||||||
option.setAttribute('data-value', tokenValue);
|
|
||||||
token.textContent = tokenText;
|
|
||||||
const deleteToken = document.createElement('span');
|
|
||||||
deleteToken.classList.add('token-autocomplete-token-delete');
|
|
||||||
deleteToken.textContent = '\u00D7';
|
|
||||||
token.appendChild(deleteToken);
|
|
||||||
const me = this;
|
|
||||||
deleteToken.addEventListener('click', function (event) {
|
|
||||||
me.removeToken(token);
|
|
||||||
});
|
|
||||||
this.container.insertBefore(token, this.parent.textInput);
|
|
||||||
this.parent.log('added token', token);
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Completely clears the currently present tokens from the field.
|
|
||||||
*/
|
|
||||||
class1.prototype.clear = function () {
|
|
||||||
const tokens = this.container.querySelectorAll('.token-autocomplete-token');
|
|
||||||
const me = this;
|
|
||||||
tokens.forEach(function (token) {
|
|
||||||
me.removeToken(token);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Removes the last token in the list of currently present token. This is the last added token next to the input field.
|
|
||||||
*/
|
|
||||||
class1.prototype.removeLastToken = function () {
|
|
||||||
const tokens = this.container.querySelectorAll('.token-autocomplete-token');
|
|
||||||
const token = tokens[tokens.length - 1];
|
|
||||||
if (tokens.length !== 0) {
|
|
||||||
this.removeToken(token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Removes the specified token from the list of currently present tokens.
|
|
||||||
*
|
|
||||||
* @param {Element} token - the token to remove
|
|
||||||
*/
|
|
||||||
class1.prototype.removeToken = function (token) {
|
|
||||||
let _a, _b;
|
|
||||||
this.container.removeChild(token);
|
|
||||||
const tokenText = token.getAttribute('data-text');
|
|
||||||
const hiddenOption = this.parent.hiddenSelect.querySelector('option[data-text="' + tokenText + '"]');
|
|
||||||
(_b = (_a = hiddenOption) === null || _a === void 0 ? void 0 : _a.parentElement) === null || _b === void 0
|
|
||||||
? void 0
|
|
||||||
: _b.removeChild(hiddenOption);
|
|
||||||
this.parent.log('removed token', token.textContent);
|
|
||||||
|
|
||||||
tokens.splice(
|
|
||||||
tokens.findIndex(t => t.value === token.value),
|
|
||||||
1
|
|
||||||
);
|
|
||||||
saveTokens();
|
|
||||||
};
|
|
||||||
class1.prototype.removeTokenWithText = function (tokenText) {
|
|
||||||
if (tokenText === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const token = this.container.querySelector('.token-autocomplete-token[data-text="' + tokenText + '"]');
|
|
||||||
if (token !== null) {
|
|
||||||
this.removeToken(token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return class1;
|
|
||||||
})();
|
|
||||||
TokenAutocomplete.Autocomplete =
|
|
||||||
((_a = /** @class */ (function () {
|
|
||||||
function class2(parent) {
|
|
||||||
this.parent = parent;
|
|
||||||
this.container = parent.container;
|
|
||||||
this.options = parent.options;
|
|
||||||
this.renderer = parent.options.suggestionRenderer;
|
|
||||||
this.suggestions = document.createElement('ul');
|
|
||||||
this.suggestions.id = this.container.id + '-suggestions';
|
|
||||||
this.suggestions.classList.add('token-autocomplete-suggestions');
|
|
||||||
this.container.appendChild(this.suggestions);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Hides the suggestions dropdown from the user.
|
|
||||||
*/
|
|
||||||
class2.prototype.hideSuggestions = function () {
|
|
||||||
this.suggestions.style.display = '';
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Shows the suggestions dropdown to the user.
|
|
||||||
*/
|
|
||||||
class2.prototype.showSuggestions = function () {
|
|
||||||
this.suggestions.style.display = 'block';
|
|
||||||
};
|
|
||||||
class2.prototype.highlightSuggestionAtPosition = function (index) {
|
|
||||||
const suggestions = this.suggestions.querySelectorAll('li');
|
|
||||||
suggestions.forEach(function (suggestion) {
|
|
||||||
suggestion.classList.remove('token-autocomplete-suggestion-highlighted');
|
|
||||||
});
|
|
||||||
suggestions[index].classList.add('token-autocomplete-suggestion-highlighted');
|
|
||||||
};
|
|
||||||
class2.prototype.highlightSuggestion = function (suggestion) {
|
|
||||||
this.suggestions.querySelectorAll('li').forEach(function (suggestion) {
|
|
||||||
suggestion.classList.remove('token-autocomplete-suggestion-highlighted');
|
|
||||||
});
|
|
||||||
suggestion.classList.add('token-autocomplete-suggestion-highlighted');
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Removes all previous suggestions from the dropdown.
|
|
||||||
*/
|
|
||||||
class2.prototype.clearSuggestions = function () {
|
|
||||||
this.suggestions.innerHTML = '';
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Loads suggestions matching the given query from the rest service behind the URI given as an option while initializing the field.
|
|
||||||
*
|
|
||||||
* @param query the query to search suggestions for
|
|
||||||
*/
|
|
||||||
class2.prototype.requestSuggestions = function (query) {
|
|
||||||
const me = this;
|
|
||||||
const request = new XMLHttpRequest();
|
|
||||||
request.onload = function () {
|
|
||||||
if (Array.isArray(request.response)) {
|
|
||||||
request.response.forEach(function (suggestion) {
|
|
||||||
me.addSuggestion(suggestion);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
request.open('GET', me.options.suggestionsUri + '?query=' + query, true);
|
|
||||||
request.responseType = 'json';
|
|
||||||
request.setRequestHeader('Content-type', 'application/json');
|
|
||||||
request.send();
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Adds a suggestion with the given text matching the users input to the dropdown.
|
|
||||||
*
|
|
||||||
* @param {string} suggestionText - the text that should be displayed for the added suggestion
|
|
||||||
*/
|
|
||||||
class2.prototype.addSuggestion = function (suggestion) {
|
|
||||||
const element = this.renderer(suggestion);
|
|
||||||
element.setAttribute('data-value', suggestion.value);
|
|
||||||
const me = this;
|
|
||||||
element.addEventListener('click', function (_event) {
|
|
||||||
if (suggestion.text === me.options.noMatchesText) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (element.classList.contains('token-autocomplete-suggestion-active')) {
|
|
||||||
me.parent.select.removeTokenWithText(suggestion.text);
|
|
||||||
} else {
|
|
||||||
me.parent.select.addToken(suggestion.value, suggestion.text);
|
|
||||||
}
|
|
||||||
me.clearSuggestions();
|
|
||||||
me.hideSuggestions();
|
|
||||||
me.parent.clearCurrentInput();
|
|
||||||
});
|
|
||||||
if (this.container.querySelector('.token-autocomplete-token[data-text="' + suggestion.text + '"]') !== null) {
|
|
||||||
element.classList.add('token-autocomplete-suggestion-active');
|
|
||||||
}
|
|
||||||
this.suggestions.appendChild(element);
|
|
||||||
this.showSuggestions();
|
|
||||||
me.parent.log('added suggestion', suggestion);
|
|
||||||
};
|
|
||||||
return class2;
|
|
||||||
})()),
|
|
||||||
(_a.defaultRenderer = function (suggestion) {
|
|
||||||
const option = document.createElement('li');
|
|
||||||
option.textContent = suggestion.text;
|
|
||||||
if (suggestion.description) {
|
|
||||||
const description = document.createElement('small');
|
|
||||||
description.textContent = suggestion.description;
|
|
||||||
description.classList.add('token-autocomplete-suggestion-description');
|
|
||||||
option.appendChild(description);
|
|
||||||
}
|
|
||||||
return option;
|
|
||||||
}),
|
|
||||||
_a);
|
|
||||||
return TokenAutocomplete;
|
|
||||||
})();
|
|
||||||
|
|
||||||
module.exports = { TokenAutocomplete };
|
|
||||||
344
src/js/trovo.js
|
|
@ -1,344 +0,0 @@
|
||||||
/* global client,axios,customEmojiList, saveCustomEmotesToFile,startTime,Sockette, playNotificationSound, chat, replaceChatMessageWithCustomEmojis, messageId, addSingleTooltip, settingsPath, fs, ini, backend, main, path, resourcesPath, customEmojis, emojiPicker,config, settings, options, sound, showChatMessage, messageTemplates, getPostTime */
|
|
||||||
|
|
||||||
function setTrovoSendButton() {
|
|
||||||
const languageSelectContent = document.querySelector('.send-to-channel');
|
|
||||||
|
|
||||||
const option = document.createElement('div');
|
|
||||||
option.classList = 'language-select';
|
|
||||||
|
|
||||||
const checkbox = document.createElement('input');
|
|
||||||
checkbox.classList = 'checkbox';
|
|
||||||
checkbox.type = 'checkbox';
|
|
||||||
checkbox.id = 'SEND_CHAT_TROVO';
|
|
||||||
option.appendChild(checkbox);
|
|
||||||
|
|
||||||
const label = document.createElement('label');
|
|
||||||
label.classList = 'toggle-small';
|
|
||||||
option.setAttribute('for', 'SEND_CHAT_TROVO');
|
|
||||||
checkbox.checked = settings.TROVO.SEND_CHAT;
|
|
||||||
option.appendChild(label);
|
|
||||||
|
|
||||||
const network = document.createElement('img');
|
|
||||||
network.src = './images/trovo.png';
|
|
||||||
network.classList = 'emote';
|
|
||||||
option.appendChild(network);
|
|
||||||
|
|
||||||
option.addEventListener('click', () => {
|
|
||||||
checkbox.checked = !checkbox.checked;
|
|
||||||
settings.TROVO.SEND_CHAT = checkbox.checked;
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
|
||||||
});
|
|
||||||
|
|
||||||
languageSelectContent.appendChild(option);
|
|
||||||
}
|
|
||||||
setTrovoSendButton();
|
|
||||||
|
|
||||||
function getTrovoUserId() {
|
|
||||||
// Get user Logo with access token
|
|
||||||
options = {
|
|
||||||
method: 'GET',
|
|
||||||
url: 'https://open-api.trovo.live/openplatform/validate',
|
|
||||||
headers: {
|
|
||||||
Accept: 'application/json',
|
|
||||||
'Client-ID': settings.TROVO.CLIENT_ID,
|
|
||||||
Authorization: `OAuth ${settings.TROVO.OAUTH_TOKEN}`
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
axios
|
|
||||||
.request(options)
|
|
||||||
.then(response => {
|
|
||||||
settings.TROVO.USERNAME = response.data.nick_name;
|
|
||||||
settings.TROVO.USER_ID = response.data.uid;
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
|
||||||
getTrovoUserInfo();
|
|
||||||
config.createNotification('Obtained user info succesfully', 'success');
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
config.createNotification('could not obtain user info, please try again', 'error');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTrovoUserInfo() {
|
|
||||||
// Get user Logo with access token
|
|
||||||
options = {
|
|
||||||
method: 'GET',
|
|
||||||
url: 'https://open-api.trovo.live/openplatform/getuserinfo',
|
|
||||||
headers: {
|
|
||||||
Accept: 'application/json',
|
|
||||||
'Client-ID': settings.TROVO.CLIENT_ID,
|
|
||||||
Authorization: `OAuth ${settings.TROVO.OAUTH_TOKEN}`
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
axios
|
|
||||||
.request(options)
|
|
||||||
.then(response => {
|
|
||||||
settings.TROVO.USER_LOGO_URL = response.data.profilePic;
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
|
||||||
config.createNotification('Obtained user info succesfully', 'success');
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
config.createNotification('could not obtain user info, please try again', 'error');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveTrovoEmotesToFile(TrovoEmotes) {
|
|
||||||
const data = JSON.stringify(TrovoEmotes);
|
|
||||||
const savePath =
|
|
||||||
main.isPackaged === true ? path.join(resourcesPath, './custom-emotes.json') : path.join(resourcesPath, './config/custom-emotes.json');
|
|
||||||
|
|
||||||
fs.writeFile(savePath, data, error => {
|
|
||||||
if (error) {
|
|
||||||
console.error(error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatTrovoEmotes(data) {
|
|
||||||
if (data.channels.customizedEmotes.channel) {
|
|
||||||
data.channels.customizedEmotes.channel.forEach(channel => {
|
|
||||||
channel.emotes.forEach(emote => {
|
|
||||||
const emojiToBeAdded = {
|
|
||||||
name: ':' + emote.name,
|
|
||||||
shortcodes: [':' + emote.name],
|
|
||||||
url: emote.url,
|
|
||||||
category: 'Trovo ' + settings.TROVO.CHANNEL_NAME
|
|
||||||
};
|
|
||||||
customEmojis.push(emojiToBeAdded);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// data.channels.eventEmotes.forEach(emote => {
|
|
||||||
// const emojiToBeAdded = {
|
|
||||||
// name: emote.name,
|
|
||||||
// shortcodes: [emote.name],
|
|
||||||
// url: emote.url,
|
|
||||||
// category: 'Trovo event emotes'
|
|
||||||
// };
|
|
||||||
// customEmojis.push(emojiToBeAdded);
|
|
||||||
// });
|
|
||||||
|
|
||||||
if (data.channels.globalEmotes) {
|
|
||||||
data.channels.globalEmotes.forEach(emote => {
|
|
||||||
const emojiToBeAdded = {
|
|
||||||
name: ':' + emote.name,
|
|
||||||
shortcodes: [':' + emote.name],
|
|
||||||
url: emote.url,
|
|
||||||
category: 'Trovo Global'
|
|
||||||
};
|
|
||||||
customEmojis.push(emojiToBeAdded);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
customEmojiList = [...customEmojis];
|
|
||||||
emojiPicker.customEmoji = customEmojiList;
|
|
||||||
saveCustomEmotesToFile(customEmojis);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTrovoEmotes() {
|
|
||||||
// Get user Logo with access token
|
|
||||||
options = {
|
|
||||||
method: 'POST',
|
|
||||||
url: 'https://open-api.trovo.live/openplatform/getemotes',
|
|
||||||
headers: {
|
|
||||||
Accept: 'application/json',
|
|
||||||
'Client-ID': settings.TROVO.CLIENT_ID,
|
|
||||||
Authorization: `OAuth ${settings.TROVO.OAUTH_TOKEN}`
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
emote_type: 0,
|
|
||||||
channel_id: [settings.TROVO.CHANNEL_ID]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
axios
|
|
||||||
.request(options)
|
|
||||||
.then(response => {
|
|
||||||
formatTrovoEmotes(response.data);
|
|
||||||
config.createNotification('Obtained user info succesfully', 'success');
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
config.createNotification('could not obtain user info, please try again', 'error');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTrovoChannelId() {
|
|
||||||
options = {
|
|
||||||
method: 'POST',
|
|
||||||
url: 'https://open-api.trovo.live/openplatform/getusers',
|
|
||||||
headers: {
|
|
||||||
Accept: 'application/json',
|
|
||||||
'Client-ID': settings.TROVO.CLIENT_ID
|
|
||||||
},
|
|
||||||
data: { user: [settings.TROVO.CHANNEL_NAME.toLowerCase()] }
|
|
||||||
};
|
|
||||||
|
|
||||||
axios
|
|
||||||
.request(options)
|
|
||||||
.then(response => {
|
|
||||||
settings.TROVO.CHANNEL_ID = response.data.users[0].channel_id;
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
|
||||||
getTrovoEmotes();
|
|
||||||
config.createNotification('Obtained user info succesfully', 'success');
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
config.createNotification('could not obtain user info, please try again', 'error');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendTrovoMessage(message) {
|
|
||||||
options = {
|
|
||||||
method: 'POST',
|
|
||||||
url: 'https://open-api.trovo.live/openplatform/chat/send',
|
|
||||||
headers: {
|
|
||||||
Accept: 'application/json',
|
|
||||||
'Client-ID': settings.TROVO.CLIENT_ID,
|
|
||||||
Authorization: `OAuth ${settings.TROVO.OAUTH_TOKEN}`
|
|
||||||
},
|
|
||||||
data: { content: message, channel_id: settings.TROVO.CHANNEL_ID }
|
|
||||||
};
|
|
||||||
|
|
||||||
axios
|
|
||||||
.request(options)
|
|
||||||
.then(response => {
|
|
||||||
console.log(response);
|
|
||||||
config.createNotification('Obtained user info succesfully', 'success');
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
config.createNotification('could not obtain user info, please try again', 'error');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const getTrovoChatToken = () =>
|
|
||||||
new Promise(resolve => {
|
|
||||||
options = {
|
|
||||||
method: 'GET',
|
|
||||||
url: `https://open-api.trovo.live/openplatform/chat/channel-token/${settings.TROVO.CHANNEL_ID}`,
|
|
||||||
headers: {
|
|
||||||
Accept: 'application/json',
|
|
||||||
'Client-ID': settings.TROVO.CLIENT_ID
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
axios
|
|
||||||
.request(options)
|
|
||||||
.then(response => {
|
|
||||||
resolve(response.data.token);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
config.createNotification('could not obtain user info, please try again', 'error');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
async function displayTrovoMessage(message) {
|
|
||||||
messageId++;
|
|
||||||
const article = document.createElement('article');
|
|
||||||
article.className = 'msg-container sender';
|
|
||||||
article.setAttribute('id', messageId);
|
|
||||||
|
|
||||||
article.innerHTML = messageTemplates.trovoTemplate;
|
|
||||||
const userImg = article.querySelector('.user-img');
|
|
||||||
if (userImg) {
|
|
||||||
userImg.src = message.avatar;
|
|
||||||
userImg.setAttribute('tip', '');
|
|
||||||
}
|
|
||||||
addSingleTooltip(userImg);
|
|
||||||
|
|
||||||
const usernameHtml = article.querySelector('.username');
|
|
||||||
if (usernameHtml) {
|
|
||||||
usernameHtml.innerText = message.nick_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const postTime = article.querySelector('.post-time');
|
|
||||||
|
|
||||||
if (postTime) {
|
|
||||||
postTime.innerText = getPostTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
article.appendChild(postTime);
|
|
||||||
|
|
||||||
const formattedMessage = article.querySelector('.msg-box');
|
|
||||||
if (formattedMessage) {
|
|
||||||
formattedMessage.innerHTML = message.content;
|
|
||||||
}
|
|
||||||
|
|
||||||
await chat.replaceChatMessageWithCustomEmojis(formattedMessage.innerHTML).then(data => {
|
|
||||||
formattedMessage.innerHTML = data;
|
|
||||||
showChatMessage(article);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function connectToTrovoChat(token) {
|
|
||||||
let startTime = new Date();
|
|
||||||
let heartbeat = null;
|
|
||||||
|
|
||||||
const wsTrovo = new Sockette('wss://open-chat.trovo.live/chat', {
|
|
||||||
onopen: e => {
|
|
||||||
// console.log('Connected!', e);
|
|
||||||
wsTrovo.json({ type: 'AUTH', nonce: 'loquendoBot', data: { token } });
|
|
||||||
},
|
|
||||||
onmessage: e => {
|
|
||||||
// console.log('Received:', e);
|
|
||||||
const data = JSON.parse(e.data);
|
|
||||||
// console.log(data);
|
|
||||||
if (data.type === 'RESPONSE' && !data.error) {
|
|
||||||
wsTrovo.json({ type: 'PING', nonce: 'loquendoBot' });
|
|
||||||
heartbeat = setInterval(() => {
|
|
||||||
wsTrovo.json({ type: 'PING', nonce: 'loquendoBot' });
|
|
||||||
}, 30e3);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.type === 'CHAT' && data.data.chats) {
|
|
||||||
data.data.chats.forEach(message => {
|
|
||||||
// console.log(message);
|
|
||||||
if (message.type === 5007) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Math.round(startTime.getTime() / 1000) < message.send_time) {
|
|
||||||
displayTrovoMessage({
|
|
||||||
nick_name: message.nick_name,
|
|
||||||
avatar: message.avatar,
|
|
||||||
content: message.content
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.type === 'PONG') {
|
|
||||||
clearInterval(heartbeat);
|
|
||||||
heartbeat = setInterval(() => {
|
|
||||||
wsTrovo.json({ type: 'PING', nonce: 'loquendoBot' });
|
|
||||||
}, data.data.gap * 1000);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onreconnect: e => {
|
|
||||||
console.log('Reconnecting...', e);
|
|
||||||
startTime = new Date();
|
|
||||||
clearInterval(heartbeat);
|
|
||||||
getTrovoChatToken().then(data => {
|
|
||||||
token = data;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onmaximum: e => console.log('Stop Attempting!', e),
|
|
||||||
onclose: e => console.log('Closed!', e),
|
|
||||||
onerror: e => console.log('Error:', e)
|
|
||||||
});
|
|
||||||
|
|
||||||
// ws.close(); // graceful shutdown
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.TROVO.CHANNEL_ID) {
|
|
||||||
getTrovoChatToken().then(data => {
|
|
||||||
connectToTrovoChat(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { getTrovoUserId, getTrovoChannelId, sendTrovoMessage };
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
/* global client, axios, playNotificationSound, betterTTVAutocomplete, saveCustomEmotesToFile, customEmojiList, chat, replaceChatMessageWithCustomEmojis, messageId, addSingleTooltip, settingsPath, fs, ini, backend, main, path, resourcesPath, customEmojis, emojiPicker,config, settings, options, sound, showChatMessage, messageTemplates, getPostTime */
|
/* global client, playNotificationSound, chat, replaceChatMessageWithCustomEmojis, messageId, addSingleTooltip, settingsPath, fs, ini, backend, main, path, resourcesPath, customEmojis, emojiPicker,config, settings, options, sound, showChatMessage, messageTemplates, getPostTime */
|
||||||
|
|
||||||
const tmi = require('tmi.js');
|
const tmi = require('tmi.js');
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
let client = null;
|
let client = null;
|
||||||
let logoUrl = null;
|
let logoUrl = null;
|
||||||
|
|
@ -28,7 +29,7 @@ if (settings.TWITCH.USERNAME && settings.TWITCH.OAUTH_TOKEN) {
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
|
|
||||||
client.on('message', (channel, tags, message, self) => {
|
client.on('message', (channel, tags, message, self) => {
|
||||||
if (self || tags['display-name'] === settings.TWITCH.USERNAME) {
|
if (self) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const emotes = tags.emotes || {};
|
const emotes = tags.emotes || {};
|
||||||
|
|
@ -138,7 +139,7 @@ async function displayTwitchMessage(logoUrl, username, messageObject, filteredMe
|
||||||
showChatMessage(article);
|
showChatMessage(article);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (settings.LANGUAGE.USE_DETECTION && filteredMessage.length > 20 && countWords(filteredMessage) > 4) {
|
if (settings.LANGUAGE.USE_DETECTION) {
|
||||||
await backend.getDetectedLanguage({ message: filteredMessage, messageId, username, logoUrl, formattedMessage }).then(language => {
|
await backend.getDetectedLanguage({ message: filteredMessage, messageId, username, logoUrl, formattedMessage }).then(language => {
|
||||||
const languageElement = document.createElement('span');
|
const languageElement = document.createElement('span');
|
||||||
languageElement.classList = `fi fi-${language.ISO3166} fis language-icon flag-icon`;
|
languageElement.classList = `fi fi-${language.ISO3166} fis language-icon flag-icon`;
|
||||||
|
|
@ -205,6 +206,25 @@ function parseString(inputString) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function saveTwitchEmotesToFile(TwitchEmotes) {
|
||||||
|
const data = JSON.stringify(TwitchEmotes);
|
||||||
|
const savePath =
|
||||||
|
main.isPackaged === true ? path.join(resourcesPath, './twitch-emotes.json') : path.join(resourcesPath, './config/twitch-emotes.json');
|
||||||
|
// console.log(savePath);
|
||||||
|
fs.writeFile(savePath, data, error => {
|
||||||
|
// throwing the error
|
||||||
|
// in case of a writing problem
|
||||||
|
if (error) {
|
||||||
|
// logging the error
|
||||||
|
console.error(error);
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log('twitch-emotes.json written correctly');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function formatTwitchEmotes(channel) {
|
function formatTwitchEmotes(channel) {
|
||||||
if (channel.emotes.length === 0) {
|
if (channel.emotes.length === 0) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -224,13 +244,27 @@ function formatTwitchEmotes(channel) {
|
||||||
name: emote.name,
|
name: emote.name,
|
||||||
shortcodes: [emote.name],
|
shortcodes: [emote.name],
|
||||||
url: emote.images.url_1x,
|
url: emote.images.url_1x,
|
||||||
category: 'Twitch ' + channel.broadcaster_name
|
category: channel.broadcaster_name
|
||||||
};
|
};
|
||||||
customEmojis.push(emojiToBeAdded);
|
customEmojis.push(emojiToBeAdded);
|
||||||
});
|
});
|
||||||
customEmojiList = [...customEmojis];
|
emojiPicker.customEmoji = customEmojis;
|
||||||
emojiPicker.customEmoji = customEmojiList;
|
saveTwitchEmotesToFile(customEmojis);
|
||||||
saveCustomEmotesToFile(customEmojis);
|
}
|
||||||
|
|
||||||
|
function saveBetterTtvEmotesToFile(BetterTtvEmotes) {
|
||||||
|
const data = JSON.stringify(BetterTtvEmotes);
|
||||||
|
const savePath =
|
||||||
|
main.isPackaged === true
|
||||||
|
? path.join(resourcesPath, './betterttv-emotes.json')
|
||||||
|
: path.join(resourcesPath, './config/betterttv-emotes.json');
|
||||||
|
fs.writeFile(savePath, data, error => {
|
||||||
|
if (error) {
|
||||||
|
console.error(error);
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatBetterTtvEmotes(data) {
|
function formatBetterTtvEmotes(data) {
|
||||||
|
|
@ -247,9 +281,8 @@ function formatBetterTtvEmotes(data) {
|
||||||
};
|
};
|
||||||
customEmojis.push(emojiToBeAdded);
|
customEmojis.push(emojiToBeAdded);
|
||||||
});
|
});
|
||||||
customEmojiList = [...customEmojis];
|
emojiPicker.customEmoji = customEmojis;
|
||||||
emojiPicker.customEmoji = customEmojiList;
|
saveBetterTtvEmotesToFile(customEmojis);
|
||||||
saveCustomEmotesToFile(customEmojis);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBetterTtvGLobalEmotes() {
|
function getBetterTtvGLobalEmotes() {
|
||||||
|
|
@ -270,32 +303,6 @@ function getBetterTtvGLobalEmotes() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBetterTtvChannelsEmotes() {
|
|
||||||
betterTTVAutocomplete.tokens.forEach(channel => {
|
|
||||||
getTwitchChannelId(channel.value).then(channelId => {
|
|
||||||
getBetterTtvChannelEmotes(channelId);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBetterTtvChannelEmotes(channel) {
|
|
||||||
// Get user Logo with access token
|
|
||||||
options = {
|
|
||||||
method: 'GET',
|
|
||||||
url: `https://api.betterttv.net/3/cached/users/twitch/${channel}`,
|
|
||||||
headers: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
axios
|
|
||||||
.request(options)
|
|
||||||
.then(response => {
|
|
||||||
formatBetterTtvEmotes({ name: 'BetterTTV Channels', emotes: [...response.data.channelEmotes, ...response.data.sharedEmotes] });
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTwitchUserFollows(paginationToken) {
|
function getTwitchUserFollows(paginationToken) {
|
||||||
let url = '';
|
let url = '';
|
||||||
if (!paginationToken) {
|
if (!paginationToken) {
|
||||||
|
|
@ -400,7 +407,7 @@ function getTwitchGlobalEmotes() {
|
||||||
axios
|
axios
|
||||||
.request(options)
|
.request(options)
|
||||||
.then(responseLogoUrl => {
|
.then(responseLogoUrl => {
|
||||||
formatTwitchEmotes({ broadcaster_name: 'Global', emotes: responseLogoUrl.data.data });
|
formatTwitchEmotes({ broadcaster_name: 'Twitch Global', emotes: responseLogoUrl.data.data });
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
|
@ -424,11 +431,10 @@ async function getUserAvailableTwitchEmotes() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getTwitchChannelId = channelName =>
|
function getTwitchChannelId() {
|
||||||
new Promise(resolve => {
|
|
||||||
options = {
|
options = {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: `https://api.twitch.tv/helix/users?login=${channelName}`,
|
url: `https://api.twitch.tv/helix/users?login=${settings.TWITCH.CHANNEL_NAME}`,
|
||||||
headers: {
|
headers: {
|
||||||
'Client-ID': settings.TWITCH.CLIENT_ID,
|
'Client-ID': settings.TWITCH.CLIENT_ID,
|
||||||
Authorization: `Bearer ${settings.TWITCH.OAUTH_TOKEN}`
|
Authorization: `Bearer ${settings.TWITCH.OAUTH_TOKEN}`
|
||||||
|
|
@ -437,14 +443,17 @@ const getTwitchChannelId = channelName =>
|
||||||
|
|
||||||
axios
|
axios
|
||||||
.request(options)
|
.request(options)
|
||||||
.then(response => {
|
.then(responseLogoUrl => {
|
||||||
resolve(response.data.data[0].id);
|
settings.TWITCH.CHANNEL_USER_ID = responseLogoUrl.data.data[0].id;
|
||||||
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
|
config.createNotification('Obtained channel info succesfully', 'success');
|
||||||
|
getUserAvailableTwitchEmotes();
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
config.createNotification('could not obtain channel info, please try again', 'error');
|
config.createNotification('could not obtain channel info, please try again', 'error');
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
function getTwitchUserId() {
|
function getTwitchUserId() {
|
||||||
// Get user Logo with access token
|
// Get user Logo with access token
|
||||||
|
|
@ -464,7 +473,7 @@ function getTwitchUserId() {
|
||||||
settings.TWITCH.USERNAME = responseLogoUrl.data.data[0].display_name;
|
settings.TWITCH.USERNAME = responseLogoUrl.data.data[0].display_name;
|
||||||
settings.TWITCH.USER_LOGO_URL = responseLogoUrl.data.data[0].profile_image_url;
|
settings.TWITCH.USER_LOGO_URL = responseLogoUrl.data.data[0].profile_image_url;
|
||||||
settings.TWITCH.USER_ID = responseLogoUrl.data.data[0].id;
|
settings.TWITCH.USER_ID = responseLogoUrl.data.data[0].id;
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
config.createNotification('Obtained user info succesfully', 'success');
|
config.createNotification('Obtained user info succesfully', 'success');
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
|
|
@ -498,8 +507,6 @@ module.exports = {
|
||||||
ping,
|
ping,
|
||||||
client,
|
client,
|
||||||
getBetterTtvGLobalEmotes,
|
getBetterTtvGLobalEmotes,
|
||||||
getBetterTtvChannelEmotes,
|
|
||||||
getBetterTtvChannelsEmotes,
|
|
||||||
getUserAvailableTwitchEmotes,
|
getUserAvailableTwitchEmotes,
|
||||||
getTwitchChannelId,
|
getTwitchChannelId,
|
||||||
getTwitchUserId,
|
getTwitchUserId,
|
||||||
|
|
|
||||||
|
|
@ -1,96 +0,0 @@
|
||||||
/* global settings, bot, messageId, showChatMessage, messageTemplates, chat, addSingleTooltip,getPostTime */
|
|
||||||
|
|
||||||
const { LiveChat } = require('youtube-chat');
|
|
||||||
const startTime = new Date();
|
|
||||||
|
|
||||||
// If channelId is specified, liveId in the current stream is automatically acquired.
|
|
||||||
// Recommended
|
|
||||||
// const liveChat = new LiveChat({ handle: settings.YOUTUBE.CHANNEL_HANDLE });
|
|
||||||
const liveChat = new LiveChat({ liveId: settings.YOUTUBE.LIVE_ID });
|
|
||||||
|
|
||||||
// Or specify LiveID in Stream manually.
|
|
||||||
// const liveChat = new LiveChat({ liveId: '4xDzrJKXOOY' });
|
|
||||||
|
|
||||||
// Emit at start of observation chat.
|
|
||||||
// liveId: string
|
|
||||||
liveChat.on('start', liveId => {
|
|
||||||
/* Your code here! */
|
|
||||||
console.log(liveId);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Emit at end of observation chat.
|
|
||||||
// reason: string?
|
|
||||||
liveChat.on('end', reason => {
|
|
||||||
/* Your code here! */
|
|
||||||
console.log(reason);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Emit at receive chat.
|
|
||||||
// chat: ChatItem
|
|
||||||
liveChat.on('chat', message => {
|
|
||||||
/* Your code here! */
|
|
||||||
if (message.timestamp > startTime) {
|
|
||||||
displayYoutubeMessage(message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Emit when an error occurs
|
|
||||||
// err: Error or any
|
|
||||||
liveChat.on('error', err => {
|
|
||||||
/* Your code here! */
|
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
async function startYoutube() {
|
|
||||||
// Start fetch loop
|
|
||||||
const ok = await liveChat.start();
|
|
||||||
if (!ok) {
|
|
||||||
console.log('Failed to start, check emitted error');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
startYoutube();
|
|
||||||
|
|
||||||
async function displayYoutubeMessage(message) {
|
|
||||||
messageId++;
|
|
||||||
const article = document.createElement('article');
|
|
||||||
article.className = 'msg-container sender';
|
|
||||||
article.setAttribute('id', messageId);
|
|
||||||
|
|
||||||
article.innerHTML = messageTemplates.youtubeTemplate;
|
|
||||||
const userImg = article.querySelector('.user-img');
|
|
||||||
if (userImg) {
|
|
||||||
userImg.src = message.author.thumbnail.url;
|
|
||||||
userImg.setAttribute('tip', '');
|
|
||||||
}
|
|
||||||
addSingleTooltip(userImg);
|
|
||||||
|
|
||||||
const usernameHtml = article.querySelector('.username');
|
|
||||||
if (usernameHtml) {
|
|
||||||
usernameHtml.innerText = message.author.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const postTime = article.querySelector('.post-time');
|
|
||||||
|
|
||||||
if (postTime) {
|
|
||||||
postTime.innerText = getPostTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
article.appendChild(postTime);
|
|
||||||
|
|
||||||
const formattedMessage = article.querySelector('.msg-box');
|
|
||||||
if (formattedMessage) {
|
|
||||||
message.message.forEach(entry => {
|
|
||||||
if (entry.text) {
|
|
||||||
formattedMessage.innerHTML += entry.text;
|
|
||||||
} else {
|
|
||||||
formattedMessage.innerHTML += `<img src="${entry.url}"/>`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await chat.replaceChatMessageWithCustomEmojis(formattedMessage.innerHTML).then(data => {
|
|
||||||
formattedMessage.innerHTML = data;
|
|
||||||
showChatMessage(article);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
90
src/main.js
|
|
@ -1,33 +1,35 @@
|
||||||
/* global pythonPath, a */
|
/* global pythonPath, a */
|
||||||
|
|
||||||
const { app, BrowserWindow, ipcMain } = require('electron');
|
const { app, BrowserWindow, ipcMain } = require('electron');
|
||||||
|
const { writeIniFile } = require('write-ini-file');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const http = require('http');
|
const http = require('http');
|
||||||
const kill = require('kill-process-by-name');
|
const kill = require('kill-process-by-name');
|
||||||
|
|
||||||
|
const ini = require('ini');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
let resourcesPath = __dirname;
|
let resourcesPath = __dirname;
|
||||||
let settingsPath = null;
|
let settingsPath;
|
||||||
|
|
||||||
let settings;
|
let settings;
|
||||||
let window;
|
let window;
|
||||||
|
|
||||||
if (app.isPackaged) {
|
if (app.isPackaged) {
|
||||||
settingsPath = path.join(process.resourcesPath, './settings.json');
|
settingsPath = path.join(process.resourcesPath, './settings.ini');
|
||||||
pythonPath = path.join(process.resourcesPath, './backend');
|
pythonPath = path.join(process.resourcesPath, './backend');
|
||||||
resourcesPath = process.resourcesPath;
|
resourcesPath = process.resourcesPath;
|
||||||
} else {
|
} else {
|
||||||
settingsPath = path.join(resourcesPath, './config/settings.json');
|
settingsPath = path.join(resourcesPath, './config/settings.ini');
|
||||||
pythonPath = path.join(resourcesPath, './backend');
|
pythonPath = path.join(resourcesPath, './backend');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createWindow() {
|
async function createWindow() {
|
||||||
if (!fs.existsSync(settingsPath)) {
|
if (!fs.existsSync(settingsPath)) {
|
||||||
settings = await createSettingsFile();
|
console.log(resourcesPath);
|
||||||
|
await createIniFile();
|
||||||
} else {
|
} else {
|
||||||
const file = fs.readFileSync(settingsPath);
|
settings = ini.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
||||||
settings = JSON.parse(file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window = new BrowserWindow({
|
window = new BrowserWindow({
|
||||||
|
|
@ -43,35 +45,15 @@ async function createWindow() {
|
||||||
enableRemoteModule: true
|
enableRemoteModule: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.loadFile(path.join(__dirname, 'index.html'));
|
window.loadFile(path.join(__dirname, 'index.html'));
|
||||||
|
|
||||||
// Create the second window
|
|
||||||
const secondWindow = new BrowserWindow({
|
|
||||||
width: 1920,
|
|
||||||
height: 1080,
|
|
||||||
// parent: window, // Set the parent window
|
|
||||||
// modal: true,
|
|
||||||
frame: false,
|
|
||||||
show: true, // Hide the second window initially if needed
|
|
||||||
webPreferences: {
|
|
||||||
nodeIntegration: true,
|
|
||||||
contextIsolation: false,
|
|
||||||
enableRemoteModule: true,
|
|
||||||
backgroundThrottling: false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Load second.html into the second window
|
|
||||||
secondWindow.loadFile(path.join(__dirname, './modules/facemask/index.html'));
|
|
||||||
// secondWindow.webContents.setFrameRate(60);
|
|
||||||
|
|
||||||
if (!app.isPackaged) {
|
if (!app.isPackaged) {
|
||||||
window.webContents.openDevTools();
|
window.webContents.openDevTools();
|
||||||
secondWindow.webContents.openDevTools();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.on('close', e => {
|
window.on('close', e => {
|
||||||
settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8')); // load newest settings in case anything changed after starting the program
|
settings = ini.parse(fs.readFileSync(settingsPath, 'utf-8')); // load newest settings in case anything changed after starting the program
|
||||||
const bounds = window.getBounds();
|
const bounds = window.getBounds();
|
||||||
|
|
||||||
settings.GENERAL.WIDTH = bounds.width;
|
settings.GENERAL.WIDTH = bounds.width;
|
||||||
|
|
@ -79,20 +61,17 @@ async function createWindow() {
|
||||||
settings.GENERAL.POSITION_X = bounds.x;
|
settings.GENERAL.POSITION_X = bounds.x;
|
||||||
settings.GENERAL.POSITION_Y = bounds.y;
|
settings.GENERAL.POSITION_Y = bounds.y;
|
||||||
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// app.disableHardwareAcceleration();
|
|
||||||
// app.disableDomainBlockingFor3DAPIs();
|
|
||||||
|
|
||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
createWindow();
|
createWindow();
|
||||||
});
|
});
|
||||||
|
|
||||||
app.on('window-all-closed', event => {
|
app.on('window-all-closed', event => {
|
||||||
if (process.platform !== 'darwin') {
|
if (process.platform !== 'darwin') {
|
||||||
// kill('loquendoBot_backend');
|
kill('loquendoBot_backend');
|
||||||
app.quit();
|
app.quit();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -105,7 +84,7 @@ app.on('activate', () => {
|
||||||
|
|
||||||
app.on('before-quit', () => {
|
app.on('before-quit', () => {
|
||||||
window.webContents.send('quit-event');
|
window.webContents.send('quit-event');
|
||||||
// kill('loquendoBot_backend');
|
kill('loquendoBot_backend');
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('resize-window', (event, width, height) => {
|
ipcMain.on('resize-window', (event, width, height) => {
|
||||||
|
|
@ -143,8 +122,8 @@ ipcMain.on('environment', event => {
|
||||||
event.returnValue = { resourcesPath, pythonPath, settingsPath, settings, isPackaged: app.isPackaged };
|
event.returnValue = { resourcesPath, pythonPath, settingsPath, settings, isPackaged: app.isPackaged };
|
||||||
});
|
});
|
||||||
|
|
||||||
async function createSettingsFile() {
|
async function createIniFile() {
|
||||||
const settingsx = {
|
await writeIniFile(settingsPath, {
|
||||||
GENERAL: {
|
GENERAL: {
|
||||||
VOICE_ENABLED: true,
|
VOICE_ENABLED: true,
|
||||||
NOTIFICATION_ENABLED: true,
|
NOTIFICATION_ENABLED: true,
|
||||||
|
|
@ -210,47 +189,17 @@ async function createSettingsFile() {
|
||||||
},
|
},
|
||||||
TWITCH: {
|
TWITCH: {
|
||||||
USE_TWITCH: false,
|
USE_TWITCH: false,
|
||||||
SEND_CHAT: false,
|
|
||||||
CHANNEL_NAME: '',
|
CHANNEL_NAME: '',
|
||||||
CHANNEL_USER_ID: '',
|
CHANNEL_USER_ID: '',
|
||||||
USERNAME: '',
|
USERNAME: '',
|
||||||
USER_ID: '',
|
USER_ID: '',
|
||||||
USER_LOGO_URL: '',
|
USER_LOGO_URL: '',
|
||||||
OAUTH_TOKEN: '',
|
OAUTH_TOKEN: '',
|
||||||
BETTERTTV_CHANNELS: [
|
|
||||||
{ value: 'turtlemaw', text: 'turtlemaw' },
|
|
||||||
{ value: 'tO_Ot', text: 'tO_Ot' },
|
|
||||||
{ value: 'adew', text: 'adew' }
|
|
||||||
],
|
|
||||||
CLIENT_ID: '2t206sj7rvtr1rutob3p627d13jch9'
|
CLIENT_ID: '2t206sj7rvtr1rutob3p627d13jch9'
|
||||||
},
|
},
|
||||||
TROVO: {
|
|
||||||
USE_TROVO: false,
|
|
||||||
SEND_CHAT: false,
|
|
||||||
CHANNEL_NAME: '',
|
|
||||||
CHANNEL_ID: '',
|
|
||||||
USERNAME: '',
|
|
||||||
USER_LOGO_URL: '',
|
|
||||||
USER_ID: '',
|
|
||||||
CLIENT_ID: '8d32385a4be4a29e345aedaf23ca772f',
|
|
||||||
OAUTH_TOKEN: ''
|
|
||||||
},
|
|
||||||
YOUTUBE: {
|
|
||||||
USE_YOUTUBE: false,
|
|
||||||
SEND_CHAT: false,
|
|
||||||
CHANNEL_ID: '',
|
|
||||||
CHANNEL_HANDLE: '',
|
|
||||||
LIVE_ID: ''
|
|
||||||
},
|
|
||||||
DLIVE: {
|
|
||||||
USE_DLIVE: false,
|
|
||||||
SEND_CHAT: false,
|
|
||||||
API_KEY: ''
|
|
||||||
},
|
|
||||||
MODULES: {
|
MODULES: {
|
||||||
USE_MODULES: false,
|
USE_MODULES: false,
|
||||||
USE_VTUBER: false,
|
USE_VTUBER: false,
|
||||||
USE_PNGTUBER: false,
|
|
||||||
USE_CHATBUBBLE: false
|
USE_CHATBUBBLE: false
|
||||||
},
|
},
|
||||||
AMAZON: {
|
AMAZON: {
|
||||||
|
|
@ -268,12 +217,7 @@ async function createSettingsFile() {
|
||||||
SECONDARY_VOICE: '',
|
SECONDARY_VOICE: '',
|
||||||
CHARACTERS_USED: 0
|
CHARACTERS_USED: 0
|
||||||
}
|
}
|
||||||
};
|
}).then(() => {
|
||||||
|
settings = ini.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
||||||
fs.writeFile(settingsPath, JSON.stringify(settingsx), error => {
|
|
||||||
if (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return settingsx;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 5.6 KiB |
|
|
@ -1,5 +1,5 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Chat</title>
|
<title>Chat</title>
|
||||||
<script
|
<script
|
||||||
|
|
@ -10,11 +10,14 @@
|
||||||
<link rel="stylesheet" href="./fonts/FRAMCDN/font.css" />
|
<link rel="stylesheet" href="./fonts/FRAMCDN/font.css" />
|
||||||
<link href="main.css" rel="stylesheet" />
|
<link href="main.css" rel="stylesheet" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="chatBox" class="message-window"></div>
|
<!-- #region Main chat box-->
|
||||||
<emoji-picker class="dark"></emoji-picker>
|
<div class="OptionPanel show" id="Chat">
|
||||||
</body>
|
<div id="chatBox" class="message-window">
|
||||||
|
<div class="texts"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<script src="main.js"></script>
|
<script src="main.js"></script>
|
||||||
<script type="module" src="https://cdn.jsdelivr.net/npm/emoji-picker-element@^1/index.js"></script>
|
<video id="camera" autoplay></video>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,204 +1,90 @@
|
||||||
@font-face {
|
body {
|
||||||
|
background-color: transparent;
|
||||||
font-family: 'FRAMDCN';
|
font-family: 'FRAMDCN';
|
||||||
src: url(../fonts/FRAMCDN/FRAMDCN.woff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
overflow: hidden;
|
--variable: 2s;
|
||||||
--main-color1: #6e2c8c;
|
--buttonBackground: #bf2c2c;
|
||||||
--main-color1-temp: #6e2c8c;
|
|
||||||
/*Left bar and top right bar*/
|
|
||||||
--main-color2: white;
|
|
||||||
--main-color2-temp: white;
|
|
||||||
/*Icons and text*/
|
|
||||||
--main-color3: #211e1e;
|
|
||||||
--main-color3-temp: #211e1e;
|
|
||||||
/*Buttons and input*/
|
|
||||||
--main-color4: #2f2c34;
|
|
||||||
--main-color4-temp: #2f2c34;
|
|
||||||
--top-bar: #100b12;
|
|
||||||
--top-bar-temp: #100b12;
|
|
||||||
--mid-section: #352d3d;
|
|
||||||
--mid-section-temp: #352d3d;
|
|
||||||
--chat-bubble: #7a6d7f;
|
|
||||||
--chat-bubble-header: #141414;
|
|
||||||
--chat-bubble-username: white;
|
|
||||||
--chat-bubble-message: white;
|
|
||||||
--chat-bubble-temp: #7a6d7f;
|
|
||||||
--chat-bubble-header-temp: #141414;
|
|
||||||
--chat-bubble-message-temp: white;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
.thomas {
|
||||||
font-family: 'FRAMDCN';
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-window {
|
|
||||||
height: calc(100% - 60px);
|
|
||||||
overflow: hidden;
|
|
||||||
overflow-y: auto;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column-reverse;
|
|
||||||
font-family: 'FRAMDCN';
|
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
float: center;
|
||||||
|
/* display: inline-block; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-box {
|
.speechbubble {
|
||||||
display: flex;
|
display: block;
|
||||||
border: none;
|
bottom: 0;
|
||||||
width: 100%;
|
position: absolute;
|
||||||
height: 30px;
|
z-index: -1;
|
||||||
font-size: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.userText {
|
.fade-outx {
|
||||||
color: var(--chat-bubble-message);
|
animation: fade-outx var(--variable) linear;
|
||||||
font-family: Helvetica;
|
|
||||||
font-size: 16px;
|
|
||||||
text-align: right;
|
|
||||||
clear: both;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.userText span {
|
@keyframes fade-outx {
|
||||||
line-height: 1.5em;
|
|
||||||
display: inline-block;
|
|
||||||
background: #5ca6fa;
|
|
||||||
padding: 10px;
|
|
||||||
border-radius: 8px;
|
|
||||||
border-bottom-right-radius: 2px;
|
|
||||||
max-width: 80%;
|
|
||||||
margin-right: 10px;
|
|
||||||
animation: floatup 0.5s forwards;
|
|
||||||
}
|
|
||||||
|
|
||||||
.botText {
|
|
||||||
color: #000;
|
|
||||||
font-family: Helvetica;
|
|
||||||
font-weight: normal;
|
|
||||||
font-size: 16px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.botText span {
|
|
||||||
line-height: 1.5em;
|
|
||||||
display: inline-block;
|
|
||||||
background: #e0e0e0;
|
|
||||||
padding: 10px;
|
|
||||||
border-radius: 8px;
|
|
||||||
border-bottom-left-radius: 2px;
|
|
||||||
max-width: 80%;
|
|
||||||
margin-left: 10px;
|
|
||||||
animation: floatup 0.5s forwards;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes floatup {
|
|
||||||
from {
|
from {
|
||||||
transform: translateY(14px);
|
opacity: 1;
|
||||||
opacity: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
transform: translateY(0px);
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-outxx {
|
||||||
|
animation: fade-outxx var(--variable) linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-outxx {
|
||||||
|
from {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 600px) {
|
to {
|
||||||
.full-chat-block {
|
opacity: 0;
|
||||||
width: 100%;
|
|
||||||
border-radius: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-bar-collapsible {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.collapsible {
|
|
||||||
width: 100%;
|
|
||||||
border: 0px;
|
|
||||||
border-radius: 0px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
.bounce-in {
|
||||||
width: 4px;
|
animation: bounce-in 1s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
@keyframes bounce-in {
|
||||||
background-color: #4c4c6a;
|
0% {
|
||||||
border-radius: 2px;
|
opacity: 0;
|
||||||
|
transform: scale(0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
70% {
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.chatBox {
|
.bounce-inx {
|
||||||
width: 300px;
|
animation: bounce-inx 1s ease;
|
||||||
height: 400px;
|
|
||||||
max-height: 400px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
box-shadow: 0 0 4px var(--main-color4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-window {
|
@keyframes bounce-inx {
|
||||||
flex: auto;
|
0% {
|
||||||
max-height: calc(100% - 60px);
|
opacity: 0;
|
||||||
background: #2f323b;
|
}
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-input {
|
50% {
|
||||||
height: 30px;
|
opacity: 1;
|
||||||
display: flex;
|
}
|
||||||
flex: 0 0 auto;
|
|
||||||
height: 60px;
|
|
||||||
background: var(--main-color3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-input input {
|
|
||||||
height: 59px;
|
|
||||||
line-height: 60px;
|
|
||||||
outline: 0 none;
|
|
||||||
border: none;
|
|
||||||
width: calc(100% - 60px);
|
|
||||||
color: var(--chat-bubble-message);
|
|
||||||
text-indent: 10px;
|
|
||||||
font-size: 12pt;
|
|
||||||
padding: 0;
|
|
||||||
background: var(--main-color3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-input button {
|
|
||||||
float: right;
|
|
||||||
outline: 0 none;
|
|
||||||
border: none;
|
|
||||||
background: var(--main-color3);
|
|
||||||
height: 40px;
|
|
||||||
width: 40px;
|
|
||||||
border-radius: 50%;
|
|
||||||
padding: 2px 0 0 0;
|
|
||||||
margin: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-input input[good] + button {
|
|
||||||
box-shadow:
|
|
||||||
0 0 2px rgba(0, 0, 0, 0.12),
|
|
||||||
0 2px 4px rgba(0, 0, 0, 0.24);
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-input input[good] + button:hover {
|
|
||||||
box-shadow:
|
|
||||||
0 8px 17px 0 rgba(0, 0, 0, 0.2),
|
|
||||||
0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
|
||||||
/* filter: brightness(150%); */
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-input input[good] + button path {
|
|
||||||
fill: var(--chat-bubble-message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.msg-container {
|
.msg-container {
|
||||||
|
|
@ -208,7 +94,8 @@ h1 {
|
||||||
padding: 10px 0px 0px 0px;
|
padding: 10px 0px 0px 0px;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template: 1fr / 1fr;
|
grid-template: 1fr / 1fr;
|
||||||
align-self: start;
|
align-self: center;
|
||||||
|
width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.msg-container > * {
|
.msg-container > * {
|
||||||
|
|
@ -216,383 +103,72 @@ h1 {
|
||||||
grid-row: 1 / 1;
|
grid-row: 1 / 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.msg-container.sender {
|
.message-window {
|
||||||
place-items: self-start;
|
height: calc(100% - 50px);
|
||||||
}
|
overflow: hidden;
|
||||||
|
overflow-y: hidden;
|
||||||
.msg-container.user {
|
|
||||||
place-items: self-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.msg-box {
|
|
||||||
background: var(--chat-bubble);
|
|
||||||
color: white;
|
|
||||||
min-width: 100px;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 18px 5px 5px 5px;
|
|
||||||
box-shadow:
|
|
||||||
0 0 2px rgba(0, 0, 0, 0.12),
|
|
||||||
0 2px 4px rgba(0, 0, 0, 0.24);
|
|
||||||
width: fit-content;
|
|
||||||
position: relative;
|
|
||||||
align-self: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.msg-box.sender {
|
|
||||||
margin: 25px 25px 0px 35px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.msg-box.user {
|
|
||||||
text-align: left;
|
|
||||||
margin: 25px 35px 0px 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.msg-box-user-temp {
|
|
||||||
background: var(--chat-bubble-temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-img {
|
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
border-radius: 50%;
|
|
||||||
height: 50px;
|
|
||||||
width: 50px;
|
|
||||||
z-index: 5;
|
|
||||||
align-self: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.messages.user {
|
|
||||||
margin-right: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.msg {
|
|
||||||
font-size: 12pt;
|
|
||||||
color: var(--chat-bubble-message);
|
|
||||||
margin: 0 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.msg-temp {
|
|
||||||
color: var(--chat-bubble-message-temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
.timestamp {
|
|
||||||
color: var(--chat-bubble-header);
|
|
||||||
font-size: 10pt;
|
|
||||||
align-items: center;
|
|
||||||
font-family: 'xxii_avenmedium';
|
|
||||||
}
|
|
||||||
|
|
||||||
.timestamp-temp {
|
|
||||||
color: var(--chat-bubble-header-temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
.username {
|
|
||||||
background-color: var(--main-color4);
|
|
||||||
color: white;
|
|
||||||
position: relative;
|
|
||||||
border-radius: 5px;
|
|
||||||
z-index: 3;
|
|
||||||
align-self: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.username.sender {
|
|
||||||
padding: 0px 5px 5px 30px;
|
|
||||||
margin: 20px 5px 5px 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.username.user {
|
|
||||||
padding: 0px 30px 5px 5px;
|
|
||||||
margin: 20px 30px 5px 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.username-temp {
|
|
||||||
color: var(--chat-bubble-header-temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
.post-time {
|
|
||||||
font-size: 8pt;
|
|
||||||
color: white;
|
|
||||||
display: inline-block;
|
|
||||||
background-color: var(--main-color4);
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
border-radius: 5px;
|
|
||||||
align-self: start;
|
|
||||||
}
|
|
||||||
.post-time.sender {
|
|
||||||
padding: 5px 5px 5px 15px;
|
|
||||||
margin: 0px 0px 0px 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.post-time.user {
|
|
||||||
padding: 5px 15px 5px 5px;
|
|
||||||
margin: 0px 50px 0px 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mmg {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 80%;
|
||||||
|
margin: auto;
|
||||||
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.img {
|
.message-window::before {
|
||||||
height: 100%;
|
content: '';
|
||||||
|
flex: 1 0 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.OptionPanel {
|
||||||
|
flex: 3;
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-radius: 50%;
|
height: calc(100% - 25px);
|
||||||
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-circle {
|
.OptionPanel.show {
|
||||||
width: 20px;
|
|
||||||
border-radius: 50%;
|
|
||||||
z-index: 6;
|
|
||||||
position: relative;
|
|
||||||
align-self: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-circle.sender {
|
|
||||||
margin-left: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-circle.user {
|
|
||||||
margin-right: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-select {
|
|
||||||
font-size: 0.9rem;
|
|
||||||
height: 40px;
|
|
||||||
border-radius: 20px;
|
|
||||||
background-color: var(--main-color3);
|
|
||||||
color: var(--main-color2);
|
|
||||||
align-items: center;
|
|
||||||
border: 0px;
|
|
||||||
padding-left: 10px;
|
|
||||||
width: 300px;
|
|
||||||
font-size: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
padding-right: 25px;
|
|
||||||
outline: none;
|
|
||||||
-webkit-appearance: none;
|
|
||||||
-moz-appearance: none;
|
|
||||||
background-image: url("data:image/svg+xml;utf8,<svg fill='white' height='34' viewBox='0 0 24 24' width='32' xmlns='http://www.w3.org/2000/svg'><path d='M7 10l5 5 5-5z'/><path d='M0 0h24v24H0z' fill='none'/></svg>");
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position-x: 100%;
|
|
||||||
background-position-y: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-select {
|
|
||||||
width: auto;
|
|
||||||
height: 24px;
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
background-color: transparent;
|
|
||||||
color: white;
|
|
||||||
-webkit-appearance: none;
|
|
||||||
-moz-appearance: none;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-image {
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-select option {
|
|
||||||
margin: 40px;
|
|
||||||
background: rgba(0, 0, 0, 0.3);
|
|
||||||
color: #fff;
|
|
||||||
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
|
|
||||||
background-color: var(--top-bar);
|
|
||||||
}
|
|
||||||
|
|
||||||
.AdvancedMenu {
|
|
||||||
border: 1px var(--main-color2) solid;
|
|
||||||
margin-top: 10px;
|
|
||||||
min-width: 555px;
|
|
||||||
border-radius: 5px;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.legendStyle {
|
|
||||||
margin-left: 1em;
|
|
||||||
padding: 0.2em 0.8em;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.AdvancedMenuRow {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: left;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.AdvancedMenuLabel {
|
|
||||||
font-size: 10pt;
|
|
||||||
padding-right: 5px;
|
|
||||||
margin-left: 10px;
|
|
||||||
width: 125px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.AdvancedMenuLabel2 {
|
|
||||||
font-size: 10pt;
|
|
||||||
padding-right: 5px;
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.AdvancedMenuLabel3 {
|
|
||||||
font-size: 12pt;
|
|
||||||
padding-right: 5px;
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#SaveAdvancedSettingsButton {
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toggle {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
width: 60px;
|
|
||||||
height: 40px;
|
|
||||||
background-color: var(--main-color3);
|
|
||||||
border-radius: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* After slide changes */
|
|
||||||
|
|
||||||
.toggle:after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: var(--main-color2);
|
|
||||||
left: 5px;
|
|
||||||
top: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Checkbox checked effect */
|
|
||||||
|
|
||||||
.checkbox:checked + .toggle::after {
|
|
||||||
left: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Checkbox checked toggle label bg color */
|
|
||||||
|
|
||||||
.checkbox:checked + .toggle {
|
|
||||||
background-color: var(--main-color1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Checkbox vanished */
|
|
||||||
|
|
||||||
.checkbox {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Small toggle */
|
|
||||||
|
|
||||||
/* toggle in label designing */
|
|
||||||
|
|
||||||
.toggle-small {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
width: 30px;
|
|
||||||
height: 20px;
|
|
||||||
background-color: var(--main-color3);
|
|
||||||
border-radius: 10px;
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* After slide changes */
|
|
||||||
|
|
||||||
.toggle-small:after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
width: 15px;
|
|
||||||
height: 15px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: white;
|
|
||||||
left: 2px;
|
|
||||||
top: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Checkbox checked effect */
|
|
||||||
|
|
||||||
.checkbox:checked + .toggle-small::after {
|
|
||||||
left: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Checkbox checked toggle label bg color */
|
|
||||||
|
|
||||||
.checkbox:checked + .toggle-small {
|
|
||||||
background-color: var(--main-color1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.emotes {
|
|
||||||
position: relative;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark {
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
top: -400px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.emotes:hover .dark {
|
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fi {
|
.message {
|
||||||
|
text-align: left;
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
min-width: fit-content;
|
||||||
|
hyphens: auto;
|
||||||
|
/* bottom: 0; */
|
||||||
|
/* right: 0; */
|
||||||
|
/* float: right; */
|
||||||
|
overflow-wrap: break-word;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 5;
|
border: 2px solid #ff80e1;
|
||||||
border-radius: 50%;
|
/* box-shadow: 0 2px 10px rgba(255, 128, 225, 0.5); */
|
||||||
|
background: linear-gradient(45deg, rgb(15, 12, 41, 0.7), rgb(48, 43, 99, 0.7));
|
||||||
|
/* background: linear-gradient(45deg, rgba(72, 0, 154, 0.7), rgba(138, 43, 226, 0.7)); */
|
||||||
|
color: white;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 20px;
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.translation-header {
|
.arrow {
|
||||||
background-color: var(--main-color4);
|
content: '';
|
||||||
border-radius: 5px;
|
border: 2px solid #ff80e1;
|
||||||
width: fit-content;
|
position: absolute;
|
||||||
padding: 5px;
|
left: 50%;
|
||||||
margin: 10px 0px 5px -5px;
|
transform: translateX(-50%) rotate(180deg);
|
||||||
position: relative;
|
border-width: 10px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: transparent transparent rgb(255, 128, 225, 0.7) transparent;
|
||||||
|
color: #ff80e1;
|
||||||
|
bottom: -10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.translation-message {
|
.sender {
|
||||||
position: relative;
|
color: #ff80e1;
|
||||||
margin: 20px 0px 0px 0px;
|
font-size: 14pt;
|
||||||
}
|
|
||||||
|
|
||||||
.translation-message.user {
|
|
||||||
margin: -20px 0px 0px 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.translation-icon {
|
|
||||||
position: relative;
|
|
||||||
padding: 0px 0px 0px 0px;
|
|
||||||
margin: -45px 0px 0px -40px;
|
|
||||||
top: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.language-icon {
|
|
||||||
position: relative;
|
|
||||||
top: 45px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flag-icon {
|
|
||||||
width: 20px !important;
|
|
||||||
height: 20px !important;
|
|
||||||
left: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flag-icon.user {
|
|
||||||
left: -18px;
|
|
||||||
top: -15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-flag {
|
|
||||||
left: unset;
|
|
||||||
right: 18px;
|
|
||||||
top: -65px;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,87 +3,123 @@
|
||||||
// Connect to the Socket.IO server
|
// Connect to the Socket.IO server
|
||||||
const socket = io();
|
const socket = io();
|
||||||
|
|
||||||
const twitchTemplate = `
|
|
||||||
<img class="user-img" src="" />
|
|
||||||
<img class="status-circle sender" src="./images/twitch-icon.png" tip="twitch" />
|
|
||||||
<span class="post-time sender"></span>
|
|
||||||
<span class="username sender"></span>
|
|
||||||
<div class="msg-box sender"></div>
|
|
||||||
`.trim();
|
|
||||||
|
|
||||||
const emojiPicker = document.body.querySelector('emoji-picker');
|
|
||||||
|
|
||||||
const replaceChatMessageWithCustomEmojis = message =>
|
|
||||||
new Promise(resolve => {
|
|
||||||
const words = message.split(' ');
|
|
||||||
words.forEach(async word => {
|
|
||||||
if (word !== '') {
|
|
||||||
await emojiPicker.database.getEmojiByUnicodeOrName(word).then(data => {
|
|
||||||
if (data && data.name === word) {
|
|
||||||
const url = `<img src="${data.url}">`;
|
|
||||||
message = message.replace(word, url);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
resolve(message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Emit a message to the server
|
// Emit a message to the server
|
||||||
socket.emit('message', 'Hello, Server!');
|
socket.emit('message', 'Hello, Server!');
|
||||||
|
|
||||||
async function displayChatMessage(message) {
|
function getPostTime() {
|
||||||
const article = document.createElement('article');
|
const d = new Date();
|
||||||
article.className = 'msg-container sender';
|
document.body.querySelectorAll('.container').innerHTML = d.getHours();
|
||||||
article.setAttribute('id', message.messageId);
|
const hours = d.getHours();
|
||||||
|
const minutes = (d.getMinutes() < 10 ? '0' : '') + d.getMinutes();
|
||||||
article.innerHTML = twitchTemplate;
|
const time = `${hours}:${minutes}`;
|
||||||
const userImg = article.querySelector('.user-img');
|
return time;
|
||||||
if (userImg) {
|
|
||||||
userImg.src = message.image;
|
|
||||||
}
|
|
||||||
|
|
||||||
const usernameHtml = article.querySelector('.username');
|
|
||||||
if (usernameHtml) {
|
|
||||||
usernameHtml.innerText = message.username;
|
|
||||||
}
|
|
||||||
|
|
||||||
const postTime = article.querySelector('.post-time');
|
|
||||||
|
|
||||||
if (postTime) {
|
|
||||||
postTime.innerText = message.postTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
article.appendChild(postTime);
|
|
||||||
|
|
||||||
const formattedMessage = article.querySelector('.msg-box');
|
|
||||||
formattedMessage.innerHTML = message.message;
|
|
||||||
// if (formattedMessage) {
|
|
||||||
// messageObject.forEach(entry => {
|
|
||||||
// if (entry.text) {
|
|
||||||
// formattedMessage.innerHTML += entry.text;
|
|
||||||
// } else {
|
|
||||||
// formattedMessage.innerHTML += entry.html;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
await replaceChatMessageWithCustomEmojis(formattedMessage.innerHTML).then(data => {
|
|
||||||
formattedMessage.innerHTML = data;
|
|
||||||
showChatMessage(article);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function showChatMessage(article) {
|
function showChatMessage(article) {
|
||||||
document.getElementById('chatBox').appendChild(article);
|
const main = document.querySelector('#chatBox');
|
||||||
|
main.appendChild(article);
|
||||||
|
main.scrollTop = main.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
const messages = document.body.querySelectorAll('.msg-container');
|
let textStreamContainer;
|
||||||
|
let x;
|
||||||
|
// const totalDuration = 5000; // Total duration in milliseconds
|
||||||
|
// const charactersPerSecond = 20; // Adjust the number of characters to display per second
|
||||||
|
|
||||||
const lastMessage = messages[messages.length - 1];
|
// const streamingSpeed = totalDuration / (textToStream.length / charactersPerSecond);
|
||||||
lastMessage.scrollIntoView({ block: 'end', behavior: 'smooth' });
|
|
||||||
|
let currentIndex = 0;
|
||||||
|
let messageStream = '';
|
||||||
|
const tempMessageObject = '';
|
||||||
|
const fullMessageLength = 0;
|
||||||
|
|
||||||
|
function getFullMessageLength(text) {
|
||||||
|
let fullMessageLength = 0;
|
||||||
|
text.forEach(element => {
|
||||||
|
if (element.text) {
|
||||||
|
fullMessageLength += element.text.length;
|
||||||
|
}
|
||||||
|
// element.html;
|
||||||
|
fullMessageLength += 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
return fullMessageLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
function streamText() {
|
||||||
|
// if (currentIndex < fullMessageLength) {
|
||||||
|
|
||||||
|
// textStreamContainer.innerHTML += messageStream.filtered.charAt(currentIndex);
|
||||||
|
// currentIndex++;
|
||||||
|
// setTimeout(streamText, 50);
|
||||||
|
// }
|
||||||
|
if (currentIndex < messageStream.length) {
|
||||||
|
textStreamContainer.innerHTML += messageStream.charAt(currentIndex);
|
||||||
|
currentIndex++;
|
||||||
|
setTimeout(streamText, 50);
|
||||||
|
} else {
|
||||||
|
currentIndex = 0;
|
||||||
|
x.classList.add('fade-outx');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayTwitchMessage(message) {
|
||||||
|
if (!message.filteredMessage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const root = document.querySelector(':root');
|
||||||
|
root.style.setProperty('--variable', '5s');
|
||||||
|
|
||||||
|
const article = document.createElement('article');
|
||||||
|
x = article;
|
||||||
|
|
||||||
|
article.className = 'msg-container';
|
||||||
|
|
||||||
|
const placeMessage = `
|
||||||
|
<div class="thomas bounce-in">
|
||||||
|
<div class="message"></div>
|
||||||
|
<div class="sender"></div>
|
||||||
|
<div class="speechbubble"></div>
|
||||||
|
<div class="arrow"></div>
|
||||||
|
</div>
|
||||||
|
`.trim();
|
||||||
|
|
||||||
|
article.innerHTML = placeMessage;
|
||||||
|
const msg = article.querySelector('.message');
|
||||||
|
|
||||||
|
msg.innerHTML = `<div class="sender">${message.username}</div>`; // \n${message}`;
|
||||||
|
|
||||||
|
msg.style.fontSize = '12pt';
|
||||||
|
|
||||||
|
showChatMessage(article);
|
||||||
|
|
||||||
|
const elements = document.getElementsByClassName('msg-container');
|
||||||
|
if (elements.length > 1) {
|
||||||
|
elements[0].remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
article.addEventListener('animationend', e => {
|
||||||
|
if (e.animationName === 'fade-outx') {
|
||||||
|
article.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (elements.length > 1) {
|
||||||
|
elements[0].classList.add('fade-outxx');
|
||||||
|
elements[0].addEventListener('animationend', e => {
|
||||||
|
if (e.animationName === 'fade-outxx') {
|
||||||
|
elements[0].remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// fullMessageLength = getFullMessageLength(messageObject);
|
||||||
|
messageStream = message.filteredMessage;
|
||||||
|
textStreamContainer = document.querySelector('.message');
|
||||||
|
streamText();
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Receive a message from the server
|
// // Receive a message from the server
|
||||||
socket.on('chat-in', message => {
|
socket.on('message', message => {
|
||||||
displayChatMessage(message);
|
displayTwitchMessage(message);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
{
|
|
||||||
"name": "chat",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "",
|
|
||||||
"main": "index.js",
|
|
||||||
"directories": {
|
|
||||||
"test": "test"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
|
||||||
},
|
|
||||||
"author": "",
|
|
||||||
"license": "ISC"
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
|
@ -1,10 +0,0 @@
|
||||||
@font-face {
|
|
||||||
font-family: 'FRAMDCN';
|
|
||||||
src: local('FRAMDCN'), url('./FRAMDCN.woff') format('woff');
|
|
||||||
}
|
|
||||||
/* use this class to attach this font to any element i.e. <p class="fontsforweb_fontid_1381">Text with this font applied</p> */
|
|
||||||
.fontsforweb_fontid_1381 {
|
|
||||||
font-family: 'FRAMDCN' !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Font downloaded from FontsForWeb.com */
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html class="no-js">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<title> web font from FontsForWeb.com</title>
|
|
||||||
<meta name="description" content="">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<link rel="stylesheet" href="font.css">
|
|
||||||
<style type="text/css">
|
|
||||||
/* when @font-face is defined(it is in font.css) you can add the font to any rule by using font-family */
|
|
||||||
h1 {
|
|
||||||
font-family: 'FRAMDCN';
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Thank you for using FontsForWeb.com</h1>
|
|
||||||
<p class="fontsforweb_fontid_1381">Look in the source of this file to see how to embed this font on your website</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
Original download page
|
|
||||||
http://ttfonts.net/font/606_FranklinGothicMediumCond.htm
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Chat</title>
|
|
||||||
<script
|
|
||||||
src="https://cdn.socket.io/4.6.0/socket.io.min.js"
|
|
||||||
integrity="sha384-c79GN5VsunZvi+Q/WObgk2in0CbZsHnjEqvFxC5DxHn9lTfNce2WW6h2pH6u/kF+"
|
|
||||||
crossorigin="anonymous"
|
|
||||||
></script>
|
|
||||||
<link rel="stylesheet" href="./fonts/FRAMCDN/font.css" />
|
|
||||||
<link href="main.css" rel="stylesheet" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!-- #region Main chat box-->
|
|
||||||
<div class="OptionPanel show" id="Chat">
|
|
||||||
<div id="chatBox" class="message-window">
|
|
||||||
<div class="texts"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script src="main.js"></script>
|
|
||||||
<video id="camera" autoplay></video>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,174 +0,0 @@
|
||||||
body {
|
|
||||||
background-color: transparent;
|
|
||||||
font-family: 'FRAMDCN';
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--variable: 2s;
|
|
||||||
--buttonBackground: #bf2c2c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.thomas {
|
|
||||||
position: relative;
|
|
||||||
float: center;
|
|
||||||
/* display: inline-block; */
|
|
||||||
}
|
|
||||||
|
|
||||||
.speechbubble {
|
|
||||||
display: block;
|
|
||||||
bottom: 0;
|
|
||||||
position: absolute;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fade-outx {
|
|
||||||
animation: fade-outx var(--variable) linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fade-outx {
|
|
||||||
from {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
to {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.fade-outxx {
|
|
||||||
animation: fade-outxx var(--variable) linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fade-outxx {
|
|
||||||
from {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
to {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bounce-in {
|
|
||||||
animation: bounce-in 1s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes bounce-in {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(1.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
70% {
|
|
||||||
transform: scale(0.9);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bounce-inx {
|
|
||||||
animation: bounce-inx 1s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes bounce-inx {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.msg-container {
|
|
||||||
direction: ltr;
|
|
||||||
position: static;
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px 0px 0px 0px;
|
|
||||||
display: grid;
|
|
||||||
grid-template: 1fr / 1fr;
|
|
||||||
align-self: center;
|
|
||||||
width: fit-content;
|
|
||||||
}
|
|
||||||
|
|
||||||
.msg-container > * {
|
|
||||||
grid-column: 1 / 1;
|
|
||||||
grid-row: 1 / 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-window {
|
|
||||||
height: calc(100% - 50px);
|
|
||||||
overflow: hidden;
|
|
||||||
overflow-y: hidden;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 80%;
|
|
||||||
margin: auto;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-window::before {
|
|
||||||
content: '';
|
|
||||||
flex: 1 0 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.OptionPanel {
|
|
||||||
flex: 3;
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
top: 10px;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: calc(100% - 25px);
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.OptionPanel.show {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message {
|
|
||||||
text-align: left;
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
min-width: fit-content;
|
|
||||||
hyphens: auto;
|
|
||||||
/* bottom: 0; */
|
|
||||||
/* right: 0; */
|
|
||||||
/* float: right; */
|
|
||||||
overflow-wrap: break-word;
|
|
||||||
position: relative;
|
|
||||||
border: 2px solid #ff80e1;
|
|
||||||
/* box-shadow: 0 2px 10px rgba(255, 128, 225, 0.5); */
|
|
||||||
background: linear-gradient(45deg, rgb(15, 12, 41, 0.7), rgb(48, 43, 99, 0.7));
|
|
||||||
/* background: linear-gradient(45deg, rgba(72, 0, 154, 0.7), rgba(138, 43, 226, 0.7)); */
|
|
||||||
color: white;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 20px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrow {
|
|
||||||
content: '';
|
|
||||||
border: 2px solid #ff80e1;
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%) rotate(180deg);
|
|
||||||
border-width: 10px;
|
|
||||||
border-style: solid;
|
|
||||||
border-color: transparent transparent rgb(255, 128, 225, 0.7) transparent;
|
|
||||||
color: #ff80e1;
|
|
||||||
bottom: -10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sender {
|
|
||||||
color: #ff80e1;
|
|
||||||
font-size: 14pt;
|
|
||||||
}
|
|
||||||
|
|
@ -1,125 +0,0 @@
|
||||||
/* global io */
|
|
||||||
|
|
||||||
// Connect to the Socket.IO server
|
|
||||||
const socket = io();
|
|
||||||
|
|
||||||
// Emit a message to the server
|
|
||||||
socket.emit('message', 'Hello, Server!');
|
|
||||||
|
|
||||||
function getPostTime() {
|
|
||||||
const d = new Date();
|
|
||||||
document.body.querySelectorAll('.container').innerHTML = d.getHours();
|
|
||||||
const hours = d.getHours();
|
|
||||||
const minutes = (d.getMinutes() < 10 ? '0' : '') + d.getMinutes();
|
|
||||||
const time = `${hours}:${minutes}`;
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
function showChatMessage(article) {
|
|
||||||
const main = document.querySelector('#chatBox');
|
|
||||||
main.appendChild(article);
|
|
||||||
main.scrollTop = main.scrollHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
let textStreamContainer;
|
|
||||||
let x;
|
|
||||||
// const totalDuration = 5000; // Total duration in milliseconds
|
|
||||||
// const charactersPerSecond = 20; // Adjust the number of characters to display per second
|
|
||||||
|
|
||||||
// const streamingSpeed = totalDuration / (textToStream.length / charactersPerSecond);
|
|
||||||
|
|
||||||
let currentIndex = 0;
|
|
||||||
let messageStream = '';
|
|
||||||
const tempMessageObject = '';
|
|
||||||
const fullMessageLength = 0;
|
|
||||||
|
|
||||||
function getFullMessageLength(text) {
|
|
||||||
let fullMessageLength = 0;
|
|
||||||
text.forEach(element => {
|
|
||||||
if (element.text) {
|
|
||||||
fullMessageLength += element.text.length;
|
|
||||||
}
|
|
||||||
// element.html;
|
|
||||||
fullMessageLength += 1;
|
|
||||||
});
|
|
||||||
|
|
||||||
return fullMessageLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
function streamText() {
|
|
||||||
// if (currentIndex < fullMessageLength) {
|
|
||||||
|
|
||||||
// textStreamContainer.innerHTML += messageStream.filtered.charAt(currentIndex);
|
|
||||||
// currentIndex++;
|
|
||||||
// setTimeout(streamText, 50);
|
|
||||||
// }
|
|
||||||
if (currentIndex < messageStream.length) {
|
|
||||||
textStreamContainer.innerHTML += messageStream.charAt(currentIndex);
|
|
||||||
currentIndex++;
|
|
||||||
setTimeout(streamText, 50);
|
|
||||||
} else {
|
|
||||||
currentIndex = 0;
|
|
||||||
x.classList.add('fade-outx');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function displayTwitchMessage(message) {
|
|
||||||
if (!message.filteredMessage) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const root = document.querySelector(':root');
|
|
||||||
root.style.setProperty('--variable', '5s');
|
|
||||||
|
|
||||||
const article = document.createElement('article');
|
|
||||||
x = article;
|
|
||||||
|
|
||||||
article.className = 'msg-container';
|
|
||||||
|
|
||||||
const placeMessage = `
|
|
||||||
<div class="thomas bounce-in">
|
|
||||||
<div class="message"></div>
|
|
||||||
<div class="sender"></div>
|
|
||||||
<div class="speechbubble"></div>
|
|
||||||
<div class="arrow"></div>
|
|
||||||
</div>
|
|
||||||
`.trim();
|
|
||||||
|
|
||||||
article.innerHTML = placeMessage;
|
|
||||||
const msg = article.querySelector('.message');
|
|
||||||
|
|
||||||
msg.innerHTML = `<div class="sender">${message.username}</div>`; // \n${message}`;
|
|
||||||
|
|
||||||
msg.style.fontSize = '12pt';
|
|
||||||
|
|
||||||
showChatMessage(article);
|
|
||||||
|
|
||||||
const elements = document.getElementsByClassName('msg-container');
|
|
||||||
if (elements.length > 1) {
|
|
||||||
elements[0].remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
article.addEventListener('animationend', e => {
|
|
||||||
if (e.animationName === 'fade-outx') {
|
|
||||||
article.remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (elements.length > 1) {
|
|
||||||
elements[0].classList.add('fade-outxx');
|
|
||||||
elements[0].addEventListener('animationend', e => {
|
|
||||||
if (e.animationName === 'fade-outxx') {
|
|
||||||
elements[0].remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// fullMessageLength = getFullMessageLength(messageObject);
|
|
||||||
messageStream = message.filteredMessage;
|
|
||||||
textStreamContainer = document.querySelector('.message');
|
|
||||||
streamText();
|
|
||||||
}
|
|
||||||
|
|
||||||
// // Receive a message from the server
|
|
||||||
socket.on('message', message => {
|
|
||||||
displayTwitchMessage(message);
|
|
||||||
});
|
|
||||||
|
|
@ -1,478 +0,0 @@
|
||||||
const { FaceLandmarker, HandLandmarker, PoseLandmarker, FilesetResolver, DrawingUtils } = require('@mediapipe/tasks-vision');
|
|
||||||
|
|
||||||
const videoBlendShapes = document.getElementById('video-blend-shapes');
|
|
||||||
|
|
||||||
const videoSelect = document.querySelector('select#videoSource');
|
|
||||||
|
|
||||||
const videoElement = document.getElementById('video');
|
|
||||||
const canvasElement = document.getElementsByClassName('output_canvas')[0];
|
|
||||||
const canvasCtx = canvasElement.getContext('2d');
|
|
||||||
|
|
||||||
let cameraRunning = false;
|
|
||||||
let cameraVisible = true;
|
|
||||||
let cameraFPS = 30;
|
|
||||||
let cameraWidth = 640;
|
|
||||||
let cameraHeight = 480;
|
|
||||||
|
|
||||||
let lastVideoTime = -1;
|
|
||||||
|
|
||||||
const drawingUtils = new DrawingUtils(canvasCtx);
|
|
||||||
|
|
||||||
getDevices().then(gotDevices);
|
|
||||||
|
|
||||||
let detections = [];
|
|
||||||
|
|
||||||
document.body.querySelector('#cameraVisible').addEventListener('click', async () => {
|
|
||||||
cameraVisible = !cameraVisible;
|
|
||||||
if (cameraVisible) {
|
|
||||||
document.body.querySelector('#cameraVisible').innerHTML = 'Hide Camera';
|
|
||||||
document.body.querySelector('#video').style.display = '';
|
|
||||||
} else {
|
|
||||||
document.body.querySelector('#cameraVisible').innerHTML = 'Show Camera';
|
|
||||||
document.body.querySelector('#video').style.display = 'none';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#cameraRunning').addEventListener('click', async () => {
|
|
||||||
cameraRunning = !cameraRunning;
|
|
||||||
if (cameraRunning) {
|
|
||||||
getStream();
|
|
||||||
document.body.querySelector('#cameraRunning').innerHTML = 'Stop Camera';
|
|
||||||
} else {
|
|
||||||
if (window.stream) {
|
|
||||||
window.stream.getTracks().forEach(track => {
|
|
||||||
track.stop();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
document.body.querySelector('#cameraRunning').innerHTML = 'Start Camera';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#cameraResolution').addEventListener('change', async e => {
|
|
||||||
cameraWidth = e.target.options[e.target.selectedIndex].getAttribute('width');
|
|
||||||
cameraHeight = e.target.options[e.target.selectedIndex].getAttribute('height');
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#cameraFPS').addEventListener('change', async () => {
|
|
||||||
cameraFPS = document.body.querySelector('#cameraFPS').value;
|
|
||||||
});
|
|
||||||
|
|
||||||
// -------------- Face Detection --------------
|
|
||||||
|
|
||||||
let faceDetectionDelegate = 'GPU';
|
|
||||||
let minFaceDetectionConfidence = 0.5;
|
|
||||||
document.getElementById('minFaceDetectionConfidenceValue').innerHTML = minFaceDetectionConfidence;
|
|
||||||
let minFacePresenceConfidence = 0.5;
|
|
||||||
document.getElementById('minFacePresenceConfidenceValue').innerHTML = minFacePresenceConfidence;
|
|
||||||
let minFaceTrackingConfidence = 0.5;
|
|
||||||
document.getElementById('minFaceTrackingConfidenceValue').innerHTML = minFaceTrackingConfidence;
|
|
||||||
let faceTrackingEnabled = false;
|
|
||||||
let hideFace = false;
|
|
||||||
let faceLandmarker;
|
|
||||||
let resultsFace;
|
|
||||||
|
|
||||||
document.body.querySelector('#face').addEventListener('click', async () => {
|
|
||||||
faceTrackingEnabled = !faceTrackingEnabled;
|
|
||||||
if (faceTrackingEnabled) {
|
|
||||||
createFaceLandmarker();
|
|
||||||
document.body.querySelector('#face').innerHTML = 'Disable face detection';
|
|
||||||
} else {
|
|
||||||
faceLandmarker = null;
|
|
||||||
document.body.querySelector('#face').innerHTML = 'Enable face detection';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#hideFace').addEventListener('click', async () => {
|
|
||||||
hideFace = !hideFace;
|
|
||||||
if (hideFace) {
|
|
||||||
document.body.querySelector('#hideFace').innerHTML = 'Show face detection';
|
|
||||||
} else {
|
|
||||||
document.body.querySelector('#hideFace').innerHTML = 'Hide face detection';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#faceDetectionDelegate').addEventListener('change', async () => {
|
|
||||||
faceDetectionDelegate = document.getElementById('faceDetectionDelegate').value;
|
|
||||||
if (faceTrackingEnabled) {
|
|
||||||
createFaceLandmarker();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#minFaceDetectionConfidence').addEventListener('change', async () => {
|
|
||||||
minFaceDetectionConfidence = parseInt(document.getElementById('minFaceDetectionConfidence').value);
|
|
||||||
document.getElementById('minFaceDetectionConfidenceValue').innerHTML = minFaceDetectionConfidence;
|
|
||||||
if (faceTrackingEnabled) {
|
|
||||||
createFaceLandmarker();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#minFacePresenceConfidence').addEventListener('change', async () => {
|
|
||||||
minFacePresenceConfidence = parseInt(document.getElementById('minFacePresenceConfidence').value);
|
|
||||||
document.getElementById('minFacePresenceConfidenceValue').innerHTML = minFacePresenceConfidence;
|
|
||||||
if (faceTrackingEnabled) {
|
|
||||||
createFaceLandmarker();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#minFaceTrackingConfidence').addEventListener('change', async () => {
|
|
||||||
minFaceTrackingConfidence = parseInt(document.getElementById('minFaceTrackingConfidence').value);
|
|
||||||
document.getElementById('minFaceTrackingConfidenceValue').innerHTML = minFaceTrackingConfidence;
|
|
||||||
if (faceTrackingEnabled) {
|
|
||||||
createFaceLandmarker();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// -------------- Hand Detection --------------
|
|
||||||
|
|
||||||
let handDetectionDelegate = 'GPU';
|
|
||||||
let minHandDetectionConfidence = 0.5;
|
|
||||||
document.getElementById('minHandDetectionConfidenceValue').innerHTML = minHandDetectionConfidence;
|
|
||||||
let minHandPresenceConfidence = 0.5;
|
|
||||||
document.getElementById('minHandPresenceConfidenceValue').innerHTML = minHandPresenceConfidence;
|
|
||||||
let minHandTrackingConfidence = 0.5;
|
|
||||||
document.getElementById('minHandTrackingConfidenceValue').innerHTML = minHandTrackingConfidence;
|
|
||||||
let handTrackingEnabled = false;
|
|
||||||
let hideHand = false;
|
|
||||||
let handLandmarker;
|
|
||||||
let resultsHands;
|
|
||||||
|
|
||||||
document.body.querySelector('#hand').addEventListener('click', async () => {
|
|
||||||
handTrackingEnabled = !handTrackingEnabled;
|
|
||||||
if (handTrackingEnabled) {
|
|
||||||
createHandLandmarker();
|
|
||||||
document.body.querySelector('#hand').innerHTML = 'Disable hand detection';
|
|
||||||
} else {
|
|
||||||
handLandmarker = null;
|
|
||||||
document.body.querySelector('#hand').innerHTML = 'Enable hand detection';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#hideHand').addEventListener('click', async () => {
|
|
||||||
hideHand = !hideHand;
|
|
||||||
if (hideFace) {
|
|
||||||
document.body.querySelector('#hideHand').innerHTML = 'Show hand detection';
|
|
||||||
} else {
|
|
||||||
document.body.querySelector('#hideHand').innerHTML = 'Hide hand detection';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#handDetectionDelegate').addEventListener('change', async () => {
|
|
||||||
handDetectionDelegate = document.getElementById('handDetectionDelegate').value;
|
|
||||||
if (handTrackingEnabled) {
|
|
||||||
createHandLandmarker();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#minHandDetectionConfidence').addEventListener('change', async () => {
|
|
||||||
minHandDetectionConfidence = parseInt(document.getElementById('minHandDetectionConfidence').value);
|
|
||||||
document.getElementById('minHandDetectionConfidenceValue').innerHTML = minHandDetectionConfidence;
|
|
||||||
if (handTrackingEnabled) {
|
|
||||||
createHandLandmarker();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#minHandPresenceConfidence').addEventListener('change', async () => {
|
|
||||||
minHandPresenceConfidence = parseInt(document.getElementById('minHandPresenceConfidence').value);
|
|
||||||
document.getElementById('minHandPresenceConfidenceValue').innerHTML = minHandPresenceConfidence;
|
|
||||||
if (handTrackingEnabled) {
|
|
||||||
createHandLandmarker();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#minHandTrackingConfidence').addEventListener('change', async () => {
|
|
||||||
minHandTrackingConfidence = parseInt(document.getElementById('minHandTrackingConfidence').value);
|
|
||||||
document.getElementById('minHandTrackingConfidenceValue').innerHTML = minHandTrackingConfidence;
|
|
||||||
if (handTrackingEnabled) {
|
|
||||||
createHandLandmarker();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// -------------- Pose Detection --------------
|
|
||||||
|
|
||||||
let poseDetectionDelegate = 'GPU';
|
|
||||||
let minPoseDetectionConfidence = 0.5;
|
|
||||||
document.getElementById('minPoseDetectionConfidenceValue').innerHTML = minPoseDetectionConfidence;
|
|
||||||
let minPosePresenceConfidence = 0.5;
|
|
||||||
document.getElementById('minPosePresenceConfidenceValue').innerHTML = minPosePresenceConfidence;
|
|
||||||
let minPoseTrackingConfidence = 0.5;
|
|
||||||
document.getElementById('minPoseTrackingConfidenceValue').innerHTML = minPoseTrackingConfidence;
|
|
||||||
let poseTrackingEnabled = false;
|
|
||||||
let hidepose = false;
|
|
||||||
let poseLandmarker;
|
|
||||||
let resultsPose;
|
|
||||||
|
|
||||||
document.body.querySelector('#pose').addEventListener('click', async () => {
|
|
||||||
poseTrackingEnabled = !poseTrackingEnabled;
|
|
||||||
if (poseTrackingEnabled) {
|
|
||||||
createPoseLandmarker();
|
|
||||||
document.body.querySelector('#pose').innerHTML = 'Disable pose detection';
|
|
||||||
} else {
|
|
||||||
poseLandmarker = null;
|
|
||||||
document.body.querySelector('#pose').innerHTML = 'Enable pose detection';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#hidePose').addEventListener('click', async () => {
|
|
||||||
hidepose = !hidepose;
|
|
||||||
if (hideFace) {
|
|
||||||
document.body.querySelector('#hidePose').innerHTML = 'Show pose detection';
|
|
||||||
} else {
|
|
||||||
document.body.querySelector('#hidePose').innerHTML = 'Hide pose detection';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#poseDetectionDelegate').addEventListener('change', async () => {
|
|
||||||
poseDetectionDelegate = document.getElementById('faceDetectionDelegate').value;
|
|
||||||
if (poseTrackingEnabled) {
|
|
||||||
createPoseLandmarker();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#minPoseDetectionConfidence').addEventListener('change', async () => {
|
|
||||||
minPoseDetectionConfidence = parseInt(document.getElementById('minPoseDetectionConfidence').value);
|
|
||||||
document.getElementById('minPoseDetectionConfidenceValue').innerHTML = minPoseDetectionConfidence;
|
|
||||||
if (poseTrackingEnabled) {
|
|
||||||
createPoseLandmarker();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#minPosePresenceConfidence').addEventListener('change', async () => {
|
|
||||||
minPosePresenceConfidence = parseInt(document.getElementById('minPosePresenceConfidence').value);
|
|
||||||
document.getElementById('minPosePresenceConfidenceValue').innerHTML = minPosePresenceConfidence;
|
|
||||||
if (poseTrackingEnabled) {
|
|
||||||
createPoseLandmarker();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.querySelector('#minPoseTrackingConfidence').addEventListener('change', async () => {
|
|
||||||
minPoseTrackingConfidence = parseInt(document.getElementById('minPoseTrackingConfidence').value);
|
|
||||||
document.getElementById('minPoseTrackingConfidenceValue').innerHTML = minPoseTrackingConfidence;
|
|
||||||
if (poseTrackingEnabled) {
|
|
||||||
createPoseLandmarker();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// -------------- Camera --------------
|
|
||||||
|
|
||||||
function getDevices() {
|
|
||||||
// AFAICT in Safari this only gets default devices until gUM is called :/
|
|
||||||
return navigator.mediaDevices.enumerateDevices();
|
|
||||||
}
|
|
||||||
|
|
||||||
function gotDevices(deviceInfos) {
|
|
||||||
window.deviceInfos = deviceInfos; // make available to console
|
|
||||||
for (const deviceInfo of deviceInfos) {
|
|
||||||
const option = document.createElement('option');
|
|
||||||
option.value = deviceInfo.deviceId;
|
|
||||||
if (deviceInfo.kind === 'videoinput') {
|
|
||||||
option.text = deviceInfo.label || `Camera ${videoSelect.length + 1}`;
|
|
||||||
videoSelect.appendChild(option);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getStream() {
|
|
||||||
if (window.stream) {
|
|
||||||
window.stream.getTracks().forEach(track => {
|
|
||||||
track.stop();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const videoSource = videoSelect.value;
|
|
||||||
const constraints = {
|
|
||||||
video: {
|
|
||||||
deviceId: videoSource ? { exact: videoSource } : undefined,
|
|
||||||
frameRate: { min: 30, ideal: cameraFPS, max: 60 },
|
|
||||||
width: cameraWidth,
|
|
||||||
height: cameraHeight
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return navigator.mediaDevices.getUserMedia(constraints).then(gotStream).catch(handleError);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gotStream(stream) {
|
|
||||||
window.stream = stream; // make stream available to console
|
|
||||||
videoSelect.selectedIndex = [...videoSelect.options].findIndex(option => option.text === stream.getVideoTracks()[0].label);
|
|
||||||
videoElement.srcObject = stream;
|
|
||||||
videoElement.addEventListener('loadeddata', predictWebcam);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleError(error) {
|
|
||||||
console.error('Error: ', error);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------- Tracking --------------
|
|
||||||
|
|
||||||
async function createFaceLandmarker() {
|
|
||||||
const filesetResolver = await FilesetResolver.forVisionTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm');
|
|
||||||
faceLandmarker = await FaceLandmarker.createFromOptions(filesetResolver, {
|
|
||||||
baseOptions: {
|
|
||||||
modelAssetPath: 'face_landmarker_model/face_landmarker.task',
|
|
||||||
delegate: faceDetectionDelegate
|
|
||||||
},
|
|
||||||
minFaceDetectionConfidence: minFaceDetectionConfidence,
|
|
||||||
minFacePresenceConfidence: minFacePresenceConfidence,
|
|
||||||
minTrackingConfidence: minFaceTrackingConfidence,
|
|
||||||
outputFaceBlendshapes: true,
|
|
||||||
runningMode: 'VIDEO',
|
|
||||||
numFaces: 1
|
|
||||||
});
|
|
||||||
|
|
||||||
window.requestAnimationFrame(predictWebcam);
|
|
||||||
}
|
|
||||||
|
|
||||||
const createHandLandmarker = async () => {
|
|
||||||
const vision = await FilesetResolver.forVisionTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm');
|
|
||||||
handLandmarker = await HandLandmarker.createFromOptions(vision, {
|
|
||||||
baseOptions: {
|
|
||||||
modelAssetPath: 'hand_landmarker_model/hand_landmarker.task',
|
|
||||||
delegate: handDetectionDelegate
|
|
||||||
},
|
|
||||||
minHandDetectionConfidence: minHandDetectionConfidence,
|
|
||||||
minHandPresenceConfidence: minHandPresenceConfidence,
|
|
||||||
minTrackingConfidence: minHandTrackingConfidence,
|
|
||||||
runningMode: 'VIDEO',
|
|
||||||
numHands: 2
|
|
||||||
});
|
|
||||||
|
|
||||||
window.requestAnimationFrame(predictWebcam);
|
|
||||||
};
|
|
||||||
|
|
||||||
const createPoseLandmarker = async () => {
|
|
||||||
const vision = await FilesetResolver.forVisionTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm');
|
|
||||||
poseLandmarker = await PoseLandmarker.createFromOptions(vision, {
|
|
||||||
baseOptions: {
|
|
||||||
modelAssetPath: 'pose_landmarker_model/pose_landmarker_heavy.task',
|
|
||||||
delegate: poseDetectionDelegate
|
|
||||||
},
|
|
||||||
minPoseDetectionConfidence: minPoseDetectionConfidence,
|
|
||||||
minPosePresenceConfidence: minPosePresenceConfidence,
|
|
||||||
minTrackingConfidence: minPoseTrackingConfidence,
|
|
||||||
runningMode: 'VIDEO',
|
|
||||||
numPoses: 1
|
|
||||||
});
|
|
||||||
|
|
||||||
window.requestAnimationFrame(predictWebcam);
|
|
||||||
};
|
|
||||||
|
|
||||||
// -------------- Detection --------------
|
|
||||||
|
|
||||||
function mediapipeRunning() {
|
|
||||||
if (faceLandmarker || handLandmarker || poseLandmarker) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function predictWebcam() {
|
|
||||||
if (!mediapipeRunning()) {
|
|
||||||
canvasCtx.clearRect(0, 0, canvasElement.width, canvasElement.height);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hideFace || !hidepose || !hideHand) {
|
|
||||||
canvasElement.width = videoElement.videoWidth;
|
|
||||||
canvasElement.height = videoElement.videoHeight;
|
|
||||||
} else {
|
|
||||||
canvasCtx.clearRect(0, 0, canvasElement.width, canvasElement.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now let's start detecting the stream.
|
|
||||||
const startTimeMs = performance.now();
|
|
||||||
if (lastVideoTime !== videoElement.currentTime) {
|
|
||||||
lastVideoTime = videoElement.currentTime;
|
|
||||||
resultsFace = faceLandmarker ? faceLandmarker.detectForVideo(videoElement, startTimeMs) : null;
|
|
||||||
// resultsHands = handLandmarker ? handLandmarker.detectForVideo(videoElement, startTimeMs) : null;
|
|
||||||
// resultsPose = poseLandmarker ? poseLandmarker.detectForVideo(videoElement, startTimeMs) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (faceTrackingEnabled && resultsFace && resultsFace.faceLandmarks) {
|
|
||||||
// console.log(resultsFace);
|
|
||||||
drawDebugFace(resultsFace);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handTrackingEnabled && resultsHands && resultsHands.landmarks) {
|
|
||||||
// drawDebugHands(resultsHands);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (poseTrackingEnabled && resultsPose && resultsPose.landmarks) {
|
|
||||||
// drawDebugPose(resultsPose);
|
|
||||||
}
|
|
||||||
|
|
||||||
// drawBlendShapes(videoBlendShapes, resultsFace.faceBlendshapes);
|
|
||||||
|
|
||||||
// canvasCtx.restore();
|
|
||||||
|
|
||||||
// Call this function again to keep predicting when the browser is ready.
|
|
||||||
if (cameraRunning === true) {
|
|
||||||
window.requestAnimationFrame(predictWebcam);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawDebugFace(results) {
|
|
||||||
if (results) {
|
|
||||||
detections = results;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hideFace) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const landmarks of results.faceLandmarks) {
|
|
||||||
drawingUtils.drawConnectors(landmarks, FaceLandmarker.FACE_LANDMARKS_TESSELATION, { color: '#C0C0C070', lineWidth: 1 });
|
|
||||||
drawingUtils.drawConnectors(landmarks, FaceLandmarker.FACE_LANDMARKS_RIGHT_EYE, { color: '#FF3030', lineWidth: 1 });
|
|
||||||
drawingUtils.drawConnectors(landmarks, FaceLandmarker.FACE_LANDMARKS_RIGHT_EYEBROW, { color: '#FF3030', lineWidth: 1 });
|
|
||||||
drawingUtils.drawConnectors(landmarks, FaceLandmarker.FACE_LANDMARKS_LEFT_EYE, { color: '#30FF30', lineWidth: 1 });
|
|
||||||
drawingUtils.drawConnectors(landmarks, FaceLandmarker.FACE_LANDMARKS_LEFT_EYEBROW, { color: '#30FF30', lineWidth: 1 });
|
|
||||||
drawingUtils.drawConnectors(landmarks, FaceLandmarker.FACE_LANDMARKS_FACE_OVAL, { color: '#E0E0E0', lineWidth: 1 });
|
|
||||||
drawingUtils.drawConnectors(landmarks, FaceLandmarker.FACE_LANDMARKS_LIPS, { color: '#E0E0E0', lineWidth: 1 });
|
|
||||||
drawingUtils.drawConnectors(landmarks, FaceLandmarker.FACE_LANDMARKS_RIGHT_IRIS, { color: '#FF3030', lineWidth: 1 });
|
|
||||||
drawingUtils.drawConnectors(landmarks, FaceLandmarker.FACE_LANDMARKS_LEFT_IRIS, { color: '#30FF30', lineWidth: 1 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawDebugHands(results) {
|
|
||||||
if (hideHand) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (const landmarks of results.landmarks) {
|
|
||||||
drawingUtils.drawConnectors(landmarks, HandLandmarker.HAND_CONNECTIONS, {
|
|
||||||
color: '#E0E0E0',
|
|
||||||
lineWidth: 1
|
|
||||||
});
|
|
||||||
drawingUtils.drawLandmarks(landmarks, { color: '#E0E0E0', lineWidth: 1 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawDebugPose(results) {
|
|
||||||
if (hidePose) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (const landmark of results.landmarks) {
|
|
||||||
drawingUtils.drawLandmarks(landmark, {
|
|
||||||
radius: data => DrawingUtils.lerp(data.from.z, -0.15, 0.1, 5, 1)
|
|
||||||
});
|
|
||||||
drawingUtils.drawConnectors(landmark, PoseLandmarker.POSE_CONNECTIONS, { color: '#E0E0E0', lineWidth: 1 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawBlendShapes(el, blendShapes) {
|
|
||||||
if (!blendShapes.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log(blendShapes[0]);
|
|
||||||
|
|
||||||
let htmlMaker = '';
|
|
||||||
blendShapes[0].categories.map(shape => {
|
|
||||||
htmlMaker += `
|
|
||||||
<li class="blend-shapes-item">
|
|
||||||
<span class="blend-shapes-label">${shape.displayName || shape.categoryName}</span>
|
|
||||||
<span class="blend-shapes-value" style="width: calc(${+shape.score * 100}% - 120px)">${(+shape.score).toFixed(4)}</span>
|
|
||||||
</li>
|
|
||||||
`;
|
|
||||||
});
|
|
||||||
|
|
||||||
el.innerHTML = htmlMaker;
|
|
||||||
}
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 15,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 263.0718090188531,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
152,
|
|
||||||
148,
|
|
||||||
176,
|
|
||||||
149,
|
|
||||||
150,
|
|
||||||
136,
|
|
||||||
172,
|
|
||||||
58,
|
|
||||||
132,
|
|
||||||
93,
|
|
||||||
234,
|
|
||||||
127,
|
|
||||||
162,
|
|
||||||
21,
|
|
||||||
54,
|
|
||||||
103,
|
|
||||||
67,
|
|
||||||
109,
|
|
||||||
10,
|
|
||||||
338,
|
|
||||||
297,
|
|
||||||
332,
|
|
||||||
284,
|
|
||||||
251,
|
|
||||||
389,
|
|
||||||
356,
|
|
||||||
454,
|
|
||||||
323,
|
|
||||||
361,
|
|
||||||
288,
|
|
||||||
397,
|
|
||||||
365,
|
|
||||||
379,
|
|
||||||
378,
|
|
||||||
400,
|
|
||||||
377,
|
|
||||||
152
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 116.38012093685805,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 234.7247860532549,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
151,
|
|
||||||
50,
|
|
||||||
280,
|
|
||||||
151,
|
|
||||||
9,
|
|
||||||
330,
|
|
||||||
101,
|
|
||||||
9,
|
|
||||||
151,
|
|
||||||
361
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,448 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 230,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 25,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
14,
|
|
||||||
87,
|
|
||||||
178,
|
|
||||||
88,
|
|
||||||
95,
|
|
||||||
78,
|
|
||||||
191,
|
|
||||||
80,
|
|
||||||
81,
|
|
||||||
82,
|
|
||||||
13,
|
|
||||||
12,
|
|
||||||
11,
|
|
||||||
0,
|
|
||||||
164,
|
|
||||||
2,
|
|
||||||
94,
|
|
||||||
19,
|
|
||||||
1,
|
|
||||||
4,
|
|
||||||
5,
|
|
||||||
195,
|
|
||||||
197,
|
|
||||||
6,
|
|
||||||
122,
|
|
||||||
245,
|
|
||||||
244,
|
|
||||||
243,
|
|
||||||
112,
|
|
||||||
26,
|
|
||||||
22,
|
|
||||||
23,
|
|
||||||
24,
|
|
||||||
110,
|
|
||||||
226,
|
|
||||||
247,
|
|
||||||
30,
|
|
||||||
29,
|
|
||||||
27,
|
|
||||||
28,
|
|
||||||
56,
|
|
||||||
190,
|
|
||||||
243,
|
|
||||||
244,
|
|
||||||
245,
|
|
||||||
122,
|
|
||||||
6,
|
|
||||||
168,
|
|
||||||
8,
|
|
||||||
9,
|
|
||||||
151,
|
|
||||||
10,
|
|
||||||
109,
|
|
||||||
67,
|
|
||||||
103,
|
|
||||||
54,
|
|
||||||
21,
|
|
||||||
162,
|
|
||||||
127,
|
|
||||||
234,
|
|
||||||
93,
|
|
||||||
132,
|
|
||||||
58,
|
|
||||||
172,
|
|
||||||
136,
|
|
||||||
150,
|
|
||||||
149,
|
|
||||||
176,
|
|
||||||
148,
|
|
||||||
152,
|
|
||||||
175,
|
|
||||||
199,
|
|
||||||
200,
|
|
||||||
18,
|
|
||||||
17,
|
|
||||||
16,
|
|
||||||
15,
|
|
||||||
14
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 75,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
152,
|
|
||||||
175,
|
|
||||||
199,
|
|
||||||
200,
|
|
||||||
18,
|
|
||||||
17,
|
|
||||||
16,
|
|
||||||
15,
|
|
||||||
14,
|
|
||||||
317,
|
|
||||||
402,
|
|
||||||
318,
|
|
||||||
324,
|
|
||||||
308,
|
|
||||||
415,
|
|
||||||
310,
|
|
||||||
311,
|
|
||||||
312,
|
|
||||||
13,
|
|
||||||
12,
|
|
||||||
11,
|
|
||||||
0,
|
|
||||||
164,
|
|
||||||
2,
|
|
||||||
94,
|
|
||||||
19,
|
|
||||||
1,
|
|
||||||
4,
|
|
||||||
5,
|
|
||||||
195,
|
|
||||||
197,
|
|
||||||
6,
|
|
||||||
351,
|
|
||||||
465,
|
|
||||||
464,
|
|
||||||
463,
|
|
||||||
341,
|
|
||||||
256,
|
|
||||||
252,
|
|
||||||
253,
|
|
||||||
254,
|
|
||||||
339,
|
|
||||||
446,
|
|
||||||
467,
|
|
||||||
260,
|
|
||||||
259,
|
|
||||||
257,
|
|
||||||
258,
|
|
||||||
286,
|
|
||||||
414,
|
|
||||||
463,
|
|
||||||
464,
|
|
||||||
465,
|
|
||||||
351,
|
|
||||||
6,
|
|
||||||
168,
|
|
||||||
8,
|
|
||||||
9,
|
|
||||||
151,
|
|
||||||
10,
|
|
||||||
338,
|
|
||||||
297,
|
|
||||||
332,
|
|
||||||
284,
|
|
||||||
251,
|
|
||||||
389,
|
|
||||||
356,
|
|
||||||
454,
|
|
||||||
323,
|
|
||||||
361,
|
|
||||||
288,
|
|
||||||
397,
|
|
||||||
365,
|
|
||||||
379,
|
|
||||||
378,
|
|
||||||
400,
|
|
||||||
377,
|
|
||||||
152,
|
|
||||||
356
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 115,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
27,
|
|
||||||
28,
|
|
||||||
56,
|
|
||||||
190,
|
|
||||||
243,
|
|
||||||
112,
|
|
||||||
26,
|
|
||||||
22,
|
|
||||||
23,
|
|
||||||
24,
|
|
||||||
110,
|
|
||||||
226,
|
|
||||||
247,
|
|
||||||
30,
|
|
||||||
29,
|
|
||||||
27,
|
|
||||||
323
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 115,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
257,
|
|
||||||
259,
|
|
||||||
260,
|
|
||||||
467,
|
|
||||||
446,
|
|
||||||
339,
|
|
||||||
254,
|
|
||||||
253,
|
|
||||||
252,
|
|
||||||
256,
|
|
||||||
341,
|
|
||||||
463,
|
|
||||||
414,
|
|
||||||
286,
|
|
||||||
258,
|
|
||||||
257
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 355,
|
|
||||||
"fill_S": 70,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
1,
|
|
||||||
44,
|
|
||||||
220,
|
|
||||||
134,
|
|
||||||
51,
|
|
||||||
5,
|
|
||||||
281,
|
|
||||||
363,
|
|
||||||
440,
|
|
||||||
274,
|
|
||||||
1
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 355,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 30,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
27,
|
|
||||||
52,
|
|
||||||
29,
|
|
||||||
27
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 355,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 30,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
23,
|
|
||||||
101,
|
|
||||||
24,
|
|
||||||
23
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 320,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 30,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 235,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
257,
|
|
||||||
282,
|
|
||||||
259,
|
|
||||||
257
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 320,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 30,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 235,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
253,
|
|
||||||
330,
|
|
||||||
254,
|
|
||||||
253
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 210,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 170,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
61,
|
|
||||||
76,
|
|
||||||
62,
|
|
||||||
78,
|
|
||||||
95,
|
|
||||||
88,
|
|
||||||
178,
|
|
||||||
87,
|
|
||||||
14,
|
|
||||||
317,
|
|
||||||
402,
|
|
||||||
318,
|
|
||||||
324,
|
|
||||||
308,
|
|
||||||
292,
|
|
||||||
306,
|
|
||||||
291,
|
|
||||||
306,
|
|
||||||
292,
|
|
||||||
308,
|
|
||||||
319,
|
|
||||||
404,
|
|
||||||
315,
|
|
||||||
16,
|
|
||||||
85,
|
|
||||||
180,
|
|
||||||
89,
|
|
||||||
78,
|
|
||||||
62,
|
|
||||||
76,
|
|
||||||
61
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 5,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 50,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
78,
|
|
||||||
191,
|
|
||||||
80,
|
|
||||||
81,
|
|
||||||
82,
|
|
||||||
13,
|
|
||||||
312,
|
|
||||||
311,
|
|
||||||
310,
|
|
||||||
415,
|
|
||||||
308,
|
|
||||||
303,
|
|
||||||
302,
|
|
||||||
12,
|
|
||||||
72,
|
|
||||||
73,
|
|
||||||
183,
|
|
||||||
78,
|
|
||||||
264
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 135,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 40,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 70,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
107,
|
|
||||||
66,
|
|
||||||
105,
|
|
||||||
63,
|
|
||||||
70
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 135,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 40,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 70,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
336,
|
|
||||||
296,
|
|
||||||
334,
|
|
||||||
293,
|
|
||||||
300
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 135,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 40,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 70,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,325 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
2,
|
|
||||||
167,
|
|
||||||
92,
|
|
||||||
216,
|
|
||||||
207,
|
|
||||||
187,
|
|
||||||
147,
|
|
||||||
137,
|
|
||||||
234,
|
|
||||||
127,
|
|
||||||
162,
|
|
||||||
21,
|
|
||||||
54,
|
|
||||||
103,
|
|
||||||
67,
|
|
||||||
109,
|
|
||||||
10,
|
|
||||||
151,
|
|
||||||
9,
|
|
||||||
8,
|
|
||||||
168,
|
|
||||||
6,
|
|
||||||
197,
|
|
||||||
195,
|
|
||||||
5,
|
|
||||||
3,
|
|
||||||
196,
|
|
||||||
188,
|
|
||||||
233,
|
|
||||||
243,
|
|
||||||
190,
|
|
||||||
56,
|
|
||||||
28,
|
|
||||||
27,
|
|
||||||
225,
|
|
||||||
130,
|
|
||||||
25,
|
|
||||||
110,
|
|
||||||
24,
|
|
||||||
23,
|
|
||||||
22,
|
|
||||||
233,
|
|
||||||
188,
|
|
||||||
196,
|
|
||||||
3,
|
|
||||||
5,
|
|
||||||
4,
|
|
||||||
1,
|
|
||||||
19,
|
|
||||||
94,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
2,
|
|
||||||
393,
|
|
||||||
322,
|
|
||||||
436,
|
|
||||||
427,
|
|
||||||
411,
|
|
||||||
376,
|
|
||||||
366,
|
|
||||||
454,
|
|
||||||
356,
|
|
||||||
389,
|
|
||||||
251,
|
|
||||||
284,
|
|
||||||
332,
|
|
||||||
297,
|
|
||||||
338,
|
|
||||||
10,
|
|
||||||
151,
|
|
||||||
9,
|
|
||||||
8,
|
|
||||||
168,
|
|
||||||
6,
|
|
||||||
197,
|
|
||||||
195,
|
|
||||||
5,
|
|
||||||
248,
|
|
||||||
419,
|
|
||||||
412,
|
|
||||||
453,
|
|
||||||
463,
|
|
||||||
414,
|
|
||||||
286,
|
|
||||||
258,
|
|
||||||
257,
|
|
||||||
445,
|
|
||||||
359,
|
|
||||||
255,
|
|
||||||
339,
|
|
||||||
254,
|
|
||||||
253,
|
|
||||||
252,
|
|
||||||
453,
|
|
||||||
412,
|
|
||||||
419,
|
|
||||||
248,
|
|
||||||
5,
|
|
||||||
4,
|
|
||||||
1,
|
|
||||||
19,
|
|
||||||
94,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 130,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
188,
|
|
||||||
245,
|
|
||||||
189,
|
|
||||||
221,
|
|
||||||
222,
|
|
||||||
223,
|
|
||||||
46,
|
|
||||||
226,
|
|
||||||
31,
|
|
||||||
228,
|
|
||||||
229,
|
|
||||||
230,
|
|
||||||
231,
|
|
||||||
128,
|
|
||||||
233,
|
|
||||||
22,
|
|
||||||
23,
|
|
||||||
24,
|
|
||||||
110,
|
|
||||||
25,
|
|
||||||
130,
|
|
||||||
225,
|
|
||||||
27,
|
|
||||||
28,
|
|
||||||
56,
|
|
||||||
190,
|
|
||||||
243,
|
|
||||||
233,
|
|
||||||
128,
|
|
||||||
188
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
412,
|
|
||||||
465,
|
|
||||||
413,
|
|
||||||
441,
|
|
||||||
442,
|
|
||||||
276,
|
|
||||||
446,
|
|
||||||
261,
|
|
||||||
448,
|
|
||||||
449,
|
|
||||||
450,
|
|
||||||
451,
|
|
||||||
357,
|
|
||||||
453,
|
|
||||||
252,
|
|
||||||
253,
|
|
||||||
254,
|
|
||||||
339,
|
|
||||||
255,
|
|
||||||
359,
|
|
||||||
445,
|
|
||||||
257,
|
|
||||||
258,
|
|
||||||
286,
|
|
||||||
414,
|
|
||||||
463,
|
|
||||||
453,
|
|
||||||
357,
|
|
||||||
412
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 70,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 30,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
19,
|
|
||||||
1,
|
|
||||||
45,
|
|
||||||
1,
|
|
||||||
275
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
355,
|
|
||||||
371,
|
|
||||||
280,
|
|
||||||
352
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
277,
|
|
||||||
329,
|
|
||||||
347,
|
|
||||||
346,
|
|
||||||
340
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 225,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
47,
|
|
||||||
100,
|
|
||||||
118,
|
|
||||||
117,
|
|
||||||
111
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 225,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
126,
|
|
||||||
142,
|
|
||||||
50,
|
|
||||||
123
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
168,
|
|
||||||
107,
|
|
||||||
151,
|
|
||||||
336,
|
|
||||||
168,
|
|
||||||
447
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,167 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 225,
|
|
||||||
"fill_S": 5,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 255,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
152,
|
|
||||||
148,
|
|
||||||
176,
|
|
||||||
149,
|
|
||||||
150,
|
|
||||||
136,
|
|
||||||
172,
|
|
||||||
58,
|
|
||||||
132,
|
|
||||||
93,
|
|
||||||
234,
|
|
||||||
127,
|
|
||||||
162,
|
|
||||||
21,
|
|
||||||
54,
|
|
||||||
103,
|
|
||||||
67,
|
|
||||||
109,
|
|
||||||
10,
|
|
||||||
338,
|
|
||||||
297,
|
|
||||||
332,
|
|
||||||
284,
|
|
||||||
251,
|
|
||||||
389,
|
|
||||||
356,
|
|
||||||
454,
|
|
||||||
323,
|
|
||||||
361,
|
|
||||||
288,
|
|
||||||
397,
|
|
||||||
365,
|
|
||||||
379,
|
|
||||||
378,
|
|
||||||
400,
|
|
||||||
377,
|
|
||||||
152
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 360,
|
|
||||||
"fill_S": 45,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 255,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
73,
|
|
||||||
180,
|
|
||||||
84,
|
|
||||||
17,
|
|
||||||
314,
|
|
||||||
404,
|
|
||||||
303,
|
|
||||||
312,
|
|
||||||
82,
|
|
||||||
73,
|
|
||||||
288
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 360,
|
|
||||||
"fill_S": 45,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 360,
|
|
||||||
"stroke_S": 60,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
13,
|
|
||||||
17
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 360,
|
|
||||||
"fill_S": 45,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 265,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
92,
|
|
||||||
73,
|
|
||||||
82,
|
|
||||||
13,
|
|
||||||
312,
|
|
||||||
303,
|
|
||||||
322
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 345,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 130,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
225,
|
|
||||||
100
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 345,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 130,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
221,
|
|
||||||
117
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 345,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 130,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
453,
|
|
||||||
452,
|
|
||||||
451,
|
|
||||||
450,
|
|
||||||
449,
|
|
||||||
448,
|
|
||||||
261
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 360,
|
|
||||||
"fill_S": 45,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 265,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,160 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 160,
|
|
||||||
"fill_S": 25,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 160,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 80,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
152,
|
|
||||||
170,
|
|
||||||
138,
|
|
||||||
177,
|
|
||||||
93,
|
|
||||||
234,
|
|
||||||
127,
|
|
||||||
162,
|
|
||||||
21,
|
|
||||||
54,
|
|
||||||
103,
|
|
||||||
67,
|
|
||||||
109,
|
|
||||||
10,
|
|
||||||
338,
|
|
||||||
297,
|
|
||||||
332,
|
|
||||||
284,
|
|
||||||
251,
|
|
||||||
389,
|
|
||||||
356,
|
|
||||||
454,
|
|
||||||
323,
|
|
||||||
401,
|
|
||||||
367,
|
|
||||||
395,
|
|
||||||
152
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 160,
|
|
||||||
"fill_S": 95,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 160,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 80,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
142,
|
|
||||||
101,
|
|
||||||
118,
|
|
||||||
31,
|
|
||||||
226,
|
|
||||||
113,
|
|
||||||
225,
|
|
||||||
224,
|
|
||||||
223,
|
|
||||||
222,
|
|
||||||
221,
|
|
||||||
189,
|
|
||||||
245,
|
|
||||||
217,
|
|
||||||
209,
|
|
||||||
142
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 160,
|
|
||||||
"fill_S": 95,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 160,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 80,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
429,
|
|
||||||
437,
|
|
||||||
465,
|
|
||||||
413,
|
|
||||||
441,
|
|
||||||
442,
|
|
||||||
443,
|
|
||||||
444,
|
|
||||||
445,
|
|
||||||
342,
|
|
||||||
446,
|
|
||||||
261,
|
|
||||||
347,
|
|
||||||
330,
|
|
||||||
371,
|
|
||||||
429
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 160,
|
|
||||||
"fill_S": 95,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 160,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 80,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
89,
|
|
||||||
81,
|
|
||||||
38,
|
|
||||||
12,
|
|
||||||
268,
|
|
||||||
311,
|
|
||||||
319,
|
|
||||||
89
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 160,
|
|
||||||
"fill_S": 95,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 160,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 25,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
60,
|
|
||||||
60,
|
|
||||||
97
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 160,
|
|
||||||
"fill_S": 95,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 160,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 25,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
290,
|
|
||||||
328,
|
|
||||||
326
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 160,
|
|
||||||
"fill_S": 95,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 160,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 25,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,115 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 270,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 285,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
55,
|
|
||||||
65,
|
|
||||||
52,
|
|
||||||
53,
|
|
||||||
70,
|
|
||||||
71,
|
|
||||||
21,
|
|
||||||
139,
|
|
||||||
143,
|
|
||||||
111,
|
|
||||||
117,
|
|
||||||
118,
|
|
||||||
126,
|
|
||||||
198,
|
|
||||||
236,
|
|
||||||
3,
|
|
||||||
195,
|
|
||||||
196,
|
|
||||||
188,
|
|
||||||
233,
|
|
||||||
23,
|
|
||||||
24,
|
|
||||||
110,
|
|
||||||
25,
|
|
||||||
130,
|
|
||||||
113,
|
|
||||||
29,
|
|
||||||
27,
|
|
||||||
28,
|
|
||||||
56,
|
|
||||||
190,
|
|
||||||
243,
|
|
||||||
233,
|
|
||||||
188,
|
|
||||||
196,
|
|
||||||
195
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 270,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 285,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
8,
|
|
||||||
285,
|
|
||||||
295,
|
|
||||||
282,
|
|
||||||
283,
|
|
||||||
300,
|
|
||||||
301,
|
|
||||||
251,
|
|
||||||
368,
|
|
||||||
372,
|
|
||||||
340,
|
|
||||||
346,
|
|
||||||
347,
|
|
||||||
355,
|
|
||||||
420,
|
|
||||||
456,
|
|
||||||
248,
|
|
||||||
195,
|
|
||||||
419,
|
|
||||||
412,
|
|
||||||
453,
|
|
||||||
253,
|
|
||||||
254,
|
|
||||||
339,
|
|
||||||
255,
|
|
||||||
359,
|
|
||||||
342,
|
|
||||||
259,
|
|
||||||
257,
|
|
||||||
258,
|
|
||||||
286,
|
|
||||||
414,
|
|
||||||
463,
|
|
||||||
453,
|
|
||||||
412,
|
|
||||||
419,
|
|
||||||
195
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 270,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 285,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,188 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 155,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 330,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
150,
|
|
||||||
150,
|
|
||||||
212,
|
|
||||||
216,
|
|
||||||
206,
|
|
||||||
98,
|
|
||||||
97,
|
|
||||||
2,
|
|
||||||
462,
|
|
||||||
250,
|
|
||||||
459,
|
|
||||||
440,
|
|
||||||
363,
|
|
||||||
456,
|
|
||||||
399,
|
|
||||||
412,
|
|
||||||
465,
|
|
||||||
413,
|
|
||||||
441,
|
|
||||||
442,
|
|
||||||
443,
|
|
||||||
444,
|
|
||||||
445,
|
|
||||||
342,
|
|
||||||
265,
|
|
||||||
372,
|
|
||||||
264,
|
|
||||||
389,
|
|
||||||
251,
|
|
||||||
284,
|
|
||||||
332,
|
|
||||||
297,
|
|
||||||
338,
|
|
||||||
10,
|
|
||||||
109,
|
|
||||||
67,
|
|
||||||
103,
|
|
||||||
54,
|
|
||||||
21,
|
|
||||||
162,
|
|
||||||
127,
|
|
||||||
34,
|
|
||||||
143,
|
|
||||||
35,
|
|
||||||
226,
|
|
||||||
113,
|
|
||||||
225,
|
|
||||||
224,
|
|
||||||
223,
|
|
||||||
222,
|
|
||||||
221,
|
|
||||||
189,
|
|
||||||
244,
|
|
||||||
233,
|
|
||||||
232,
|
|
||||||
231,
|
|
||||||
230,
|
|
||||||
229,
|
|
||||||
228,
|
|
||||||
31,
|
|
||||||
226,
|
|
||||||
35,
|
|
||||||
143,
|
|
||||||
34,
|
|
||||||
127,
|
|
||||||
234,
|
|
||||||
93,
|
|
||||||
132,
|
|
||||||
58,
|
|
||||||
172,
|
|
||||||
136,
|
|
||||||
150
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 155,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 330,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
389,
|
|
||||||
356,
|
|
||||||
454,
|
|
||||||
323,
|
|
||||||
361,
|
|
||||||
288,
|
|
||||||
397,
|
|
||||||
365,
|
|
||||||
379,
|
|
||||||
378,
|
|
||||||
400,
|
|
||||||
377,
|
|
||||||
152,
|
|
||||||
148,
|
|
||||||
176,
|
|
||||||
149,
|
|
||||||
150,
|
|
||||||
212,
|
|
||||||
216,
|
|
||||||
206,
|
|
||||||
98,
|
|
||||||
97,
|
|
||||||
2,
|
|
||||||
164,
|
|
||||||
0,
|
|
||||||
11,
|
|
||||||
12,
|
|
||||||
13,
|
|
||||||
82,
|
|
||||||
81,
|
|
||||||
80,
|
|
||||||
191,
|
|
||||||
78,
|
|
||||||
95,
|
|
||||||
88,
|
|
||||||
178,
|
|
||||||
87,
|
|
||||||
14,
|
|
||||||
317,
|
|
||||||
402,
|
|
||||||
318,
|
|
||||||
324,
|
|
||||||
308,
|
|
||||||
415,
|
|
||||||
310,
|
|
||||||
311,
|
|
||||||
312,
|
|
||||||
13,
|
|
||||||
12,
|
|
||||||
11,
|
|
||||||
0,
|
|
||||||
164,
|
|
||||||
2,
|
|
||||||
250,
|
|
||||||
459,
|
|
||||||
440,
|
|
||||||
363,
|
|
||||||
456,
|
|
||||||
399,
|
|
||||||
412,
|
|
||||||
465,
|
|
||||||
413,
|
|
||||||
464,
|
|
||||||
453,
|
|
||||||
452,
|
|
||||||
451,
|
|
||||||
450,
|
|
||||||
449,
|
|
||||||
448,
|
|
||||||
261,
|
|
||||||
446,
|
|
||||||
342,
|
|
||||||
265,
|
|
||||||
372,
|
|
||||||
264,
|
|
||||||
389,
|
|
||||||
397
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 155,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 330,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,206 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 155,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 330,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
4,
|
|
||||||
45,
|
|
||||||
218,
|
|
||||||
235,
|
|
||||||
203,
|
|
||||||
205,
|
|
||||||
123,
|
|
||||||
227,
|
|
||||||
162,
|
|
||||||
21,
|
|
||||||
54,
|
|
||||||
104,
|
|
||||||
69,
|
|
||||||
108,
|
|
||||||
151,
|
|
||||||
9,
|
|
||||||
8,
|
|
||||||
168,
|
|
||||||
6,
|
|
||||||
122,
|
|
||||||
245,
|
|
||||||
244,
|
|
||||||
243,
|
|
||||||
190,
|
|
||||||
56,
|
|
||||||
28,
|
|
||||||
27,
|
|
||||||
225,
|
|
||||||
130,
|
|
||||||
25,
|
|
||||||
110,
|
|
||||||
24,
|
|
||||||
23,
|
|
||||||
22,
|
|
||||||
26,
|
|
||||||
112,
|
|
||||||
243,
|
|
||||||
244,
|
|
||||||
245,
|
|
||||||
122,
|
|
||||||
6,
|
|
||||||
197,
|
|
||||||
195,
|
|
||||||
5,
|
|
||||||
4
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 155,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 330,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
130,
|
|
||||||
46,
|
|
||||||
223,
|
|
||||||
222,
|
|
||||||
221,
|
|
||||||
189,
|
|
||||||
245,
|
|
||||||
188,
|
|
||||||
174,
|
|
||||||
114,
|
|
||||||
121,
|
|
||||||
231,
|
|
||||||
24,
|
|
||||||
23,
|
|
||||||
22,
|
|
||||||
26,
|
|
||||||
112,
|
|
||||||
243,
|
|
||||||
190,
|
|
||||||
56,
|
|
||||||
28,
|
|
||||||
27,
|
|
||||||
225,
|
|
||||||
247,
|
|
||||||
25,
|
|
||||||
130,
|
|
||||||
397
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 155,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 330,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
4,
|
|
||||||
275,
|
|
||||||
438,
|
|
||||||
455,
|
|
||||||
423,
|
|
||||||
425,
|
|
||||||
352,
|
|
||||||
447,
|
|
||||||
389,
|
|
||||||
251,
|
|
||||||
284,
|
|
||||||
333,
|
|
||||||
299,
|
|
||||||
337,
|
|
||||||
151,
|
|
||||||
9,
|
|
||||||
8,
|
|
||||||
168,
|
|
||||||
6,
|
|
||||||
351,
|
|
||||||
465,
|
|
||||||
464,
|
|
||||||
463,
|
|
||||||
414,
|
|
||||||
286,
|
|
||||||
258,
|
|
||||||
257,
|
|
||||||
445,
|
|
||||||
359,
|
|
||||||
255,
|
|
||||||
339,
|
|
||||||
254,
|
|
||||||
253,
|
|
||||||
252,
|
|
||||||
256,
|
|
||||||
341,
|
|
||||||
463,
|
|
||||||
464,
|
|
||||||
465,
|
|
||||||
351,
|
|
||||||
6,
|
|
||||||
197,
|
|
||||||
195,
|
|
||||||
5,
|
|
||||||
4
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 155,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 330,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
399,
|
|
||||||
412,
|
|
||||||
465,
|
|
||||||
413,
|
|
||||||
441,
|
|
||||||
442,
|
|
||||||
443,
|
|
||||||
276,
|
|
||||||
342,
|
|
||||||
255,
|
|
||||||
467,
|
|
||||||
445,
|
|
||||||
257,
|
|
||||||
258,
|
|
||||||
286,
|
|
||||||
414,
|
|
||||||
463,
|
|
||||||
341,
|
|
||||||
256,
|
|
||||||
252,
|
|
||||||
253,
|
|
||||||
254,
|
|
||||||
451,
|
|
||||||
350,
|
|
||||||
343,
|
|
||||||
399
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 155,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 330,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,159 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 40,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 90,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 30,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 50,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
10,
|
|
||||||
338,
|
|
||||||
297,
|
|
||||||
332,
|
|
||||||
284,
|
|
||||||
251,
|
|
||||||
389,
|
|
||||||
356,
|
|
||||||
454,
|
|
||||||
323,
|
|
||||||
361,
|
|
||||||
288,
|
|
||||||
397,
|
|
||||||
365,
|
|
||||||
379,
|
|
||||||
378,
|
|
||||||
400,
|
|
||||||
377,
|
|
||||||
152,
|
|
||||||
148,
|
|
||||||
176,
|
|
||||||
149,
|
|
||||||
150,
|
|
||||||
136,
|
|
||||||
172,
|
|
||||||
58,
|
|
||||||
132,
|
|
||||||
93,
|
|
||||||
234,
|
|
||||||
127,
|
|
||||||
162,
|
|
||||||
21,
|
|
||||||
54,
|
|
||||||
103,
|
|
||||||
67,
|
|
||||||
109,
|
|
||||||
10
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 40,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 30,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 50,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
6,
|
|
||||||
6,
|
|
||||||
294,
|
|
||||||
64,
|
|
||||||
6
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 40,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 30,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 50,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
31,
|
|
||||||
65,
|
|
||||||
233,
|
|
||||||
31
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 40,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 30,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 50,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
465,
|
|
||||||
258,
|
|
||||||
265,
|
|
||||||
253,
|
|
||||||
465
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 40,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 30,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 50,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
0,
|
|
||||||
312,
|
|
||||||
302,
|
|
||||||
311,
|
|
||||||
303,
|
|
||||||
310,
|
|
||||||
270,
|
|
||||||
409,
|
|
||||||
291,
|
|
||||||
375,
|
|
||||||
320,
|
|
||||||
324,
|
|
||||||
404,
|
|
||||||
402,
|
|
||||||
315,
|
|
||||||
14,
|
|
||||||
85,
|
|
||||||
178,
|
|
||||||
180,
|
|
||||||
88,
|
|
||||||
91,
|
|
||||||
95,
|
|
||||||
146,
|
|
||||||
61,
|
|
||||||
185,
|
|
||||||
40,
|
|
||||||
42,
|
|
||||||
39,
|
|
||||||
81,
|
|
||||||
37,
|
|
||||||
82
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 40,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 30,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 50,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
397
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 933 KiB |
|
Before Width: | Height: | Size: 258 B |
|
Before Width: | Height: | Size: 441 B |
|
Before Width: | Height: | Size: 305 B |
|
Before Width: | Height: | Size: 306 B |
|
|
@ -1,123 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="select">
|
|
||||||
<div>
|
|
||||||
<h3>Camera</h3>
|
|
||||||
<label for="videoSource">Camera:</label
|
|
||||||
><select id="videoSource">
|
|
||||||
<option value="">None</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="fname">W x H</label>
|
|
||||||
<select id="cameraResolution">
|
|
||||||
<option value="0" width="640" height="480">640 x 480 (4:3)</option>
|
|
||||||
<option value="1" width="1920" height="1080">1920 x 1080 (16:9)</option>
|
|
||||||
<option value="2" width="1280" height="720">1280 x 720 (16:9)</option>
|
|
||||||
<option value="3" width="320" height="240">320 x 240 (4:3)</option>
|
|
||||||
</select>
|
|
||||||
<label for="fname">FPS</label>
|
|
||||||
<select id="cameraFPS">
|
|
||||||
<option value="30">30</option>
|
|
||||||
<option value="60">60</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button id="cameraRunning">Start camera</button>
|
|
||||||
<button id="cameraVisible">Hide Camera</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h3>Face</h3>
|
|
||||||
<label>Face Inference delegate</label>
|
|
||||||
<select id="faceDetectionDelegate">
|
|
||||||
<option value="GPU">GPU</option>
|
|
||||||
<option value="CPU">CPU</option>
|
|
||||||
</select>
|
|
||||||
<div class="slidecontainer">
|
|
||||||
<label>Minimum face detection confidence</label>
|
|
||||||
<input type="range" min="0" max="1" step="0.1" value="0.5" class="slider" id="minFaceDetectionConfidence" />
|
|
||||||
<span id="minFaceDetectionConfidenceValue"></span>
|
|
||||||
</div>
|
|
||||||
<div class="slidecontainer">
|
|
||||||
<label>Minimum face presence confidence</label>
|
|
||||||
<input type="range" min="0" max="1" step="0.1" value="0.5" class="slider" id="minFacePresenceConfidence" />
|
|
||||||
<span id="minFacePresenceConfidenceValue"></span>
|
|
||||||
</div>
|
|
||||||
<div class="slidecontainer">
|
|
||||||
<label>Minimum face tracking confidence</label>
|
|
||||||
<input type="range" min="0" max="1" step="0.1" value="0.5" class="slider" id="minFaceTrackingConfidence" />
|
|
||||||
<span id="minFaceTrackingConfidenceValue"></span>
|
|
||||||
</div>
|
|
||||||
<button id="face">Enable face detection</button>
|
|
||||||
<button id="hideFace">Hide face detection</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h3>Hands</h3>
|
|
||||||
<label>Hands Inference delegate</label>
|
|
||||||
<select id="handDetectionDelegate">
|
|
||||||
<option value="GPU">GPU</option>
|
|
||||||
<option value="CPU">CPU</option>
|
|
||||||
</select>
|
|
||||||
<div class="slidecontainer">
|
|
||||||
<label>Minimum hand detection confidence</label>
|
|
||||||
<input type="range" min="0" max="1" step="0.1" value="0.5" class="slider" id="minHandDetectionConfidence" />
|
|
||||||
<span id="minHandDetectionConfidenceValue"></span>
|
|
||||||
</div>
|
|
||||||
<div class="slidecontainer">
|
|
||||||
<label>Minimum hand presence confidence</label>
|
|
||||||
<input type="range" min="0" max="1" step="0.1" value="0.5" class="slider" id="minHandPresenceConfidence" />
|
|
||||||
<span id="minHandPresenceConfidenceValue"></span>
|
|
||||||
</div>
|
|
||||||
<div class="slidecontainer">
|
|
||||||
<label>Minimum hand tracking confidence</label>
|
|
||||||
<input type="range" min="0" max="1" step="0.1" value="0.5" class="slider" id="minHandTrackingConfidence" />
|
|
||||||
<span id="minHandTrackingConfidenceValue"></span>
|
|
||||||
</div>
|
|
||||||
<button id="hand">Enable hand detection</button>
|
|
||||||
<button id="hideHand">Hide hand detection</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h3>Pose</h3>
|
|
||||||
<label>Pose Inference delegate</label>
|
|
||||||
<select id="poseDetectionDelegate">
|
|
||||||
<option value="GPU">GPU</option>
|
|
||||||
<option value="CPU">CPU</option>
|
|
||||||
</select>
|
|
||||||
<div class="slidecontainer">
|
|
||||||
<label>Minimum pose detection confidence</label>
|
|
||||||
<input type="range" min="0" max="1" step="0.1" value="0.5" class="slider" id="minPoseDetectionConfidence" />
|
|
||||||
<span id="minPoseDetectionConfidenceValue"></span>
|
|
||||||
</div>
|
|
||||||
<div class="slidecontainer">
|
|
||||||
<label>Minimum pose presence confidence</label>
|
|
||||||
<input type="range" min="0" max="1" step="0.1" value="0.5" class="slider" id="minPosePresenceConfidence" />
|
|
||||||
<span id="minPosePresenceConfidenceValue"></span>
|
|
||||||
</div>
|
|
||||||
<div class="slidecontainer">
|
|
||||||
<label>Minimum pose tracking confidence</label>
|
|
||||||
<input type="range" min="0" max="1" step="0.1" value="0.5" class="slider" id="minPoseTrackingConfidence" />
|
|
||||||
<span id="minPoseTrackingConfidenceValue"></span>
|
|
||||||
</div>
|
|
||||||
<button id="pose">Enable pose detection</button>
|
|
||||||
<button id="hidePose">Hide pose detection</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="canvas-container">
|
|
||||||
<video class="camera" id="video" autoplay muted playsinline></video>
|
|
||||||
<canvas class="output_canvas"></canvas>
|
|
||||||
<main></main>
|
|
||||||
</div>
|
|
||||||
<div class="blend-shapes">
|
|
||||||
<ul class="blend-shapes-list" id="video-blend-shapes"></ul>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
<!-- <script defer language="javascript" type="text/javascript" src="sketch.js"></script> -->
|
|
||||||
<script src="detection.js"></script>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 15,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 263.0718090188531,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
152,
|
|
||||||
148,
|
|
||||||
176,
|
|
||||||
149,
|
|
||||||
150,
|
|
||||||
136,
|
|
||||||
172,
|
|
||||||
58,
|
|
||||||
132,
|
|
||||||
93,
|
|
||||||
234,
|
|
||||||
127,
|
|
||||||
162,
|
|
||||||
21,
|
|
||||||
54,
|
|
||||||
103,
|
|
||||||
67,
|
|
||||||
109,
|
|
||||||
10,
|
|
||||||
338,
|
|
||||||
297,
|
|
||||||
332,
|
|
||||||
284,
|
|
||||||
251,
|
|
||||||
389,
|
|
||||||
356,
|
|
||||||
454,
|
|
||||||
323,
|
|
||||||
361,
|
|
||||||
288,
|
|
||||||
397,
|
|
||||||
365,
|
|
||||||
379,
|
|
||||||
378,
|
|
||||||
400,
|
|
||||||
377,
|
|
||||||
152
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 116.38012093685805,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 234.7247860532549,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
151,
|
|
||||||
50,
|
|
||||||
280,
|
|
||||||
151,
|
|
||||||
9,
|
|
||||||
330,
|
|
||||||
101,
|
|
||||||
9,
|
|
||||||
151,
|
|
||||||
361
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,448 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 230,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 25,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
14,
|
|
||||||
87,
|
|
||||||
178,
|
|
||||||
88,
|
|
||||||
95,
|
|
||||||
78,
|
|
||||||
191,
|
|
||||||
80,
|
|
||||||
81,
|
|
||||||
82,
|
|
||||||
13,
|
|
||||||
12,
|
|
||||||
11,
|
|
||||||
0,
|
|
||||||
164,
|
|
||||||
2,
|
|
||||||
94,
|
|
||||||
19,
|
|
||||||
1,
|
|
||||||
4,
|
|
||||||
5,
|
|
||||||
195,
|
|
||||||
197,
|
|
||||||
6,
|
|
||||||
122,
|
|
||||||
245,
|
|
||||||
244,
|
|
||||||
243,
|
|
||||||
112,
|
|
||||||
26,
|
|
||||||
22,
|
|
||||||
23,
|
|
||||||
24,
|
|
||||||
110,
|
|
||||||
226,
|
|
||||||
247,
|
|
||||||
30,
|
|
||||||
29,
|
|
||||||
27,
|
|
||||||
28,
|
|
||||||
56,
|
|
||||||
190,
|
|
||||||
243,
|
|
||||||
244,
|
|
||||||
245,
|
|
||||||
122,
|
|
||||||
6,
|
|
||||||
168,
|
|
||||||
8,
|
|
||||||
9,
|
|
||||||
151,
|
|
||||||
10,
|
|
||||||
109,
|
|
||||||
67,
|
|
||||||
103,
|
|
||||||
54,
|
|
||||||
21,
|
|
||||||
162,
|
|
||||||
127,
|
|
||||||
234,
|
|
||||||
93,
|
|
||||||
132,
|
|
||||||
58,
|
|
||||||
172,
|
|
||||||
136,
|
|
||||||
150,
|
|
||||||
149,
|
|
||||||
176,
|
|
||||||
148,
|
|
||||||
152,
|
|
||||||
175,
|
|
||||||
199,
|
|
||||||
200,
|
|
||||||
18,
|
|
||||||
17,
|
|
||||||
16,
|
|
||||||
15,
|
|
||||||
14
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 75,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
152,
|
|
||||||
175,
|
|
||||||
199,
|
|
||||||
200,
|
|
||||||
18,
|
|
||||||
17,
|
|
||||||
16,
|
|
||||||
15,
|
|
||||||
14,
|
|
||||||
317,
|
|
||||||
402,
|
|
||||||
318,
|
|
||||||
324,
|
|
||||||
308,
|
|
||||||
415,
|
|
||||||
310,
|
|
||||||
311,
|
|
||||||
312,
|
|
||||||
13,
|
|
||||||
12,
|
|
||||||
11,
|
|
||||||
0,
|
|
||||||
164,
|
|
||||||
2,
|
|
||||||
94,
|
|
||||||
19,
|
|
||||||
1,
|
|
||||||
4,
|
|
||||||
5,
|
|
||||||
195,
|
|
||||||
197,
|
|
||||||
6,
|
|
||||||
351,
|
|
||||||
465,
|
|
||||||
464,
|
|
||||||
463,
|
|
||||||
341,
|
|
||||||
256,
|
|
||||||
252,
|
|
||||||
253,
|
|
||||||
254,
|
|
||||||
339,
|
|
||||||
446,
|
|
||||||
467,
|
|
||||||
260,
|
|
||||||
259,
|
|
||||||
257,
|
|
||||||
258,
|
|
||||||
286,
|
|
||||||
414,
|
|
||||||
463,
|
|
||||||
464,
|
|
||||||
465,
|
|
||||||
351,
|
|
||||||
6,
|
|
||||||
168,
|
|
||||||
8,
|
|
||||||
9,
|
|
||||||
151,
|
|
||||||
10,
|
|
||||||
338,
|
|
||||||
297,
|
|
||||||
332,
|
|
||||||
284,
|
|
||||||
251,
|
|
||||||
389,
|
|
||||||
356,
|
|
||||||
454,
|
|
||||||
323,
|
|
||||||
361,
|
|
||||||
288,
|
|
||||||
397,
|
|
||||||
365,
|
|
||||||
379,
|
|
||||||
378,
|
|
||||||
400,
|
|
||||||
377,
|
|
||||||
152,
|
|
||||||
356
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 115,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
27,
|
|
||||||
28,
|
|
||||||
56,
|
|
||||||
190,
|
|
||||||
243,
|
|
||||||
112,
|
|
||||||
26,
|
|
||||||
22,
|
|
||||||
23,
|
|
||||||
24,
|
|
||||||
110,
|
|
||||||
226,
|
|
||||||
247,
|
|
||||||
30,
|
|
||||||
29,
|
|
||||||
27,
|
|
||||||
323
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 115,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
257,
|
|
||||||
259,
|
|
||||||
260,
|
|
||||||
467,
|
|
||||||
446,
|
|
||||||
339,
|
|
||||||
254,
|
|
||||||
253,
|
|
||||||
252,
|
|
||||||
256,
|
|
||||||
341,
|
|
||||||
463,
|
|
||||||
414,
|
|
||||||
286,
|
|
||||||
258,
|
|
||||||
257
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 355,
|
|
||||||
"fill_S": 70,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
1,
|
|
||||||
44,
|
|
||||||
220,
|
|
||||||
134,
|
|
||||||
51,
|
|
||||||
5,
|
|
||||||
281,
|
|
||||||
363,
|
|
||||||
440,
|
|
||||||
274,
|
|
||||||
1
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 355,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 30,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
27,
|
|
||||||
52,
|
|
||||||
29,
|
|
||||||
27
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 355,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 30,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
23,
|
|
||||||
101,
|
|
||||||
24,
|
|
||||||
23
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 320,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 30,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 235,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
257,
|
|
||||||
282,
|
|
||||||
259,
|
|
||||||
257
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 320,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 30,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 235,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
253,
|
|
||||||
330,
|
|
||||||
254,
|
|
||||||
253
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 210,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 170,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
61,
|
|
||||||
76,
|
|
||||||
62,
|
|
||||||
78,
|
|
||||||
95,
|
|
||||||
88,
|
|
||||||
178,
|
|
||||||
87,
|
|
||||||
14,
|
|
||||||
317,
|
|
||||||
402,
|
|
||||||
318,
|
|
||||||
324,
|
|
||||||
308,
|
|
||||||
292,
|
|
||||||
306,
|
|
||||||
291,
|
|
||||||
306,
|
|
||||||
292,
|
|
||||||
308,
|
|
||||||
319,
|
|
||||||
404,
|
|
||||||
315,
|
|
||||||
16,
|
|
||||||
85,
|
|
||||||
180,
|
|
||||||
89,
|
|
||||||
78,
|
|
||||||
62,
|
|
||||||
76,
|
|
||||||
61
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 5,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 50,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
78,
|
|
||||||
191,
|
|
||||||
80,
|
|
||||||
81,
|
|
||||||
82,
|
|
||||||
13,
|
|
||||||
312,
|
|
||||||
311,
|
|
||||||
310,
|
|
||||||
415,
|
|
||||||
308,
|
|
||||||
303,
|
|
||||||
302,
|
|
||||||
12,
|
|
||||||
72,
|
|
||||||
73,
|
|
||||||
183,
|
|
||||||
78,
|
|
||||||
264
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 135,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 40,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 70,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
107,
|
|
||||||
66,
|
|
||||||
105,
|
|
||||||
63,
|
|
||||||
70
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 135,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 40,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 70,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
336,
|
|
||||||
296,
|
|
||||||
334,
|
|
||||||
293,
|
|
||||||
300
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 135,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 40,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 70,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,325 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
2,
|
|
||||||
167,
|
|
||||||
92,
|
|
||||||
216,
|
|
||||||
207,
|
|
||||||
187,
|
|
||||||
147,
|
|
||||||
137,
|
|
||||||
234,
|
|
||||||
127,
|
|
||||||
162,
|
|
||||||
21,
|
|
||||||
54,
|
|
||||||
103,
|
|
||||||
67,
|
|
||||||
109,
|
|
||||||
10,
|
|
||||||
151,
|
|
||||||
9,
|
|
||||||
8,
|
|
||||||
168,
|
|
||||||
6,
|
|
||||||
197,
|
|
||||||
195,
|
|
||||||
5,
|
|
||||||
3,
|
|
||||||
196,
|
|
||||||
188,
|
|
||||||
233,
|
|
||||||
243,
|
|
||||||
190,
|
|
||||||
56,
|
|
||||||
28,
|
|
||||||
27,
|
|
||||||
225,
|
|
||||||
130,
|
|
||||||
25,
|
|
||||||
110,
|
|
||||||
24,
|
|
||||||
23,
|
|
||||||
22,
|
|
||||||
233,
|
|
||||||
188,
|
|
||||||
196,
|
|
||||||
3,
|
|
||||||
5,
|
|
||||||
4,
|
|
||||||
1,
|
|
||||||
19,
|
|
||||||
94,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
2,
|
|
||||||
393,
|
|
||||||
322,
|
|
||||||
436,
|
|
||||||
427,
|
|
||||||
411,
|
|
||||||
376,
|
|
||||||
366,
|
|
||||||
454,
|
|
||||||
356,
|
|
||||||
389,
|
|
||||||
251,
|
|
||||||
284,
|
|
||||||
332,
|
|
||||||
297,
|
|
||||||
338,
|
|
||||||
10,
|
|
||||||
151,
|
|
||||||
9,
|
|
||||||
8,
|
|
||||||
168,
|
|
||||||
6,
|
|
||||||
197,
|
|
||||||
195,
|
|
||||||
5,
|
|
||||||
248,
|
|
||||||
419,
|
|
||||||
412,
|
|
||||||
453,
|
|
||||||
463,
|
|
||||||
414,
|
|
||||||
286,
|
|
||||||
258,
|
|
||||||
257,
|
|
||||||
445,
|
|
||||||
359,
|
|
||||||
255,
|
|
||||||
339,
|
|
||||||
254,
|
|
||||||
253,
|
|
||||||
252,
|
|
||||||
453,
|
|
||||||
412,
|
|
||||||
419,
|
|
||||||
248,
|
|
||||||
5,
|
|
||||||
4,
|
|
||||||
1,
|
|
||||||
19,
|
|
||||||
94,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 130,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
188,
|
|
||||||
245,
|
|
||||||
189,
|
|
||||||
221,
|
|
||||||
222,
|
|
||||||
223,
|
|
||||||
46,
|
|
||||||
226,
|
|
||||||
31,
|
|
||||||
228,
|
|
||||||
229,
|
|
||||||
230,
|
|
||||||
231,
|
|
||||||
128,
|
|
||||||
233,
|
|
||||||
22,
|
|
||||||
23,
|
|
||||||
24,
|
|
||||||
110,
|
|
||||||
25,
|
|
||||||
130,
|
|
||||||
225,
|
|
||||||
27,
|
|
||||||
28,
|
|
||||||
56,
|
|
||||||
190,
|
|
||||||
243,
|
|
||||||
233,
|
|
||||||
128,
|
|
||||||
188
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
412,
|
|
||||||
465,
|
|
||||||
413,
|
|
||||||
441,
|
|
||||||
442,
|
|
||||||
276,
|
|
||||||
446,
|
|
||||||
261,
|
|
||||||
448,
|
|
||||||
449,
|
|
||||||
450,
|
|
||||||
451,
|
|
||||||
357,
|
|
||||||
453,
|
|
||||||
252,
|
|
||||||
253,
|
|
||||||
254,
|
|
||||||
339,
|
|
||||||
255,
|
|
||||||
359,
|
|
||||||
445,
|
|
||||||
257,
|
|
||||||
258,
|
|
||||||
286,
|
|
||||||
414,
|
|
||||||
463,
|
|
||||||
453,
|
|
||||||
357,
|
|
||||||
412
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 70,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 30,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
19,
|
|
||||||
1,
|
|
||||||
45,
|
|
||||||
1,
|
|
||||||
275
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
355,
|
|
||||||
371,
|
|
||||||
280,
|
|
||||||
352
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
277,
|
|
||||||
329,
|
|
||||||
347,
|
|
||||||
346,
|
|
||||||
340
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 225,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
47,
|
|
||||||
100,
|
|
||||||
118,
|
|
||||||
117,
|
|
||||||
111
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 225,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
126,
|
|
||||||
142,
|
|
||||||
50,
|
|
||||||
123
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
168,
|
|
||||||
107,
|
|
||||||
151,
|
|
||||||
336,
|
|
||||||
168,
|
|
||||||
447
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,167 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 225,
|
|
||||||
"fill_S": 5,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 255,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
152,
|
|
||||||
148,
|
|
||||||
176,
|
|
||||||
149,
|
|
||||||
150,
|
|
||||||
136,
|
|
||||||
172,
|
|
||||||
58,
|
|
||||||
132,
|
|
||||||
93,
|
|
||||||
234,
|
|
||||||
127,
|
|
||||||
162,
|
|
||||||
21,
|
|
||||||
54,
|
|
||||||
103,
|
|
||||||
67,
|
|
||||||
109,
|
|
||||||
10,
|
|
||||||
338,
|
|
||||||
297,
|
|
||||||
332,
|
|
||||||
284,
|
|
||||||
251,
|
|
||||||
389,
|
|
||||||
356,
|
|
||||||
454,
|
|
||||||
323,
|
|
||||||
361,
|
|
||||||
288,
|
|
||||||
397,
|
|
||||||
365,
|
|
||||||
379,
|
|
||||||
378,
|
|
||||||
400,
|
|
||||||
377,
|
|
||||||
152
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 360,
|
|
||||||
"fill_S": 45,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 255,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
73,
|
|
||||||
180,
|
|
||||||
84,
|
|
||||||
17,
|
|
||||||
314,
|
|
||||||
404,
|
|
||||||
303,
|
|
||||||
312,
|
|
||||||
82,
|
|
||||||
73,
|
|
||||||
288
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 360,
|
|
||||||
"fill_S": 45,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 360,
|
|
||||||
"stroke_S": 60,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
13,
|
|
||||||
17
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 360,
|
|
||||||
"fill_S": 45,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 265,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
92,
|
|
||||||
73,
|
|
||||||
82,
|
|
||||||
13,
|
|
||||||
312,
|
|
||||||
303,
|
|
||||||
322
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 345,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 130,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
225,
|
|
||||||
100
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 345,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 130,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
221,
|
|
||||||
117
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 345,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 0,
|
|
||||||
"stroke_H": 130,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
453,
|
|
||||||
452,
|
|
||||||
451,
|
|
||||||
450,
|
|
||||||
449,
|
|
||||||
448,
|
|
||||||
261
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 360,
|
|
||||||
"fill_S": 45,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 265,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,160 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 160,
|
|
||||||
"fill_S": 25,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 160,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 80,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
152,
|
|
||||||
170,
|
|
||||||
138,
|
|
||||||
177,
|
|
||||||
93,
|
|
||||||
234,
|
|
||||||
127,
|
|
||||||
162,
|
|
||||||
21,
|
|
||||||
54,
|
|
||||||
103,
|
|
||||||
67,
|
|
||||||
109,
|
|
||||||
10,
|
|
||||||
338,
|
|
||||||
297,
|
|
||||||
332,
|
|
||||||
284,
|
|
||||||
251,
|
|
||||||
389,
|
|
||||||
356,
|
|
||||||
454,
|
|
||||||
323,
|
|
||||||
401,
|
|
||||||
367,
|
|
||||||
395,
|
|
||||||
152
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 160,
|
|
||||||
"fill_S": 95,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 160,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 80,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
142,
|
|
||||||
101,
|
|
||||||
118,
|
|
||||||
31,
|
|
||||||
226,
|
|
||||||
113,
|
|
||||||
225,
|
|
||||||
224,
|
|
||||||
223,
|
|
||||||
222,
|
|
||||||
221,
|
|
||||||
189,
|
|
||||||
245,
|
|
||||||
217,
|
|
||||||
209,
|
|
||||||
142
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 160,
|
|
||||||
"fill_S": 95,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 160,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 80,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
429,
|
|
||||||
437,
|
|
||||||
465,
|
|
||||||
413,
|
|
||||||
441,
|
|
||||||
442,
|
|
||||||
443,
|
|
||||||
444,
|
|
||||||
445,
|
|
||||||
342,
|
|
||||||
446,
|
|
||||||
261,
|
|
||||||
347,
|
|
||||||
330,
|
|
||||||
371,
|
|
||||||
429
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 160,
|
|
||||||
"fill_S": 95,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 160,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 80,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
89,
|
|
||||||
81,
|
|
||||||
38,
|
|
||||||
12,
|
|
||||||
268,
|
|
||||||
311,
|
|
||||||
319,
|
|
||||||
89
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 160,
|
|
||||||
"fill_S": 95,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 160,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 25,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
60,
|
|
||||||
60,
|
|
||||||
97
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 160,
|
|
||||||
"fill_S": 95,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 160,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 25,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
290,
|
|
||||||
328,
|
|
||||||
326
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 160,
|
|
||||||
"fill_S": 95,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 160,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 25,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,115 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 270,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 285,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
55,
|
|
||||||
65,
|
|
||||||
52,
|
|
||||||
53,
|
|
||||||
70,
|
|
||||||
71,
|
|
||||||
21,
|
|
||||||
139,
|
|
||||||
143,
|
|
||||||
111,
|
|
||||||
117,
|
|
||||||
118,
|
|
||||||
126,
|
|
||||||
198,
|
|
||||||
236,
|
|
||||||
3,
|
|
||||||
195,
|
|
||||||
196,
|
|
||||||
188,
|
|
||||||
233,
|
|
||||||
23,
|
|
||||||
24,
|
|
||||||
110,
|
|
||||||
25,
|
|
||||||
130,
|
|
||||||
113,
|
|
||||||
29,
|
|
||||||
27,
|
|
||||||
28,
|
|
||||||
56,
|
|
||||||
190,
|
|
||||||
243,
|
|
||||||
233,
|
|
||||||
188,
|
|
||||||
196,
|
|
||||||
195
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 270,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 285,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
8,
|
|
||||||
285,
|
|
||||||
295,
|
|
||||||
282,
|
|
||||||
283,
|
|
||||||
300,
|
|
||||||
301,
|
|
||||||
251,
|
|
||||||
368,
|
|
||||||
372,
|
|
||||||
340,
|
|
||||||
346,
|
|
||||||
347,
|
|
||||||
355,
|
|
||||||
420,
|
|
||||||
456,
|
|
||||||
248,
|
|
||||||
195,
|
|
||||||
419,
|
|
||||||
412,
|
|
||||||
453,
|
|
||||||
253,
|
|
||||||
254,
|
|
||||||
339,
|
|
||||||
255,
|
|
||||||
359,
|
|
||||||
342,
|
|
||||||
259,
|
|
||||||
257,
|
|
||||||
258,
|
|
||||||
286,
|
|
||||||
414,
|
|
||||||
463,
|
|
||||||
453,
|
|
||||||
412,
|
|
||||||
419,
|
|
||||||
195
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 270,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 285,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,188 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 155,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 330,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
150,
|
|
||||||
150,
|
|
||||||
212,
|
|
||||||
216,
|
|
||||||
206,
|
|
||||||
98,
|
|
||||||
97,
|
|
||||||
2,
|
|
||||||
462,
|
|
||||||
250,
|
|
||||||
459,
|
|
||||||
440,
|
|
||||||
363,
|
|
||||||
456,
|
|
||||||
399,
|
|
||||||
412,
|
|
||||||
465,
|
|
||||||
413,
|
|
||||||
441,
|
|
||||||
442,
|
|
||||||
443,
|
|
||||||
444,
|
|
||||||
445,
|
|
||||||
342,
|
|
||||||
265,
|
|
||||||
372,
|
|
||||||
264,
|
|
||||||
389,
|
|
||||||
251,
|
|
||||||
284,
|
|
||||||
332,
|
|
||||||
297,
|
|
||||||
338,
|
|
||||||
10,
|
|
||||||
109,
|
|
||||||
67,
|
|
||||||
103,
|
|
||||||
54,
|
|
||||||
21,
|
|
||||||
162,
|
|
||||||
127,
|
|
||||||
34,
|
|
||||||
143,
|
|
||||||
35,
|
|
||||||
226,
|
|
||||||
113,
|
|
||||||
225,
|
|
||||||
224,
|
|
||||||
223,
|
|
||||||
222,
|
|
||||||
221,
|
|
||||||
189,
|
|
||||||
244,
|
|
||||||
233,
|
|
||||||
232,
|
|
||||||
231,
|
|
||||||
230,
|
|
||||||
229,
|
|
||||||
228,
|
|
||||||
31,
|
|
||||||
226,
|
|
||||||
35,
|
|
||||||
143,
|
|
||||||
34,
|
|
||||||
127,
|
|
||||||
234,
|
|
||||||
93,
|
|
||||||
132,
|
|
||||||
58,
|
|
||||||
172,
|
|
||||||
136,
|
|
||||||
150
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 155,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 330,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
389,
|
|
||||||
356,
|
|
||||||
454,
|
|
||||||
323,
|
|
||||||
361,
|
|
||||||
288,
|
|
||||||
397,
|
|
||||||
365,
|
|
||||||
379,
|
|
||||||
378,
|
|
||||||
400,
|
|
||||||
377,
|
|
||||||
152,
|
|
||||||
148,
|
|
||||||
176,
|
|
||||||
149,
|
|
||||||
150,
|
|
||||||
212,
|
|
||||||
216,
|
|
||||||
206,
|
|
||||||
98,
|
|
||||||
97,
|
|
||||||
2,
|
|
||||||
164,
|
|
||||||
0,
|
|
||||||
11,
|
|
||||||
12,
|
|
||||||
13,
|
|
||||||
82,
|
|
||||||
81,
|
|
||||||
80,
|
|
||||||
191,
|
|
||||||
78,
|
|
||||||
95,
|
|
||||||
88,
|
|
||||||
178,
|
|
||||||
87,
|
|
||||||
14,
|
|
||||||
317,
|
|
||||||
402,
|
|
||||||
318,
|
|
||||||
324,
|
|
||||||
308,
|
|
||||||
415,
|
|
||||||
310,
|
|
||||||
311,
|
|
||||||
312,
|
|
||||||
13,
|
|
||||||
12,
|
|
||||||
11,
|
|
||||||
0,
|
|
||||||
164,
|
|
||||||
2,
|
|
||||||
250,
|
|
||||||
459,
|
|
||||||
440,
|
|
||||||
363,
|
|
||||||
456,
|
|
||||||
399,
|
|
||||||
412,
|
|
||||||
465,
|
|
||||||
413,
|
|
||||||
464,
|
|
||||||
453,
|
|
||||||
452,
|
|
||||||
451,
|
|
||||||
450,
|
|
||||||
449,
|
|
||||||
448,
|
|
||||||
261,
|
|
||||||
446,
|
|
||||||
342,
|
|
||||||
265,
|
|
||||||
372,
|
|
||||||
264,
|
|
||||||
389,
|
|
||||||
397
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 155,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 330,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,206 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 155,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 330,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
4,
|
|
||||||
45,
|
|
||||||
218,
|
|
||||||
235,
|
|
||||||
203,
|
|
||||||
205,
|
|
||||||
123,
|
|
||||||
227,
|
|
||||||
162,
|
|
||||||
21,
|
|
||||||
54,
|
|
||||||
104,
|
|
||||||
69,
|
|
||||||
108,
|
|
||||||
151,
|
|
||||||
9,
|
|
||||||
8,
|
|
||||||
168,
|
|
||||||
6,
|
|
||||||
122,
|
|
||||||
245,
|
|
||||||
244,
|
|
||||||
243,
|
|
||||||
190,
|
|
||||||
56,
|
|
||||||
28,
|
|
||||||
27,
|
|
||||||
225,
|
|
||||||
130,
|
|
||||||
25,
|
|
||||||
110,
|
|
||||||
24,
|
|
||||||
23,
|
|
||||||
22,
|
|
||||||
26,
|
|
||||||
112,
|
|
||||||
243,
|
|
||||||
244,
|
|
||||||
245,
|
|
||||||
122,
|
|
||||||
6,
|
|
||||||
197,
|
|
||||||
195,
|
|
||||||
5,
|
|
||||||
4
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 155,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 330,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
130,
|
|
||||||
46,
|
|
||||||
223,
|
|
||||||
222,
|
|
||||||
221,
|
|
||||||
189,
|
|
||||||
245,
|
|
||||||
188,
|
|
||||||
174,
|
|
||||||
114,
|
|
||||||
121,
|
|
||||||
231,
|
|
||||||
24,
|
|
||||||
23,
|
|
||||||
22,
|
|
||||||
26,
|
|
||||||
112,
|
|
||||||
243,
|
|
||||||
190,
|
|
||||||
56,
|
|
||||||
28,
|
|
||||||
27,
|
|
||||||
225,
|
|
||||||
247,
|
|
||||||
25,
|
|
||||||
130,
|
|
||||||
397
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 155,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 330,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
4,
|
|
||||||
275,
|
|
||||||
438,
|
|
||||||
455,
|
|
||||||
423,
|
|
||||||
425,
|
|
||||||
352,
|
|
||||||
447,
|
|
||||||
389,
|
|
||||||
251,
|
|
||||||
284,
|
|
||||||
333,
|
|
||||||
299,
|
|
||||||
337,
|
|
||||||
151,
|
|
||||||
9,
|
|
||||||
8,
|
|
||||||
168,
|
|
||||||
6,
|
|
||||||
351,
|
|
||||||
465,
|
|
||||||
464,
|
|
||||||
463,
|
|
||||||
414,
|
|
||||||
286,
|
|
||||||
258,
|
|
||||||
257,
|
|
||||||
445,
|
|
||||||
359,
|
|
||||||
255,
|
|
||||||
339,
|
|
||||||
254,
|
|
||||||
253,
|
|
||||||
252,
|
|
||||||
256,
|
|
||||||
341,
|
|
||||||
463,
|
|
||||||
464,
|
|
||||||
465,
|
|
||||||
351,
|
|
||||||
6,
|
|
||||||
197,
|
|
||||||
195,
|
|
||||||
5,
|
|
||||||
4
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 155,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 330,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
399,
|
|
||||||
412,
|
|
||||||
465,
|
|
||||||
413,
|
|
||||||
441,
|
|
||||||
442,
|
|
||||||
443,
|
|
||||||
276,
|
|
||||||
342,
|
|
||||||
255,
|
|
||||||
467,
|
|
||||||
445,
|
|
||||||
257,
|
|
||||||
258,
|
|
||||||
286,
|
|
||||||
414,
|
|
||||||
463,
|
|
||||||
341,
|
|
||||||
256,
|
|
||||||
252,
|
|
||||||
253,
|
|
||||||
254,
|
|
||||||
451,
|
|
||||||
350,
|
|
||||||
343,
|
|
||||||
399
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 155,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 330,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,159 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 40,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 90,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 30,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 50,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
10,
|
|
||||||
338,
|
|
||||||
297,
|
|
||||||
332,
|
|
||||||
284,
|
|
||||||
251,
|
|
||||||
389,
|
|
||||||
356,
|
|
||||||
454,
|
|
||||||
323,
|
|
||||||
361,
|
|
||||||
288,
|
|
||||||
397,
|
|
||||||
365,
|
|
||||||
379,
|
|
||||||
378,
|
|
||||||
400,
|
|
||||||
377,
|
|
||||||
152,
|
|
||||||
148,
|
|
||||||
176,
|
|
||||||
149,
|
|
||||||
150,
|
|
||||||
136,
|
|
||||||
172,
|
|
||||||
58,
|
|
||||||
132,
|
|
||||||
93,
|
|
||||||
234,
|
|
||||||
127,
|
|
||||||
162,
|
|
||||||
21,
|
|
||||||
54,
|
|
||||||
103,
|
|
||||||
67,
|
|
||||||
109,
|
|
||||||
10
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 40,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 30,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 50,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
6,
|
|
||||||
6,
|
|
||||||
294,
|
|
||||||
64,
|
|
||||||
6
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 40,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 30,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 50,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
31,
|
|
||||||
65,
|
|
||||||
233,
|
|
||||||
31
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 40,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 30,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 50,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
465,
|
|
||||||
258,
|
|
||||||
265,
|
|
||||||
253,
|
|
||||||
465
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 40,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 30,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 50,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
0,
|
|
||||||
312,
|
|
||||||
302,
|
|
||||||
311,
|
|
||||||
303,
|
|
||||||
310,
|
|
||||||
270,
|
|
||||||
409,
|
|
||||||
291,
|
|
||||||
375,
|
|
||||||
320,
|
|
||||||
324,
|
|
||||||
404,
|
|
||||||
402,
|
|
||||||
315,
|
|
||||||
14,
|
|
||||||
85,
|
|
||||||
178,
|
|
||||||
180,
|
|
||||||
88,
|
|
||||||
91,
|
|
||||||
95,
|
|
||||||
146,
|
|
||||||
61,
|
|
||||||
185,
|
|
||||||
40,
|
|
||||||
42,
|
|
||||||
39,
|
|
||||||
81,
|
|
||||||
37,
|
|
||||||
82
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 40,
|
|
||||||
"fill_S": 100,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 30,
|
|
||||||
"stroke_S": 100,
|
|
||||||
"stroke_B": 50,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": [
|
|
||||||
397
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 5.3 MiB |
|
|
@ -1,391 +0,0 @@
|
||||||
const P = require('p5');
|
|
||||||
|
|
||||||
const sketch = function (p) {
|
|
||||||
let canvas;
|
|
||||||
const dMouse = [];
|
|
||||||
let closest = 0;
|
|
||||||
let isEditMode = true;
|
|
||||||
|
|
||||||
let fillHSlider, fillSSlider, fillBSlider, fillOSlider;
|
|
||||||
let fillHValue, fillSValue, fillBValue, fillOValue;
|
|
||||||
let strokeHSlider, strokeSSlider, strokeBSlider, strokeOSlider;
|
|
||||||
let strokeHValue, strokeSValue, strokeBValue, strokeOValue;
|
|
||||||
|
|
||||||
let editButton;
|
|
||||||
let saveDrawingButton;
|
|
||||||
let indexUoButton;
|
|
||||||
let indexDownButton;
|
|
||||||
let completeButton;
|
|
||||||
let undoButton;
|
|
||||||
let deleteButton;
|
|
||||||
|
|
||||||
let shapes = [
|
|
||||||
{
|
|
||||||
fill_H: p.random(360),
|
|
||||||
fill_S: 50,
|
|
||||||
fill_B: 100,
|
|
||||||
fill_O: 100,
|
|
||||||
stroke_H: p.random(360),
|
|
||||||
stroke_S: 50,
|
|
||||||
stroke_B: 100,
|
|
||||||
stroke_O: 100,
|
|
||||||
indices: []
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
let shapeIndex = 0;
|
|
||||||
let tParameters;
|
|
||||||
let isDraggedOver = false;
|
|
||||||
|
|
||||||
p.setup = function () {
|
|
||||||
canvas = p.createCanvas(cameraWidth, cameraHeight);
|
|
||||||
canvas.id('canvas');
|
|
||||||
canvas.dragOver(() => {
|
|
||||||
isDraggedOver = true;
|
|
||||||
});
|
|
||||||
canvas.dragLeave(() => {
|
|
||||||
isDraggedOver = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
canvas.drop(file => {
|
|
||||||
if (file.subtype === 'json') {
|
|
||||||
shapes = file.data.shapes;
|
|
||||||
shapeIndex = shapes.length - 1;
|
|
||||||
isDraggedOver = false;
|
|
||||||
} else {
|
|
||||||
isDraggedOver = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
p.colorMode(p.HSB, 360, 100, 100, 100);
|
|
||||||
|
|
||||||
editButton = p.createButton('Edit mode off');
|
|
||||||
editButton.mousePressed(p.toggleEdit);
|
|
||||||
editButton.class('Buttons');
|
|
||||||
editButton.id('editButton');
|
|
||||||
|
|
||||||
fillHValue = p.createDiv();
|
|
||||||
fillHValue.class('valueDisplay');
|
|
||||||
fillHSlider = p.createSlider(0, 360, p.random(360), 5);
|
|
||||||
fillHSlider.class('Slider');
|
|
||||||
|
|
||||||
fillSValue = p.createDiv();
|
|
||||||
fillSValue.class('valueDisplay');
|
|
||||||
fillSSlider = p.createSlider(0, 100, 50, 5);
|
|
||||||
fillSSlider.class('Slider');
|
|
||||||
|
|
||||||
fillBValue = p.createDiv();
|
|
||||||
fillBValue.class('valueDisplay');
|
|
||||||
fillBSlider = p.createSlider(0, 100, 100, 5);
|
|
||||||
fillBSlider.class('Slider');
|
|
||||||
|
|
||||||
fillOValue = p.createDiv();
|
|
||||||
fillOValue.class('valueDisplay');
|
|
||||||
fillOSlider = p.createSlider(0, 100, 100, 5);
|
|
||||||
fillOSlider.class('Slider');
|
|
||||||
|
|
||||||
strokeHValue = p.createDiv();
|
|
||||||
strokeHValue.class('valueDisplay');
|
|
||||||
strokeHSlider = p.createSlider(0, 360, p.random(360), 5);
|
|
||||||
strokeHSlider.class('Slider');
|
|
||||||
|
|
||||||
strokeSValue = p.createDiv();
|
|
||||||
strokeSValue.class('valueDisplay');
|
|
||||||
strokeSSlider = p.createSlider(0, 100, 50, 5);
|
|
||||||
strokeSSlider.class('Slider');
|
|
||||||
|
|
||||||
strokeBValue = p.createDiv();
|
|
||||||
strokeBValue.class('valueDisplay');
|
|
||||||
strokeBSlider = p.createSlider(0, 100, 100, 5);
|
|
||||||
strokeBSlider.class('Slider');
|
|
||||||
|
|
||||||
strokeOValue = p.createDiv();
|
|
||||||
strokeOValue.class('valueDisplay');
|
|
||||||
strokeOSlider = p.createSlider(0, 100, 100, 5);
|
|
||||||
strokeOSlider.class('Slider');
|
|
||||||
|
|
||||||
saveDrawingButton = p.createButton('');
|
|
||||||
saveDrawingButton.mousePressed(p.saveDrawing);
|
|
||||||
saveDrawingButton.class('imageButtons');
|
|
||||||
saveDrawingButton.id('saveDrawingButton');
|
|
||||||
|
|
||||||
indexUoButton = p.createButton('');
|
|
||||||
indexUoButton.mousePressed(p.upIndex);
|
|
||||||
indexUoButton.class('imageButtons');
|
|
||||||
indexUoButton.id('indexUoButton');
|
|
||||||
|
|
||||||
indexDownButton = p.createButton('');
|
|
||||||
indexDownButton.mousePressed(p.downIndex);
|
|
||||||
indexDownButton.class('imageButtons');
|
|
||||||
indexDownButton.id('indexDownButton');
|
|
||||||
|
|
||||||
completeButton = p.createButton('complete');
|
|
||||||
completeButton.mousePressed(p.complete);
|
|
||||||
completeButton.class('Buttons');
|
|
||||||
completeButton.id('completeButton');
|
|
||||||
|
|
||||||
undoButton = p.createButton('undo');
|
|
||||||
undoButton.mousePressed(p.undo);
|
|
||||||
undoButton.class('Buttons');
|
|
||||||
undoButton.id('undoButton');
|
|
||||||
|
|
||||||
deleteButton = p.createButton('delete');
|
|
||||||
deleteButton.mousePressed(p.deleteDrawing);
|
|
||||||
deleteButton.class('Buttons');
|
|
||||||
deleteButton.id('deleteButton');
|
|
||||||
|
|
||||||
tParameters = {
|
|
||||||
fill_H: fillHSlider.value(),
|
|
||||||
fill_S: fillSSlider.value(),
|
|
||||||
fill_B: fillBSlider.value(),
|
|
||||||
fill_O: fillOSlider.value(),
|
|
||||||
stroke_H: strokeHSlider.value(),
|
|
||||||
stroke_S: strokeSSlider.value(),
|
|
||||||
stroke_B: strokeBSlider.value(),
|
|
||||||
stroke_O: strokeOSlider.value()
|
|
||||||
};
|
|
||||||
|
|
||||||
p.textAlign(p.CENTER, p.CENTER);
|
|
||||||
p.textSize(24);
|
|
||||||
};
|
|
||||||
|
|
||||||
p.draw = function () {
|
|
||||||
p.clear();
|
|
||||||
if (detections !== undefined) {
|
|
||||||
if (detections.faceLandmarks !== undefined && detections.faceLandmarks.length >= 1) {
|
|
||||||
p.drawShapes();
|
|
||||||
if (isEditMode === true) {
|
|
||||||
p.faceMesh();
|
|
||||||
p.editShapes();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDraggedOver === true) {
|
|
||||||
p.noStroke();
|
|
||||||
p.fill(0, 0, 100, 10);
|
|
||||||
p.rect(0, 0, p.width, p.height);
|
|
||||||
p.fill(0, 0, 100);
|
|
||||||
// p.text('Drag your drawing here', p.width / 2, p.height / 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fillHValue.html('fill hue: ' + fillHSlider.value());
|
|
||||||
fillSValue.html('fill saturation: ' + fillSSlider.value());
|
|
||||||
fillBValue.html('fill brightness: ' + fillBSlider.value());
|
|
||||||
fillOValue.html('fill opacity: ' + fillOSlider.value());
|
|
||||||
|
|
||||||
strokeHValue.html('stroke hue: ' + strokeHSlider.value());
|
|
||||||
strokeSValue.html('stroke saturation: ' + strokeSSlider.value());
|
|
||||||
strokeBValue.html('stroke brightness: ' + strokeBSlider.value());
|
|
||||||
strokeOValue.html('stroke opacity: ' + strokeOSlider.value());
|
|
||||||
};
|
|
||||||
|
|
||||||
p.faceMesh = function () {
|
|
||||||
p.stroke(0, 0, 100);
|
|
||||||
p.strokeWeight(3);
|
|
||||||
|
|
||||||
p.beginShape(p.POINTS);
|
|
||||||
for (let i = 0; i < detections.faceLandmarks[0].length; i++) {
|
|
||||||
const x = detections.faceLandmarks[0][i].x * p.width;
|
|
||||||
const y = detections.faceLandmarks[0][i].y * p.height;
|
|
||||||
p.vertex(x, y);
|
|
||||||
|
|
||||||
const d = p.dist(x, y, p.mouseX, p.mouseY);
|
|
||||||
dMouse.push(d);
|
|
||||||
}
|
|
||||||
p.endShape();
|
|
||||||
|
|
||||||
const minimum = p.min(dMouse);
|
|
||||||
closest = dMouse.indexOf(minimum);
|
|
||||||
|
|
||||||
p.stroke(0, 100, 100);
|
|
||||||
p.strokeWeight(10);
|
|
||||||
p.point(detections.faceLandmarks[0][closest].x * p.width, detections.faceLandmarks[0][closest].y * p.height);
|
|
||||||
|
|
||||||
dMouse.splice(0, dMouse.length);
|
|
||||||
};
|
|
||||||
|
|
||||||
p.mouseClicked = function () {
|
|
||||||
if (p.mouseX >= 0 && p.mouseX <= p.width) {
|
|
||||||
if (p.mouseY >= 0 && p.mouseY <= p.height) {
|
|
||||||
if (isEditMode === true) {
|
|
||||||
shapes[shapeIndex].indices.push(closest);
|
|
||||||
console.log(shapes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
p.drawShapes = function () {
|
|
||||||
for (let s = 0; s < shapes.length; s++) {
|
|
||||||
p.fill(shapes[s].fill_H, shapes[s].fill_S, shapes[s].fill_B, shapes[s].fill_O);
|
|
||||||
p.stroke(shapes[s].stroke_H, shapes[s].stroke_S, shapes[s].stroke_B, shapes[s].stroke_O);
|
|
||||||
p.strokeWeight(3);
|
|
||||||
|
|
||||||
if (isEditMode === true) {
|
|
||||||
if (s === shapeIndex) p.glow('rgba(255, 255, 255, 100)');
|
|
||||||
else p.glow('rgba(255, 255, 255, 0)');
|
|
||||||
} else if (isEditMode === false) {
|
|
||||||
p.glow('rgba(255, 255, 255, 100)');
|
|
||||||
}
|
|
||||||
|
|
||||||
p.beginShape();
|
|
||||||
for (let i = 0; i < shapes[s].indices.length; i++) {
|
|
||||||
p.vertex(
|
|
||||||
detections.faceLandmarks[0][shapes[s].indices[i]].x * p.width,
|
|
||||||
detections.faceLandmarks[0][shapes[s].indices[i]].y * p.height
|
|
||||||
);
|
|
||||||
}
|
|
||||||
p.endShape();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
p.editShapes = function () {
|
|
||||||
// --- fill ---
|
|
||||||
if (tParameters.fill_H !== fillHSlider.value()) {
|
|
||||||
tParameters.fill_H = fillHSlider.value();
|
|
||||||
shapes[shapeIndex].fill_H = fillHSlider.value();
|
|
||||||
}
|
|
||||||
if (tParameters.fill_S !== fillSSlider.value()) {
|
|
||||||
tParameters.fill_S = fillSSlider.value();
|
|
||||||
shapes[shapeIndex].fill_S = fillSSlider.value();
|
|
||||||
}
|
|
||||||
if (tParameters.fill_B !== fillBSlider.value()) {
|
|
||||||
tParameters.fill_B = fillBSlider.value();
|
|
||||||
shapes[shapeIndex].fill_B = fillBSlider.value();
|
|
||||||
}
|
|
||||||
if (tParameters.fill_O !== fillOSlider.value()) {
|
|
||||||
tParameters.fill_O = fillOSlider.value();
|
|
||||||
shapes[shapeIndex].fill_O = fillOSlider.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- stroke ---
|
|
||||||
if (tParameters.stroke_H !== strokeHSlider.value()) {
|
|
||||||
tParameters.stroke_H = strokeHSlider.value();
|
|
||||||
shapes[shapeIndex].stroke_H = strokeHSlider.value();
|
|
||||||
}
|
|
||||||
if (tParameters.stroke_S !== strokeSSlider.value()) {
|
|
||||||
tParameters.stroke_S = strokeSSlider.value();
|
|
||||||
shapes[shapeIndex].stroke_S = strokeSSlider.value();
|
|
||||||
}
|
|
||||||
if (tParameters.stroke_B !== strokeBSlider.value()) {
|
|
||||||
tParameters.stroke_B = strokeBSlider.value();
|
|
||||||
shapes[shapeIndex].stroke_B = strokeBSlider.value();
|
|
||||||
}
|
|
||||||
if (tParameters.stroke_O !== strokeOSlider.value()) {
|
|
||||||
tParameters.stroke_O = strokeOSlider.value();
|
|
||||||
shapes[shapeIndex].stroke_O = strokeOSlider.value();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
p.keyTyped = function () {
|
|
||||||
if (p.key === 'e') p.toggleEdit();
|
|
||||||
if (p.key === 'c') p.complete();
|
|
||||||
if (p.key === 'z') p.undo();
|
|
||||||
if (p.key === 'd') p.deleteDrawing();
|
|
||||||
if (p.key === 'j') p.saveDrawing();
|
|
||||||
};
|
|
||||||
|
|
||||||
p.toggleEdit = function () {
|
|
||||||
isEditMode = !isEditMode;
|
|
||||||
|
|
||||||
if (isEditMode === true) {
|
|
||||||
editButton.html('Edit mode on');
|
|
||||||
} else if (isEditMode === false) {
|
|
||||||
editButton.html('Edit mode off');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
p.complete = function () {
|
|
||||||
if (shapes[shapes.length - 1].indices.length > 0) {
|
|
||||||
if (shapes[shapeIndex].indices.length === 0 && shapes.length > 1) shapes.splice(shapeIndex, 1);
|
|
||||||
|
|
||||||
shapes.push({
|
|
||||||
fill_H: p.random(360),
|
|
||||||
fill_S: 50,
|
|
||||||
fill_B: 100,
|
|
||||||
fill_O: 100,
|
|
||||||
stroke_H: p.random(360),
|
|
||||||
stroke_S: 50,
|
|
||||||
stroke_B: 100,
|
|
||||||
stroke_O: 100,
|
|
||||||
indices: []
|
|
||||||
});
|
|
||||||
shapeIndex = shapes.length - 1;
|
|
||||||
}
|
|
||||||
console.log(shapes);
|
|
||||||
};
|
|
||||||
|
|
||||||
p.undo = function () {
|
|
||||||
if (shapes[shapeIndex] !== undefined) {
|
|
||||||
if (shapes[shapeIndex].indices.length > 0) shapes[shapeIndex].indices.pop();
|
|
||||||
}
|
|
||||||
console.log(shapes[shapeIndex].indices);
|
|
||||||
};
|
|
||||||
|
|
||||||
p.deleteDrawing = function () {
|
|
||||||
shapes = [
|
|
||||||
{
|
|
||||||
fill_H: p.random(360),
|
|
||||||
fill_S: 50,
|
|
||||||
fill_B: 100,
|
|
||||||
fill_O: 100,
|
|
||||||
stroke_H: p.random(360),
|
|
||||||
stroke_S: 50,
|
|
||||||
stroke_B: 100,
|
|
||||||
stroke_O: 100,
|
|
||||||
indices: []
|
|
||||||
}
|
|
||||||
];
|
|
||||||
shapeIndex = 0;
|
|
||||||
console.log(shapes);
|
|
||||||
};
|
|
||||||
|
|
||||||
p.saveDrawing = function () {
|
|
||||||
const s = { shapes };
|
|
||||||
p.saveJSON(s, 'untitled_shapes.json');
|
|
||||||
};
|
|
||||||
|
|
||||||
p.keyPressed = function () {
|
|
||||||
if (p.keyCode === p.UP_ARROW) p.upIndex();
|
|
||||||
else if (p.keyCode === p.DOWN_ARROW) p.downIndex();
|
|
||||||
};
|
|
||||||
|
|
||||||
p.upIndex = function () {
|
|
||||||
if (shapes[shapeIndex] !== undefined) {
|
|
||||||
if (shapes[shapeIndex].indices.length === 0 && shapes.length > 1) shapes.splice(shapeIndex, 1);
|
|
||||||
if (shapeIndex < shapes.length - 1) shapeIndex++;
|
|
||||||
p.resetSliders();
|
|
||||||
console.log(shapeIndex);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
p.downIndex = function () {
|
|
||||||
if (shapes[shapeIndex] !== undefined) {
|
|
||||||
if (shapes[shapeIndex].indices.length === 0 && shapes.length > 1) shapes.splice(shapeIndex, 1);
|
|
||||||
if (shapeIndex > 0) shapeIndex--;
|
|
||||||
p.resetSliders();
|
|
||||||
console.log(shapeIndex);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
p.resetSliders = function () {
|
|
||||||
fillHSlider.value(shapes[shapeIndex].fill_H);
|
|
||||||
fillSSlider.value(shapes[shapeIndex].fill_S);
|
|
||||||
fillBSlider.value(shapes[shapeIndex].fill_B);
|
|
||||||
fillOSlider.value(shapes[shapeIndex].fill_O);
|
|
||||||
strokeHSlider.value(shapes[shapeIndex].stroke_H);
|
|
||||||
strokeSSlider.value(shapes[shapeIndex].stroke_S);
|
|
||||||
strokeBSlider.value(shapes[shapeIndex].stroke_B);
|
|
||||||
strokeOSlider.value(shapes[shapeIndex].stroke_O);
|
|
||||||
};
|
|
||||||
|
|
||||||
p.glow = function (glowColor) {
|
|
||||||
p.drawingContext.shadowOffsetX = 0;
|
|
||||||
p.drawingContext.shadowOffsetY = 0;
|
|
||||||
p.drawingContext.shadowBlur = 20;
|
|
||||||
p.drawingContext.shadowColor = glowColor;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const myp5 = new P(sketch);
|
|
||||||
|
|
@ -1,175 +0,0 @@
|
||||||
body {
|
|
||||||
background-color: black;
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select {
|
|
||||||
color: white;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 500px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inputResolution {
|
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
position: relative;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
#canvas {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvas-container {
|
|
||||||
position: relative;
|
|
||||||
width: 640px;
|
|
||||||
height: 480px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.output_canvas {
|
|
||||||
position: absolute;
|
|
||||||
object-fit: contain;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#video {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: contain;
|
|
||||||
}
|
|
||||||
|
|
||||||
#camera {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.valueDisplay {
|
|
||||||
position: relative;
|
|
||||||
margin-left: 665px;
|
|
||||||
color: #f7bd8f;
|
|
||||||
font-size: 10pt;
|
|
||||||
font-family: Helvetica, Arial, sans-serif;
|
|
||||||
font-weight: 100;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Slider {
|
|
||||||
-webkit-appearance: none;
|
|
||||||
position: relative;
|
|
||||||
margin-top: 5px;
|
|
||||||
margin-left: 665px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
|
|
||||||
background: none;
|
|
||||||
height: 12px;
|
|
||||||
width: 200px;
|
|
||||||
border-radius: 6px;
|
|
||||||
border: 1px solid #f7bd8f;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Slider::-webkit-slider-thumb {
|
|
||||||
-webkit-appearance: none;
|
|
||||||
width: 9px;
|
|
||||||
height: 9px;
|
|
||||||
border-radius: 5px;
|
|
||||||
background: #bf794e;
|
|
||||||
outline: none;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.imageButtons {
|
|
||||||
position: relative;
|
|
||||||
margin-top: 10px;
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#screenshot_button {
|
|
||||||
margin-left: 1320px; /*Or 675px*/
|
|
||||||
/* background: url('/images/screenshot.png'); */
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#save_drawing_button {
|
|
||||||
margin-left: 20px;
|
|
||||||
/* background: url('/images/savejson.png'); */
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#index_UP_button {
|
|
||||||
margin-left: 20px;
|
|
||||||
/* background: url('/images/shapeindex_up.png'); */
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#index_DOWN_button {
|
|
||||||
margin-left: 20px;
|
|
||||||
/* background: url('/images/shapeindex_down.png'); */
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Buttons {
|
|
||||||
position: relative;
|
|
||||||
-webkit-appearance: none;
|
|
||||||
margin-top: 10px;
|
|
||||||
|
|
||||||
height: 36px;
|
|
||||||
border: 2px solid #fff;
|
|
||||||
border-radius: 18px;
|
|
||||||
|
|
||||||
background: none;
|
|
||||||
font-size: 10pt;
|
|
||||||
font-family: Helvetica, Arial, sans-serif;
|
|
||||||
font-weight: 100;
|
|
||||||
cursor: pointer;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#edit_button {
|
|
||||||
margin-top: 5px;
|
|
||||||
margin-left: 1310px; /*Or 665px*/
|
|
||||||
margin-bottom: 15px;
|
|
||||||
width: 200px;
|
|
||||||
border-color: #fff;
|
|
||||||
font-size: 14pt;
|
|
||||||
color: #fff;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#complete_button {
|
|
||||||
margin-left: 1310px; /*Or 665px*/
|
|
||||||
border-color: #89c3eb;
|
|
||||||
color: #89c3eb;
|
|
||||||
width: 80px;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#undo_button {
|
|
||||||
margin-left: 5px;
|
|
||||||
border-color: #fff;
|
|
||||||
color: #fff;
|
|
||||||
width: 50px;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#delete_button {
|
|
||||||
margin-left: 5px;
|
|
||||||
border-color: #ee827c;
|
|
||||||
color: #ee827c;
|
|
||||||
width: 60px;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<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" />
|
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js" crossorigin="anonymous"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/control_utils/control_utils.js" crossorigin="anonymous"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/drawing_utils/drawing_utils.js" crossorigin="anonymous"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/face_mesh/face_mesh.js" crossorigin="anonymous"></script>
|
|
||||||
|
|
||||||
<link
|
|
||||||
rel="stylesheet"
|
|
||||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"
|
|
||||||
integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA=="
|
|
||||||
crossorigin="anonymous"
|
|
||||||
referrerpolicy="no-referrer"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../../css/home.css" />
|
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
|
|
||||||
<!-- <script src="sketch.js"></script> -->
|
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<!--#region title bar -->
|
|
||||||
<header id="titlebar">
|
|
||||||
<div id="drag-region">
|
|
||||||
<div id="window-controls">
|
|
||||||
<div class="button" id="min-button" tip="Minimize window">
|
|
||||||
<i class="fa-solid fa-window-minimize"></i>
|
|
||||||
</div>
|
|
||||||
<div class="button" id="max-button" tip="Maximize window">
|
|
||||||
<i class="fa-solid fa-window-maximize"></i>
|
|
||||||
</div>
|
|
||||||
<div class="button" id="close-button" tip="Close application">
|
|
||||||
<i class="fa-solid fa-xmark"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<video autoplay playsinline id="video"></video>
|
|
||||||
<div class="select">
|
|
||||||
<label for="videoSource">Video source: </label
|
|
||||||
><select id="videoSource">
|
|
||||||
<option value="dba62f19023fcf5419be5deb87956950d5553bc211d92e0e82a1f2eb482c8d81">OBS Virtual Camera</option>
|
|
||||||
</select>
|
|
||||||
<button id="startCapture">start capture</button>
|
|
||||||
<button id="startFaceMask">start faceMask</button>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
<script src="detection.js"></script>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,163 +0,0 @@
|
||||||
{
|
|
||||||
"shapes": [
|
|
||||||
{
|
|
||||||
"fill_H": 91.49429372473857,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 0,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
361,
|
|
||||||
323,
|
|
||||||
454,
|
|
||||||
356,
|
|
||||||
389,
|
|
||||||
251,
|
|
||||||
284,
|
|
||||||
332,
|
|
||||||
297,
|
|
||||||
338,
|
|
||||||
10,
|
|
||||||
109,
|
|
||||||
67,
|
|
||||||
103,
|
|
||||||
54,
|
|
||||||
21,
|
|
||||||
162,
|
|
||||||
127,
|
|
||||||
234,
|
|
||||||
93,
|
|
||||||
132,
|
|
||||||
58,
|
|
||||||
172,
|
|
||||||
136,
|
|
||||||
150,
|
|
||||||
149,
|
|
||||||
176,
|
|
||||||
148,
|
|
||||||
152,
|
|
||||||
377,
|
|
||||||
400,
|
|
||||||
378,
|
|
||||||
379,
|
|
||||||
365,
|
|
||||||
397,
|
|
||||||
288,
|
|
||||||
361,
|
|
||||||
356,
|
|
||||||
356,
|
|
||||||
356,
|
|
||||||
356,
|
|
||||||
389
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 0,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 289.82746786711664,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
33,
|
|
||||||
7,
|
|
||||||
163,
|
|
||||||
144,
|
|
||||||
145,
|
|
||||||
153,
|
|
||||||
154,
|
|
||||||
155,
|
|
||||||
133,
|
|
||||||
173,
|
|
||||||
157,
|
|
||||||
158,
|
|
||||||
159,
|
|
||||||
160,
|
|
||||||
161,
|
|
||||||
246,
|
|
||||||
33,
|
|
||||||
389
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 21.511087878199753,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 321.581288983916,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
263,
|
|
||||||
466,
|
|
||||||
388,
|
|
||||||
387,
|
|
||||||
386,
|
|
||||||
385,
|
|
||||||
384,
|
|
||||||
398,
|
|
||||||
362,
|
|
||||||
382,
|
|
||||||
381,
|
|
||||||
380,
|
|
||||||
374,
|
|
||||||
373,
|
|
||||||
390,
|
|
||||||
249,
|
|
||||||
263,
|
|
||||||
356
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 360,
|
|
||||||
"fill_S": 0,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 0,
|
|
||||||
"stroke_S": 0,
|
|
||||||
"stroke_B": 0,
|
|
||||||
"stroke_O": 0,
|
|
||||||
"indices": [
|
|
||||||
14,
|
|
||||||
87,
|
|
||||||
178,
|
|
||||||
88,
|
|
||||||
95,
|
|
||||||
78,
|
|
||||||
191,
|
|
||||||
80,
|
|
||||||
81,
|
|
||||||
82,
|
|
||||||
13,
|
|
||||||
312,
|
|
||||||
311,
|
|
||||||
310,
|
|
||||||
415,
|
|
||||||
308,
|
|
||||||
324,
|
|
||||||
318,
|
|
||||||
402,
|
|
||||||
317,
|
|
||||||
14,
|
|
||||||
454
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fill_H": 139.54068362704467,
|
|
||||||
"fill_S": 50,
|
|
||||||
"fill_B": 100,
|
|
||||||
"fill_O": 100,
|
|
||||||
"stroke_H": 164.8282901046115,
|
|
||||||
"stroke_S": 50,
|
|
||||||
"stroke_B": 100,
|
|
||||||
"stroke_O": 100,
|
|
||||||
"indices": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,186 +0,0 @@
|
||||||
CHANNEL POINTS: Pesythos
|
|
||||||
|
|
||||||
REDEMPTIONS:
|
|
||||||
- GACHA TALK - 100
|
|
||||||
- GACHA RNGSUS- 500
|
|
||||||
- GACHA SOUNDS- 1K
|
|
||||||
- GACHA GIFS - 2K
|
|
||||||
- GACHA ASMR - 5K
|
|
||||||
- GACHA TROLL - 10K
|
|
||||||
|
|
||||||
GENERAL CATEGORIES:
|
|
||||||
- [GIF], meme
|
|
||||||
- [SOUND], meme
|
|
||||||
- [TROLL], viewer,streamer
|
|
||||||
- [INSULT], viewer,streamer
|
|
||||||
- [COMPLIMENT], viewer,streamer
|
|
||||||
|
|
||||||
ASMR CATEGORIES:
|
|
||||||
- [SOFT SPOKEN], NORMAL, ECHO
|
|
||||||
- [SUSURADO] , NORMAL, ECHO
|
|
||||||
- [PUTO], NORMAL, ECHO
|
|
||||||
- [PROTA], NORMAL, ECHO
|
|
||||||
- [TRIGGER], Normal, Echo
|
|
||||||
|
|
||||||
RARITY COLORS:
|
|
||||||
- Grey / Silver / COMÚN / 1 star / 100
|
|
||||||
- Green / Emerald / NO-COMÚN / 2 stars / 500
|
|
||||||
- Blue / Diamond / RARO / 3 stars / 1K
|
|
||||||
- Purple / Sapphire / ÉPICO / 4 stars / 10K
|
|
||||||
- Yellow / Gold / LEGENDARIO / 5 stars / 100K
|
|
||||||
|
|
||||||
TROLL:
|
|
||||||
invert mouse
|
|
||||||
flip screen
|
|
||||||
mirror screen
|
|
||||||
|
|
||||||
ASMR_EN:
|
|
||||||
tighten screws
|
|
||||||
brain massage
|
|
||||||
countdown
|
|
||||||
inaudible
|
|
||||||
mouth sounds
|
|
||||||
heavy breathing
|
|
||||||
beanbag
|
|
||||||
bubbles
|
|
||||||
water
|
|
||||||
sounds
|
|
||||||
card play
|
|
||||||
cepillar mic
|
|
||||||
acariciar mic
|
|
||||||
hand play
|
|
||||||
|
|
||||||
ASMR_ES:
|
|
||||||
apretar tornillos
|
|
||||||
masajear cerebro
|
|
||||||
cuenta regresiva
|
|
||||||
inaudible
|
|
||||||
sonidos de boca
|
|
||||||
respiración profunda
|
|
||||||
bolsita de frijoles
|
|
||||||
burbujas
|
|
||||||
sonidos de agua
|
|
||||||
juego de barajas, brush mic
|
|
||||||
caress mic
|
|
||||||
juego de manos
|
|
||||||
|
|
||||||
|
|
||||||
idea para tarjeta: "seguro dejas loot común cuando te matan"
|
|
||||||
|
|
||||||
GIFS_EN:
|
|
||||||
aaah
|
|
||||||
aproaching
|
|
||||||
beetch
|
|
||||||
damn
|
|
||||||
dead
|
|
||||||
deeznutz
|
|
||||||
drama
|
|
||||||
helpme
|
|
||||||
hidaddy
|
|
||||||
holyshit
|
|
||||||
howaboutno
|
|
||||||
illumina
|
|
||||||
fun
|
|
||||||
gaaay
|
|
||||||
gotem
|
|
||||||
sonofabitch
|
|
||||||
imout
|
|
||||||
justdoit
|
|
||||||
kabuki
|
|
||||||
lick
|
|
||||||
menacing
|
|
||||||
mudamudamuda
|
|
||||||
nani
|
|
||||||
nice
|
|
||||||
nogod
|
|
||||||
ohno
|
|
||||||
ohshit
|
|
||||||
omaewa
|
|
||||||
omg
|
|
||||||
omgwow
|
|
||||||
run
|
|
||||||
running
|
|
||||||
oraroraora
|
|
||||||
pirate
|
|
||||||
simuation
|
|
||||||
stopit
|
|
||||||
surprise
|
|
||||||
thisisfine
|
|
||||||
slowclap
|
|
||||||
wrongnumber
|
|
||||||
wtf
|
|
||||||
yareyaredaze
|
|
||||||
youknowhowmuchisacrificed
|
|
||||||
youserious
|
|
||||||
yesyesyes
|
|
||||||
|
|
||||||
GIFS_ES:
|
|
||||||
algonocuadra
|
|
||||||
aqueroso
|
|
||||||
baca
|
|
||||||
balsammg
|
|
||||||
bienhecho
|
|
||||||
bonita
|
|
||||||
callate
|
|
||||||
carga
|
|
||||||
comemierda
|
|
||||||
coñooo
|
|
||||||
corre
|
|
||||||
delincuente
|
|
||||||
diablopapi
|
|
||||||
droga
|
|
||||||
eldiablo
|
|
||||||
elmoreno
|
|
||||||
gritos
|
|
||||||
hablabien
|
|
||||||
hdp
|
|
||||||
inteligente
|
|
||||||
mmg
|
|
||||||
tmm
|
|
||||||
unmoreno
|
|
||||||
vegeta
|
|
||||||
klkconmigo
|
|
||||||
konodioda
|
|
||||||
ladrone
|
|
||||||
loro
|
|
||||||
lotuyo
|
|
||||||
mierda
|
|
||||||
misojos
|
|
||||||
mmg
|
|
||||||
mmm
|
|
||||||
muchachito
|
|
||||||
nacho
|
|
||||||
nomeden
|
|
||||||
nomevanacallar
|
|
||||||
nonono
|
|
||||||
nosabencuantohesacrificado
|
|
||||||
nosedimetu
|
|
||||||
pajaro
|
|
||||||
prepotente
|
|
||||||
preso
|
|
||||||
respeto
|
|
||||||
simetria
|
|
||||||
sobame
|
|
||||||
tiguere
|
|
||||||
vaina
|
|
||||||
yoresuelvo
|
|
||||||
zawarudo
|
|
||||||
|
|
||||||
AUDIO:
|
|
||||||
airhorn
|
|
||||||
applause
|
|
||||||
badumtiss
|
|
||||||
crickets
|
|
||||||
eso_pasa
|
|
||||||
goat_scream
|
|
||||||
johncena
|
|
||||||
ooo
|
|
||||||
Sad_Trombone
|
|
||||||
Sad_Violin
|
|
||||||
saludo
|
|
||||||
scream
|
|
||||||
tutturuu
|
|
||||||
whaawhaa
|
|
||||||
wilhelmscream
|
|
||||||
wombo_combo
|
|
||||||
yesyes
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<link rel="stylesheet" href="css/style.css" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body></body>
|
|
||||||
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
|
|
||||||
<script src="./js/local_creds.js"></script>
|
|
||||||
<script src="./js/rates.js"></script>
|
|
||||||
<script src="./js/choices.js"></script>
|
|
||||||
<script src="./js/script.js"></script>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,314 +0,0 @@
|
||||||
@font-face {
|
|
||||||
font-family: 'genshin';
|
|
||||||
src: url('../fonts/zh-cn.ttf') format('truetype');
|
|
||||||
}
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
font-family: 'genshin';
|
|
||||||
color: #fff;
|
|
||||||
text-shadow: 0 0 25px rgba(0, 0, 0, 1);
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 4rem;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.container {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
/* background: rgba(0, 0, 0, 0.7); */
|
|
||||||
position: absolute;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.container img#character {
|
|
||||||
/* animation: wishAppear 5s steps(100, end) forwards;
|
|
||||||
transform-origin: center;
|
|
||||||
display: block;
|
|
||||||
margin: 0 auto;
|
|
||||||
height: 100%;
|
|
||||||
max-width: 100%; */
|
|
||||||
}
|
|
||||||
.container h1#name {
|
|
||||||
animation: nameAppear 0.8s steps(100, end) forwards;
|
|
||||||
animation-delay: 1s;
|
|
||||||
animation-timing-function: ease;
|
|
||||||
position: absolute;
|
|
||||||
top: calc(50% - 250px);
|
|
||||||
left: calc(50% - 200px);
|
|
||||||
opacity: 0;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
.container h2#redeemer {
|
|
||||||
animation: nameAppear 1.5s steps(100, end) forwards;
|
|
||||||
animation-delay: 3.5s;
|
|
||||||
animation-timing-function: ease;
|
|
||||||
position: absolute;
|
|
||||||
top: calc(50% - 185px);
|
|
||||||
left: calc(50% - 200px);
|
|
||||||
opacity: 0;
|
|
||||||
z-index: 20;
|
|
||||||
}
|
|
||||||
.container h2#redeemer::before {
|
|
||||||
content: 'redeemed by\A';
|
|
||||||
white-space: pre;
|
|
||||||
}
|
|
||||||
.container h2#redeemer span#actual_name {
|
|
||||||
font-size: 2.5rem;
|
|
||||||
}
|
|
||||||
.container img#element {
|
|
||||||
animation: nameAppear 0.6s steps(100, end) forwards;
|
|
||||||
animation-delay: 1.2s;
|
|
||||||
animation-timing-function: ease;
|
|
||||||
width: 158px;
|
|
||||||
height: 158px;
|
|
||||||
position: absolute;
|
|
||||||
top: calc(50% - 250px);
|
|
||||||
left: calc(50% - 350px);
|
|
||||||
opacity: 0;
|
|
||||||
filter: drop-shadow(0px 0px 5px rgb(0 0 0 / 0.8));
|
|
||||||
}
|
|
||||||
.container div#stars {
|
|
||||||
z-index: 20;
|
|
||||||
position: absolute;
|
|
||||||
top: calc(50% - 190px);
|
|
||||||
left: calc(50% - 200px);
|
|
||||||
filter: drop-shadow(0px 0px 5px rgb(0 0 0 / 0.8));
|
|
||||||
}
|
|
||||||
.container div#stars img {
|
|
||||||
animation: starAppear 0.3s steps(100, end) forwards;
|
|
||||||
animation-delay: 1s;
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
display: inline-block;
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(10);
|
|
||||||
}
|
|
||||||
.container.exit {
|
|
||||||
animation: genshinExit 0.3s steps(100, end) forwards;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes wishAppear {
|
|
||||||
0% {
|
|
||||||
filter: brightness(0) blur(20px);
|
|
||||||
transform: scale(10) translate(0, 0);
|
|
||||||
}
|
|
||||||
10% {
|
|
||||||
filter: brightness(0) blur(0);
|
|
||||||
transform: scale(1) translate(0, 0);
|
|
||||||
}
|
|
||||||
20% {
|
|
||||||
filter: brightness(0) blur(0);
|
|
||||||
transform: scale(1) translate(0, 0);
|
|
||||||
}
|
|
||||||
28% {
|
|
||||||
filter: brightness(0) blur(0);
|
|
||||||
transform: scale(1) translate(50px, 0);
|
|
||||||
}
|
|
||||||
30% {
|
|
||||||
filter: brightness(0) blur(0);
|
|
||||||
transform: scale(1) translate(50px, 0);
|
|
||||||
}
|
|
||||||
40% {
|
|
||||||
filter: brightness(1) blur(0);
|
|
||||||
transform: scale(1) translate(50px, 0);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
filter: brightness(1) blur(0);
|
|
||||||
transform: scale(1) translate(50px, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes nameAppear {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translate(50px, 0);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translate(0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes starAppear {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(10);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes genshinExit {
|
|
||||||
0% {
|
|
||||||
transform: scale(1);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: scale(10);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#link_to_token {
|
|
||||||
text-align: center;
|
|
||||||
display: block;
|
|
||||||
padding: 1em;
|
|
||||||
background: #59f;
|
|
||||||
color: #fff;
|
|
||||||
text-decoration: none;
|
|
||||||
width: 50%;
|
|
||||||
text-shadow: 2px 2px 2px rgb(0 0 0 / 30%);
|
|
||||||
min-width: 400px;
|
|
||||||
margin: 2em auto;
|
|
||||||
border-radius: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-stack {
|
|
||||||
animation: fade-in-up 0.5s ease forwards;
|
|
||||||
position: absolute;
|
|
||||||
bottom: -128px;
|
|
||||||
left: 50%;
|
|
||||||
width: 256px;
|
|
||||||
height: 384px;
|
|
||||||
left: calc(50% - 128px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.single-card {
|
|
||||||
width: 256px;
|
|
||||||
height: 384px;
|
|
||||||
position: absolute;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
perspective: 900px;
|
|
||||||
transition: all 0.2s cubic-bezier(0.7, -0.5, 0.3, 1.8);
|
|
||||||
transform-style: preserve-3d;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fade-in-up {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translate(0, 256px);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.front,
|
|
||||||
.back {
|
|
||||||
position: relative;
|
|
||||||
width: 256px;
|
|
||||||
height: 384px;
|
|
||||||
top: 0;
|
|
||||||
|
|
||||||
border-radius: 5px;
|
|
||||||
-webkit-backface-visibility: hidden;
|
|
||||||
backface-visibility: hidden;
|
|
||||||
background-size: cover;
|
|
||||||
background-position: center center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.front {
|
|
||||||
background-image: url(../img/characters/back.png);
|
|
||||||
}
|
|
||||||
|
|
||||||
.back {
|
|
||||||
position: absolute;
|
|
||||||
transform: rotateY(180deg);
|
|
||||||
/* background-image: url(../img/characters/tmm.png); */
|
|
||||||
/* img/characters/imout.png */
|
|
||||||
}
|
|
||||||
|
|
||||||
.single-card:nth-child(1) {
|
|
||||||
animation: card1 0.5s forwards;
|
|
||||||
}
|
|
||||||
@keyframes card1 {
|
|
||||||
100% {
|
|
||||||
transform: translate(200px, 100px) rotate(26deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.single-card:nth-child(2) {
|
|
||||||
animation: card2 0.5s forwards;
|
|
||||||
}
|
|
||||||
@keyframes card2 {
|
|
||||||
100% {
|
|
||||||
transform: translate(100px, 25px) rotate(16deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.single-card:nth-child(3) {
|
|
||||||
animation: card3 0.5s forwards;
|
|
||||||
}
|
|
||||||
@keyframes card3 {
|
|
||||||
100% {
|
|
||||||
transform: translate(0px, 0px) rotate(0deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.single-card:nth-child(4) {
|
|
||||||
animation: card4 0.5s forwards;
|
|
||||||
}
|
|
||||||
@keyframes card4 {
|
|
||||||
100% {
|
|
||||||
transform: translate(-100px, 25px) rotate(-16deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.single-card:nth-child(5) {
|
|
||||||
animation: card5 0.5s forwards;
|
|
||||||
}
|
|
||||||
@keyframes card5 {
|
|
||||||
100% {
|
|
||||||
transform: translate(-200px, 100px) rotate(-26deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotateCard1 {
|
|
||||||
0% {
|
|
||||||
transform: translateX(200px);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translate(0px, -250px) rotateY(180deg) scale(1.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotateCard2 {
|
|
||||||
0% {
|
|
||||||
transform: translateX(100px);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translate(0px, -250px) rotateY(180deg) scale(1.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotateCard3 {
|
|
||||||
0% {
|
|
||||||
transform: translateX(0px);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translate(0px, -250px) rotateY(180deg) scale(1.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotateCard4 {
|
|
||||||
0% {
|
|
||||||
transform: translateX(-100px);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translate(0px, -250px) rotateY(180deg) scale(1.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotateCard5 {
|
|
||||||
0% {
|
|
||||||
transform: translateX(-200px);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translate(0px, -250px) rotateY(180deg) scale(1.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 569 KiB |
|
Before Width: | Height: | Size: 282 KiB |
|
Before Width: | Height: | Size: 354 KiB |
|
Before Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 350 KiB |
|
Before Width: | Height: | Size: 322 KiB |
|
Before Width: | Height: | Size: 195 KiB |
|
Before Width: | Height: | Size: 569 KiB |
|
Before Width: | Height: | Size: 315 KiB |