diff --git a/.vscode/launch.json b/.vscode/launch.json index 7e69fb8..e071eaa 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,7 @@ "name": "Python: Web", "type": "python", "request": "launch", - "program": "${workspaceFolder}/web/app.py", + "program": "web.py", "console": "integratedTerminal" }, { diff --git a/requirements.txt b/requirements.txt index 2c15ccb..f8aec04 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,4 +14,8 @@ PyQt5 multiprocess numba webrtcvad; platform_system != "Windows" -pypinyin \ No newline at end of file +pypinyin +flask +flask_wtf +flask_cors +gevent==21.8.0 diff --git a/synthesizer/hparams.py b/synthesizer/hparams.py index 77db2ce..897b6d4 100644 --- a/synthesizer/hparams.py +++ b/synthesizer/hparams.py @@ -49,12 +49,12 @@ hparams = HParams( # frame that has all values < -3.4 ### Tacotron Training - tts_schedule = [(2, 1e-3, 20_000, 12), # Progressive training schedule - (2, 5e-4, 40_000, 12), # (r, lr, step, batch_size) - (2, 2e-4, 80_000, 12), # - (2, 1e-4, 160_000, 12), # r = reduction factor (# of mel frames - (2, 3e-5, 320_000, 12), # synthesized for each decoder iteration) - (2, 1e-5, 640_000, 12)], # lr = learning rate + tts_schedule = [(2, 1e-3, 20_000, 24), # Progressive training schedule + (2, 5e-4, 40_000, 24), # (r, lr, step, batch_size) + (2, 2e-4, 80_000, 24), # + (2, 1e-4, 160_000, 24), # r = reduction factor (# of mel frames + (2, 3e-5, 320_000, 24), # synthesized for each decoder iteration) + (2, 1e-5, 640_000, 24)], # lr = learning rate tts_clip_grad_norm = 1.0, # clips the gradient norm to prevent explosion - set to None if not needed tts_eval_interval = 500, # Number of steps between model evaluation (sample generation) diff --git a/web.py b/web.py new file mode 100644 index 0000000..56ac93c --- /dev/null +++ b/web.py @@ -0,0 +1,11 @@ +from web import webApp +from gevent import pywsgi as wsgi + + +if __name__ == "__main__": + app = webApp() + host = app.config.get("HOST") + port = app.config.get("PORT") + print(f"Web server: http://{host}:{port}") + server = wsgi.WSGIServer((host, port), app) + server.serve_forever() diff --git a/web/DOCKERFILE b/web/DOCKERFILE new file mode 100644 index 0000000..64e8c53 --- /dev/null +++ b/web/DOCKERFILE @@ -0,0 +1,10 @@ + +FROM python:3.7 + +RUN pip install gevent uwsgi flask + +COPY app.py /app.py + +EXPOSE 3000 + +ENTRYPOINT ["uwsgi", "--http", ":3000", "--master", "--module", "app:app"] \ No newline at end of file diff --git a/web/__init__.py b/web/__init__.py new file mode 100644 index 0000000..91e071c --- /dev/null +++ b/web/__init__.py @@ -0,0 +1,167 @@ +import os +from pathlib import Path +from gevent import pywsgi as wsgi +from flask import Flask, jsonify, Response, request, render_template +from synthesizer.inference import Synthesizer +from encoder import inference as encoder +from vocoder.hifigan import inference as gan_vocoder +from vocoder.wavernn import inference as rnn_vocoder +import numpy as np +import re +from scipy.io.wavfile import write, read +import io +import base64 +from flask_cors import CORS +from flask_wtf import CSRFProtect + +def webApp(): + # Init and load config + app = Flask(__name__, instance_relative_config=True) + + app.config.from_object("web.config.default") + + CORS(app) #允许跨域,注释掉此行则禁止跨域请求 + csrf = CSRFProtect(app) + csrf.init_app(app) + # API For Non-Trainer + # 1. list sample audio files + # 2. record / upload / select audio files + # 3. load melspetron of audio + # 4. inference by audio + text + models(encoder, vocoder, synthesizer) + # 5. export result + audio_samples = [] + AUDIO_SAMPLES_DIR = app.config.get("AUDIO_SAMPLES_DIR") + if os.path.isdir(AUDIO_SAMPLES_DIR): + audio_samples = list(Path(AUDIO_SAMPLES_DIR).glob("*.wav")) + print("Loaded samples: " + str(len(audio_samples))) + # enc_models_dir = "encoder/saved_models" + # voc_models_di = "vocoder/saved_models" + # encoders = list(Path(enc_models_dir).glob("*.pt")) + # vocoders = list(Path(voc_models_di).glob("**/*.pt")) + syn_models_dirt = "synthesizer/saved_models" + synthesizers = list(Path(syn_models_dirt).glob("**/*.pt")) + # print("Loaded encoder models: " + str(len(encoders))) + # print("Loaded vocoder models: " + str(len(vocoders))) + print("Loaded synthesizer models: " + str(len(synthesizers))) + synthesizers_cache = {} + encoder.load_model(Path("encoder/saved_models/pretrained.pt")) + gan_vocoder.load_model(Path("vocoder/saved_models/pretrained/g_hifigan.pt")) + + # TODO: move to utils + def generate(wav_path): + with open(wav_path, "rb") as fwav: + data = fwav.read(1024) + while data: + yield data + data = fwav.read(1024) + + @app.route("/api/audios", methods=["GET"]) + def audios(): + return jsonify( + {"data": list(a.name for a in audio_samples), "total": len(audio_samples)} + ) + + @app.route("/api/audios/", methods=["GET"]) + def audio_play(name): + return Response(generate(AUDIO_SAMPLES_DIR + name), mimetype="audio/x-wav") + + @app.route("/api/models", methods=["GET"]) + def models(): + return jsonify( + { + # "encoder": list(e.name for e in encoders), + # "vocoder": list(e.name for e in vocoders), + "synthesizers": + list({"name": e.name, "path": str(e)} for e in synthesizers), + } + ) + + def pcm2float(sig, dtype='float32'): + """Convert PCM signal to floating point with a range from -1 to 1. + Use dtype='float32' for single precision. + Parameters + ---------- + sig : array_like + Input array, must have integral type. + dtype : data type, optional + Desired (floating point) data type. + Returns + ------- + numpy.ndarray + Normalized floating point data. + See Also + -------- + float2pcm, dtype + """ + sig = np.asarray(sig) + if sig.dtype.kind not in 'iu': + raise TypeError("'sig' must be an array of integers") + dtype = np.dtype(dtype) + if dtype.kind != 'f': + raise TypeError("'dtype' must be a floating point type") + + i = np.iinfo(sig.dtype) + abs_max = 2 ** (i.bits - 1) + offset = i.min + abs_max + return (sig.astype(dtype) - offset) / abs_max + + # Cache for synthesizer + @csrf.exempt + @app.route("/api/synthesize", methods=["POST"]) + def synthesize(): + # TODO Implementation with json to support more platform + + # Load synthesizer + if "synt_path" in request.form: + synt_path = request.form["synt_path"] + else: + synt_path = synthesizers[0] + print("NO synthsizer is specified, try default first one.") + if synthesizers_cache.get(synt_path) is None: + current_synt = Synthesizer(Path(synt_path)) + synthesizers_cache[synt_path] = current_synt + else: + current_synt = synthesizers_cache[synt_path] + print("using synthesizer model: " + str(synt_path)) + # Load input wav + wav_base64 = request.form["upfile_b64"] + wav = base64.b64decode(bytes(wav_base64, 'utf-8')) + wav = pcm2float(np.frombuffer(wav, dtype=np.int16), dtype=np.float32) + encoder_wav = encoder.preprocess_wav(wav, 16000) + embed, _, _ = encoder.embed_utterance(encoder_wav, return_partials=True) + + # Load input text + texts = request.form["text"].split("\n") + punctuation = '!,。、,' # punctuate and split/clean text + processed_texts = [] + for text in texts: + for processed_text in re.sub(r'[{}]+'.format(punctuation), '\n', text).split('\n'): + if processed_text: + processed_texts.append(processed_text.strip()) + texts = processed_texts + + # synthesize and vocode + embeds = [embed] * len(texts) + specs = current_synt.synthesize_spectrograms(texts, embeds) + spec = np.concatenate(specs, axis=1) + wav = gan_vocoder.infer_waveform(spec) + + # Return cooked wav + out = io.BytesIO() + write(out, Synthesizer.sample_rate, wav) + return Response(out, mimetype="audio/wav") + + @app.route('/', methods=['GET']) + def index(): + return render_template("index.html") + + host = app.config.get("HOST") + port = app.config.get("PORT") + print(f"Web server: http://{host}:{port}") + server = wsgi.WSGIServer((host, port), app) + server.serve_forever() + + return app + +if __name__ == "__main__": + webApp() \ No newline at end of file diff --git a/web/config/__init__.py b/web/config/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web/config/default.py b/web/config/default.py new file mode 100644 index 0000000..e75d266 --- /dev/null +++ b/web/config/default.py @@ -0,0 +1,7 @@ +AUDIO_SAMPLES_DIR = 'samples\\' +DEVICE = '0' +HOST = 'localhost' +PORT = 8080 +MAX_CONTENT_PATH =1024 * 1024 * 4 # mp3文件大小限定不能超过4M +SECRET_KEY = "mockingbird_key" +WTF_CSRF_SECRET_KEY = "mockingbird_key" \ No newline at end of file diff --git a/web/static/js/eruda.min.js b/web/static/js/eruda.min.js new file mode 100644 index 0000000..0609b9e --- /dev/null +++ b/web/static/js/eruda.min.js @@ -0,0 +1,2 @@ +/*! eruda v1.5.4 https://eruda.liriliri.io/ */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.eruda=t():e.eruda=t()}("undefined"!=typeof self?self:this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="/assets/",t(t.s=82)}([function(e,t,n){"use strict";(function(e,r){function i(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0}),t.wrap=t.viewportScale=t.unique=t.uniqId=t.tryIt=t.stripHtmlTag=t.LocalStore=t.stringify=t.type=t.ajax=t.Url=t.query=t.getFileName=t.trim=t.rtrim=t.rmCookie=t.pxToNum=t.perfNow=t.orientation=t.Store=t.Logger=t.Emitter=t.once=t.partial=t.restArgs=t.now=t.nextTick=t.detectBrowser=t.toInt=t.ms=t.toNum=t.meta=t.safeStorage=t.memStorage=t.$=t.$class=t.some=t.cloneDeep=t.mapObj=void 0,t.concat=t.$event=t.delegate=t.$show=t.$remove=t.$property=t.$offset=t.$insert=t.$css=t.$data=t.$attr=t.$safeEls=t.Select=t.MutationObserver=t.Enum=t.Class=t.toArr=t.cookie=t.decodeUriComponent=t.map=t.evalCss=t.filter=t.safeCb=t.matcher=t.ltrim=t.dateFormat=t.lpad=t.repeat=t.loadJs=t.isRegExp=t.isNull=t.isNative=t.toSrc=t.isNil=t.isNaN=t.prefix=t.isMobile=t.memoize=t.isMatch=t.isErudaEl=t.isErr=t.isEl=t.isCrossOrig=t.startWith=t.isBool=t.isEmpty=t.isStr=t.contain=t.values=t.extendOwn=t.clone=t.extend=t.defaults=t.createAssigner=t.each=t.isArrLike=t.isNum=t.isMiniProgram=t.isFn=t.isDate=t.safeGet=t.castPath=t.isArr=t.isArgs=t.objToStr=t.identity=t.getObjType=t.upperFirst=t.fullUrl=t.fileSize=t.escapeRegExp=t.escapeJsonStr=t.escapeJsStr=t.escape=t.endWith=t.optimizeCb=t.detectOs=t.freeze=t.keys=t.detectMocha=t.root=t.utf8=t.ucs2=t.toStr=t.idxOf=t.clamp=t.chunk=t.kebabCase=t.camelCase=t.splitCase=t.before=t.allKeys=t.noop=t.isBrowser=t.slice=t.has=t.inherits=t.isObj=t.isUndef=t.last=void 0;var o=n(28),a=i(o),s=n(123),u=i(s),l=n(66),c=i(l),d=n(34),f=i(d),p=n(130),h=i(p),v=n(35),g=i(v),m=n(135),_=i(m),b=n(73),y=i(b),x=n(25),w=i(x),k={},E=k.last=function(){function e(e){var t=e?e.length:0;if(t)return e[t-1]}return e}();t.last=E;var S=t.isUndef=k.isUndef=function(){function e(e){return void 0===e}return e}(),T=t.isObj=k.isObj=function(){function e(e){var t=void 0===e?"undefined":(0,w.default)(e);return!!e&&("function"===t||"object"===t)}return e}(),O=t.inherits=k.inherits=function(){function e(e,r){if(n)return e.prototype=n(r.prototype);t.prototype=r.prototype,e.prototype=new t}function t(){}var n=y.default;return e}(),A=t.has=k.has=function(){function e(e,n){return t.call(e,n)}var t=Object.prototype.hasOwnProperty;return e}(),C=t.slice=k.slice=function(){function e(e,t,n){var r=e.length;t=null==t?0:t<0?Math.max(r+t,0):Math.min(t,r),n=null==n?r:n<0?Math.max(r+n,0):Math.min(n,r);for(var i=[];t0&&(n=t.apply(this,arguments)),e<=1&&(t=null),n}}return e}(),L=t.splitCase=k.splitCase=function(){function e(e){return e=e.replace(t,"-$1").toLowerCase().replace(n,"-").replace(r,""),e.split("-")}var t=/([A-Z])/g,n=/[_.\- ]+/g,r=/(^-)|(-$)/g;return e}(),N=t.camelCase=k.camelCase=function(){function e(e){var n=L(e),r=n[0];return n.shift(),n.forEach(t,n),r+=n.join("")}function t(e,t){this[t]=e.replace(/\w/,function(e){return e.toUpperCase()})}return e}(),D=t.kebabCase=k.kebabCase=function(){function e(e){return L(e).join("-")}return e}(),I=(t.chunk=k.chunk=function(){function e(e,t){var n=[];t=t||1;for(var r=0,i=Math.ceil(e.length/t);rn?n:e}return e}()),K=t.idxOf=k.idxOf=function(){function e(e,t,n){return Array.prototype.indexOf.call(e,t,n)}return e}(),z=t.toStr=k.toStr=function(){function e(e){return null==e?"":e.toString()}return e}(),F=t.ucs2=k.ucs2=function(e){return{encode:function(e){return _.default.apply(String,e)},decode:function(e){for(var t=[],n=0,r=e.length;n=55296&&i<=56319&&n>6*t)+n);t>0;){r+=f(128|63&e>>6*(t-1)),t--}return r}function n(e){for(;;){if(o>=a&&l){if(e)return r();throw new Error("Invalid byte index")}if(o===a)return!1;var t=i[o];if(o++,l){if(td){if(e)return o--,r();throw new Error("Invalid continuation byte")}if(c=128,d=191,s=s<<6|63&t,++u===l){var n=s;return s=0,l=0,u=0,n}}else{if(0==(128&t))return t;if(192==(224&t))l=1,s=31&t;else if(224==(240&t))224===t&&(c=160),237===t&&(d=159),l=2,s=15&t;else{if(240!=(248&t)){if(e)return r();throw new Error("Invalid UTF-8 detected")}240===t&&(c=144),244===t&&(d=143),l=3,s=7&t}}}}function r(){var e=o-u-1;return o=e+1,s=0,l=0,u=0,c=128,d=191,i[e]}e={encode:function(e){for(var n=F.decode(e),r="",i=0,o=n.length;i-1}return e=e||(j?navigator.userAgent:""),e=e.toLowerCase(),t("windows phone")?"windows phone":t("win")?"windows":t("android")?"android":t("ipad")||t("iphone")||t("ipod")?"ios":t("mac")?"os x":t("linux")?"linux":"unknown"}return e}(),t.optimizeCb=k.optimizeCb=function(){function e(e,t,n){if(S(t))return e;switch(null==n?3:n){case 1:return function(n){return e.call(t,n)};case 3:return function(n,r,i){return e.call(t,n,r,i)};case 4:return function(n,r,i,o){return e.call(t,n,r,i,o)}}return function(){return e.apply(t,arguments)}}return e}()),G=(t.endWith=k.endWith=function(){function e(e,t){var n=e.length-t.length;return n>=0&&e.indexOf(t,n)===n}return e}(),t.escape=k.escape=function(){function e(e){return i.test(e)?e.replace(o,t):e}function t(e){return n[e]}var n=e.map={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},r="(?:"+U(n).join("|")+")",i=new RegExp(r),o=new RegExp(r,"g");return e}(),t.escapeJsStr=k.escapeJsStr=function(){function e(e){return z(e).replace(t,function(e){switch(e){case'"':case"'":case"\\":return"\\"+e;case"\n":return"\\n";case"\r":return"\\r";case"\u2028":return"\\u2028";case"\u2029":return"\\u2029"}})}var t=/["'\\\n\r\u2028\u2029]/g;return e}()),q=(t.escapeJsonStr=k.escapeJsonStr=function(){function e(e){return G(e).replace(/\\'/g,"'").replace(/\t/g,"\\t")}return e}(),t.escapeRegExp=k.escapeRegExp=function(){function e(e){return e.replace(/\W/g,"\\$&")}return e}(),t.fileSize=k.fileSize=function(){function e(e){if(e<=0)return"0";var n=Math.floor(Math.log(e)/Math.log(1024));return+(e/Math.pow(2,10*n)).toFixed(2)+t[n]}var t=["","K","M","G","T"];return e}(),t.fullUrl=k.fullUrl=function(){function e(e){return t.href=e,t.protocol+"//"+t.host+t.pathname+t.search+t.hash}var t=document.createElement("a");return e}(),t.upperFirst=k.upperFirst=function(){function e(e){return e.length<1?e:e[0].toUpperCase()+e.slice(1)}return e}()),J=(t.getObjType=k.getObjType=function(){function e(e){return e.constructor&&e.constructor.name?e.constructor.name:q({}.toString.call(e).replace(/(\[object )|]/g,""))}return e}(),t.identity=k.identity=function(){function e(e){return e}return e}()),Y=t.objToStr=k.objToStr=function(){function e(e){return t.call(e)}var t=Object.prototype.toString;return e}(),Q=t.isArgs=k.isArgs=function(){function e(e){return"[object Arguments]"===Y(e)}return e}(),X=t.isArr=k.isArr=function(e){return Array.isArray||function(e){return"[object Array]"===Y(e)}}(),Z=t.castPath=k.castPath=function(){function e(e,r){if(X(e))return e;if(r&&A(r,e))return[e];var i=[];return e.replace(t,function(e,t,r,o){i.push(r?o.replace(n,"$1"):t||e)}),i}var t=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,n=/\\(\\)?/g;return e}(),ee=t.safeGet=k.safeGet=function(){function e(e,t){t=Z(t,e);var n;for(n=t.shift();!S(n);){if(null==(e=e[n]))return;n=t.shift()}return e}return e}(),te=t.isDate=k.isDate=function(){function e(e){return"[object Date]"===Y(e)}return e}(),ne=t.isFn=k.isFn=function(){function e(e){var t=Y(e);return"[object Function]"===t||"[object GeneratorFunction]"===t}return e}(),re=t.isMiniProgram=k.isMiniProgram=function(e){return"undefined"!=typeof wx&&ne(wx.openLocation)}(),ie=t.isNum=k.isNum=function(){function e(e){return"[object Number]"===Y(e)}return e}(),oe=t.isArrLike=k.isArrLike=function(){function e(e){if(!e)return!1;var n=e.length;return ie(n)&&n>=0&&n<=t&&!ne(e)}var t=Math.pow(2,53)-1;return e}(),ae=k.each=function(){function e(e,t,n){t=W(t,n);var r,i;if(oe(e))for(r=0,i=e.length;r=0}return e}(),he=t.isStr=k.isStr=function(){function e(e){return"[object String]"===Y(e)}return e}(),ve=t.isEmpty=k.isEmpty=function(){function e(e){return null==e||(oe(e)&&(X(e)||he(e)||Q(e))?0===e.length:0===U(e).length)}return e}(),ge=(t.isBool=k.isBool=function(){function e(e){return!0===e||!1===e}return e}(),t.startWith=k.startWith=function(){function e(e,t){return 0===e.indexOf(t)}return e}()),me=(t.isCrossOrig=k.isCrossOrig=function(){function e(e){return!ge(e,t)}var t=window.location.origin;return e}(),t.isEl=k.isEl=function(){function e(e){return!(!e||1!==e.nodeType)}return e}(),t.isErr=k.isErr=function(){function e(e){return"[object Error]"===Y(e)}return e}(),t.isErudaEl=k.isErudaEl=function(){function e(e){var t=e.parentNode;if(!t)return!1;for(;t;)if((t=t.parentNode)&&"eruda"===t.id)return!0;return!1}return e}(),t.isMatch=k.isMatch=function(){function e(e,t){var n=U(t),r=n.length;if(null==e)return!r;e=Object(e);for(var i=0;i0;)1&t&&(n+=e),t>>=1,e+=e;return n}}()),Se=t.lpad=k.lpad=function(){function e(e,t,n){e=z(e);var r=e.length;return n=n||" ",r0?"-":"+")+t(100*Math.floor(Math.abs(y)/60)+Math.abs(y)%60,4),S:["th","st","nd","rd"][f%10>3?0:(f%100-f%10!=10)*f%10]};return s.replace(n,function(e){return e in x?x[e]:e.slice(1,e.length-1)})}function t(e,t){return Se(z(e),t||2,"0")}var n=/d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZWN]|'[^']*'|'[^']*'/g,r=/\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,i=/\d/,o=/[^-+\dA-Z]/g;return e.masks={default:"ddd mmm dd yyyy HH:MM:ss",shortDate:"m/d/yy",mediumDate:"mmm d, yyyy",longDate:"mmmm d, yyyy",fullDate:"dddd, mmmm d, yyyy",shortTime:"h:MM TT",mediumTime:"h:MM:ss TT",longTime:"h:MM:ss TT Z",isoDate:"yyyy-mm-dd",isoTime:"HH:MM:ss",isoDateTime:"yyyy-mm-dd'T'HH:MM:sso",isoUtcDateTime:"UTC:yyyy-mm-dd'T'HH:MM:ss'Z'",expiresHeaderFormat:"ddd, dd mmm yyyy HH:MM:ss Z"},e.i18n={dayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],monthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec","January","February","March","April","May","June","July","August","September","October","November","December"]},e}(),t.ltrim=k.ltrim=function(){function e(e,n){if(null==n)return e.replace(t,"");for(var r,i,o=0,a=e.length,s=n.length,u=!0;u&&o=a?"":e.substr(o,a)}var t=/^\s+/;return e}()),Oe=t.matcher=k.matcher=function(){function e(e){return e=de({},e),function(t){return me(t,e)}}return e}(),Ae=t.safeCb=k.safeCb=function(e){return function(e,t,n){return null==e?J:ne(e)?W(e,t,n):T(e)?Oe(e):function(e){return function(t){return null==t?void 0:t[e]}}}}(),Ce=t.filter=k.filter=function(){function e(e,t,n){var r=[];return t=Ae(t,n),ae(e,function(e,n,i){t(e,n,i)&&r.push(e)}),r}return e}(),je=(t.evalCss=k.evalCss=function(){function e(r,i){r=z(r);for(var o=0,a=n.length;o=0&&e=t[n[s]]){a=n[s];break}return+(o/t[a]).toFixed(2)+a}var t={ms:1,s:1e3};t.m=60*t.s,t.h=60*t.m,t.d=24*t.h,t.y=365.25*t.d;var n=["y","d","h","m","s"],r=/^((?:\d+)?\.?\d+) *(s|m|h|d|y)?$/;return e}(),t.toInt=k.toInt=function(){function e(e){return e?(e=et(e))-e%1:0===e?e:0}return e}()),nt=(t.detectBrowser=k.detectBrowser=function(){function e(e){e=e||(j?navigator.userAgent:""),e=e.toLowerCase();var o=t(e,"msie ");if(o)return{version:o,name:"ie"};if(r.test(e))return{version:11,name:"ie"};for(var a=0,s=i.length;a-1)return tt(e.substring(n+t.length,e.indexOf(".",n)))}var n={edge:/edge\/([0-9._]+)/,firefox:/firefox\/([0-9.]+)(?:\s|$)/,opera:/opera\/([0-9.]+)(?:\s|$)/,android:/android\s([0-9.]+)/,ios:/version\/([0-9._]+).*mobile.*safari.*/,safari:/version\/([0-9._]+).*safari/,chrome:/(?!chrom.*opr)chrom(?:e|ium)\/([0-9.]+)(:?\s|$)/},r=/trident\/7\./,i=U(n);return e}(),t.nextTick=k.nextTick=function(e){function t(e){if("function"!=typeof e)throw new TypeError(e+" is not a function");return e}return"object"===(void 0===r?"undefined":(0,w.default)(r))&&r.nextTick?r.nextTick:"function"==typeof u.default?function(e){(0,u.default)(t(e))}:function(e){setTimeout(t(e),0)}}(),t.now=k.now=function(e){return Date.now||function(){return(new Date).getTime()}}()),rt=t.restArgs=k.restArgs=function(){function e(e,t){return t=null==t?e.length-1:+t,function(){var n,r=Math.max(arguments.length-t,0),i=new Array(r);for(n=0;nwindow.innerHeight?"landscape":"portrait"}},at.mixin(e),window.addEventListener("orientationchange",function(){setTimeout(function(){e.emit("change",e.get())},200)},!1),e}({}),t.perfNow=k.perfNow=function(e){var t,n=H.performance,r=H.process;if(n&&n.now)e=function(){return n.now()};else if(r&&r.hrtime){var i=function(){var e=r.hrtime();return 1e9*e[0]+e[1]};t=i()-1e9*r.uptime(),e=function(){return(i()-t)/1e6}}else t=nt(),e=function(){return nt()-t};return e}({}),t.pxToNum=k.pxToNum=function(){function e(e){return et(e.replace("px",""))}return e}(),t.rmCookie=k.rmCookie=function(){function e(e){function t(t){return t=t||{},Pe.remove(e,t),!Pe.get(e)}var n,r=window.location,i=r.hostname,o=r.pathname,a=i.split("."),s=o.split("/"),u="",l=s.length;if(!t())for(var c=a.length-1;c>=0;c--){var d=a[c];if(""!==d){if(u=""===u?d:d+"."+u,n="/",t({domain:u,path:n})||t({domain:u}))return;for(var f=0;f=0;)for(s=!1,r=-1,i=e.charAt(o);++r=0?e.substring(0,o+1):""}var t=/\s+$/;return e}()),lt=t.trim=k.trim=function(){function e(e,n){return null==n?e.replace(t,""):Te(ut(e,n),n)}var t=/^\s+|\s+$/g;return e}(),ct=(t.getFileName=k.getFileName=function(){function e(e){var t=E(e.split("/"));return t.indexOf("?")>-1&&(t=lt(t.split("?")[0])),""===t?"unknown":t}return e}(),t.query=k.query=function(e){e={parse:function(e){var n={};return e=lt(e).replace(t,""),ae(e.split("&"),function(e){var t=e.split("="),r=t.shift(),i=t.length>0?t.join("="):null;r=decodeURIComponent(r),i=decodeURIComponent(i),S(n[r])?n[r]=i:X(n[r])?n[r].push(i):n[r]=[n[r],i]}),n},stringify:function(t,n){return Ce(je(t,function(t,r){return T(t)&&ve(t)?"":X(t)?e.stringify(t,r):(n?encodeURIComponent(n):encodeURIComponent(r))+"="+encodeURIComponent(t)}),function(e){return e.length>0}).join("&")}};var t=/^(\?|#|&)/g;return e}({})),dt=(t.Url=k.Url=function(e){e=Le({className:"Url",initialize:function(t){!t&&j&&(t=window.location.href),le(this,e.parse(t||""))},setQuery:function(e,t){var n=this.query;return T(e)?ae(e,function(e,t){n[t]=e}):n[e]=t,this},rmQuery:function(e){var t=this.query;return X(e)||(e=Re(e)),ae(e,function(e){delete t[e]}),this},toString:function(){return e.stringify(this)}},{parse:function(e){var i={protocol:"",auth:"",hostname:"",hash:"",query:{},port:"",pathname:"",slashes:!1},o=lt(e),a=o.match(t);if(a&&(a=a[0],i.protocol=a.toLowerCase(),o=o.substr(a.length)),a){var s="//"===o.substr(0,2);s&&(o=o.slice(2),i.slashes=!0)}if(s){for(var u=-1,l=0,c=r.length;l=200&&t<300||304===t){e=f.responseText,"xml"===s&&(e=f.responseXML);try{"json"===s&&(e=JSON.parse(e))}catch(e){}u(e,f)}else l(f);d(f)}},"GET"===r?(o=ct.stringify(o),i+=i.indexOf("?")>-1?"&"+o:"?"+o):"application/x-www-form-urlencoded"===t.contentType?T(o)&&(o=ct.stringify(o)):"application/json"===t.contentType&&T(o)&&(o=(0,a.default)(o)),f.open(r,i,!0),f.setRequestHeader("Content-Type",t.contentType),c>0&&(n=setTimeout(function(){f.onreadystatechange=M,f.abort(),l(f,"timeout"),d(f)},c)),f.send("GET"===r?null:o),f}function t(e,t,n,r){return ne(t)&&(r=n,n=t,t={}),{url:e,data:t,success:n,dataType:r}}return e.setting={type:"GET",success:M,error:M,complete:M,dataType:"json",contentType:"application/x-www-form-urlencoded",data:{},xhr:function(){return new XMLHttpRequest},timeout:0},e.get=function(){return e(t.apply(null,arguments))},e.post=function(){var n=t.apply(null,arguments);return n.type="POST",e(n)},e}(),t.type=k.type=function(){function e(e){if(null===e)return"null";if(void 0===e)return"undefined";if(ye(e))return"nan";var n=Y(e).match(t);return n?n[1].toLowerCase():""}var t=/^\[object\s+(.*?)]$/;return e}()),ft=t.stringify=k.stringify=function(){function e(e,n){return(0,a.default)(e,t(),n)}function t(){var e=[],t=[];return function(n,r){if(e.length>0){var i=e.indexOf(this);i>-1?(e.splice(i+1),t.splice(i,1/0,n)):(e.push(this),t.push(n));var o=e.indexOf(r);o>-1&&(r=e[0]===r?"[Circular ~]":"[Circular ~."+t.slice(0,o).join(".")+"]")}else e.push(r);return ke(r)||ne(r)?r="["+q(dt(r))+" "+z(r)+"]":S(r)&&(r=null),r}}return e}();t.LocalStore=k.LocalStore=function(e){var t=Xe("local");return st.extend({initialize:function(e,n){this._name=e;var r=t.getItem(e);try{r=JSON.parse(r)}catch(e){r={}}T(r)||(r={}),n=ue(r,n),this.callSuper(st,"initialize",[n])},save:function(e){if(ve(e))return t.removeItem(this._name);t.setItem(this._name,ft(e))}})}(),t.stripHtmlTag=k.stripHtmlTag=function(){function e(e){return e.replace(t,"")}var t=/<[^>]*>/g;return e}(),t.tryIt=k.tryIt=function(){function e(e,t){t=t||M;try{t(null,e())}catch(e){return void t(e)}}return e}(),t.uniqId=k.uniqId=function(){function e(e){var n=++t+"";return e?e+n:n}var t=0;return e}(),t.unique=k.unique=function(){function e(e,n){return n=n||t,Ce(e,function(e,t,r){for(var i=r.length;++t= 2.0.0-beta.1",7:">= 4.0.0"};t.REVISION_CHANGES=f;r.prototype={constructor:r,logger:d.default,log:d.default.log,registerHelper:function(e,t){if("[object Object]"===o.toString.call(e)){if(t)throw new s.default("Arg not supported with multiple helpers");o.extend(this.helpers,e)}else this.helpers[e]=t},unregisterHelper:function(e){delete this.helpers[e]},registerPartial:function(e,t){if("[object Object]"===o.toString.call(e))o.extend(this.partials,e);else{if(void 0===t)throw new s.default('Attempting to register a partial called "'+e+'" as undefined');this.partials[e]=t}},unregisterPartial:function(e){delete this.partials[e]},registerDecorator:function(e,t){if("[object Object]"===o.toString.call(e)){if(t)throw new s.default("Arg not supported with multiple decorators");o.extend(this.decorators,e)}else this.decorators[e]=t},unregisterDecorator:function(e){delete this.decorators[e]}};var p=d.default.log;t.log=p,t.createFrame=o.createFrame,t.logger=d.default},function(e,t){"use strict";function n(e){return c[e]}function r(e){for(var t=1;t":">",'"':""","'":"'","`":"`","=":"="},d=/[&<>"'`=]/g,f=/[&<>"'`=]/,p=Object.prototype.toString;t.toString=p;var h=function(e){return"function"==typeof e};h(/x/)&&(t.isFunction=h=function(e){return"function"==typeof e&&"[object Function]"===p.call(e)}),t.isFunction=h;var v=Array.isArray||function(e){return!(!e||"object"!=typeof e)&&"[object Array]"===p.call(e)};t.isArray=v},function(e,t,n){"use strict";function r(e,t){var n=t&&t.loc,a=void 0,s=void 0;n&&(a=n.start.line,s=n.start.column,e+=" - "+a+":"+s);for(var u=Error.prototype.constructor.call(this,e),l=0;l0?(n.ids&&(n.ids=[n.name]),e.helpers.each(t,n)):i(this);if(n.data&&n.ids){var a=r.createFrame(n.data);a.contextPath=r.appendContextPath(n.data.contextPath,n.name),n={data:a}}return o(t,n)})},e.exports=t.default},function(e,t,n){"use strict";var r=n(2).default;t.__esModule=!0;var i=n(4),o=n(5),a=r(o);t.default=function(e){e.registerHelper("each",function(e,t){function n(t,n,o){l&&(l.key=t,l.index=n,l.first=0===n,l.last=!!o,c&&(l.contextPath=c+t)),u+=r(e[t],{data:l,blockParams:i.blockParams([e[t],t],[c+t,null])})}if(!t)throw new a.default("Must pass iterator to #each");var r=t.fn,o=t.inverse,s=0,u="",l=void 0,c=void 0;if(t.data&&t.ids&&(c=i.appendContextPath(t.data.contextPath,t.ids[0])+"."),i.isFunction(e)&&(e=e.call(this)),t.data&&(l=i.createFrame(t.data)),e&&"object"==typeof e)if(i.isArray(e))for(var d=e.length;s=0?t:parseInt(e,10)}return e},log:function(e){if(e=i.lookupLevel(e),"undefined"!=typeof console&&i.lookupLevel(i.level)<=e){var t=i.methodMap[e];console[t]||(t="log");for(var n=arguments.length,r=Array(n>1?n-1:0),o=1;o3&&void 0!==arguments[3]?arguments[3]:["#2196f3","#707d8b","#f44336","#009688","#ffc107"],i=this._genId("settings");return this._settings.push({config:e,key:t,id:i}),this._$el.append(this._colorTpl({desc:n,colors:r,id:i,val:e.get(t)})),this}},{key:"select",value:function(e,t,n,r){var i=this._genId("settings");return this._settings.push({config:e,key:t,id:i}),this._$el.append(this._selectTpl({desc:n,selections:r,id:i,val:e.get(t)})),this}},{key:"range",value:function(e,t,n,r){var i=r.min,o=void 0===i?0:i,a=r.max,s=void 0===a?1:a,u=r.step,l=void 0===u?.1:u,c=this._genId("settings");this._settings.push({config:e,key:t,min:o,max:s,step:l,id:c});var d=e.get(t);return this._$el.append(this._rangeTpl({desc:n,min:o,max:s,step:l,val:d,progress:y(d,o,s),id:c})),this}},{key:"separator",value:function(){return this._$el.append('
'),this}},{key:"text",value:function(e){return this._$el.append('
'+e+"
"),this}},{key:"_cleanSeparator",value:function(){function e(e){return"eruda-separator"===e.getAttribute("class")}for(var t=(0,_.clone)(this._$el.get(0).children),n=0,r=t.length;n0?r:n)(e)}},function(e,t,n){var r=n(44)("keys"),i=n(31);e.exports=function(e){return r[e]||(r[e]=i(e))}},function(e,t,n){var r=n(11),i=r["__core-js_shared__"]||(r["__core-js_shared__"]={});e.exports=function(e){return i[e]||(i[e]={})}},function(e,t){e.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(e,t){t.f=Object.getOwnPropertySymbols},function(e,t,n){"use strict";var r=n(96)(!0);n(67)(String,"String",function(e){this._t=String(e),this._i=0},function(){var e,t=this._t,n=this._i;return n>=t.length?{value:void 0,done:!0}:(e=r(t,n),this._i+=e.length,{value:e,done:!1})})},function(e,t){e.exports=!0},function(e,t,n){var r=n(21),i=n(98),o=n(45),a=n(43)("IE_PROTO"),s=function(){},u=function(){var e,t=n(39)("iframe"),r=o.length;for(t.style.display="none",n(69).appendChild(t),t.src="javascript:",e=t.contentWindow.document,e.open(),e.write(" + + + + + + + + + + + +
+ +
+
+ + + + +
+ + +
+
+
+
+
+
+
+
+
+
+ 音频预览
+
+
+
+
请输入文本:
+ +
+
+ +
+
+ + +
+
+
+
+ + + + + + + + + + + + + + + \ No newline at end of file