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
|
|