Spaces:
Running
Running
init2
Browse files- .gitignore +1 -0
- app.py +1 -1
- frontend/README.md +2 -0
- frontend/babel.config.js +5 -0
- frontend/package.json +54 -0
- {static → frontend/public}/dict/base.datgz +0 -0
- {static → frontend/public}/dict/cc.datgz +0 -0
- {static → frontend/public}/dict/check.datgz +0 -0
- {static → frontend/public}/dict/tid.datgz +0 -0
- {static → frontend/public}/dict/tid_map.datgz +0 -0
- {static → frontend/public}/dict/tid_pos.datgz +0 -0
- {static → frontend/public}/dict/unk.datgz +0 -0
- {static → frontend/public}/dict/unk_char.datgz +0 -0
- {static → frontend/public}/dict/unk_compat.datgz +0 -0
- {static → frontend/public}/dict/unk_invoke.datgz +0 -0
- {static → frontend/public}/dict/unk_map.datgz +0 -0
- {static → frontend/public}/dict/unk_pos.datgz +0 -0
- {static → frontend/public}/favicon.ico +0 -0
- {static → frontend/public}/font/materialdesignicons-webfont.eot +0 -0
- {static → frontend/public}/font/materialdesignicons-webfont.ttf +0 -0
- {static → frontend/public}/font/materialdesignicons-webfont.woff +0 -0
- {static → frontend/public}/font/materialdesignicons-webfont.woff2 +0 -0
- {static → frontend/public}/font/materialdesignicons-webfont_ie.eot +0 -0
- {static → frontend/public}/font/materialdesignicons.min.css +0 -0
- {static → frontend/public}/font/roboto.css +0 -0
- {static → frontend/public}/font/vuetify.min.css +0 -0
- frontend/public/index.html +19 -0
- frontend/src/App.vue +383 -0
- frontend/src/main.js +12 -0
- frontend/src/plugins/vuetify.js +7 -0
- frontend/src/router/index.js +18 -0
- frontend/vue.config.js +7 -0
- frontend/yarn.lock +0 -0
- static/css/chunk-vendors.67710748.css +0 -0
- static/index.html +0 -1
- static/js/app.1cddaf0c.js +0 -1
- static/js/chunk-vendors.4a28e83e.js +0 -0
.gitignore
CHANGED
|
@@ -114,3 +114,4 @@ dmypy.json
|
|
| 114 |
.pyre/
|
| 115 |
|
| 116 |
.idea/
|
|
|
|
|
|
| 114 |
.pyre/
|
| 115 |
|
| 116 |
.idea/
|
| 117 |
+
node_modules/
|
app.py
CHANGED
|
@@ -49,7 +49,7 @@ def gen_lyric(title: str, prompt_text: str):
|
|
| 49 |
return title, lyric
|
| 50 |
|
| 51 |
|
| 52 |
-
app = Flask(__name__, static_url_path="", static_folder="
|
| 53 |
|
| 54 |
|
| 55 |
@app.route('/')
|
|
|
|
| 49 |
return title, lyric
|
| 50 |
|
| 51 |
|
| 52 |
+
app = Flask(__name__, static_url_path="", static_folder="frontend/dist")
|
| 53 |
|
| 54 |
|
| 55 |
@app.route('/')
|
frontend/README.md
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# lyric-generator
|
| 2 |
+
歌词生成器网站
|
frontend/babel.config.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
module.exports = {
|
| 2 |
+
presets: [
|
| 3 |
+
'@vue/cli-plugin-babel/preset'
|
| 4 |
+
]
|
| 5 |
+
}
|
frontend/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "lyric-generator",
|
| 3 |
+
"version": "0.1.0",
|
| 4 |
+
"private": true,
|
| 5 |
+
"scripts": {
|
| 6 |
+
"serve": "vue-cli-service serve",
|
| 7 |
+
"build": "vue-cli-service build",
|
| 8 |
+
"lint": "vue-cli-service lint"
|
| 9 |
+
},
|
| 10 |
+
"dependencies": {
|
| 11 |
+
"core-js": "^3.6.5",
|
| 12 |
+
"kod-cloud-web-deploy": "^1.0.2",
|
| 13 |
+
"kuroshiro": "^1.2.0",
|
| 14 |
+
"kuroshiro-analyzer-kuromoji": "^1.1.0",
|
| 15 |
+
"vue": "^2.6.11",
|
| 16 |
+
"vue-router": "^3.2.0",
|
| 17 |
+
"vuetify": "^2.6.0"
|
| 18 |
+
},
|
| 19 |
+
"devDependencies": {
|
| 20 |
+
"@vue/cli-plugin-babel": "~4.5.9",
|
| 21 |
+
"@vue/cli-plugin-eslint": "~4.5.9",
|
| 22 |
+
"@vue/cli-plugin-router": "~4.5.9",
|
| 23 |
+
"@vue/cli-service": "~4.5.9",
|
| 24 |
+
"axios": "^0.18.0",
|
| 25 |
+
"babel-eslint": "^10.1.0",
|
| 26 |
+
"eslint": "^6.7.2",
|
| 27 |
+
"eslint-plugin-vue": "^6.2.2",
|
| 28 |
+
"sass": "~1.32.0",
|
| 29 |
+
"sass-loader": "^10.0.0",
|
| 30 |
+
"vue-cli-plugin-axios": "~0.0.4",
|
| 31 |
+
"vue-cli-plugin-vuetify": "~2.4.8",
|
| 32 |
+
"vue-template-compiler": "^2.6.11",
|
| 33 |
+
"vuetify-loader": "^1.7.0"
|
| 34 |
+
},
|
| 35 |
+
"eslintConfig": {
|
| 36 |
+
"root": true,
|
| 37 |
+
"env": {
|
| 38 |
+
"node": true
|
| 39 |
+
},
|
| 40 |
+
"extends": [
|
| 41 |
+
"plugin:vue/essential",
|
| 42 |
+
"eslint:recommended"
|
| 43 |
+
],
|
| 44 |
+
"parserOptions": {
|
| 45 |
+
"parser": "babel-eslint"
|
| 46 |
+
},
|
| 47 |
+
"rules": {}
|
| 48 |
+
},
|
| 49 |
+
"browserslist": [
|
| 50 |
+
"> 1%",
|
| 51 |
+
"last 2 versions",
|
| 52 |
+
"not dead"
|
| 53 |
+
]
|
| 54 |
+
}
|
{static → frontend/public}/dict/base.datgz
RENAMED
|
File without changes
|
{static → frontend/public}/dict/cc.datgz
RENAMED
|
File without changes
|
{static → frontend/public}/dict/check.datgz
RENAMED
|
File without changes
|
{static → frontend/public}/dict/tid.datgz
RENAMED
|
File without changes
|
{static → frontend/public}/dict/tid_map.datgz
RENAMED
|
File without changes
|
{static → frontend/public}/dict/tid_pos.datgz
RENAMED
|
File without changes
|
{static → frontend/public}/dict/unk.datgz
RENAMED
|
File without changes
|
{static → frontend/public}/dict/unk_char.datgz
RENAMED
|
File without changes
|
{static → frontend/public}/dict/unk_compat.datgz
RENAMED
|
File without changes
|
{static → frontend/public}/dict/unk_invoke.datgz
RENAMED
|
File without changes
|
{static → frontend/public}/dict/unk_map.datgz
RENAMED
|
File without changes
|
{static → frontend/public}/dict/unk_pos.datgz
RENAMED
|
File without changes
|
{static → frontend/public}/favicon.ico
RENAMED
|
File without changes
|
{static → frontend/public}/font/materialdesignicons-webfont.eot
RENAMED
|
File without changes
|
{static → frontend/public}/font/materialdesignicons-webfont.ttf
RENAMED
|
File without changes
|
{static → frontend/public}/font/materialdesignicons-webfont.woff
RENAMED
|
File without changes
|
{static → frontend/public}/font/materialdesignicons-webfont.woff2
RENAMED
|
File without changes
|
{static → frontend/public}/font/materialdesignicons-webfont_ie.eot
RENAMED
|
File without changes
|
{static → frontend/public}/font/materialdesignicons.min.css
RENAMED
|
File without changes
|
{static → frontend/public}/font/roboto.css
RENAMED
|
File without changes
|
{static → frontend/public}/font/vuetify.min.css
RENAMED
|
File without changes
|
frontend/public/index.html
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="utf-8">
|
| 5 |
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
| 6 |
+
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
| 7 |
+
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
| 8 |
+
<title>日语歌词生成器</title>
|
| 9 |
+
<link rel="stylesheet" href="font/roboto.css">
|
| 10 |
+
<link rel="stylesheet" href="font/materialdesignicons.min.css">
|
| 11 |
+
</head>
|
| 12 |
+
<body>
|
| 13 |
+
<noscript>
|
| 14 |
+
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
| 15 |
+
</noscript>
|
| 16 |
+
<div id="app"></div>
|
| 17 |
+
<!-- built files will be auto injected -->
|
| 18 |
+
</body>
|
| 19 |
+
</html>
|
frontend/src/App.vue
ADDED
|
@@ -0,0 +1,383 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<template>
|
| 2 |
+
<v-app style="overflow: scroll">
|
| 3 |
+
<v-app-bar app dark color="primary">
|
| 4 |
+
<v-toolbar-title>{{i18n.title}}</v-toolbar-title>
|
| 5 |
+
<v-spacer></v-spacer>
|
| 6 |
+
<v-select style="max-width: 10rem" v-model="locale_name" @change="set_locale(locale_name)" :items="['English','Chinese']" prepend-icon="mdi-web" hide-details></v-select>
|
| 7 |
+
<v-btn href="https://github.com/SkyTNT/gpt2-japanese-lyric" icon><v-icon>mdi-github</v-icon></v-btn>
|
| 8 |
+
<v-btn href="https://fab.moe" icon><v-icon>mdi-home</v-icon></v-btn>
|
| 9 |
+
</v-app-bar>
|
| 10 |
+
<v-main>
|
| 11 |
+
<v-container v-if="loading_kuroshiro" style="height:100%;" fluid>
|
| 12 |
+
<div class="py-2 d-flex flex-column justify-center align-center" style="height:100%;">
|
| 13 |
+
<v-progress-circular color="blue" indeterminate></v-progress-circular>
|
| 14 |
+
<label class="py-4 text">{{i18n.loading}}</label>
|
| 15 |
+
</div>
|
| 16 |
+
</v-container>
|
| 17 |
+
<v-row v-if="!loading_kuroshiro" class="mx-3">
|
| 18 |
+
<div class="col-12 offset-0 col-sm-8 offset-sm-2 col-md-8 offset-md-2 col-lg-6 offset-lg-3 col-xl-6 offset-xl-3 mt-8">
|
| 19 |
+
<v-textarea
|
| 20 |
+
v-model="prompt_title"
|
| 21 |
+
:label="i18n.input_title_label"
|
| 22 |
+
:disabled="loading"
|
| 23 |
+
rows="1"
|
| 24 |
+
prepend-icon="mdi-comment"
|
| 25 |
+
:hint="i18n.input_title_hint"
|
| 26 |
+
no-resize
|
| 27 |
+
></v-textarea>
|
| 28 |
+
<v-textarea
|
| 29 |
+
v-model="prompt_text"
|
| 30 |
+
:label="i18n.input_text_label"
|
| 31 |
+
:disabled="loading"
|
| 32 |
+
rows="2"
|
| 33 |
+
prepend-icon="mdi-comment"
|
| 34 |
+
:hint="i18n.input_text_hint"
|
| 35 |
+
no-resize
|
| 36 |
+
></v-textarea>
|
| 37 |
+
<v-row>
|
| 38 |
+
<v-checkbox class="col-6" v-model="show_romaji" :disabled="loading" @change="show_type=show_romaji?0:1" :label="i18n.show_romaji"></v-checkbox>
|
| 39 |
+
<v-scroll-x-transition>
|
| 40 |
+
<v-select class="col-6" v-if="show_romaji" v-model="romaji_system" :disabled="loading" :items="romaji_systems" :hint="i18n.romaji_system"></v-select>
|
| 41 |
+
</v-scroll-x-transition>
|
| 42 |
+
</v-row>
|
| 43 |
+
<v-row class="mt-n8">
|
| 44 |
+
<v-checkbox class="col-6" v-model="use_trans" :disabled="loading" @change="show_type=use_trans?1:0" :label="i18n.use_translate"></v-checkbox>
|
| 45 |
+
<v-scroll-x-transition>
|
| 46 |
+
<v-select class="col-6" v-if="use_trans" v-model="trans_target_lang" :disabled="loading" :items="google_supported_languages" :hint="i18n.target_lang"></v-select>
|
| 47 |
+
</v-scroll-x-transition>
|
| 48 |
+
</v-row>
|
| 49 |
+
<v-btn color="primary" class="mb-10" elevation="5" @click="do_gen(0)" :loading="loading" text block large tile>{{i18n.generate}}</v-btn>
|
| 50 |
+
<v-expand-transition>
|
| 51 |
+
<v-simple-table v-if="lyric.length !== 0" class="py-5" dense>
|
| 52 |
+
<template v-slot:default>
|
| 53 |
+
<thead>
|
| 54 |
+
<tr>
|
| 55 |
+
<th>{{i18n.lyric}}<v-btn class="ml-2" elevation="0" @click="copy_lyric('s')" fab x-small><v-icon>mdi-content-copy</v-icon></v-btn></th>
|
| 56 |
+
<v-scroll-x-transition>
|
| 57 |
+
<th v-if="use_trans||show_romaji">
|
| 58 |
+
<span v-if="show_romaji&&!use_trans">{{i18n.romaji}}</span>
|
| 59 |
+
<span v-if="!show_romaji&&use_trans">{{i18n.translation}}</span>
|
| 60 |
+
<v-btn v-if="use_trans&&show_romaji" class="mr-n2" elevation="0" @click="show_type=show_type===0?1:0" text small>
|
| 61 |
+
<span v-if="show_romaji" :class="{'grey--text':show_type===1}">{{i18n.romaji_s}}</span>/<span v-if="use_trans" :class="{'grey--text':show_type===0}">{{i18n.translation_s}}</span>
|
| 62 |
+
</v-btn>
|
| 63 |
+
<v-btn class="ml-2" elevation="0" @click="copy_lyric(show_type===0?'r':'t')" fab x-small><v-icon>mdi-content-copy</v-icon></v-btn>
|
| 64 |
+
</th>
|
| 65 |
+
</v-scroll-x-transition>
|
| 66 |
+
</tr>
|
| 67 |
+
</thead>
|
| 68 |
+
<tbody style="word-break: break-word; word-wrap:break-word;">
|
| 69 |
+
<tr v-for="(item, idx) in lyric" :key="idx" @mouseenter="hover=idx" @mouseleave="hover=-1">
|
| 70 |
+
<td :class="{'text-h6': idx===0, 'text-center': !item.is_lyric}">
|
| 71 |
+
{{item.s}}
|
| 72 |
+
<v-scroll-x-transition v-if="tts_support">
|
| 73 |
+
<v-btn v-if="!tts_loading&&item.s!==''&&(speaking===idx||(speaking===-1&&hover===idx))" :class="{'mr-n9':true,'blue--text':speaking===idx}" icon small @click="ja_tts(idx)">
|
| 74 |
+
<v-icon>mdi-volume-high</v-icon>
|
| 75 |
+
</v-btn>
|
| 76 |
+
</v-scroll-x-transition >
|
| 77 |
+
<v-progress-circular v-if="tts_support&&speaking===idx&&tts_loading" class="mr-n9" indeterminate size="20" width="2" color="primary"></v-progress-circular>
|
| 78 |
+
</td>
|
| 79 |
+
<v-scroll-x-transition>
|
| 80 |
+
<td v-if="use_trans||show_romaji" :class="{'text-center': !item.is_lyric}">{{show_type===0?item.r:item.t}}</td>
|
| 81 |
+
</v-scroll-x-transition>
|
| 82 |
+
</tr>
|
| 83 |
+
</tbody>
|
| 84 |
+
</template>
|
| 85 |
+
</v-simple-table>
|
| 86 |
+
</v-expand-transition>
|
| 87 |
+
</div>
|
| 88 |
+
</v-row>
|
| 89 |
+
<v-snackbar dark v-model="snackbar" :timeout="2000">
|
| 90 |
+
{{ snackbar_msg }}
|
| 91 |
+
<template v-slot:action="{ attrs }">
|
| 92 |
+
<v-btn color="blue" text v-bind="attrs" @click="snackbar = false">
|
| 93 |
+
Close
|
| 94 |
+
</v-btn>
|
| 95 |
+
</template>
|
| 96 |
+
</v-snackbar>
|
| 97 |
+
</v-main>
|
| 98 |
+
<v-footer>
|
| 99 |
+
<v-row class="ma-0">
|
| 100 |
+
<div class="text-center caption col-12 pa-0">{{i18n.footer}}</div>
|
| 101 |
+
<div class="text-center caption col-12 pa-0">© 2022 SkyTNT</div>
|
| 102 |
+
</v-row>
|
| 103 |
+
</v-footer>
|
| 104 |
+
</v-app>
|
| 105 |
+
</template>
|
| 106 |
+
|
| 107 |
+
<style lang="scss">
|
| 108 |
+
</style>
|
| 109 |
+
<script>
|
| 110 |
+
import axios from 'axios'
|
| 111 |
+
import Kuroshiro from "kuroshiro";
|
| 112 |
+
import KuromojiAnalyzer from "kuroshiro-analyzer-kuromoji";
|
| 113 |
+
|
| 114 |
+
if (!String.prototype.trim) {
|
| 115 |
+
String.prototype.trim = function () {
|
| 116 |
+
return this.triml().trimr();
|
| 117 |
+
}
|
| 118 |
+
String.prototype.triml = function () {
|
| 119 |
+
return this.replace(/^[\s\n\t]+/g, "");
|
| 120 |
+
}
|
| 121 |
+
String.prototype.trimr = function () {
|
| 122 |
+
return this.replace(/[\s\n\t]+$/g, "");
|
| 123 |
+
}
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
function isMobile(){
|
| 127 |
+
return /(iPhone|iPad|iPod|iOS|Android|Windows Phone)/i.test(navigator.userAgent);
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
export default {
|
| 131 |
+
name: "App",
|
| 132 |
+
data:()=>({
|
| 133 |
+
locale_name: "English",
|
| 134 |
+
i18n:{},
|
| 135 |
+
use_trans: false,
|
| 136 |
+
google_supported_languages:['af', 'sq', 'am', 'ar', 'hy', 'az', 'eu', 'be', 'bn', 'bs', 'bg', 'my', 'ca', 'ca', 'ceb', 'co', 'cs', 'da', 'nl', 'nl', 'en', 'eo', 'et', 'fi', 'fr', 'fy', 'ka', 'de', 'gd', 'gd', 'ga', 'gl', 'el', 'gu', 'ht', 'ht', 'ha', 'haw', 'he', 'hi', 'hr', 'hu', 'ig', 'is', 'id', 'it', 'jw', 'ja', 'kn', 'kk', 'km', 'ky', 'ky', 'ko', 'ku', 'lo', 'la', 'lv', 'lt', 'lb', 'lb', 'mk', 'ml', 'mi', 'mr', 'ms', 'mg', 'mt', 'mn', 'ne', 'no', 'ny', 'ny', 'ny', 'or', 'pa', 'pa', 'fa', 'pl', 'pt', 'ps', 'ps', 'ro', 'ro', 'ro', 'ru', 'si', 'si', 'sk', 'sl', 'sm', 'sn', 'sd', 'so', 'st', 'es', 'es', 'sr', 'su', 'sw', 'sv', 'ta', 'te', 'tg', 'tl', 'th', 'tr', 'ug', 'ug', 'uk', 'ur', 'uz', 'vi', 'cy', 'xh', 'yi', 'yo', 'zu', 'zh-CN', 'zh-TW'],
|
| 137 |
+
trans_target_lang:"zh-CN",
|
| 138 |
+
show_romaji:false,
|
| 139 |
+
show_type:0,
|
| 140 |
+
romaji_systems:["nippon","passport","hepburn"],
|
| 141 |
+
romaji_system:"hepburn",
|
| 142 |
+
prompt_title:"桜",
|
| 143 |
+
prompt_text:"",
|
| 144 |
+
loading_kuroshiro:true,
|
| 145 |
+
loading:false,
|
| 146 |
+
lyric:[],
|
| 147 |
+
tts_cache:{},//tts缓存
|
| 148 |
+
tts_loading:false,
|
| 149 |
+
tts_support:false,
|
| 150 |
+
speaking:-1,//正在tts的行数
|
| 151 |
+
hover:-1,//鼠标悬停的行数
|
| 152 |
+
snackbar:false,
|
| 153 |
+
snackbar_msg:"",
|
| 154 |
+
kuroshiro: new Kuroshiro()
|
| 155 |
+
}),
|
| 156 |
+
mounted() {
|
| 157 |
+
this.locale_name = (navigator.language ||navigator.userLanguage)==="zh-CN"?"Chinese":"English"
|
| 158 |
+
if(this.locale_name==="English")
|
| 159 |
+
this.trans_target_lang="en";
|
| 160 |
+
this.set_locale(this.locale_name);
|
| 161 |
+
this.loads();
|
| 162 |
+
},
|
| 163 |
+
methods:{
|
| 164 |
+
set_locale(name){
|
| 165 |
+
let locale = name==="English"?"en":"zh";
|
| 166 |
+
let langs={
|
| 167 |
+
en:{
|
| 168 |
+
title:"Japanese Lyric Generator",
|
| 169 |
+
loading:"Loading",
|
| 170 |
+
input_title_label:"Title (can be empty)",
|
| 171 |
+
input_text_label:"Beginning (can be empty)",
|
| 172 |
+
input_title_hint:"Generate lyric for a given title",
|
| 173 |
+
input_text_hint:"The generator continues with this text",
|
| 174 |
+
show_romaji:"Show romaji",
|
| 175 |
+
romaji_system:"Romaji system",
|
| 176 |
+
use_translate:"Translate",
|
| 177 |
+
target_lang:"Target language",
|
| 178 |
+
generate:"Generate!",
|
| 179 |
+
lyric:"Lyric",
|
| 180 |
+
romaji:"Romaji",
|
| 181 |
+
romaji_s:"R",
|
| 182 |
+
translation:"Translation",
|
| 183 |
+
translation_s:"T",
|
| 184 |
+
footer:"The generated content can be used as you like, please share this site if you like.",
|
| 185 |
+
copy_successful:"Copy successful",
|
| 186 |
+
error:"Error",
|
| 187 |
+
error_network:"Network error",
|
| 188 |
+
error_failed_load_kuromoji:"Failed to load romaji converter",
|
| 189 |
+
error_failed_covert_romaji:"Failed to convert lyric to romaji",
|
| 190 |
+
error_failed_translate:"Failed to translate lyric",
|
| 191 |
+
error_copy:"Copy failed, browser does not support"
|
| 192 |
+
},
|
| 193 |
+
zh:{
|
| 194 |
+
title:"日语歌词生成器",
|
| 195 |
+
loading:"加载中",
|
| 196 |
+
input_title_label:"歌词标题(可不填)",
|
| 197 |
+
input_text_label:"歌词开头(可不填)",
|
| 198 |
+
input_title_hint:"给定标题生成歌词",
|
| 199 |
+
input_text_hint:"生成器以这段文本进行续写",
|
| 200 |
+
show_romaji:"显示罗马音",
|
| 201 |
+
romaji_system:"罗马音系统",
|
| 202 |
+
use_translate:"是否进行翻译",
|
| 203 |
+
target_lang:"目标语言",
|
| 204 |
+
generate:"生成!",
|
| 205 |
+
lyric:"歌词",
|
| 206 |
+
romaji:"罗马音",
|
| 207 |
+
romaji_s:"音",
|
| 208 |
+
translation:"翻译",
|
| 209 |
+
translation_s:"译",
|
| 210 |
+
footer:"生成的内容可以随意使用,喜欢的话就请分享本网站",
|
| 211 |
+
copy_successful:"复制成功",
|
| 212 |
+
error:"错误",
|
| 213 |
+
error_network:"网络错误",
|
| 214 |
+
error_failed_load_kuromoji:"罗马音转换器加载失败",
|
| 215 |
+
error_failed_covert_romaji:"转换罗马音错误",
|
| 216 |
+
error_failed_translate:"翻译出错",
|
| 217 |
+
error_copy:"复制失败,浏览器不支持"
|
| 218 |
+
}
|
| 219 |
+
};
|
| 220 |
+
this.i18n = langs[locale];
|
| 221 |
+
},
|
| 222 |
+
async loads(){
|
| 223 |
+
await this.load_kuroshiro();
|
| 224 |
+
if(!isMobile()){
|
| 225 |
+
eval((await axios.get('https://l2d.fab.moe/js/autoload.js')).data);
|
| 226 |
+
}
|
| 227 |
+
},
|
| 228 |
+
async load_kuroshiro(){
|
| 229 |
+
try {
|
| 230 |
+
await this.kuroshiro.init(new KuromojiAnalyzer({dictPath:"dict/"}));
|
| 231 |
+
}catch (e) {
|
| 232 |
+
this.show_snackbar(this.i18n.error_failed_load_kuromoji+":"+e.message);
|
| 233 |
+
console.log(e);
|
| 234 |
+
}
|
| 235 |
+
this.loading_kuroshiro=false;
|
| 236 |
+
console.log("kuroshiro loaded");
|
| 237 |
+
},
|
| 238 |
+
async do_gen(){
|
| 239 |
+
let prompt_title = this.prompt_title.trim();
|
| 240 |
+
let prompt_text = this.prompt_text.trim();
|
| 241 |
+
this.loading = true;
|
| 242 |
+
this.lyric = [];
|
| 243 |
+
this.tts_cache = {};
|
| 244 |
+
|
| 245 |
+
try {
|
| 246 |
+
let result = await axios.post("gen",
|
| 247 |
+
{title:prompt_title, text:prompt_text})
|
| 248 |
+
let gen_text = `${result.data.title}\n\n${result.data.lyric}`
|
| 249 |
+
let lines = gen_text.split('\n')
|
| 250 |
+
for (let i in lines) {
|
| 251 |
+
let line = lines[i].trim().replace(/ /g, "\u3000")
|
| 252 |
+
this.lyric.push({s: line, r: "", t: "", is_lyric: line!=="---end---"})
|
| 253 |
+
}
|
| 254 |
+
this.lyric[0].is_lyric = false; //title
|
| 255 |
+
|
| 256 |
+
try {
|
| 257 |
+
let romajis = await this.kuroshiro.convert(gen_text, { to: "romaji" ,mode:"spaced",romajiSystem:this.romaji_system})
|
| 258 |
+
romajis = romajis.split('\n')
|
| 259 |
+
for (let i in romajis) {
|
| 260 |
+
this.lyric[i].r = romajis[i]
|
| 261 |
+
}
|
| 262 |
+
}catch (e) {
|
| 263 |
+
this.show_snackbar(this.i18n.error_failed_covert_romaji+":" + e.message)
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
if (this.use_trans) {
|
| 267 |
+
let trans = await this.google_translate(gen_text);
|
| 268 |
+
if (trans !== "") {
|
| 269 |
+
trans = trans.split("\n")
|
| 270 |
+
for (let i in trans) {
|
| 271 |
+
this.lyric[i].t = trans[i].trim().replace(/ /g, "\u3000")
|
| 272 |
+
}
|
| 273 |
+
}
|
| 274 |
+
}
|
| 275 |
+
this.loading = false;
|
| 276 |
+
|
| 277 |
+
} catch (e) {
|
| 278 |
+
console.log(e)
|
| 279 |
+
if(e.message==="Network Error"||e.response === undefined){
|
| 280 |
+
this.show_snackbar(this.i18n.error_network)
|
| 281 |
+
this.loading = false;
|
| 282 |
+
}else {
|
| 283 |
+
this.show_snackbar(this.i18n.error+":" + e.response.data.msg)
|
| 284 |
+
this.loading = false;
|
| 285 |
+
}
|
| 286 |
+
}
|
| 287 |
+
|
| 288 |
+
},
|
| 289 |
+
async google_translate(text){
|
| 290 |
+
let params = {client: "gtx", dt: "t", sl: "ja", tl: this.trans_target_lang, q: text};
|
| 291 |
+
try {
|
| 292 |
+
let result = await axios.get("https://translate.googleapis.com/translate_a/single",{
|
| 293 |
+
params:params
|
| 294 |
+
});
|
| 295 |
+
let out = "";
|
| 296 |
+
let lines = result.data[0];
|
| 297 |
+
for(let i in lines)
|
| 298 |
+
out += lines[i][0];
|
| 299 |
+
return out;
|
| 300 |
+
}catch(e){
|
| 301 |
+
this.show_snackbar(this.i18n.error_failed_translate+":"+e.message);
|
| 302 |
+
}
|
| 303 |
+
return "";
|
| 304 |
+
},
|
| 305 |
+
async ja_tts(line){
|
| 306 |
+
let text = this.lyric[line].s;
|
| 307 |
+
if(this.speaking !== -1||text === ""){
|
| 308 |
+
return;
|
| 309 |
+
}
|
| 310 |
+
|
| 311 |
+
this.speaking = line;
|
| 312 |
+
try{
|
| 313 |
+
let context = new AudioContext();
|
| 314 |
+
let gain = context.createGain();
|
| 315 |
+
gain.gain.value=2;
|
| 316 |
+
if(this.tts_cache[text] === undefined){
|
| 317 |
+
this.tts_loading=true;
|
| 318 |
+
let audio_query = (await axios.post("https://voicevox-skytnt.cloud.okteto.net/audio_query",null,
|
| 319 |
+
{params:{speaker:4,text:text}})).data;
|
| 320 |
+
let wave = (await axios.post("https://voicevox-skytnt.cloud.okteto.net/synthesis",audio_query,
|
| 321 |
+
{params:{speaker:4},responseType:"arraybuffer"})).data;
|
| 322 |
+
this.tts_loading=false;
|
| 323 |
+
this.tts_cache[text] = await context.decodeAudioData(wave);
|
| 324 |
+
}
|
| 325 |
+
let source = context.createBufferSource();
|
| 326 |
+
source.buffer = this.tts_cache[text];
|
| 327 |
+
source.loop = false;
|
| 328 |
+
source.connect(gain);
|
| 329 |
+
gain.connect(context.destination);
|
| 330 |
+
await new Promise((resolve) => {
|
| 331 |
+
source.onended = () => {resolve()}
|
| 332 |
+
source.start(0);//立即播放
|
| 333 |
+
});
|
| 334 |
+
}catch (e) {
|
| 335 |
+
this.show_snackbar(this.i18n.error+":"+e.message)
|
| 336 |
+
}
|
| 337 |
+
this.speaking = -1;
|
| 338 |
+
this.tts_loading=false;//防止网络出错导致tts_loading为true
|
| 339 |
+
},
|
| 340 |
+
copy_lyric(attr_name){
|
| 341 |
+
let text = ""
|
| 342 |
+
for(let i in this.lyric){
|
| 343 |
+
text += this.lyric[i][attr_name] + "\n"
|
| 344 |
+
}
|
| 345 |
+
text = text.trim()
|
| 346 |
+
this.copy(text)
|
| 347 |
+
},
|
| 348 |
+
async copy(text){
|
| 349 |
+
try {
|
| 350 |
+
await navigator.clipboard.writeText(text)
|
| 351 |
+
this.show_snackbar(this.i18n.copy_successful)
|
| 352 |
+
}catch (e) {
|
| 353 |
+
let input = document.createElement('textarea')
|
| 354 |
+
input.style.position = 'fixed'
|
| 355 |
+
input.style.top = '-10000px'
|
| 356 |
+
input.style.zIndex = '-999'
|
| 357 |
+
document.body.appendChild(input)
|
| 358 |
+
console.log('input', input)
|
| 359 |
+
input.value = text
|
| 360 |
+
input.focus()
|
| 361 |
+
input.select()
|
| 362 |
+
try {
|
| 363 |
+
let result = document.execCommand('copy')
|
| 364 |
+
if (!result || result === 'unsuccessful') {
|
| 365 |
+
this.show_snackbar(this.i18n.error_copy)
|
| 366 |
+
} else {
|
| 367 |
+
this.show_snackbar(this.i18n.copy_successful)
|
| 368 |
+
}
|
| 369 |
+
} catch (e) {
|
| 370 |
+
this.show_snackbar(this.i18n.error_copy)
|
| 371 |
+
}finally {
|
| 372 |
+
document.body.removeChild(input)
|
| 373 |
+
}
|
| 374 |
+
}
|
| 375 |
+
},
|
| 376 |
+
show_snackbar(msg){
|
| 377 |
+
this.snackbar=true;
|
| 378 |
+
this.snackbar_msg=msg;
|
| 379 |
+
}
|
| 380 |
+
}
|
| 381 |
+
}
|
| 382 |
+
|
| 383 |
+
</script>
|
frontend/src/main.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import Vue from 'vue'
|
| 2 |
+
import App from './App.vue'
|
| 3 |
+
import vuetify from './plugins/vuetify'
|
| 4 |
+
import router from './router'
|
| 5 |
+
|
| 6 |
+
Vue.config.productionTip = false
|
| 7 |
+
|
| 8 |
+
new Vue({
|
| 9 |
+
vuetify,
|
| 10 |
+
router,
|
| 11 |
+
render: h => h(App)
|
| 12 |
+
}).$mount('#app')
|
frontend/src/plugins/vuetify.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import Vue from 'vue';
|
| 2 |
+
import Vuetify from 'vuetify/lib/framework';
|
| 3 |
+
|
| 4 |
+
Vue.use(Vuetify);
|
| 5 |
+
|
| 6 |
+
export default new Vuetify({
|
| 7 |
+
});
|
frontend/src/router/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import Vue from 'vue'
|
| 2 |
+
import VueRouter from 'vue-router'
|
| 3 |
+
|
| 4 |
+
Vue.use(VueRouter)
|
| 5 |
+
|
| 6 |
+
const routes = [
|
| 7 |
+
// {
|
| 8 |
+
// path: '/',
|
| 9 |
+
// name: 'Home',
|
| 10 |
+
// component: Home
|
| 11 |
+
// }
|
| 12 |
+
]
|
| 13 |
+
|
| 14 |
+
const router = new VueRouter({
|
| 15 |
+
routes
|
| 16 |
+
})
|
| 17 |
+
|
| 18 |
+
export default router
|
frontend/vue.config.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
module.exports = {
|
| 2 |
+
transpileDependencies: [
|
| 3 |
+
'vuetify'
|
| 4 |
+
],
|
| 5 |
+
publicPath: '',
|
| 6 |
+
productionSourceMap: false
|
| 7 |
+
}
|
frontend/yarn.lock
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
static/css/chunk-vendors.67710748.css
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
static/index.html
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>日语歌词生成器</title><link rel="stylesheet" href="font/roboto.css"><link rel="stylesheet" href="font/materialdesignicons.min.css"><link href="css/chunk-vendors.67710748.css" rel="preload" as="style"><link href="js/app.1cddaf0c.js" rel="preload" as="script"><link href="js/chunk-vendors.4a28e83e.js" rel="preload" as="script"><link href="css/chunk-vendors.67710748.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but lyric-generator doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.4a28e83e.js"></script><script src="js/app.1cddaf0c.js"></script></body></html>
|
|
|
|
|
|
static/js/app.1cddaf0c.js
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
(function(t){function e(e){for(var a,s,i=e[0],l=e[1],c=e[2],p=0,_=[];p<i.length;p++)s=i[p],Object.prototype.hasOwnProperty.call(n,s)&&n[s]&&_.push(n[s][0]),n[s]=0;for(a in l)Object.prototype.hasOwnProperty.call(l,a)&&(t[a]=l[a]);u&&u(e);while(_.length)_.shift()();return o.push.apply(o,c||[]),r()}function r(){for(var t,e=0;e<o.length;e++){for(var r=o[e],a=!0,i=1;i<r.length;i++){var l=r[i];0!==n[l]&&(a=!1)}a&&(o.splice(e--,1),t=s(s.s=r[0]))}return t}var a={},n={app:0},o=[];function s(e){if(a[e])return a[e].exports;var r=a[e]={i:e,l:!1,exports:{}};return t[e].call(r.exports,r,r.exports,s),r.l=!0,r.exports}s.m=t,s.c=a,s.d=function(t,e,r){s.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},s.r=function(t){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},s.t=function(t,e){if(1&e&&(t=s(t)),8&e)return t;if(4&e&&"object"===typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(s.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var a in t)s.d(r,a,function(e){return t[e]}.bind(null,a));return r},s.n=function(t){var e=t&&t.__esModule?function(){return t["default"]}:function(){return t};return s.d(e,"a",e),e},s.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},s.p="";var i=window["webpackJsonp"]=window["webpackJsonp"]||[],l=i.push.bind(i);i.push=e,i=i.slice();for(var c=0;c<i.length;c++)e(i[c]);var u=l;o.push([0,"chunk-vendors"]),r()})({0:function(t,e,r){t.exports=r("56d7")},"56d7":function(t,e,r){"use strict";r.r(e);r("e260"),r("e6cf"),r("cca6"),r("a79d");var a=r("2b0e"),n=function(){var t=this,e=t.$createElement,r=t._self._c||e;return r("v-app",[r("v-app-bar",{attrs:{app:"",dark:"",color:"primary"}},[r("v-toolbar-title",[t._v(t._s(t.i18n.title))]),r("v-spacer"),r("v-select",{staticStyle:{"max-width":"10rem"},attrs:{items:["English","Chinese"],"prepend-icon":"mdi-web","hide-details":""},on:{change:function(e){return t.set_locale(t.locale_name)}},model:{value:t.locale_name,callback:function(e){t.locale_name=e},expression:"locale_name"}}),r("v-btn",{attrs:{href:"https://github.com/SkyTNT/gpt2-japanese-lyric",icon:""}},[r("v-icon",[t._v("mdi-github")])],1),r("v-btn",{attrs:{href:"https://fab.moe",icon:""}},[r("v-icon",[t._v("mdi-home")])],1)],1),r("v-main",[t.loading_kuroshiro?r("v-container",{staticStyle:{height:"100%"},attrs:{fluid:""}},[r("div",{staticClass:"py-2 d-flex flex-column justify-center align-center",staticStyle:{height:"100%"}},[r("v-progress-circular",{attrs:{color:"blue",indeterminate:""}}),r("label",{staticClass:"py-4 text"},[t._v(t._s(t.i18n.loading))])],1)]):t._e(),t.loading_kuroshiro?t._e():r("v-row",{staticClass:"mx-3"},[r("div",{staticClass:"col-12 offset-0 col-sm-8 offset-sm-2 col-md-8 offset-md-2 col-lg-6 offset-lg-3 col-xl-6 offset-xl-3 mt-8"},[r("v-textarea",{attrs:{label:t.i18n.input_title_label,disabled:t.loading,rows:"1","prepend-icon":"mdi-comment",hint:t.i18n.input_title_hint,"no-resize":""},model:{value:t.prompt_title,callback:function(e){t.prompt_title=e},expression:"prompt_title"}}),r("v-textarea",{attrs:{label:t.i18n.input_text_label,disabled:t.loading,rows:"2","prepend-icon":"mdi-comment",hint:t.i18n.input_text_hint,"no-resize":""},model:{value:t.prompt_text,callback:function(e){t.prompt_text=e},expression:"prompt_text"}}),r("v-row",[r("v-checkbox",{staticClass:"col-6",attrs:{disabled:t.loading,label:t.i18n.show_romaji},on:{change:function(e){t.show_type=t.show_romaji?0:1}},model:{value:t.show_romaji,callback:function(e){t.show_romaji=e},expression:"show_romaji"}}),r("v-scroll-x-transition",[t.show_romaji?r("v-select",{staticClass:"col-6",attrs:{disabled:t.loading,items:t.romaji_systems,hint:t.i18n.romaji_system},model:{value:t.romaji_system,callback:function(e){t.romaji_system=e},expression:"romaji_system"}}):t._e()],1)],1),r("v-row",{staticClass:"mt-n8"},[r("v-checkbox",{staticClass:"col-6",attrs:{disabled:t.loading,label:t.i18n.use_translate},on:{change:function(e){t.show_type=t.use_trans?1:0}},model:{value:t.use_trans,callback:function(e){t.use_trans=e},expression:"use_trans"}}),r("v-scroll-x-transition",[t.use_trans?r("v-select",{staticClass:"col-6",attrs:{disabled:t.loading,items:t.google_supported_languages,hint:t.i18n.target_lang},model:{value:t.trans_target_lang,callback:function(e){t.trans_target_lang=e},expression:"trans_target_lang"}}):t._e()],1)],1),r("v-btn",{staticClass:"mb-10",attrs:{color:"primary",elevation:"5",loading:t.loading,text:"",block:"",large:"",tile:""},on:{click:function(e){return t.do_gen(0)}}},[t._v(t._s(t.i18n.generate))]),r("v-expand-transition",[0!==t.lyric.length?r("v-simple-table",{staticClass:"py-5",attrs:{dense:""},scopedSlots:t._u([{key:"default",fn:function(){return[r("thead",[r("tr",[r("th",[t._v(t._s(t.i18n.lyric)),r("v-btn",{staticClass:"ml-2",attrs:{elevation:"0",fab:"","x-small":""},on:{click:function(e){return t.copy_lyric("s")}}},[r("v-icon",[t._v("mdi-content-copy")])],1)],1),r("v-scroll-x-transition",[t.use_trans||t.show_romaji?r("th",[t.show_romaji&&!t.use_trans?r("span",[t._v(t._s(t.i18n.romaji))]):t._e(),!t.show_romaji&&t.use_trans?r("span",[t._v(t._s(t.i18n.translation))]):t._e(),t.use_trans&&t.show_romaji?r("v-btn",{staticClass:"mr-n2",attrs:{elevation:"0",text:"",small:""},on:{click:function(e){t.show_type=0===t.show_type?1:0}}},[t.show_romaji?r("span",{class:{"grey--text":1===t.show_type}},[t._v(t._s(t.i18n.romaji_s))]):t._e(),t._v("/"),t.use_trans?r("span",{class:{"grey--text":0===t.show_type}},[t._v(t._s(t.i18n.translation_s))]):t._e()]):t._e(),r("v-btn",{staticClass:"ml-2",attrs:{elevation:"0",fab:"","x-small":""},on:{click:function(e){return t.copy_lyric(0===t.show_type?"r":"t")}}},[r("v-icon",[t._v("mdi-content-copy")])],1)],1):t._e()])],1)]),r("tbody",{staticStyle:{"word-break":"break-word","word-wrap":"break-word"}},t._l(t.lyric,(function(e,a){return r("tr",{key:a,on:{mouseenter:function(e){t.hover=a},mouseleave:function(e){t.hover=-1}}},[r("td",{class:{"text-h6":0===a,"text-center":!e.is_lyric}},[t._v(" "+t._s(e.s)+" "),t.tts_support?r("v-scroll-x-transition",[t.tts_loading||""===e.s||t.speaking!==a&&(-1!==t.speaking||t.hover!==a)?t._e():r("v-btn",{class:{"mr-n9":!0,"blue--text":t.speaking===a},attrs:{icon:"",small:""},on:{click:function(e){return t.ja_tts(a)}}},[r("v-icon",[t._v("mdi-volume-high")])],1)],1):t._e(),t.tts_support&&t.speaking===a&&t.tts_loading?r("v-progress-circular",{staticClass:"mr-n9",attrs:{indeterminate:"",size:"20",width:"2",color:"primary"}}):t._e()],1),r("v-scroll-x-transition",[t.use_trans||t.show_romaji?r("td",{class:{"text-center":!e.is_lyric}},[t._v(t._s(0===t.show_type?e.r:e.t))]):t._e()])],1)})),0)]},proxy:!0}],null,!1,3397400449)}):t._e()],1)],1)]),r("v-snackbar",{attrs:{dark:"",timeout:2e3},scopedSlots:t._u([{key:"action",fn:function(e){var a=e.attrs;return[r("v-btn",t._b({attrs:{color:"blue",text:""},on:{click:function(e){t.snackbar=!1}}},"v-btn",a,!1),[t._v(" Close ")])]}}]),model:{value:t.snackbar,callback:function(e){t.snackbar=e},expression:"snackbar"}},[t._v(" "+t._s(t.snackbar_msg)+" ")])],1),r("v-footer",[r("v-row",{staticClass:"ma-0"},[r("div",{staticClass:"text-center caption col-12 pa-0"},[t._v(t._s(t.i18n.footer))]),r("div",{staticClass:"text-center caption col-12 pa-0"},[t._v("© 2022 SkyTNT")])])],1)],1)},o=[],s=r("1da1"),i=(r("96cf"),r("498a"),r("ac1f"),r("5319"),r("00b4"),r("99af"),r("1276"),r("d3b7"),r("bc3a")),l=r.n(i),c=r("1539"),u=r("856a");function p(){return/(iPhone|iPad|iPod|iOS|Android|Windows Phone)/i.test(navigator.userAgent)}String.prototype.trim||(String.prototype.trim=function(){return this.triml().trimr()},String.prototype.triml=function(){return this.replace(/^[\s\n\t]+/g,"")},String.prototype.trimr=function(){return this.replace(/[\s\n\t]+$/g,"")});var _={name:"App",data:function(){return{locale_name:"English",i18n:{},use_trans:!1,google_supported_languages:["af","sq","am","ar","hy","az","eu","be","bn","bs","bg","my","ca","ca","ceb","co","cs","da","nl","nl","en","eo","et","fi","fr","fy","ka","de","gd","gd","ga","gl","el","gu","ht","ht","ha","haw","he","hi","hr","hu","ig","is","id","it","jw","ja","kn","kk","km","ky","ky","ko","ku","lo","la","lv","lt","lb","lb","mk","ml","mi","mr","ms","mg","mt","mn","ne","no","ny","ny","ny","or","pa","pa","fa","pl","pt","ps","ps","ro","ro","ro","ru","si","si","sk","sl","sm","sn","sd","so","st","es","es","sr","su","sw","sv","ta","te","tg","tl","th","tr","ug","ug","uk","ur","uz","vi","cy","xh","yi","yo","zu","zh-CN","zh-TW"],trans_target_lang:"zh-CN",show_romaji:!1,show_type:0,romaji_systems:["nippon","passport","hepburn"],romaji_system:"hepburn",prompt_title:"桜",prompt_text:"",loading_kuroshiro:!0,loading:!1,lyric:[],tts_cache:{},tts_loading:!1,tts_support:!1,speaking:-1,hover:-1,snackbar:!1,snackbar_msg:"",kuroshiro:new c["a"]}},mounted:function(){this.locale_name="zh-CN"===(navigator.language||navigator.userLanguage)?"Chinese":"English","English"===this.locale_name&&(this.trans_target_lang="en"),this.set_locale(this.locale_name),this.loads()},methods:{set_locale:function(t){var e="English"===t?"en":"zh",r={en:{title:"Japanese Lyric Generator",loading:"Loading",input_title_label:"Title (can be empty)",input_text_label:"Beginning (can be empty)",input_title_hint:"Generate lyric for a given title",input_text_hint:"The generator continues with this text",show_romaji:"Show romaji",romaji_system:"Romaji system",use_translate:"Translate",target_lang:"Target language",generate:"Generate!",lyric:"Lyric",romaji:"Romaji",romaji_s:"R",translation:"Translation",translation_s:"T",footer:"The generated content can be used as you like, please share this site if you like.",copy_successful:"Copy successful",error:"Error",error_network:"Network error",error_failed_load_kuromoji:"Failed to load romaji converter",error_failed_covert_romaji:"Failed to convert lyric to romaji",error_failed_translate:"Failed to translate lyric",error_copy:"Copy failed, browser does not support"},zh:{title:"日语歌词生成器",loading:"加载中",input_title_label:"歌词标题(可不填)",input_text_label:"歌词开头(可不填)",input_title_hint:"给定标题生成歌词",input_text_hint:"生成器��这段文本进行续写",show_romaji:"显示罗马音",romaji_system:"罗马音系统",use_translate:"是否进行翻译",target_lang:"目标语言",generate:"生成!",lyric:"歌词",romaji:"罗马音",romaji_s:"音",translation:"翻译",translation_s:"译",footer:"生成的内容可以随意使用,喜欢的话就请分享本网站",copy_successful:"复制成功",error:"错误",error_network:"网络错误",error_failed_load_kuromoji:"罗马音转换器加载失败",error_failed_covert_romaji:"转换罗马音错误",error_failed_translate:"翻译出错",error_copy:"复制失败,浏览器不支持"}};this.i18n=r[e]},loads:function(){var t=this;return Object(s["a"])(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return e.next=2,t.load_kuroshiro();case 2:if(p()){e.next=8;break}return e.t0=eval,e.next=6,l.a.get("https://l2d.fab.moe/js/autoload.js");case 6:e.t1=e.sent.data,(0,e.t0)(e.t1);case 8:case"end":return e.stop()}}),e)})))()},load_kuroshiro:function(){var t=this;return Object(s["a"])(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,t.kuroshiro.init(new u["a"]({dictPath:"dict/"}));case 3:e.next=9;break;case 5:e.prev=5,e.t0=e["catch"](0),t.show_snackbar(t.i18n.error_failed_load_kuromoji+":"+e.t0.message),console.log(e.t0);case 9:t.loading_kuroshiro=!1,console.log("kuroshiro loaded");case 11:case"end":return e.stop()}}),e,null,[[0,5]])})))()},do_gen:function(){var t=this;return Object(s["a"])(regeneratorRuntime.mark((function e(){var r,a,n,o,s,i,c,u,p,_,m;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return r=t.prompt_title.trim(),a=t.prompt_text.trim(),t.loading=!0,t.lyric=[],t.tts_cache={},e.prev=5,e.next=8,l.a.post("gen",{title:r,text:a});case 8:for(i in n=e.sent,o="".concat(n.data.title,"\n\n").concat(n.data.lyric),s=o.split("\n"),s)c=s[i].trim().replace(/ /g," "),t.lyric.push({s:c,r:"",t:"",is_lyric:"---end---"!==c});return t.lyric[0].is_lyric=!1,e.prev=13,e.next=16,t.kuroshiro.convert(o,{to:"romaji",mode:"spaced",romajiSystem:t.romaji_system});case 16:for(p in u=e.sent,u=u.split("\n"),u)t.lyric[p].r=u[p];e.next=24;break;case 21:e.prev=21,e.t0=e["catch"](13),t.show_snackbar(t.i18n.error_failed_covert_romaji+":"+e.t0.message);case 24:if(!t.use_trans){e.next=29;break}return e.next=27,t.google_translate(o);case 27:if(_=e.sent,""!==_)for(m in _=_.split("\n"),_)t.lyric[m].t=_[m].trim().replace(/ /g," ");case 29:t.loading=!1,e.next=36;break;case 32:e.prev=32,e.t1=e["catch"](5),console.log(e.t1),"Network Error"===e.t1.message||void 0===e.t1.response?(t.show_snackbar(t.i18n.error_network),t.loading=!1):(t.show_snackbar(t.i18n.error+":"+e.t1.response.data.msg),t.loading=!1);case 36:case"end":return e.stop()}}),e,null,[[5,32],[13,21]])})))()},google_translate:function(t){var e=this;return Object(s["a"])(regeneratorRuntime.mark((function r(){var a,n,o,s,i;return regeneratorRuntime.wrap((function(r){while(1)switch(r.prev=r.next){case 0:return a={client:"gtx",dt:"t",sl:"ja",tl:e.trans_target_lang,q:t},r.prev=1,r.next=4,l.a.get("https://translate.googleapis.com/translate_a/single",{params:a});case 4:for(i in n=r.sent,o="",s=n.data[0],s)o+=s[i][0];return r.abrupt("return",o);case 11:r.prev=11,r.t0=r["catch"](1),e.show_snackbar(e.i18n.error_failed_translate+":"+r.t0.message);case 14:return r.abrupt("return","");case 15:case"end":return r.stop()}}),r,null,[[1,11]])})))()},ja_tts:function(t){var e=this;return Object(s["a"])(regeneratorRuntime.mark((function r(){var a,n,o,s,i,c;return regeneratorRuntime.wrap((function(r){while(1)switch(r.prev=r.next){case 0:if(a=e.lyric[t].s,-1===e.speaking&&""!==a){r.next=3;break}return r.abrupt("return");case 3:if(e.speaking=t,r.prev=4,n=new AudioContext,o=n.createGain(),o.gain.value=2,void 0!==e.tts_cache[a]){r.next=20;break}return e.tts_loading=!0,r.next=12,l.a.post("https://voicevox-skytnt.cloud.okteto.net/audio_query",null,{params:{speaker:4,text:a}});case 12:return s=r.sent.data,r.next=15,l.a.post("https://voicevox-skytnt.cloud.okteto.net/synthesis",s,{params:{speaker:4},responseType:"arraybuffer"});case 15:return i=r.sent.data,e.tts_loading=!1,r.next=19,n.decodeAudioData(i);case 19:e.tts_cache[a]=r.sent;case 20:return c=n.createBufferSource(),c.buffer=e.tts_cache[a],c.loop=!1,c.connect(o),o.connect(n.destination),r.next=27,new Promise((function(t){c.onended=function(){t()},c.start(0)}));case 27:r.next=32;break;case 29:r.prev=29,r.t0=r["catch"](4),e.show_snackbar(e.i18n.error+":"+r.t0.message);case 32:e.speaking=-1,e.tts_loading=!1;case 34:case"end":return r.stop()}}),r,null,[[4,29]])})))()},copy_lyric:function(t){var e="";for(var r in this.lyric)e+=this.lyric[r][t]+"\n";e=e.trim(),this.copy(e)},copy:function(t){var e=this;return Object(s["a"])(regeneratorRuntime.mark((function r(){var a,n;return regeneratorRuntime.wrap((function(r){while(1)switch(r.prev=r.next){case 0:return r.prev=0,r.next=3,navigator.clipboard.writeText(t);case 3:e.show_snackbar(e.i18n.copy_successful),r.next=18;break;case 6:r.prev=6,r.t0=r["catch"](0),a=document.createElement("textarea"),a.style.position="fixed",a.style.top="-10000px",a.style.zIndex="-999",document.body.appendChild(a),console.log("input",a),a.value=t,a.focus(),a.select();try{n=document.execCommand("copy"),n&&"unsuccessful"!==n?e.show_snackbar(e.i18n.copy_successful):e.show_snackbar(e.i18n.error_copy)}catch(o){e.show_snackbar(e.i18n.error_copy)}finally{document.body.removeChild(a)}case 18:case"end":return r.stop()}}),r,null,[[0,6]])})))()},show_snackbar:function(t){this.snackbar=!0,this.snackbar_msg=t}}},m=_,d=r("2877"),h=r("6544"),g=r.n(h),f=r("7496"),v=r("40dc"),b=r("8336"),y=r("ac7c"),k=r("a523"),x=r("0789"),w=r("553a"),j=r("132d"),C=r("f6c4"),S=r("490a"),T=r("0fd9"),O=r("b974"),V=r("1f4f"),R=r("2db4"),P=r("2fa4"),z=r("a844"),E=r("2a7f"),A=Object(d["a"])(m,n,o,!1,null,null,null),N=A.exports;g()(A,{VApp:f["a"],VAppBar:v["a"],VBtn:b["a"],VCheckbox:y["a"],VContainer:k["a"],VExpandTransition:x["a"],VFooter:w["a"],VIcon:j["a"],VMain:C["a"],VProgressCircular:S["a"],VRow:T["a"],VScrollXTransition:x["d"],VSelect:O["a"],VSimpleTable:V["a"],VSnackbar:R["a"],VSpacer:P["a"],VTextarea:z["a"],VToolbarTitle:E["a"]});var M=r("f309");a["a"].use(M["a"]);var B=new M["a"]({}),F=r("8c4f");a["a"].use(F["a"]);var G=[],L=new F["a"]({routes:G}),q=L;a["a"].config.productionTip=!1,new a["a"]({vuetify:B,router:q,render:function(t){return t(N)}}).$mount("#app")}});
|
|
|
|
|
|
static/js/chunk-vendors.4a28e83e.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|