fmode-ng 0.0.39 → 0.0.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/esm2022/fmode-ng.mjs +5 -10
  2. package/esm2022/lib/aigc/agent/agent.prompt.mjs +122 -10
  3. package/esm2022/lib/aigc/agent/index.mjs +2 -10
  4. package/esm2022/lib/aigc/avatar/avatar.module.mjs +45 -10
  5. package/esm2022/lib/aigc/avatar/comp-avatar-particle/avatar.role.mjs +2 -10
  6. package/esm2022/lib/aigc/avatar/comp-avatar-particle/comp-avatar-particle.component.mjs +315 -10
  7. package/esm2022/lib/aigc/avatar/comp-avatar-particle/index.mjs +3 -10
  8. package/esm2022/lib/aigc/avatar/comp-avatar-particle/role-points.class.mjs +57 -10
  9. package/esm2022/lib/aigc/avatar/comp-avatar-role-image/comp-avatar-role-image.component.mjs +97 -10
  10. package/esm2022/lib/aigc/avatar/comp-avatar-role-video/comp-avatar-role-video.component.mjs +104 -10
  11. package/esm2022/lib/aigc/avatar/comp-avatar-talk/comp-avatar-talk.component.mjs +111 -10
  12. package/esm2022/lib/aigc/avatar/index.mjs +8 -10
  13. package/esm2022/lib/aigc/avatar/interface-avatar-role.mjs +2 -10
  14. package/esm2022/lib/aigc/avatar/modal-chat-voice-input/modal-chat-voice-input.component.mjs +166 -8
  15. package/esm2022/lib/aigc/chat/chat-header-area/comp-header-area.component.mjs +36 -10
  16. package/esm2022/lib/aigc/chat/chat-header-area/index.mjs +2 -10
  17. package/esm2022/lib/aigc/chat/chat-list/chat-list.component.mjs +141 -8
  18. package/esm2022/lib/aigc/chat/chat-list/index.mjs +2 -10
  19. package/esm2022/lib/aigc/chat/chat-message-area/comp-message-area.component.mjs +40 -10
  20. package/esm2022/lib/aigc/chat/chat-message-area/index.mjs +2 -10
  21. package/esm2022/lib/aigc/chat/chat-message-card/comp-message-card.component.mjs +92 -10
  22. package/esm2022/lib/aigc/chat/chat-message-card/index.mjs +2 -10
  23. package/esm2022/lib/aigc/chat/chat-modal-input/index.mjs +2 -10
  24. package/esm2022/lib/aigc/chat/chat-modal-input/modal-audio-message/modal-audio-message.component.mjs +207 -8
  25. package/esm2022/lib/aigc/chat/chat-modal-input/modal-input.component.mjs +236 -10
  26. package/esm2022/lib/aigc/chat/chat-panel/chat-panel.component.mjs +137 -10
  27. package/esm2022/lib/aigc/chat/comp-role-prompt/comp-role-prompt.component.mjs +69 -10
  28. package/esm2022/lib/aigc/chat/comp-role-prompt/index.mjs +2 -10
  29. package/esm2022/lib/aigc/chat/index.mjs +8 -10
  30. package/esm2022/lib/aigc/comp-markdown-preview/clipboard.service.mjs +82 -10
  31. package/esm2022/lib/aigc/comp-markdown-preview/markdown-parse.mjs +269 -8
  32. package/esm2022/lib/aigc/comp-markdown-preview/markdown-preview.component.mjs +51 -10
  33. package/esm2022/lib/aigc/comp-markdown-preview/markdown-preview.module.mjs +24 -10
  34. package/esm2022/lib/aigc/comp-markdown-preview/plugins/md-mathjax/index.mjs +94 -10
  35. package/esm2022/lib/aigc/index.mjs +13 -10
  36. package/esm2022/lib/aigc/service-fmai/fmai.service.mjs +21 -10
  37. package/esm2022/lib/aigc/service-fmai/service-chat/chat-class.mjs +736 -8
  38. package/esm2022/lib/aigc/service-fmai/service-chat/chat.service.mjs +181 -8
  39. package/esm2022/lib/aigc/service-fmai/service-chat/index.mjs +7 -10
  40. package/esm2022/lib/aigc/service-fmai/service-chat/mask-list.mjs +194 -9
  41. package/esm2022/lib/aigc/service-fmai/service-chat/pipes/chat-content.pipe.mjs +27 -10
  42. package/esm2022/lib/aigc/service-fmai/service-chat/pipes/hidexml.pipe.mjs +27 -10
  43. package/esm2022/lib/aigc/service-fmai/service-chat/utilnow.pipe.mjs +68 -10
  44. package/esm2022/lib/aigc/service-fmai/service-imagine/imagine.service.mjs +229 -8
  45. package/esm2022/lib/aigc/service-fmai/service-imagine/index.mjs +2 -10
  46. package/esm2022/lib/aigc/voice/audio.player.mjs +52 -10
  47. package/esm2022/lib/aigc/voice/class-asr.mjs +79 -8
  48. package/esm2022/lib/aigc/voice/fmode-voice.service.mjs +501 -8
  49. package/esm2022/lib/aigc/voice/index.mjs +3 -10
  50. package/esm2022/lib/aigc/voice/lib/pcm2wav.mjs +38 -10
  51. package/esm2022/lib/aigc/voice/lib/resample.mjs +34 -10
  52. package/esm2022/lib/aigc/voice/tts/fmode-tts-class.mjs +233 -8
  53. package/esm2022/lib/aigc/voice/tts/index.mjs +2 -10
  54. package/esm2022/lib/map/comp-poi-picker/comp-poi-picker.component.mjs +190 -10
  55. package/esm2022/lib/map/comp-poi-picker/comp-poi-picker.module.mjs +33 -10
  56. package/esm2022/lib/map/index.mjs +4 -10
  57. package/esm2022/lib/map/map.module.mjs +61 -10
  58. package/esm2022/lib/map/page-loca-scatter/page-loca-scatter.component.mjs +110 -10
  59. package/esm2022/lib/map/page-map.start/page-map.start.component.mjs +98 -8
  60. package/esm2022/lib/map/page-plan-route/page-plan-route.component.mjs +100 -8
  61. package/esm2022/lib/nova-cloud/index.mjs +2 -10
  62. package/esm2022/lib/nova-cloud/nova-cloud.service.mjs +148 -10
  63. package/esm2022/lib/platform/cross.service.mjs +63 -10
  64. package/esm2022/lib/platform/index.mjs +2 -10
  65. package/esm2022/lib/social/index.mjs +2 -10
  66. package/esm2022/lib/social/wechat/wechat-jssdk.service.mjs +236 -8
  67. package/esm2022/lib/storage/comp-hwobs-manager/hwobs-manager.component.mjs +59 -10
  68. package/esm2022/lib/storage/index.mjs +5 -10
  69. package/esm2022/lib/storage/service-hwobs/hwobs.service.mjs +130 -8
  70. package/esm2022/lib/storage/service-upload/index.mjs +2 -10
  71. package/esm2022/lib/storage/service-upload/nova-upload.service.mjs +462 -8
  72. package/esm2022/lib/storage/service-upload/util-file-md5.mjs +28 -10
  73. package/esm2022/lib/storage/storage.module.mjs +41 -10
  74. package/esm2022/lib/user/account/account.service.mjs +221 -10
  75. package/esm2022/lib/user/captcha/captcha.component.mjs +135 -10
  76. package/esm2022/lib/user/comp-user-avatar/comp-user-avatar.component.mjs +62 -10
  77. package/esm2022/lib/user/index.mjs +17 -10
  78. package/esm2022/lib/user/login/auth.guard.mjs +28 -10
  79. package/esm2022/lib/user/login/auth.service.mjs +373 -8
  80. package/esm2022/lib/user/login/login.component.mjs +913 -10
  81. package/esm2022/lib/user/modal-user-login/modal-user-login.component.mjs +273 -10
  82. package/esm2022/lib/user/profile/auth-profile.guard.mjs +27 -10
  83. package/esm2022/lib/user/profile/auth-profile.service.mjs +122 -10
  84. package/esm2022/lib/user/profile/profile-bind/profile-bind.component.mjs +115 -10
  85. package/esm2022/lib/user/profile/profile.module.mjs +57 -10
  86. package/esm2022/lib/user/staff/index.mjs +4 -10
  87. package/esm2022/lib/user/staff/staff.guard.mjs +26 -10
  88. package/esm2022/lib/user/staff/staff.module.mjs +18 -10
  89. package/esm2022/lib/user/staff/staff.service.mjs +85 -10
  90. package/esm2022/lib/user/user-name.pipe.mjs +29 -10
  91. package/esm2022/lib/user/user.module.mjs +106 -10
  92. package/esm2022/lib/video/fm-video/fm-video.component.mjs +67 -10
  93. package/esm2022/lib/video/index.mjs +2 -10
  94. package/esm2022/public-api.mjs +13 -10
  95. package/fesm2022/fmode-ng.mjs +8895 -7
  96. package/fesm2022/fmode-ng.mjs.map +1 -1
  97. package/lib/user/login/auth.service.d.ts +18 -3
  98. package/lib/user/modal-user-login/modal-user-login.component.d.ts +4 -2
  99. package/package.json +1 -1
  100. package/LICENSE.md +0 -8
@@ -1,10 +1,503 @@
1
-
1
+ import { Injectable } from '@angular/core';
2
+ // import RecorderManager from "./lib/xunfei-recorder"
3
+ // import {RecorderManager} from "./lib/recorder/recorder-manager"
4
+ import Recorder from 'recorder-core';
5
+ import 'recorder-core/src/engine/pcm';
6
+ import 'recorder-core/src/engine/wav';
7
+ import 'recorder-core/src/extensions/waveview';
8
+ import CryptoJS from "crypto-js";
9
+ import { pcmtoWav } from './lib/pcm2wav';
10
+ import { convertFrameBufferToBase64, resampleBuffer } from './lib/resample';
11
+ import { WebSpeech } from './class-asr';
12
+ import { Platform } from '@ionic/angular';
13
+ import { Diagnostic } from '@awesome-cordova-plugins/diagnostic/ngx';
14
+ import * as i0 from "@angular/core";
15
+ import * as i1 from "@ionic/angular";
16
+ import * as i2 from "@awesome-cordova-plugins/diagnostic/ngx";
17
+ // import { FmodeTTSXunfei } fro./class-tts-xunfei.ts.bakfei'
18
+ export class FmodeVoiceService {
19
+ constructor(platform, diagnostic) {
20
+ this.platform = platform;
21
+ this.diagnostic = diagnostic;
22
+ /**
23
+ * 讯飞TTS语音合成
24
+ */
25
+ // ttsXunfei = new FmodeTTSXunfei()
26
+ /**
27
+ * WebSpeech 语音库
28
+ */
29
+ this.webSpeech = WebSpeech;
30
+ /**
31
+ * 用户操作:完成录音,并处理转录结果
32
+ */
33
+ this.isUserFinish = false;
34
+ this.recordWavBlob = null;
35
+ this.recordPcmBlob = null;
36
+ this.recordDuration = 0;
37
+ this.recordType = "pcm";
38
+ this.encodingType = "raw";
39
+ this.connStatus = ""; // 录音中 建立连接中 关闭连接中
40
+ this.btnStatus = "UNDEFINED"; // "UNDEFINED" "CONNECTING" "OPEN" "CLOSING" "CLOSED"
41
+ this.resultText = "";
42
+ this.resultTextTemp = "";
43
+ /**
44
+ * 获取websocket url
45
+ * 该接口需要后端提供,这里为了方便前端处理
46
+ */
47
+ this.APPID = "50f4a46c";
48
+ this.API_SECRET = "NzFlNmFhZDJjMDNkZGM3NzI0Mzg2OGNm";
49
+ this.API_KEY = "106ddc40dfd4b9ca6d7b47c70fada749";
50
+ this.requestPermission();
51
+ // this.recorder.on("start",() => {
52
+ // })
53
+ // this.recorder.on("frameRecorded", ({ isLastFrame, frameBuffer }) => {
54
+ // if (this.iatWS.readyState === this.iatWS.OPEN) {
55
+ // this.iatWS.send(
56
+ // JSON.stringify({
57
+ // data: {
58
+ // status: isLastFrame ? 2 : 1,
59
+ // format: "audio/L16;rate=16000",
60
+ // encoding: this.encodingType,
61
+ // audio: this.toBase64(frameBuffer),
62
+ // },
63
+ // })
64
+ // );
65
+ // if (isLastFrame) {
66
+ // this.changeBtnStatus("CLOSING");
67
+ // }
68
+ // }
69
+ // })
70
+ // this.recorder.on("stop",() => {
71
+ // })
72
+ }
73
+ /**()
74
+ * 用户操作:录音按钮快捷触发操作
75
+ */
76
+ toggleRecord() {
77
+ console.log(this.btnStatus);
78
+ if (this.btnStatus === "UNDEFINED" || this.btnStatus === "CLOSED") {
79
+ // 开始讲话`
80
+ this.startTalk();
81
+ }
82
+ else if (this.btnStatus === "CONNECTING" || this.btnStatus === "OPEN") {
83
+ // 结束录音 并发送消息等待回复
84
+ this.finishTalk();
85
+ }
86
+ }
87
+ finishTalk() {
88
+ this.isUserFinish = true;
89
+ this.onBeforeFinishTalk && this.onBeforeFinishTalk();
90
+ this.recordStop();
91
+ }
92
+ /**
93
+ * 用户操作:开始讲话,实时转录语言
94
+ */
95
+ async startTalk(evnet) {
96
+ this.resultText = "";
97
+ this.resultTextTemp = "";
98
+ this.onBeforeStartTalk && this.onBeforeStartTalk();
99
+ event?.preventDefault();
100
+ await this.openWithPriviledge();
101
+ setTimeout(() => {
102
+ this.connectWebSocket();
103
+ }, 100);
104
+ this.onAfterStartTalk && this.onAfterStartTalk();
105
+ }
106
+ /**
107
+ * 用户操作:取消讲话,且不发送结果
108
+ */
109
+ cancelTalk() {
110
+ this.onBeforeCancelTalk && this.onBeforeCancelTalk();
111
+ this.recordStop(); // 停止录制
112
+ this.iatWS?.close(); // 断开连接
113
+ this.resultText = null; // 设置转录结果为空
114
+ this.onAfterCancelTalk && this.onAfterCancelTalk();
115
+ }
2
116
  /**
3
- * @copyright © 未来飞马 © 未来全栈 www.fmode.cn
4
- * 版权所有 © 未来飞马 © 江西脑控科技有限公司 Copyright © Fmode Technology Co., Ltd.
5
- * 保留所有权利 All Rights Reserved.
6
- * /home/ryan/workspace/nova/nova-admin/dist/fmode-ng/esm2022/lib/aigc/voice/fmode-voice.service.mjs
117
+ * 程序逻辑
7
118
  */
8
- import{Injectable}from"@angular/core";import Recorder from"recorder-core";import"recorder-core/src/engine/pcm";import"recorder-core/src/engine/wav";import"recorder-core/src/extensions/waveview";import CryptoJS from"crypto-js";import{pcmtoWav}from"./lib/pcm2wav";import{convertFrameBufferToBase64,resampleBuffer}from"./lib/resample";import{WebSpeech}from"./class-asr";import{Platform}from"@ionic/angular";import{Diagnostic}from"@awesome-cordova-plugins/diagnostic/ngx";import*as i0 from"@angular/core";import*as i1 from"@ionic/angular";import*as i2 from"@awesome-cordova-plugins/diagnostic/ngx";export class FmodeVoiceService{constructor(t,e){this.platform=t,this.diagnostic=e,this.webSpeech=WebSpeech,this.isUserFinish=!1,this.recordWavBlob=null,this.recordPcmBlob=null,this.recordDuration=0,this.recordType="pcm",this.encodingType="raw",this.connStatus="",this.btnStatus="UNDEFINED",this.resultText="",this.resultTextTemp="",this.APPID="50f4a46c",this.API_SECRET="NzFlNmFhZDJjMDNkZGM3NzI0Mzg2OGNm",this.API_KEY="106ddc40dfd4b9ca6d7b47c70fada749",this.requestPermission()}toggleRecord(){console.log(this.btnStatus),"UNDEFINED"===this.btnStatus||"CLOSED"===this.btnStatus?this.startTalk():"CONNECTING"!==this.btnStatus&&"OPEN"!==this.btnStatus||this.finishTalk()}finishTalk(){this.isUserFinish=!0,this.onBeforeFinishTalk&&this.onBeforeFinishTalk(),this.recordStop()}async startTalk(t){this.resultText="",this.resultTextTemp="",this.onBeforeStartTalk&&this.onBeforeStartTalk(),event?.preventDefault(),await this.openWithPriviledge(),setTimeout((()=>{this.connectWebSocket()}),100),this.onAfterStartTalk&&this.onAfterStartTalk()}cancelTalk(){this.onBeforeCancelTalk&&this.onBeforeCancelTalk(),this.recordStop(),this.iatWS?.close(),this.resultText=null,this.onAfterCancelTalk&&this.onAfterCancelTalk()}async recordStart(){this.createRecorder(),await this.openWithPriviledge(),this.recorder.start(),this.changeBtnStatus("OPEN"),this.onAfterRecordStart&&this.onAfterRecordStart()}recordStop(){return new Promise((t=>{clearInterval(this.countdownInterval),this.changeBtnStatus("CLOSED"),this.recorder?.stop((async(e,i)=>{try{this.iatWS.send(JSON.stringify({data:{status:2,format:"audio/L16;rate=16000",encoding:this.encodingType,audio:""}}))}catch(t){}let s=(window.URL||webkitURL).createObjectURL(e);console.log(e,s,"时长:"+i+"ms"),this.recordPcmBlob=e,this.recordWavBlob=await this.pcmBlobToWavBlob(e,44100),this.recordDuration=i,console.log("this.recordWavBlob",this.recordWavBlob),setTimeout((()=>{this.isUserFinish&&(this.onAfterFinishTalk&&this.onAfterFinishTalk(),this.isUserFinish=!1)}),2e3),this.recorder?.close(),this.recorder=null,console.log("localUrl",s),t(!0)}),(e=>{console.log("录音失败:"+e),this.recorder.close(),this.recorder=null,t(null)}))}))}playRecord(){this.playPCM(this.recordPcmBlob,44100)}async pcmBlobToWavBlob(t,e){return new Promise((i=>{let s=new FileReader;s.onload=function(t){let s=t.target.result,o=pcmtoWav(s,e,1,16);i(o)},s.readAsArrayBuffer(t)}))}async playPCM(t,e){let i=await this.pcmBlobToWavBlob(t,e),s=window.URL.createObjectURL(i),o=new Audio;o.src=s,o.play()}async playBuffers(){let t=await this.BuffersToBlob(this.buffers);this.playPCM(t,44100)}BuffersToBlob(t){let e=[];return t.forEach((t=>{t.forEach((t=>{e.push(t)}))})),new Blob([e],{type:"audio/pcm"})}splitAudioData(t){const e=1280,i=Math.ceil(t.length/e),s=[];for(let o=0;o<i;o++){const i=o*e,r=i+e,a=t.slice(i,r);s.push(a)}return s}BufferToBlob(t){return new Blob([t],{type:"audio/pcm"})}createRecorder(){this.recorder||(this.recorder=Recorder({type:this.recordType,sampleRate:44100,bitRate:16,onProcess:(t,e,i,s,o,r)=>{let a=t.length&&t[t.length-1];if(this.buffers=t,a=resampleBuffer(a,44100,16e3),this.iatWS.readyState===this.iatWS.OPEN){if(this.disableASR)return;this.iatWS.send(JSON.stringify({data:{status:1,format:"audio/L16;rate=16000",encoding:this.encodingType,audio:convertFrameBufferToBase64(a)}}))}this.waveClient?.input(t[t.length-1],e,s)}}))}async openWithPriviledge(){return console.log(this.btnStatus),await this.requestPermission(),this.createRecorder(),!!Recorder.IsOpen()||new Promise((t=>{this.recorder.open((()=>{let e=document.querySelector(".record-wave");e&&(console.log(e),Recorder.WaveView&&(this.waveClient=Recorder.WaveView({elem:".record-wave"}))),t(!0)}),((t,e)=>{console.log((e?"UserNotAllow,":"")+"无法录音:"+t)}))}))}getWebSocketUrl(){let t="wss://iat-api.xfyun.cn/v2/iat",e="iat-api.xfyun.cn",i=this.API_KEY,s=this.API_SECRET,o=(new Date).toUTCString(),r=`host: ${e}\ndate: ${o}\nGET /v2/iat HTTP/1.1`,a=CryptoJS.HmacSHA256(r,s),n=CryptoJS.enc.Base64.stringify(a);return t=`${t}?authorization=${btoa(`api_key="${i}", algorithm="hmac-sha256", headers="host date request-line", signature="${n}"`)}&date=${o}&host=${e}`,t}toBase64(t){for(var e="",i=new Uint8Array(t),s=i.byteLength,o=0;o<s;o++)e+=String.fromCharCode(i[o]);return window.btoa(e)}countdown(){let t=60;this.connStatus=`录音中(${t}s)`,this.countdownInterval=setInterval((()=>{t-=1,console.log(t),t<=0?(clearInterval(this.countdownInterval),this.recordStop()):this.connStatus=`录音中(${t}s)`}),1e3)}changeBtnStatus(t){this.btnStatus=t,"CONNECTING"===t?this.connStatus="建立连接中":"OPEN"===t?this.countdown():"CLOSING"===t?this.connStatus="关闭连接中":"CLOSED"===t&&(this.connStatus="开始录音")}renderResult(t){let e=JSON.parse(t);if(e.data&&e.data.result){let t=e.data.result,i="",s=t.ws;for(let t=0;t<s.length;t++)i+=s[t].cw[0].w,console.log(i);t.pgs?("apd"===t.pgs&&(this.resultText=this.resultTextTemp),this.resultTextTemp=this.resultText+i):this.resultText=this.resultText+i,this.resultTextTemp||this.resultText,console.log("diff temp",this.resultTextTemp),console.log("diff result",this.resultText)}0===e.code&&2===e.data.status&&this.iatWS.close(),0!==e.code&&(this.iatWS.close(),console.error(e))}connectWebSocket(){console.log("connectWebSocket");const t=this.getWebSocketUrl();if("WebSocket"in window)this.iatWS=new WebSocket(t);else if(!("MozWebSocket"in window))return void alert("浏览器不支持WebSocket");console.log("connectWebSocket",this.btnStatus),this.changeBtnStatus("CONNECTING"),this.iatWS.onopen=t=>{this.recordStart();var e={common:{app_id:this.APPID},business:{language:"zh_cn",domain:"iat",accent:"mandarin",vad_eos:5e3,dwa:"wpgs"},data:{status:0,format:"audio/L16;rate=16000",encoding:this.encodingType}};this.iatWS.send(JSON.stringify(e))},this.iatWS.onmessage=t=>{console.log("onmessage"+this.resultText),this.renderResult(t.data)},this.iatWS.onerror=t=>{console.error("error",t),this.recordStop(),this.changeBtnStatus("CLOSED")},this.iatWS.onclose=async t=>{console.log("onclose"+this.resultText),console.error("close",t),await this.recordStop(),this.changeBtnStatus("CLOSED")}}isCapacitor(){return this.platform.is("capacitor")||this.platform.is("cordova")}async requestPermission(){if(this.isCapacitor())try{await this.requestStoagePermission(),await this.requestCameraPermission(),await this.requestMicPermission(),await this.requestRecordAudioPermission()}catch(t){console.error(t)}}async requestRecordAudioPermission(){let t=await this.diagnostic.requestRuntimePermissions([this.diagnostic.permission.RECORD_AUDIO]);console.log("record permission request:",t)}async requestMicPermission(){let t=await this.diagnostic.isMicrophoneAuthorized();if(console.log("permisson_MIC:",t),!t){await this.diagnostic.requestMicrophoneAuthorization()}}async requestStoagePermission(){let t=await this.diagnostic.isExternalStorageAuthorized();if(console.log("permisson_STORAGE:",t),!t){await this.diagnostic.requestExternalStorageAuthorization()}}async requestCameraPermission(){let t=await this.diagnostic.isCameraAuthorized();if(console.log("permisson_Camera:",t),!t){await this.diagnostic.requestCameraAuthorization()}}static{this.ɵfac=i0.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:FmodeVoiceService,deps:[{token:i1.Platform},{token:i2.Diagnostic}],target:i0.ɵɵFactoryTarget.Injectable})}static{this.ɵprov=i0.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:FmodeVoiceService,providedIn:"root"})}}i0.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:FmodeVoiceService,decorators:[{type:Injectable,args:[{providedIn:"root"}]}],ctorParameters:()=>[{type:i1.Platform},{type:i2.Diagnostic}]});
9
- var MODULE_PATH_NEED = `6K+l5paH5Lu25piv5pys6aG555uu55qE5LiA6YOo5YiGIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBDb21wb25lbnRzIGluIEZtb2RlIEluYy4KICAgIOeJiOadg+aJgOaciSDCqSDmnKrmnaXpo57pqawgwqkg5rGf6KW/6ISR5o6n56eR5oqA5pyJ6ZmQ5YWs5Y+4IENvcHlyaWdodCDCqSBGbW9kZSBUZWNobm9sb2d5IENvLiwgTHRkLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAgICDkuKXnpoHlnKjmnKrnu4/mjojmnYPnmoTmg4XlhrXkuIvvvIzpgJrov4fku7vkvZXlqpLku4vlpI3liLbmraTmlofku7YgVW5hdXRob3JpemVkIGNvcHlpbmcgb2YgdGhpcyBmaWxlLCB2aWEgYW55IG1lZGl1bSBpcyBzdHJpY3RseSBwcm9oaWJpdGVkCiAgICDor6Xmlofku7bmmK/kuJPmnInnmoTmnLrlr4bmlofku7YgUHJvcHJpZXRhcnkgYW5kIGNvbmZpZGVudGlhbAogICAKICAgIENvcHlyaWdodCAyMDIxLW5vdyBGbW9kZSBJbmMuIHN1cHBvcnRAZm1vZGUuY24uIDE4NjA3MDA3MDczLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUEFUSDovaG9tZS9yeWFuL3dvcmtzcGFjZS9ub3ZhL25vdmEtYWRtaW4vZGlzdC9mbW9kZS1uZy9lc20yMDIyL2xpYi9haWdjL3ZvaWNlL2Ztb2RlLXZvaWNlLnNlcnZpY2UubWpz`
10
-
119
+ async recordStart() {
120
+ this.createRecorder();
121
+ await this.openWithPriviledge();
122
+ this.recorder.start();
123
+ this.changeBtnStatus("OPEN");
124
+ this.onAfterRecordStart && this.onAfterRecordStart();
125
+ }
126
+ recordStop() {
127
+ return new Promise((resolve) => {
128
+ clearInterval(this.countdownInterval);
129
+ this.changeBtnStatus("CLOSED");
130
+ this.recorder?.stop(async (blob, duration) => {
131
+ //录音结束后,发送录音结束帧
132
+ try {
133
+ this.iatWS.send(JSON.stringify({ "data": { "status": 2, "format": "audio/L16;rate=16000", "encoding": this.encodingType, "audio": "" } }));
134
+ }
135
+ catch (err) { }
136
+ //简单利用URL生成本地文件地址,注意不用了时需要revokeObjectURL,否则霸占内存
137
+ //此地址只能本地使用,比如赋值给audio.src进行播放,赋值给a.href然后a.click()进行下载(a需提供download="xxx.mp3"属性)
138
+ let localUrl = (window.URL || webkitURL).createObjectURL(blob);
139
+ console.log(blob, localUrl, "时长:" + duration + "ms");
140
+ this.recordPcmBlob = blob;
141
+ this.recordWavBlob = await this.pcmBlobToWavBlob(blob, 44100);
142
+ this.recordDuration = duration;
143
+ console.log("this.recordWavBlob", this.recordWavBlob);
144
+ setTimeout(() => {
145
+ if (this.isUserFinish) {
146
+ this.onAfterFinishTalk && this.onAfterFinishTalk();
147
+ this.isUserFinish = false;
148
+ }
149
+ }, 2000);
150
+ this.recorder?.close(); //释放录音资源,当然可以不释放,后面可以连续调用start;但不释放时系统或浏览器会一直提示在录音,最佳操作是录完就close掉
151
+ this.recorder = null;
152
+ //已经拿到blob文件对象想干嘛就干嘛:立即播放、上传、下载保存
153
+ /*** 【立即播放例子】 ***/
154
+ // this.audioPlayer= new Audio();
155
+ // this.audioPlayer.controls=true;
156
+ // this.audioPlayer.src=localUrl;
157
+ console.log("localUrl", localUrl);
158
+ // 等待语音转义完成,处理转录结果
159
+ // 需要准确判断websocket已经close了
160
+ resolve(true);
161
+ }, (msg) => {
162
+ console.log("录音失败:" + msg);
163
+ this.recorder.close(); //可以通过stop方法的第3个参数来自动调用close
164
+ this.recorder = null;
165
+ resolve(null);
166
+ });
167
+ });
168
+ }
169
+ playRecord() {
170
+ this.playPCM(this.recordPcmBlob, 44100);
171
+ }
172
+ async pcmBlobToWavBlob(pcmBlob, sampleRate) {
173
+ return new Promise(resolve => {
174
+ let fileReader = new FileReader();
175
+ // 读取Blob数据
176
+ fileReader.onload = function (event) {
177
+ let pcmData = event.target.result;
178
+ // Convert PCM data to WAV format
179
+ let wavBlob = pcmtoWav(pcmData, sampleRate, 1, 16);
180
+ resolve(wavBlob);
181
+ };
182
+ // 将Blob转换为ArrayBuffer
183
+ fileReader.readAsArrayBuffer(pcmBlob);
184
+ });
185
+ }
186
+ async playPCM(pcmBlob, sampleRate) {
187
+ let wavBlob = await this.pcmBlobToWavBlob(pcmBlob, sampleRate);
188
+ let wavUrl = window.URL.createObjectURL(wavBlob);
189
+ let audio = new Audio();
190
+ audio.src = wavUrl;
191
+ audio.play();
192
+ }
193
+ async playBuffers() {
194
+ // let audioBuffer = []
195
+ // this.buffers.forEach(buffer=>{
196
+ // audioBuffer.push(buffer)
197
+ // })
198
+ let audioBlob = await this.BuffersToBlob(this.buffers);
199
+ this.playPCM(audioBlob, 44100);
200
+ }
201
+ BuffersToBlob(buffers) {
202
+ let audioBuffer = [];
203
+ buffers.forEach(buffer => {
204
+ buffer.forEach(int16 => {
205
+ audioBuffer.push(int16);
206
+ });
207
+ });
208
+ return new Blob([audioBuffer], { type: 'audio/pcm' });
209
+ }
210
+ // 将录音数据分割为每次发送的音频片段 1280字节
211
+ splitAudioData(audioData) {
212
+ const segmentSize = 1280; // 目标切片大小,单位为字节
213
+ const segmentCount = Math.ceil(audioData.length / segmentSize); // 切片数量
214
+ const segments = [];
215
+ for (let i = 0; i < segmentCount; i++) {
216
+ const start = i * segmentSize;
217
+ const end = start + segmentSize;
218
+ const segment = audioData.slice(start, end);
219
+ segments.push(segment);
220
+ }
221
+ return segments;
222
+ }
223
+ BufferToBlob(buffer) {
224
+ return new Blob([buffer], { type: 'audio/pcm' });
225
+ }
226
+ createRecorder() {
227
+ if (this.recorder)
228
+ return;
229
+ this.recorder = Recorder({
230
+ type: this.recordType, sampleRate: 44100, bitRate: 16 //pcm格式,指定采样率hz、比特率kbps,其他参数使用默认配置;注意:是数字的参数必须提供数字,不要用字符串;需要使用的type类型,需提前把格式支持文件加载进来,比如使用wav格式需要提前加载wav.js编码引擎
231
+ ,
232
+ onProcess: (buffers, powerLevel, bufferDuration, bufferSampleRate, newBufferIdx, asyncEnd) => {
233
+ //录音实时回调,大约1秒调用12次本回调,buffers为开始到现在的所有录音pcm数据块(16位小端LE)
234
+ //可利用extensions/sonic.js插件实时变速变调,此插件计算量巨大,onProcess需要返回true开启异步模式
235
+ //可实时上传(发送)数据,配合Recorder.SampleData方法,将buffers中的新数据连续的转换成pcm上传,或使用mock方法将新数据连续的转码成其他格式上传,可以参考文档里面的:Demo片段列表 -> 实时转码并上传-通用版;基于本功能可以做到:实时转发数据、实时保存数据、实时语音识别(ASR)等
236
+ // 实时发送录音至接口
237
+ // console.log("asyncEnd:",asyncEnd)
238
+ // console.log(buffers.length,bufferDuration,bufferSampleRate,newBufferIdx)
239
+ let isLastFrame = false && this.btnStatus == "CLOSED"; // 主动关闭作为最后帧
240
+ // 录音默认为 44100 采样率 pcm不支持再process中实时转换
241
+ // 需要压缩为 16000 上传
242
+ let frameBuffer = buffers.length && buffers[buffers.length - 1];
243
+ this.buffers = buffers;
244
+ frameBuffer = resampleBuffer(frameBuffer, 44100, 16000);
245
+ // this.playPCM(this.BufferToBlob(frameBuffer),16000) // 切片数据播放,采样率测试
246
+ if (this.iatWS.readyState === this.iatWS.OPEN) {
247
+ if (this.disableASR)
248
+ return;
249
+ this.iatWS.send(JSON.stringify({
250
+ data: {
251
+ status: isLastFrame ? 2 : 1,
252
+ format: "audio/L16;rate=16000",
253
+ encoding: this.encodingType,
254
+ audio: convertFrameBufferToBase64(frameBuffer) // this.toBase64(audioData),
255
+ },
256
+ }));
257
+ if (isLastFrame) {
258
+ this.changeBtnStatus("CLOSING");
259
+ }
260
+ }
261
+ //可实时绘制波形(extensions目录内的waveview.js、wavesurfer.view.js、frequency.histogram.view.js插件功能)
262
+ this.waveClient?.input(buffers[buffers.length - 1], powerLevel, bufferSampleRate);
263
+ }
264
+ });
265
+ }
266
+ async openWithPriviledge() {
267
+ console.log(this.btnStatus);
268
+ await this.requestPermission();
269
+ this.createRecorder();
270
+ if (Recorder.IsOpen())
271
+ return true;
272
+ return new Promise(resolve => {
273
+ //var dialog=createDelayDialog(); 我们可以选择性的弹一个对话框:为了防止移动端浏览器存在第三种情况:用户忽略,并且(或者国产系统UC系)浏览器没有任何回调,此处demo省略了弹窗的代码
274
+ this.recorder.open(() => {
275
+ //dialog&&dialog.Cancel(); 如果开启了弹框,此处需要取消
276
+ //rec.start() 此处可以立即开始录音,但不建议这样编写,因为open是一个延迟漫长的操作,通过两次用户操作来分别调用open和start是推荐的最佳流程
277
+ //创建可视化,指定一个要显示的div
278
+ let waveDiv = document.querySelector(".record-wave");
279
+ if (waveDiv) { // 存在波形区域时,加载渲染组件
280
+ console.log(waveDiv);
281
+ if (Recorder.WaveView)
282
+ this.waveClient = Recorder.WaveView({ elem: ".record-wave" });
283
+ }
284
+ resolve(true);
285
+ }, (msg, isUserNotAllow) => {
286
+ //dialog&&dialog.Cancel(); 如果开启了弹框,此处需要取消
287
+ console.log((isUserNotAllow ? "UserNotAllow," : "") + "无法录音:" + msg);
288
+ });
289
+ });
290
+ }
291
+ getWebSocketUrl() {
292
+ // 请求地址根据语种不同变化
293
+ let url = "wss://iat-api.xfyun.cn/v2/iat";
294
+ let host = "iat-api.xfyun.cn";
295
+ let apiKey = this.API_KEY;
296
+ let apiSecret = this.API_SECRET;
297
+ let date = new Date().toUTCString();
298
+ let algorithm = "hmac-sha256";
299
+ let headers = "host date request-line";
300
+ let signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/iat HTTP/1.1`;
301
+ let signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret);
302
+ let signature = CryptoJS.enc.Base64.stringify(signatureSha);
303
+ let authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`;
304
+ let authorization = btoa(authorizationOrigin);
305
+ url = `${url}?authorization=${authorization}&date=${date}&host=${host}`;
306
+ return url;
307
+ }
308
+ toBase64(buffer) {
309
+ var binary = "";
310
+ var bytes = new Uint8Array(buffer);
311
+ var len = bytes.byteLength;
312
+ for (var i = 0; i < len; i++) {
313
+ binary += String.fromCharCode(bytes[i]);
314
+ }
315
+ return window.btoa(binary);
316
+ }
317
+ /**
318
+ * 倒计时:最长支持60秒实时语音转录,如果持续7-10秒无声音,服务端将自动CLOSE链接
319
+ */
320
+ countdown() {
321
+ let seconds = 60;
322
+ this.connStatus = `录音中(${seconds}s)`;
323
+ this.countdownInterval = setInterval(() => {
324
+ seconds = seconds - 1;
325
+ console.log(seconds);
326
+ if (seconds <= 0) {
327
+ clearInterval(this.countdownInterval);
328
+ this.recordStop();
329
+ }
330
+ else {
331
+ this.connStatus = `录音中(${seconds}s)`;
332
+ }
333
+ }, 1000);
334
+ }
335
+ changeBtnStatus(status) {
336
+ this.btnStatus = status;
337
+ if (status === "CONNECTING") {
338
+ this.connStatus = "建立连接中";
339
+ }
340
+ else if (status === "OPEN") {
341
+ this.countdown();
342
+ }
343
+ else if (status === "CLOSING") {
344
+ this.connStatus = "关闭连接中";
345
+ }
346
+ else if (status === "CLOSED") {
347
+ this.connStatus = "开始录音";
348
+ }
349
+ }
350
+ renderResult(resultData) {
351
+ // 识别结束
352
+ let jsonData = JSON.parse(resultData);
353
+ // console.log(jsonData.data.result)
354
+ if (jsonData.data && jsonData.data.result) {
355
+ let data = jsonData.data.result;
356
+ let str = "";
357
+ let ws = data.ws;
358
+ for (let i = 0; i < ws.length; i++) {
359
+ str = str + ws[i].cw[0].w;
360
+ console.log(str);
361
+ }
362
+ // 开启wpgs会有此字段(前提:在控制台开通动态修正功能)
363
+ // 取值为 "apd"时表示该片结果是追加到前面的最终结果;取值为"rpl" 时表示替换前面的部分结果,替换范围为rg字段
364
+ if (data.pgs) {
365
+ if (data.pgs === "apd") {
366
+ // 将this.resultTextTemp同步给this.resultText
367
+ this.resultText = this.resultTextTemp;
368
+ }
369
+ // 将结果存储在this.resultTextTemp中
370
+ this.resultTextTemp = this.resultText + str;
371
+ }
372
+ else {
373
+ this.resultText = this.resultText + str;
374
+ }
375
+ this.resultTextTemp || this.resultText || "";
376
+ console.log("diff temp", this.resultTextTemp);
377
+ console.log("diff result", this.resultText);
378
+ }
379
+ if (jsonData.code === 0 && jsonData.data.status === 2) {
380
+ this.iatWS.close();
381
+ }
382
+ if (jsonData.code !== 0) {
383
+ this.iatWS.close();
384
+ console.error(jsonData);
385
+ }
386
+ }
387
+ connectWebSocket() {
388
+ console.log("connectWebSocket");
389
+ const websocketUrl = this.getWebSocketUrl();
390
+ if ("WebSocket" in window) {
391
+ this.iatWS = new WebSocket(websocketUrl);
392
+ }
393
+ else if ("MozWebSocket" in window) {
394
+ // this.iatWS = new MozWebSocket(websocketUrl); // Moz兼容
395
+ }
396
+ else {
397
+ alert("浏览器不支持WebSocket");
398
+ return;
399
+ }
400
+ console.log("connectWebSocket", this.btnStatus);
401
+ this.changeBtnStatus("CONNECTING");
402
+ this.iatWS.onopen = (e) => {
403
+ // 开始录音
404
+ this.recordStart();
405
+ var params = {
406
+ common: {
407
+ app_id: this.APPID,
408
+ },
409
+ business: {
410
+ language: "zh_cn",
411
+ domain: "iat",
412
+ accent: "mandarin",
413
+ vad_eos: 5000,
414
+ dwa: "wpgs",
415
+ },
416
+ data: {
417
+ status: 0,
418
+ format: "audio/L16;rate=16000",
419
+ encoding: this.encodingType,
420
+ // encoding: "speex-wb",
421
+ },
422
+ };
423
+ this.iatWS.send(JSON.stringify(params));
424
+ };
425
+ this.iatWS.onmessage = (e) => {
426
+ console.log("onmessage" + this.resultText);
427
+ this.renderResult(e.data);
428
+ };
429
+ this.iatWS.onerror = (e) => {
430
+ console.error("error", e);
431
+ this.recordStop();
432
+ this.changeBtnStatus("CLOSED");
433
+ };
434
+ this.iatWS.onclose = async (e) => {
435
+ // 5秒停顿会导致结束录制
436
+ console.log("onclose" + this.resultText);
437
+ console.error("close", e);
438
+ await this.recordStop();
439
+ this.changeBtnStatus("CLOSED");
440
+ };
441
+ }
442
+ /**
443
+ * 移动端兼容方法
444
+ */
445
+ /**
446
+ * 移动端上传专用方法
447
+ * @returns
448
+ */
449
+ isCapacitor() {
450
+ return this.platform.is("capacitor") || this.platform.is("cordova");
451
+ }
452
+ async requestPermission() {
453
+ if (!this.isCapacitor())
454
+ return;
455
+ try {
456
+ await this.requestStoagePermission();
457
+ await this.requestCameraPermission();
458
+ await this.requestMicPermission();
459
+ await this.requestRecordAudioPermission();
460
+ }
461
+ catch (err) {
462
+ console.error(err);
463
+ }
464
+ }
465
+ async requestRecordAudioPermission() {
466
+ let data = await this.diagnostic.requestRuntimePermissions([this.diagnostic.permission.RECORD_AUDIO]);
467
+ console.log("record permission request:", data);
468
+ return;
469
+ }
470
+ async requestMicPermission() {
471
+ let isAvailable = await this.diagnostic.isMicrophoneAuthorized();
472
+ console.log("permisson_MIC:", isAvailable);
473
+ if (!isAvailable) {
474
+ let data = await this.diagnostic.requestMicrophoneAuthorization();
475
+ }
476
+ return;
477
+ }
478
+ async requestStoagePermission() {
479
+ let isAvailable = await this.diagnostic.isExternalStorageAuthorized();
480
+ console.log("permisson_STORAGE:", isAvailable);
481
+ if (!isAvailable) {
482
+ let data = await this.diagnostic.requestExternalStorageAuthorization();
483
+ }
484
+ return;
485
+ }
486
+ async requestCameraPermission() {
487
+ let isAvailable = await this.diagnostic.isCameraAuthorized();
488
+ console.log("permisson_Camera:", isAvailable);
489
+ if (!isAvailable) {
490
+ let data = await this.diagnostic.requestCameraAuthorization();
491
+ }
492
+ return;
493
+ }
494
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FmodeVoiceService, deps: [{ token: i1.Platform }, { token: i2.Diagnostic }], target: i0.ɵɵFactoryTarget.Injectable }); }
495
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FmodeVoiceService, providedIn: 'root' }); }
496
+ }
497
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FmodeVoiceService, decorators: [{
498
+ type: Injectable,
499
+ args: [{
500
+ providedIn: 'root'
501
+ }]
502
+ }], ctorParameters: () => [{ type: i1.Platform }, { type: i2.Diagnostic }] });
503
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm1vZGUtdm9pY2Uuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Ztb2RlLW5nL3NyYy9saWIvYWlnYy92b2ljZS9mbW9kZS12b2ljZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBZ0IsVUFBVSxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQ2pFLHNEQUFzRDtBQUN0RCxrRUFBa0U7QUFDbEUsT0FBTyxRQUFRLE1BQU0sZUFBZSxDQUFBO0FBQ3BDLE9BQU8sOEJBQThCLENBQUE7QUFDckMsT0FBTyw4QkFBOEIsQ0FBQTtBQUNyQyxPQUFPLHVDQUF1QyxDQUFBO0FBQzlDLE9BQU8sUUFBUSxNQUFNLFdBQVcsQ0FBQTtBQUNoQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSwwQkFBMEIsRUFBaUIsY0FBYyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0YsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN4QyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDMUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHlDQUF5QyxDQUFDOzs7O0FBQ3JFLDZEQUE2RDtBQUs3RCxNQUFNLE9BQU8saUJBQWlCO0lBYzVCLFlBQ1UsUUFBaUIsRUFDakIsVUFBc0I7UUFEdEIsYUFBUSxHQUFSLFFBQVEsQ0FBUztRQUNqQixlQUFVLEdBQVYsVUFBVSxDQUFZO1FBVmhDOztXQUVHO1FBQ0gsbUNBQW1DO1FBQ25DOztXQUVHO1FBQ0gsY0FBUyxHQUFHLFNBQVMsQ0FBQTtRQWlEdEI7O1dBRUc7UUFDSCxpQkFBWSxHQUFXLEtBQUssQ0FBQztRQW9HNUIsa0JBQWEsR0FBUSxJQUFJLENBQUE7UUFDekIsa0JBQWEsR0FBUSxJQUFJLENBQUE7UUFDekIsbUJBQWMsR0FBVSxDQUFDLENBQUM7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RUFBRSxDQUFBO1FBQ3JFLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLEVBQUUsV0FBVyxDQUFDLENBQUE7UUFDOUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ2pCLElBQUksSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxtQ0FBbUMsRUFBRSxDQUFBO1FBQ3hFLENBQUM7UUFDRCxPQUFNO0lBQ1YsQ0FBQztJQUNELEtBQUssQ0FBQyx1QkFBdUI7UUFDM0IsSUFBSSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLGtCQUFrQixFQUFFLENBQUE7UUFDNUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsRUFBRSxXQUFXLENBQUMsQ0FBQTtRQUM3QyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDakIsSUFBSSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLDBCQUEwQixFQUFFLENBQUE7UUFDL0QsQ0FBQztRQUNELE9BQU07SUFDVixDQUFDOytHQTNnQlUsaUJBQWlCO21IQUFqQixpQkFBaUIsY0FGaEIsTUFBTTs7NEZBRVAsaUJBQWlCO2tCQUg3QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEV2ZW50RW1pdHRlciwgSW5qZWN0YWJsZSwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG4vLyBpbXBvcnQgUmVjb3JkZXJNYW5hZ2VyIGZyb20gXCIuL2xpYi94dW5mZWktcmVjb3JkZXJcIlxuLy8gaW1wb3J0IHtSZWNvcmRlck1hbmFnZXJ9IGZyb20gXCIuL2xpYi9yZWNvcmRlci9yZWNvcmRlci1tYW5hZ2VyXCJcbmltcG9ydCBSZWNvcmRlciBmcm9tICdyZWNvcmRlci1jb3JlJ1xuaW1wb3J0ICdyZWNvcmRlci1jb3JlL3NyYy9lbmdpbmUvcGNtJ1xuaW1wb3J0ICdyZWNvcmRlci1jb3JlL3NyYy9lbmdpbmUvd2F2J1xuaW1wb3J0ICdyZWNvcmRlci1jb3JlL3NyYy9leHRlbnNpb25zL3dhdmV2aWV3J1xuaW1wb3J0IENyeXB0b0pTIGZyb20gXCJjcnlwdG8tanNcIlxuaW1wb3J0IHsgcGNtdG9XYXYgfSBmcm9tICcuL2xpYi9wY20yd2F2JztcbmltcG9ydCB7IGNvbnZlcnRGcmFtZUJ1ZmZlclRvQmFzZTY0LCByZXNhbXBsZUF1ZGlvLCByZXNhbXBsZUJ1ZmZlciB9IGZyb20gJy4vbGliL3Jlc2FtcGxlJztcbmltcG9ydCB7IFdlYlNwZWVjaCB9IGZyb20gJy4vY2xhc3MtYXNyJztcbmltcG9ydCB7IFBsYXRmb3JtIH0gZnJvbSAnQGlvbmljL2FuZ3VsYXInO1xuaW1wb3J0IHsgRGlhZ25vc3RpYyB9IGZyb20gJ0Bhd2Vzb21lLWNvcmRvdmEtcGx1Z2lucy9kaWFnbm9zdGljL25neCc7XG4vLyBpbXBvcnQgeyBGbW9kZVRUU1h1bmZlaSB9IGZyby4vY2xhc3MtdHRzLXh1bmZlaS50cy5iYWtmZWknXG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEZtb2RlVm9pY2VTZXJ2aWNlIHtcblxuICAvKipcbiAgICog5YWz6ZetQVNS77ya55So5LqO5rWL6K+V5YW25LuW5Yqf6IO95pe277yM5Y+v5YWz6ZetQVNS6IqC55yB6K+t6Z+z5o6l5Y+j5raI6ICXXG4gICAqL1xuICBkaXNhYmxlQVNSOmZhbHNlO1xuICAvKipcbiAgICog6K6v6aOeVFRT6K+t6Z+z5ZCI5oiQXG4gICAqL1xuICAvLyB0dHNYdW5mZWkgPSBuZXcgRm1vZGVUVFNYdW5mZWkoKVxuICAvKipcbiAgICogV2ViU3BlZWNoIOivremfs+W6k1xuICAgKi9cbiAgd2ViU3BlZWNoID0gV2ViU3BlZWNoXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcGxhdGZvcm06UGxhdGZvcm0sXG4gICAgcHJpdmF0ZSBkaWFnbm9zdGljOiBEaWFnbm9zdGljLCBcbiAgKSB7IFxuICAgIHRoaXMucmVxdWVzdFBlcm1pc3Npb24oKTtcbiAgICAvLyB0aGlzLnJlY29yZGVyLm9uKFwic3RhcnRcIiwoKSA9PiB7XG4gICAgLy8gfSlcblxuICAgIC8vIHRoaXMucmVjb3JkZXIub24oXCJmcmFtZVJlY29yZGVkXCIsICh7IGlzTGFzdEZyYW1lLCBmcmFtZUJ1ZmZlciB9KSA9PiB7XG4gICAgLy8gICBpZiAodGhpcy5pYXRXUy5yZWFkeVN0YXRlID09PSB0aGlzLmlhdFdTLk9QRU4pIHtcbiAgICAvLyAgICAgdGhpcy5pYXRXUy5zZW5kKFxuICAgIC8vICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAvLyAgICAgICAgIGRhdGE6IHtcbiAgICAvLyAgICAgICAgICAgc3RhdHVzOiBpc0xhc3RGcmFtZSA/IDIgOiAxLFxuICAgIC8vICAgICAgICAgICBmb3JtYXQ6IFwiYXVkaW8vTDE2O3JhdGU9MTYwMDBcIixcbiAgICAvLyAgICAgICAgICAgZW5jb2Rpbmc6IHRoaXMuZW5jb2RpbmdUeXBlLFxuICAgIC8vICAgICAgICAgICBhdWRpbzogdGhpcy50b0Jhc2U2NChmcmFtZUJ1ZmZlciksXG4gICAgLy8gICAgICAgICB9LFxuICAgIC8vICAgICAgIH0pXG4gICAgLy8gICAgICk7XG4gICAgLy8gICAgIGlmIChpc0xhc3RGcmFtZSkge1xuICAgIC8vICAgICAgIHRoaXMuY2hhbmdlQnRuU3RhdHVzKFwiQ0xPU0lOR1wiKTtcbiAgICAvLyAgICAgfVxuICAgIC8vICAgfVxuICAgIC8vIH0pXG5cbiAgICAvLyB0aGlzLnJlY29yZGVyLm9uKFwic3RvcFwiLCgpID0+IHtcbiAgICAvLyB9KVxuXG5cbiAgfVxuXG5cblxuICBvblJlc3VsdFRleHRDaGFuZ2VkOkZ1bmN0aW9uXG4gIC8qKigpXG4gICAqIOeUqOaIt+aTjeS9nO+8muW9lemfs+aMiemSruW/q+aNt+inpuWPkeaTjeS9nFxuICAgKi9cbiAgIHRvZ2dsZVJlY29yZCgpe1xuICAgIGNvbnNvbGUubG9nKHRoaXMuYnRuU3RhdHVzKVxuICAgIGlmICh0aGlzLmJ0blN0YXR1cyA9PT0gXCJVTkRFRklORURcIiB8fCB0aGlzLmJ0blN0YXR1cyA9PT0gXCJDTE9TRURcIikge1xuICAgICAgLy8g5byA5aeL6K6y6K+dYFxuICAgICAgdGhpcy5zdGFydFRhbGsoKVxuICAgIH0gZWxzZSBpZiAodGhpcy5idG5TdGF0dXMgPT09IFwiQ09OTkVDVElOR1wiIHx8IHRoaXMuYnRuU3RhdHVzID09PSBcIk9QRU5cIikge1xuICAgICAgLy8g57uT5p2f5b2V6Z+zIOW5tuWPkemAgea2iOaBr+etieW+heWbnuWkjVxuICAgICAgdGhpcy5maW5pc2hUYWxrKClcbiAgICB9XG4gIH1cbiAvKipcbiAgICog55So5oi35pON5L2c77ya5a6M5oiQ5b2V6Z+z77yM5bm25aSE55CG6L2s5b2V57uT5p6cXG4gICovXG4gaXNVc2VyRmluaXNoOmJvb2xlYW4gPSBmYWxzZTtcbiBmaW5pc2hUYWxrKCl7XG4gICAgdGhpcy5pc1VzZXJGaW5pc2ggPSB0cnVlO1xuICAgIHRoaXMub25CZWZvcmVGaW5pc2hUYWxrJiZ0aGlzLm9uQmVmb3JlRmluaXNoVGFsaygpXG4gICAgdGhpcy5yZWNvcmRTdG9wKClcbiB9XG4gb25CZWZvcmVGaW5pc2hUYWxrOiBGdW5jdGlvblxuIG9uQWZ0ZXJGaW5pc2hUYWxrOiBGdW5jdGlvblxuICAvKipcbiAgICog55So5oi35pON5L2c77ya5byA5aeL6K6y6K+d77yM5a6e5pe26L2s5b2V6K+t6KiAXG4gICAqL1xuICBhc3luYyBzdGFydFRhbGsoZXZuZXQ/KXtcbiAgICB0aGlzLnJlc3VsdFRleHQgPSBcIlwiXG4gICAgdGhpcy5yZXN1bHRUZXh0VGVtcCA9IFwiXCJcbiAgICB0aGlzLm9uQmVmb3JlU3RhcnRUYWxrJiZ0aGlzLm9uQmVmb3JlU3RhcnRUYWxrKClcbiAgICBldmVudD8ucHJldmVudERlZmF1bHQoKVxuICAgIGF3YWl0IHRoaXMub3BlbldpdGhQcml2aWxlZGdlKClcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuY29ubmVjdFdlYlNvY2tldCgpXG4gICAgfSwgMTAwKTtcblxuICAgIHRoaXMub25BZnRlclN0YXJ0VGFsayYmdGhpcy5vbkFmdGVyU3RhcnRUYWxrKClcbiAgfVxuICBvbkJlZm9yZVN0YXJ0VGFsazogRnVuY3Rpb25cbiAgb25BZnRlclN0YXJ0VGFsazogRnVuY3Rpb25cbiAgXG4gIC8qKlxuICAgKiDnlKjmiLfmk43kvZzvvJrlj5bmtojorrLor53vvIzkuJTkuI3lj5HpgIHnu5PmnpxcbiAgICovXG4gIGNhbmNlbFRhbGsoKXtcbiAgICB0aGlzLm9uQmVmb3JlQ2FuY2VsVGFsayYmdGhpcy5vbkJlZm9yZUNhbmNlbFRhbGsoKVxuICAgIHRoaXMucmVjb3JkU3RvcCgpOyAvLyDlgZzmraLlvZXliLZcbiAgICB0aGlzLmlhdFdTPy5jbG9zZSgpOyAvLyDmlq3lvIDov57mjqVcbiAgICB0aGlzLnJlc3VsdFRleHQgPSBudWxsOyAvLyDorr7nva7ovazlvZXnu5PmnpzkuLrnqbpcbiAgICB0aGlzLm9uQWZ0ZXJDYW5jZWxUYWxrJiZ0aGlzLm9uQWZ0ZXJDYW5jZWxUYWxrKClcbiAgfVxuICAvKipcbiAgICog5pON5L2c5Zue6LCDXG4gICAqL1xuICBvbkJlZm9yZUNhbmNlbFRhbGs6IEZ1bmN0aW9uXG4gIG9uQWZ0ZXJDYW5jZWxUYWxrOiBGdW5jdGlvblxuICBvbkFmdGVyUmVjb3JkU3RhcnQ6IEZ1bmN0aW9uXG5cbiAgLyoqXG4gICAqIOeoi+W6j+mAu+i+kVxuICAgKi9cbiAgYXN5bmMgcmVjb3JkU3RhcnQoKXtcbiAgICB0aGlzLmNyZWF0ZVJlY29yZGVyKCk7XG4gICAgYXdhaXQgdGhpcy5vcGVuV2l0aFByaXZpbGVkZ2UoKVxuICAgIHRoaXMucmVjb3JkZXIuc3RhcnQoKTtcbiAgICB0aGlzLmNoYW5nZUJ0blN0YXR1cyhcIk9QRU5cIik7XG4gICAgdGhpcy5vbkFmdGVyUmVjb3JkU3RhcnQmJnRoaXMub25BZnRlclJlY29yZFN0YXJ0KClcbiAgfVxuICByZWNvcmRTdG9wKCl7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKT0+e1xuICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmNvdW50ZG93bkludGVydmFsKTtcbiAgICAgIHRoaXMuY2hhbmdlQnRuU3RhdHVzKFwiQ0xPU0VEXCIpO1xuICAgICAgdGhpcy5yZWNvcmRlcj8uc3RvcChhc3luYyAoYmxvYjpCbG9iLGR1cmF0aW9uOm51bWJlcik9PntcbiAgICAgICAgICAvL+W9lemfs+e7k+adn+WQju+8jOWPkemAgeW9lemfs+e7k+adn+W4p1xuICAgICAgICAgIHRyeXtcbiAgICAgICAgICAgIHRoaXMuaWF0V1Muc2VuZChcbiAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkoe1wiZGF0YVwiOntcInN0YXR1c1wiOjIsXCJmb3JtYXRcIjpcImF1ZGlvL0wxNjtyYXRlPTE2MDAwXCIsXCJlbmNvZGluZ1wiOnRoaXMuZW5jb2RpbmdUeXBlLFwiYXVkaW9cIjpcIlwifX0pXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgfWNhdGNoKGVycil7fVxuXG4gICAgICAgICAgLy/nroDljZXliKnnlKhVUkznlJ/miJDmnKzlnLDmlofku7blnLDlnYDvvIzms6jmhI/kuI3nlKjkuobml7bpnIDopoFyZXZva2VPYmplY3RVUkzvvIzlkKbliJnpnLjljaDlhoXlrZhcbiAgICAgICAgICAvL+atpOWcsOWdgOWPquiDveacrOWcsOS9v+eUqO+8jOavlOWmgui1i+WAvOe7mWF1ZGlvLnNyY+i/m+ihjOaSreaUvu+8jOi1i+WAvOe7mWEuaHJlZueEtuWQjmEuY2xpY2soKei/m+ihjOS4i+i9ve+8iGHpnIDmj5Dkvptkb3dubG9hZD1cInh4eC5tcDNcIuWxnuaAp++8iVxuICAgICAgICAgIGxldCBsb2NhbFVybD0od2luZG93LlVSTHx8d2Via2l0VVJMKS5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgICAgY29uc29sZS5sb2coYmxvYixsb2NhbFVybCxcIuaXtumVvzpcIitkdXJhdGlvbitcIm1zXCIpO1xuICAgICAgICAgIHRoaXMucmVjb3JkUGNtQmxvYiA9IGJsb2I7XG4gICAgICAgICAgdGhpcy5yZWNvcmRXYXZCbG9iID0gYXdhaXQgdGhpcy5wY21CbG9iVG9XYXZCbG9iKGJsb2IsNDQxMDApO1xuICAgICAgICAgIHRoaXMucmVjb3JkRHVyYXRpb24gPSBkdXJhdGlvbjtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcInRoaXMucmVjb3JkV2F2QmxvYlwiLHRoaXMucmVjb3JkV2F2QmxvYilcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGlmKHRoaXMuaXNVc2VyRmluaXNoKXtcbiAgICAgICAgICAgICAgdGhpcy5vbkFmdGVyRmluaXNoVGFsayYmdGhpcy5vbkFmdGVyRmluaXNoVGFsaygpXG4gICAgICAgICAgICAgIHRoaXMuaXNVc2VyRmluaXNoID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwgMjAwMCk7XG4gICAgICAgICAgdGhpcy5yZWNvcmRlcj8uY2xvc2UoKTsvL+mHiuaUvuW9lemfs+i1hOa6kO+8jOW9k+eEtuWPr+S7peS4jemHiuaUvu+8jOWQjumdouWPr+S7pei/nue7reiwg+eUqHN0YXJ077yb5L2G5LiN6YeK5pS+5pe257O757uf5oiW5rWP6KeI5Zmo5Lya5LiA55u05o+Q56S65Zyo5b2V6Z+z77yM5pyA5L2z5pON5L2c5piv5b2V5a6M5bCxY2xvc2XmjolcbiAgICAgICAgICB0aGlzLnJlY29yZGVyPW51bGw7XG4gICAgICAgICAgXG4gICAgICAgICAgLy/lt7Lnu4/mi7/liLBibG9i5paH5Lu25a+56LGh5oOz5bmy5Zib5bCx5bmy5Zib77ya56uL5Y2z5pKt5pS+44CB5LiK5Lyg44CB5LiL6L295L+d5a2YXG4gICAgICAgICAgXG4gICAgICAgICAgLyoqKiDjgJDnq4vljbPmkq3mlL7kvovlrZDjgJEgKioqL1xuICAgICAgICAgIC8vIHRoaXMuYXVkaW9QbGF5ZXI9IG5ldyBBdWRpbygpO1xuICAgICAgICAgIC8vIHRoaXMuYXVkaW9QbGF5ZXIuY29udHJvbHM9dHJ1ZTtcbiAgICAgICAgICAvLyB0aGlzLmF1ZGlvUGxheWVyLnNyYz1sb2NhbFVybDtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcImxvY2FsVXJsXCIsbG9jYWxVcmwpXG4gICAgICAgICAgLy8g562J5b6F6K+t6Z+z6L2s5LmJ5a6M5oiQ77yM5aSE55CG6L2s5b2V57uT5p6cXG4gICAgICAgICAgLy8g6ZyA6KaB5YeG56Gu5Yik5patd2Vic29ja2V05bey57uPY2xvc2XkuoZcbiAgICAgICAgICByZXNvbHZlKHRydWUpO1xuICAgICAgfSwobXNnKT0+e1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwi5b2V6Z+z5aSx6LSlOlwiK21zZyk7XG4gICAgICAgICAgdGhpcy5yZWNvcmRlci5jbG9zZSgpOy8v5Y+v5Lul6YCa6L+Hc3RvcOaWueazleeahOesrDPkuKrlj4LmlbDmnaXoh6rliqjosIPnlKhjbG9zZVxuICAgICAgICAgIHRoaXMucmVjb3JkZXI9bnVsbDtcbiAgICAgICAgICByZXNvbHZlKG51bGwpXG4gICAgICB9KVxuICAgIH0pXG4gIH1cbiAgcmVjb3JkV2F2QmxvYjpCbG9iID0gbnVsbFxuICByZWNvcmRQY21CbG9iOkJsb2IgPSBudWxsXG4gIHJlY29yZER1cmF0aW9uOm51bWJlciA9IDA7XG4gIHBsYXlSZWNvcmQoKXtcbiAgICB0aGlzLnBsYXlQQ00odGhpcy5yZWNvcmRQY21CbG9iLDQ0MTAwKVxuICB9XG4gIGFzeW5jIHBjbUJsb2JUb1dhdkJsb2IocGNtQmxvYiwgc2FtcGxlUmF0ZSk6UHJvbWlzZTxCbG9iPntcbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZT0+e1xuICAgICAgbGV0IGZpbGVSZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgICAgXG4gICAgICAvLyDor7vlj5ZCbG9i5pWw5o2uXG4gICAgICBmaWxlUmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgIGxldCBwY21EYXRhOmFueSA9IGV2ZW50LnRhcmdldC5yZXN1bHQ7XG4gICAgICAgIC8vIENvbnZlcnQgUENNIGRhdGEgdG8gV0FWIGZvcm1hdFxuICAgICAgICBsZXQgd2F2QmxvYiA9IHBjbXRvV2F2KHBjbURhdGEsIHNhbXBsZVJhdGUsMSwxNik7XG4gICAgICAgIHJlc29sdmUod2F2QmxvYilcbiAgICAgIH07XG4gICAgICBcbiAgICAgIC8vIOWwhkJsb2LovazmjaLkuLpBcnJheUJ1ZmZlclxuICAgICAgZmlsZVJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihwY21CbG9iKTtcbiAgICB9KVxuICB9XG4gIGFzeW5jIHBsYXlQQ00ocGNtQmxvYiwgc2FtcGxlUmF0ZSkge1xuICAgIGxldCB3YXZCbG9iID0gYXdhaXQgdGhpcy5wY21CbG9iVG9XYXZCbG9iKHBjbUJsb2Isc2FtcGxlUmF0ZSk7XG4gICAgbGV0IHdhdlVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHdhdkJsb2IpXG4gICAgbGV0IGF1ZGlvID0gbmV3IEF1ZGlvKCk7XG4gICAgYXVkaW8uc3JjID0gd2F2VXJsO1xuICAgIGF1ZGlvLnBsYXkoKTtcbiAgfVxuICBidWZmZXJzOkFycmF5PGFueT5cbiAgYXN5bmMgcGxheUJ1ZmZlcnMoKXtcbiAgICAvLyBsZXQgYXVkaW9CdWZmZXIgPSBbXVxuICAgIC8vIHRoaXMuYnVmZmVycy5mb3JFYWNoKGJ1ZmZlcj0+e1xuICAgIC8vICAgYXVkaW9CdWZmZXIucHVzaChidWZmZXIpXG4gICAgLy8gfSlcbiAgICBsZXQgYXVkaW9CbG9iID0gYXdhaXQgdGhpcy5CdWZmZXJzVG9CbG9iKHRoaXMuYnVmZmVycylcbiAgICB0aGlzLnBsYXlQQ00oYXVkaW9CbG9iLDQ0MTAwKVxuICB9XG4gIEJ1ZmZlcnNUb0Jsb2IoYnVmZmVycykge1xuICAgIGxldCBhdWRpb0J1ZmZlcjphbnkgPSBbXVxuICAgIGJ1ZmZlcnMuZm9yRWFjaChidWZmZXI9PntcbiAgICAgIGJ1ZmZlci5mb3JFYWNoKGludDE2PT57XG4gICAgICAgIGF1ZGlvQnVmZmVyLnB1c2goaW50MTYpXG4gICAgICB9KVxuICAgIH0pXG4gICAgcmV0dXJuIG5ldyBCbG9iKFthdWRpb0J1ZmZlcl0sIHsgdHlwZTogJ2F1ZGlvL3BjbScgfSk7XG4gIH1cbiAgLy8g5bCG5b2V6Z+z5pWw5o2u5YiG5Ymy5Li65q+P5qyh5Y+R6YCB55qE6Z+z6aKR54mH5q61IDEyODDlrZfoioJcbiAgIHNwbGl0QXVkaW9EYXRhKGF1ZGlvRGF0YSkge1xuICAgIGNvbnN0IHNlZ21lbnRTaXplID0gMTI4MDsgLy8g55uu5qCH5YiH54mH5aSn5bCP77yM5Y2V5L2N5Li65a2X6IqCXG4gICAgY29uc3Qgc2VnbWVudENvdW50ID0gTWF0aC5jZWlsKGF1ZGlvRGF0YS5sZW5ndGggLyBzZWdtZW50U2l6ZSk7IC8vIOWIh+eJh+aVsOmHj1xuICAgIGNvbnN0IHNlZ21lbnRzID0gW107XG4gIFxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VnbWVudENvdW50OyBpKyspIHtcbiAgICAgIGNvbnN0IHN0YXJ0ID0gaSAqIHNlZ21lbnRTaXplO1xuICAgICAgY29uc3QgZW5kID0gc3RhcnQgKyBzZWdtZW50U2l6ZTtcbiAgICAgIGNvbnN0IHNlZ21lbnQgPSBhdWRpb0RhdGEuc2xpY2Uoc3RhcnQsIGVuZCk7XG4gIFxuICAgICAgc2VnbWVudHMucHVzaChzZWdtZW50KTtcbiAgICB9XG4gIFxuICAgIHJldHVybiBzZWdtZW50cztcbiAgfVxuICBCdWZmZXJUb0Jsb2IoYnVmZmVyKSB7XG4gICAgcmV0dXJuIG5ldyBCbG9iKFtidWZmZXJdLCB7IHR5cGU6ICdhdWRpby9wY20nIH0pO1xuICB9XG4gIHJlY29yZFR5cGUgPSBcInBjbVwiXG4gIGVuY29kaW5nVHlwZSA9IFwicmF3XCJcbiAgY3JlYXRlUmVjb3JkZXIoKXtcbiAgICBpZih0aGlzLnJlY29yZGVyKSByZXR1cm5cbiAgICB0aGlzLnJlY29yZGVyID0gUmVjb3JkZXIoeyAvL+acrOmFjee9ruWPguaVsOivt+WPguiAg+S4i+mdoueahOaWh+aho++8jOacieivpue7huS7i+e7jVxuICAgICAgdHlwZTp0aGlzLnJlY29yZFR5cGUsc2FtcGxlUmF0ZTo0NDEwMCxiaXRSYXRlOjE2IC8vcGNt5qC85byP77yM5oyH5a6a6YeH5qC3546HaHrjgIHmr5TnibnnjodrYnBz77yM5YW25LuW5Y+C5pWw5L2/55So6buY6K6k6YWN572u77yb5rOo5oSP77ya5piv5pWw5a2X55qE5Y+C5pWw5b+F6aG75o+Q5L6b5pWw5a2X77yM5LiN6KaB55So5a2X56ym5Liy77yb6ZyA6KaB5L2/55So55qEdHlwZeexu+Wei++8jOmcgOaPkOWJjeaKiuagvOW8j+aUr+aMgeaWh+S7tuWKoOi9vei/m+adpe+8jOavlOWmguS9v+eUqHdhduagvOW8j+mcgOimgeaPkOWJjeWKoOi9vXdhdi5qc+e8lueggeW8leaTjlxuICAgICAgLG9uUHJvY2VzczooYnVmZmVycyxwb3dlckxldmVsLGJ1ZmZlckR1cmF0aW9uLGJ1ZmZlclNhbXBsZVJhdGUsbmV3QnVmZmVySWR4LGFzeW5jRW5kKT0+e1xuICAgICAgICAgIC8v5b2V6Z+z5a6e5pe25Zue6LCD77yM5aSn57qmMeenkuiwg+eUqDEy5qyh5pys5Zue6LCD77yMYnVmZmVyc+S4uuW8gOWni+WIsOeOsOWcqOeahOaJgOacieW9lemfs3BjbeaVsOaNruWdlygxNuS9jeWwj+err0xFKVxuICAgICAgICAgIC8v5Y+v5Yip55SoZXh0ZW5zaW9ucy9zb25pYy5qc+aPkuS7tuWunuaXtuWPmOmAn+WPmOiwg++8jOatpOaPkuS7tuiuoeeul+mHj+W3qOWkp++8jG9uUHJvY2Vzc+mcgOimgei/lOWbnnRydWXlvIDlkK/lvILmraXmqKHlvI9cbiAgICAgICAgICAvL+WPr+WunuaXtuS4iuS8oO+8iOWPkemAge+8ieaVsOaNru+8jOmFjeWQiFJlY29yZGVyLlNhbXBsZURhdGHmlrnms5XvvIzlsIZidWZmZXJz5Lit55qE5paw5pWw5o2u6L+e57ut55qE6L2s5o2i5oiQcGNt5LiK5Lyg77yM5oiW5L2/55SobW9ja+aWueazleWwhuaWsOaVsOaNrui/nue7reeahOi9rOeggeaIkOWFtuS7luagvOW8j+S4iuS8oO+8jOWPr+S7peWPguiAg+aWh+aho+mHjOmdoueahO+8mkRlbW/niYfmrrXliJfooaggLT4g5a6e5pe26L2s56CB5bm25LiK5LygLemAmueUqOeJiO+8m+WfuuS6juacrOWKn+iDveWPr+S7peWBmuWIsO+8muWunuaXtui9rOWPkeaVsOaNruOAgeWunuaXtuS/neWtmOaVsOaNruOAgeWunuaXtuivremfs+ivhuWIq++8iEFTUu+8ieetiVxuICAgICAgICAgIC8vIOWunuaXtuWPkemAgeW9lemfs+iHs+aOpeWPo1xuICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwiYXN5bmNFbmQ6XCIsYXN5bmNFbmQpXG4gICAgICAgICAgLy8gY29uc29sZS5sb2coYnVmZmVycy5sZW5ndGgsYnVmZmVyRHVyYXRpb24sYnVmZmVyU2FtcGxlUmF0ZSxuZXdCdWZmZXJJZHgpXG4gICAgICAgICAgbGV0IGlzTGFzdEZyYW1lID0gZmFsc2UgJiYgdGhpcy5idG5TdGF0dXM9PVwiQ0xPU0VEXCI7IC8vIOS4u+WKqOWFs+mXreS9nOS4uuacgOWQjuW4p1xuICAgICAgICAgIC8vIOW9lemfs+m7mOiupOS4uiA0NDEwMCDph4fmoLfnjocgcGNt5LiN5pSv5oyB5YaNcHJvY2Vzc+S4reWunuaXtui9rOaNolxuICAgICAgICAgIC8vIOmcgOimgeWOi+e8qeS4uiAxNjAwMCDkuIrkvKBcbiAgICAgICAgICBsZXQgZnJhbWVCdWZmZXIgPSBidWZmZXJzLmxlbmd0aCYmYnVmZmVyc1tidWZmZXJzLmxlbmd0aC0xXTtcbiAgICAgICAgICB0aGlzLmJ1ZmZlcnMgPSBidWZmZXJzXG4gICAgICAgICAgZnJhbWVCdWZmZXIgPSByZXNhbXBsZUJ1ZmZlcihmcmFtZUJ1ZmZlciw0NDEwMCwxNjAwMCk7XG4gICAgICAgICAgLy8gdGhpcy5wbGF5UENNKHRoaXMuQnVmZmVyVG9CbG9iKGZyYW1lQnVmZmVyKSwxNjAwMCkgLy8g5YiH54mH5pWw5o2u5pKt5pS+77yM6YeH5qC3546H5rWL6K+VXG5cbiAgICAgICAgICBpZiAodGhpcy5pYXRXUy5yZWFkeVN0YXRlID09PSB0aGlzLmlhdFdTLk9QRU4pIHtcbiAgICAgICAgICAgICAgICBpZih0aGlzLmRpc2FibGVBU1IpIHJldHVyblxuICAgICAgICAgICAgICAgIHRoaXMuaWF0V1Muc2VuZChcbiAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICAgIHN0YXR1czogaXNMYXN0RnJhbWUgPyAyIDogMSxcbiAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQ6IFwiYXVkaW8vTDE2O3JhdGU9MTYwMDBcIixcbiAgICAgICAgICAgICAgICAgICAgICBlbmNvZGluZzogdGhpcy5lbmNvZGluZ1R5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGNvbnZlcnRGcmFtZUJ1ZmZlclRvQmFzZTY0KGZyYW1lQnVmZmVyKS8vIHRoaXMudG9CYXNlNjQoYXVkaW9EYXRhKSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgXG4gICAgICAgICAgICBpZiAoaXNMYXN0RnJhbWUpIHtcbiAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VCdG5TdGF0dXMoXCJDTE9TSU5HXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICAvL+WPr+WunuaXtue7mOWItuazouW9ou+8iGV4dGVuc2lvbnPnm67lvZXlhoXnmoR3YXZldmlldy5qc+OAgXdhdmVzdXJmZXIudmlldy5qc+OAgWZyZXF1ZW5jeS5oaXN0b2dyYW0udmlldy5qc+aPkuS7tuWKn+iDve+8iVxuICAgICAgICAgIHRoaXMud2F2ZUNsaWVudD8uaW5wdXQoYnVmZmVyc1tidWZmZXJzLmxlbmd0aC0xXSxwb3dlckxldmVsLGJ1ZmZlclNhbXBsZVJhdGUpO1xuICAgICAgfVxuICB9KTtcbiAgfVxuICBcbiAgYXN5bmMgb3BlbldpdGhQcml2aWxlZGdlKCl7XG4gICAgY29uc29sZS5sb2codGhpcy5idG5TdGF0dXMpXG4gICAgYXdhaXQgdGhpcy5yZXF1ZXN0UGVybWlzc2lvbigpO1xuICAgIHRoaXMuY3JlYXRlUmVjb3JkZXIoKTtcbiAgICBpZihSZWNvcmRlci5Jc09wZW4oKSkgcmV0dXJuIHRydWVcbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZT0+e1xuICAgICAgLy92YXIgZGlhbG9nPWNyZWF0ZURlbGF5RGlhbG9nKCk7IOaIkeS7rOWPr+S7pemAieaLqeaAp+eahOW8ueS4gOS4quWvueivneahhu+8muS4uuS6humYsuatouenu+WKqOerr+a1j+iniOWZqOWtmOWcqOesrOS4ieenjeaDheWGte+8mueUqOaIt+W/veeVpe+8jOW5tuS4lO+8iOaIluiAheWbveS6p+ezu+e7n1VD57O777yJ5rWP6KeI5Zmo5rKh5pyJ5Lu75L2V5Zue6LCD77yM5q2k5aSEZGVtb+ecgeeVpeS6huW8ueeql+eahOS7o+eggVxuICAgICAgdGhpcy5yZWNvcmRlci5vcGVuKCgpPT57Ly/miZPlvIDpuqblhYvpo47mjojmnYPojrflvpfnm7jlhbPotYTmupBcbiAgICAgICAgLy9kaWFsb2cmJmRpYWxvZy5DYW5jZWwoKTsg5aaC5p6c5byA5ZCv5LqG5by55qGG77yM5q2k5aSE6ZyA6KaB5Y+W5raIXG4gICAgICAgIC8vcmVjLnN0YXJ0KCkg5q2k5aSE5Y+v5Lul56uL5Y2z5byA5aeL5b2V6Z+z77yM5L2G5LiN5bu66K6u6L+Z5qC357yW5YaZ77yM5Zug5Li6b3BlbuaYr+S4gOS4quW7tui/n+a8q+mVv+eahOaTjeS9nO+8jOmAmui/h+S4pOasoeeUqOaIt+aTjeS9nOadpeWIhuWIq+iwg+eUqG9wZW7lkoxzdGFydOaYr+aOqOiNkOeahOacgOS9s+a1geeoi1xuICAgICAgICAvL+WIm+W7uuWPr+inhuWMlu+8jOaMh+WumuS4gOS4quimgeaYvuekuueahGRpdlxuICAgICAgICBsZXQgd2F2ZURpdiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIucmVjb3JkLXdhdmVcIik7XG4gICAgICAgIGlmKHdhdmVEaXYpeyAvLyDlrZjlnKjms6LlvaLljLrln5/ml7bvvIzliqDovb3muLLmn5Pnu4Tku7ZcbiAgICAgICAgICBjb25zb2xlLmxvZyh3YXZlRGl2KVxuICAgICAgICAgIGlmKFJlY29yZGVyLldhdmVWaWV3KXRoaXMud2F2ZUNsaWVudD1SZWNvcmRlci5XYXZlVmlldyh7ZWxlbTpcIi5yZWNvcmQtd2F2ZVwifSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICB9LChtc2csaXNVc2VyTm90QWxsb3cpPT57Ly/nlKjmiLfmi5Lnu53mnKrmjojmnYPmiJbkuI3mlK/mjIFcbiAgICAgICAgLy9kaWFsb2cmJmRpYWxvZy5DYW5jZWwoKTsg5aaC5p6c5byA5ZCv5LqG5by55qGG77yM5q2k5aSE6ZyA6KaB5Y+W5raIXG4gICAgICAgIGNvbnNvbGUubG9nKChpc1VzZXJOb3RBbGxvdz9cIlVzZXJOb3RBbGxvd++8jFwiOlwiXCIpK1wi5peg5rOV5b2V6Z+zOlwiK21zZyk7XG4gICAgfSk7XG4gIH0pXG5cbiAgfVxuXG4gIGNvbm5TdGF0dXMgPSBcIlwiIC8vIOW9lemfs+S4rSDlu7rnq4vov57mjqXkuK0g5YWz6Zet6L+e5o6l5LitXG5cbiAgYnRuU3RhdHVzID0gXCJVTkRFRklORURcIjsgLy8gXCJVTkRFRklORURcIiBcIkNPTk5FQ1RJTkdcIiBcIk9QRU5cIiBcIkNMT1NJTkdcIiBcIkNMT1NFRFwiXG5cbiAgd2F2ZUNsaWVudDphbnkgLy8g55So5oi35rOi5b2iXG4gIHJlY29yZGVyOmFueVxuICAvLyByZWNvcmRlciA9IG5ldyBSZWNvcmRlck1hbmFnZXIoKTtcbiAgLy8gcmVjb3JkZXIgPSBuZXcgUmVjb3JkZXJNYW5hZ2VyKFwiLi9saWIveHVuZmVpLXJlY29yZGVyXCIpO1xuICBcbiAgaWF0V1M7XG4gIHJlc3VsdFRleHQgPSBcIlwiO1xuICByZXN1bHRUZXh0VGVtcCA9IFwiXCI7XG4gIGNvdW50ZG93bkludGVydmFsO1xuXG4gIC8qKlxuICAgKiDojrflj5Z3ZWJzb2NrZXQgdXJsXG4gICAqIOivpeaOpeWPo+mcgOimgeWQjuerr+aPkOS+m++8jOi/memHjOS4uuS6huaWueS+v+WJjeerr+WkhOeQhlxuICAgKi9cbiAgQVBQSUQgPSBcIjUwZjRhNDZjXCI7XG4gIEFQSV9TRUNSRVQgPSBcIk56RmxObUZoWkRKak1ETmtaR00zTnpJME16ZzJPR05tXCI7XG4gIEFQSV9LRVkgPSBcIjEwNmRkYzQwZGZkNGI5Y2E2ZDdiNDdjNzBmYWRhNzQ5XCI7XG4gIGdldFdlYlNvY2tldFVybCgpIHtcbiAgICAvLyDor7fmsYLlnLDlnYDmoLnmja7or63np43kuI3lkIzlj5jljJZcbiAgICBsZXQgdXJsID0gXCJ3c3M6Ly9pYXQtYXBpLnhmeXVuLmNuL3YyL2lhdFwiO1xuICAgIGxldCBob3N0ID0gXCJpYXQtYXBpLnhmeXVuLmNuXCI7XG4gICAgXG4gICAgbGV0IGFwaUtleSA9IHRoaXMuQVBJX0tFWTtcbiAgICBsZXQgYXBpU2VjcmV0ID0gdGhpcy5BUElfU0VDUkVUO1xuICAgIGxldCBkYXRlID0gbmV3IERhdGUoKS50b1VUQ1N0cmluZygpO1xuICAgIGxldCBhbGdvcml0aG0gPSBcImhtYWMtc2hhMjU2XCI7XG4gICAgbGV0IGhlYWRlcnMgPSBcImhvc3QgZGF0ZSByZXF1ZXN0LWxpbmVcIjtcbiAgICBsZXQgc2lnbmF0dXJlT3JpZ2luID0gYGhvc3Q6ICR7aG9zdH1cXG5kYXRlOiAke2RhdGV9XFxuR0VUIC92Mi9pYXQgSFRUUC8xLjFgO1xuICAgIGxldCBzaWduYXR1cmVTaGEgPSBDcnlwdG9KUy5IbWFjU0hBMjU2KHNpZ25hdHVyZU9yaWdpbiwgYXBpU2VjcmV0KTtcbiAgICBsZXQgc2lnbmF0dXJlID0gQ3J5cHRvSlMuZW5jLkJhc2U2NC5zdHJpbmdpZnkoc2lnbmF0dXJlU2hhKTtcbiAgICBsZXQgYXV0aG9yaXphdGlvbk9yaWdpbiA9IGBhcGlfa2V5PVwiJHthcGlLZXl9XCIsIGFsZ29yaXRobT1cIiR7YWxnb3JpdGhtfVwiLCBoZWFkZXJzPVwiJHtoZWFkZXJzfVwiLCBzaWduYXR1cmU9XCIke3NpZ25hdHVyZX1cImA7XG4gICAgbGV0IGF1dGhvcml6YXRpb24gPSBidG9hKGF1dGhvcml6YXRpb25PcmlnaW4pO1xuICAgIHVybCA9IGAke3VybH0/YXV0aG9yaXphdGlvbj0ke2F1dGhvcml6YXRpb259JmRhdGU9JHtkYXRlfSZob3N0PSR7aG9zdH1gO1xuICAgIHJldHVybiB1cmw7XG4gIH1cblxuICB0b0Jhc2U2NChidWZmZXIpIHtcbiAgICB2YXIgYmluYXJ5ID0gXCJcIjtcbiAgICB2YXIgYnl0ZXMgPSBuZXcgVWludDhBcnJheShidWZmZXIpO1xuICAgIHZhciBsZW4gPSBieXRlcy5ieXRlTGVuZ3RoO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGJpbmFyeSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldKTtcbiAgICB9XG4gICAgcmV0dXJuIHdpbmRvdy5idG9hKGJpbmFyeSk7XG4gIH1cblxuICAvKipcbiAgICog5YCS6K6h5pe277ya5pyA6ZW/5pSv5oyBNjDnp5Llrp7ml7bor63pn7PovazlvZXvvIzlpoLmnpzmjIHnu603LTEw56eS5peg5aOw6Z+z77yM5pyN5Yqh56uv5bCG6Ieq5YqoQ0xPU0Xpk77mjqVcbiAgICovXG4gIGNvdW50ZG93bigpIHtcbiAgICBsZXQgc2Vjb25kcyA9IDYwO1xuICAgIHRoaXMuY29ublN0YXR1cyA9IGDlvZXpn7PkuK3vvIgke3NlY29uZHN9c++8iWA7XG4gICAgdGhpcy5jb3VudGRvd25JbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIHNlY29uZHMgPSBzZWNvbmRzIC0gMTtcbiAgICAgIGNvbnNvbGUubG9nKHNlY29uZHMpO1xuICAgICAgaWYgKHNlY29uZHMgPD0gMCkge1xuICAgICAgICBjbGVhckludGVydmFsKHRoaXMuY291bnRkb3duSW50ZXJ2YWwpO1xuICAgICAgICB0aGlzLnJlY29yZFN0b3AoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY29ublN0YXR1cyA9IGDlvZXpn7PkuK3vvIgke3NlY29uZHN9c++8iWA7XG4gICAgICB9XG4gICAgfSwgMTAwMCk7XG4gIH1cblxuICBjaGFuZ2VCdG5TdGF0dXMoc3RhdHVzKSB7XG4gICAgdGhpcy5idG5TdGF0dXMgPSBzdGF0dXM7XG4gICAgaWYgKHN0YXR1cyA9PT0gXCJDT05ORUNUSU5HXCIpIHtcbiAgICAgIHRoaXMuY29ublN0YXR1cyA9IFwi5bu656uL6L+e5o6l5LitXCI7XG4gICAgfSBlbHNlIGlmIChzdGF0dXMgPT09IFwiT1BFTlwiKSB7XG4gICAgICB0aGlzLmNvdW50ZG93bigpO1xuICAgIH0gZWxzZSBpZiAoc3RhdHVzID09PSBcIkNMT1NJTkdcIikge1xuICAgICAgdGhpcy5jb25uU3RhdHVzID0gXCLlhbPpl63ov57mjqXkuK1cIjtcbiAgICB9IGVsc2UgaWYgKHN0YXR1cyA9PT0gXCJDTE9TRURcIikge1xuICAgICAgdGhpcy5jb25uU3RhdHVzID0gXCLlvIDlp4vlvZXpn7NcIjtcbiAgICB9XG4gIH1cblxuICByZW5kZXJSZXN1bHQocmVzdWx0RGF0YSkge1xuICAgIC8vIOivhuWIq+e7k+adn1xuICAgIGxldCBqc29uRGF0YSA9IEpTT04ucGFyc2UocmVzdWx0RGF0YSk7XG4gICAgLy8gY29uc29sZS5sb2coanNvbkRhdGEuZGF0YS5yZXN1bHQpXG4gICAgaWYgKGpzb25EYXRhLmRhdGEgJiYganNvbkRhdGEuZGF0YS5yZXN1bHQpIHtcbiAgICAgIGxldCBkYXRhID0ganNvbkRhdGEuZGF0YS5yZXN1bHQ7XG4gICAgICBsZXQgc3RyID0gXCJcIjtcbiAgICAgIGxldCB3cyA9IGRhdGEud3M7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHN0ciA9IHN0ciArIHdzW2ldLmN3WzBdLnc7XG4gICAgICAgIGNvbnNvbGUubG9nKHN0cilcbiAgICAgIH1cbiAgICAgIC8vIOW8gOWQr3dwZ3PkvJrmnInmraTlrZfmrrUo5YmN5o+Q77ya5Zyo5o6n5Yi25Y+w5byA6YCa5Yqo5oCB5L+u5q2j5Yqf6IO9KVxuICAgICAgLy8g5Y+W5YC85Li6IFwiYXBkXCLml7booajnpLror6XniYfnu5PmnpzmmK/ov73liqDliLDliY3pnaLnmoTmnIDnu4jnu5PmnpzvvJvlj5blgLzkuLpcInJwbFwiIOaXtuihqOekuuabv+aNouWJjemdoueahOmDqOWIhue7k+aenO+8jOabv+aNouiMg+WbtOS4unJn5a2X5q61XG4gICAgICBpZiAoZGF0YS5wZ3MpIHtcbiAgICAgICAgaWYgKGRhdGEucGdzID09PSBcImFwZFwiKSB7XG4gICAgICAgICAgLy8g5bCGdGhpcy5yZXN1bHRUZXh0VGVtcOWQjOatpee7mXRoaXMucmVzdWx0VGV4dFxuICAgICAgICAgIHRoaXMucmVzdWx0VGV4dCA9IHRoaXMucmVzdWx0VGV4dFRlbXA7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5bCG57uT5p6c5a2Y5YKo5ZyodGhpcy5yZXN1bHRUZXh0VGVtcOS4rVxuICAgICAgICB0aGlzLnJlc3VsdFRleHRUZW1wID0gdGhpcy5yZXN1bHRUZXh0ICsgc3RyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yZXN1bHRUZXh0ID0gdGhpcy5yZXN1bHRUZXh0ICsgc3RyO1xuICAgICAgfVxuICAgICAgICB0aGlzLnJlc3VsdFRleHRUZW1wIHx8IHRoaXMucmVzdWx0VGV4dCB8fCBcIlwiO1xuICAgICAgY29uc29sZS5sb2coXCJkaWZmIHRlbXBcIix0aGlzLnJlc3VsdFRleHRUZW1wKVxuICAgICAgY29uc29sZS5sb2coXCJkaWZmIHJlc3VsdFwiLHRoaXMucmVzdWx0VGV4dClcbiAgICB9XG4gICAgaWYgKGpzb25EYXRhLmNvZGUgPT09IDAgJiYganNvbkRhdGEuZGF0YS5zdGF0dXMgPT09IDIpIHtcbiAgICAgIHRoaXMuaWF0V1MuY2xvc2UoKTtcbiAgICB9XG4gICAgaWYgKGpzb25EYXRhLmNvZGUgIT09IDApIHtcbiAgICAgIHRoaXMuaWF0V1MuY2xvc2UoKTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoanNvbkRhdGEpO1xuICAgIH1cbiAgfVxuXG4gIGNvbm5lY3RXZWJTb2NrZXQoKSB7XG4gICAgY29uc29sZS5sb2coXCJjb25uZWN0V2ViU29ja2V0XCIpO1xuICAgIGNvbnN0IHdlYnNvY2tldFVybCA9IHRoaXMuZ2V0V2ViU29ja2V0VXJsKCk7XG4gICAgaWYgKFwiV2ViU29ja2V0XCIgaW4gd2luZG93KSB7XG4gICAgICB0aGlzLmlhdFdTID0gbmV3IFdlYlNvY2tldCh3ZWJzb2NrZXRVcmwpO1xuICAgIH0gZWxzZSBpZiAoXCJNb3pXZWJTb2NrZXRcIiBpbiB3aW5kb3cpIHtcbiAgICAgIC8vIHRoaXMuaWF0V1MgPSBuZXcgTW96V2ViU29ja2V0KHdlYnNvY2tldFVybCk7IC8vIE1veuWFvOWuuVxuICAgIH0gZWxzZSB7XG4gICAgICBhbGVydChcIua1j+iniOWZqOS4jeaUr+aMgVdlYlNvY2tldFwiKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc29sZS5sb2coXCJjb25uZWN0V2ViU29ja2V0XCIsdGhpcy5idG5TdGF0dXMpO1xuICAgIHRoaXMuY2hhbmdlQnRuU3RhdHVzKFwiQ09OTkVDVElOR1wiKTtcbiAgICB0aGlzLmlhdFdTLm9ub3BlbiA9IChlKSA9PiB7XG4gICAgICAvLyDlvIDlp4vlvZXpn7NcbiAgICAgIHRoaXMucmVjb3JkU3RhcnQoKTtcbiAgICAgIHZhciBwYXJhbXMgPSB7XG4gICAgICAgIGNvbW1vbjoge1xuICAgICAgICAgIGFwcF9pZDogdGhpcy5BUFBJRCxcbiAgICAgICAgfSxcbiAgICAgICAgYnVzaW5lc3M6IHtcbiAgICAgICAgICBsYW5ndWFnZTogXCJ6aF9jblwiLFxuICAgICAgICAgIGRvbWFpbjogXCJpYXRcIixcbiAgICAgICAgICBhY2NlbnQ6IFwibWFuZGFyaW5cIixcbiAgICAgICAgICB2YWRfZW9zOiA1MDAwLFxuICAgICAgICAgIGR3YTogXCJ3cGdzXCIsXG4gICAgICAgIH0sXG4gICAgICAgIGRhdGE6IHtcbiAgICAgICAgICBzdGF0dXM6IDAsXG4gICAgICAgICAgZm9ybWF0OiBcImF1ZGlvL0wxNjtyYXRlPTE2MDAwXCIsXG4gICAgICAgICAgZW5jb2Rpbmc6IHRoaXMuZW5jb2RpbmdUeXBlLFxuICAgICAgICAgIC8vIGVuY29kaW5nOiBcInNwZWV4LXdiXCIsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgdGhpcy5pYXRXUy5zZW5kKEpTT04uc3RyaW5naWZ5KHBhcmFtcykpO1xuICAgIH07XG4gICAgdGhpcy5pYXRXUy5vbm1lc3NhZ2UgPSAoZSkgPT4ge1xuICAgICAgY29uc29sZS5sb2coXCJvbm1lc3NhZ2VcIit0aGlzLnJlc3VsdFRleHQpXG4gICAgICB0aGlzLnJlbmRlclJlc3VsdChlLmRhdGEpO1xuICAgIH07XG4gICAgdGhpcy5pYXRXUy5vbmVycm9yID0gKGUpID0+IHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJlcnJvclwiLGUpO1xuICAgICAgdGhpcy5yZWNvcmRTdG9wKCk7XG4gICAgICB0aGlzLmNoYW5nZUJ0blN0YXR1cyhcIkNMT1NFRFwiKTtcbiAgICB9O1xuICAgIHRoaXMuaWF0V1Mub25jbG9zZSA9IGFzeW5jIChlKSA9PiB7XG4gICAgICAvLyA156eS5YGc6aG/5Lya5a+86Ie057uT5p2f5b2V5Yi2XG4gICAgICBjb25zb2xlLmxvZyhcIm9uY2xvc2VcIit0aGlzLnJlc3VsdFRleHQpXG4gICAgICBjb25zb2xlLmVycm9yKFwiY2xvc2VcIixlKVxuICAgICAgYXdhaXQgdGhpcy5yZWNvcmRTdG9wKCk7XG4gICAgICB0aGlzLmNoYW5nZUJ0blN0YXR1cyhcIkNMT1NFRFwiKTtcblxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICog56e75Yqo56uv5YW85a655pa55rOVXG4gICAqL1xuXG4gICAvKipcbiAgICog56e75Yqo56uv5LiK5Lyg5LiT55So5pa55rOVXG4gICAqIEByZXR1cm5zIFxuICAgKi9cbiAgICBpc0NhcGFjaXRvcigpe1xuICAgICAgcmV0dXJuIHRoaXMucGxhdGZvcm0uaXMoXCJjYXBhY2l0b3JcIikgfHwgdGhpcy5wbGF0Zm9ybS5pcyhcImNvcmRvdmFcIilcbiAgICB9XG4gICAgYXN5bmMgcmVxdWVzdFBlcm1pc3Npb24oKXtcbiAgICAgIGlmKCF0aGlzLmlzQ2FwYWNpdG9yKCkpIHJldHVyblxuICAgICAgdHJ5e1xuICAgICAgICBhd2FpdCB0aGlzLnJlcXVlc3RTdG9hZ2VQZXJtaXNzaW9uKCk7XG4gICAgICAgIGF3YWl0IHRoaXMucmVxdWVzdENhbWVyYVBlcm1pc3Npb24oKTtcbiAgICAgICAgYXdhaXQgdGhpcy5yZXF1ZXN0TWljUGVybWlzc2lvbigpO1xuICAgICAgICBhd2FpdCB0aGlzLnJlcXVlc3RSZWNvcmRBdWRpb1Blcm1pc3Npb24oKTtcbiAgICAgIH1jYXRjaChlcnIpe1xuICAgICAgICBjb25zb2xlLmVycm9yKGVycilcbiAgICAgIH1cbiAgICB9XG4gICAgYXN5bmMgcmVxdWVzdFJlY29yZEF1ZGlvUGVybWlzc2lvbigpe1xuICAgICAgbGV0IGRhdGEgPSBhd2FpdCB0aGlzLmRpYWdub3N0aWMucmVxdWVzdFJ1bnRpbWVQZXJtaXNzaW9ucyhbdGhpcy5kaWFnbm9zdGljLnBlcm1pc3Npb24uUkVDT1JEX0FVRElPXSlcbiAgICAgIGNvbnNvbGUubG9nKFwicmVjb3JkIHBlcm1pc3Npb24gcmVxdWVzdDpcIixkYXRhKVxuICAgICAgcmV0dXJuXG4gIH1cbiAgICBhc3luYyByZXF1ZXN0TWljUGVybWlzc2lvbigpe1xuICAgICAgICBsZXQgaXNBdmFpbGFibGUgPSBhd2FpdCB0aGlzLmRpYWdub3N0aWMuaXNNaWNyb3Bob25lQXV0aG9yaXplZCgpXG4gICAgICAgIGNvbnNvbGUubG9nKFwicGVybWlzc29uX01JQzpcIiwgaXNBdmFpbGFibGUpXG4gICAgICAgIGlmICghaXNBdmFpbGFibGUpIHtcbiAgICAgICAgICBsZXQgZGF0YSA9IGF3YWl0IHRoaXMuZGlhZ25vc3RpYy5yZXF1ZXN0TWljcm9waG9uZUF1dGhvcml6YXRpb24oKVxuICAgICAgICB9XG4gICAgICAgIHJldHVyblxuICAgIH1cbiAgICBhc3luYyByZXF1ZXN0U3RvYWdlUGVybWlzc2lvbigpe1xuICAgICAgICBsZXQgaXNBdmFpbGFibGUgPSBhd2FpdCB0aGlzLmRpYWdub3N0aWMuaXNFeHRlcm5hbFN0b3JhZ2VBdXRob3JpemVkKClcbiAgICAgICAgY29uc29sZS5sb2coXCJwZXJtaXNzb25fU1RPUkFHRTpcIiwgaXNBdmFpbGFibGUpXG4gICAgICAgIGlmICghaXNBdmFpbGFibGUpIHtcbiAgICAgICAgICBsZXQgZGF0YSA9IGF3YWl0IHRoaXMuZGlhZ25vc3RpYy5yZXF1ZXN0RXh0ZXJuYWxTdG9yYWdlQXV0aG9yaXphdGlvbigpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGFzeW5jIHJlcXVlc3RDYW1lcmFQZXJtaXNzaW9uKCl7XG4gICAgICBsZXQgaXNBdmFpbGFibGUgPSBhd2FpdCB0aGlzLmRpYWdub3N0aWMuaXNDYW1lcmFBdXRob3JpemVkKClcbiAgICAgIGNvbnNvbGUubG9nKFwicGVybWlzc29uX0NhbWVyYTpcIiwgaXNBdmFpbGFibGUpXG4gICAgICBpZiAoIWlzQXZhaWxhYmxlKSB7XG4gICAgICAgIGxldCBkYXRhID0gYXdhaXQgdGhpcy5kaWFnbm9zdGljLnJlcXVlc3RDYW1lcmFBdXRob3JpemF0aW9uKClcbiAgICAgIH1cbiAgICAgIHJldHVyblxuICB9XG59XG4iXX0=
@@ -1,10 +1,3 @@
1
-
2
- /**
3
- * @copyright © 未来飞马 © 未来全栈 www.fmode.cn
4
- * 版权所有 © 未来飞马 © 江西脑控科技有限公司 Copyright © Fmode Technology Co., Ltd.
5
- * 保留所有权利 All Rights Reserved.
6
- * /home/ryan/workspace/nova/nova-admin/dist/fmode-ng/esm2022/lib/aigc/voice/index.mjs
7
- */
8
- export*from"./fmode-voice.service";export*from"./audio.player";
9
- var MODULE_PATH_NEED = `6K+l5paH5Lu25piv5pys6aG555uu55qE5LiA6YOo5YiGIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBDb21wb25lbnRzIGluIEZtb2RlIEluYy4KICAgIOeJiOadg+aJgOaciSDCqSDmnKrmnaXpo57pqawgwqkg5rGf6KW/6ISR5o6n56eR5oqA5pyJ6ZmQ5YWs5Y+4IENvcHlyaWdodCDCqSBGbW9kZSBUZWNobm9sb2d5IENvLiwgTHRkLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAgICDkuKXnpoHlnKjmnKrnu4/mjojmnYPnmoTmg4XlhrXkuIvvvIzpgJrov4fku7vkvZXlqpLku4vlpI3liLbmraTmlofku7YgVW5hdXRob3JpemVkIGNvcHlpbmcgb2YgdGhpcyBmaWxlLCB2aWEgYW55IG1lZGl1bSBpcyBzdHJpY3RseSBwcm9oaWJpdGVkCiAgICDor6Xmlofku7bmmK/kuJPmnInnmoTmnLrlr4bmlofku7YgUHJvcHJpZXRhcnkgYW5kIGNvbmZpZGVudGlhbAogICAKICAgIENvcHlyaWdodCAyMDIxLW5vdyBGbW9kZSBJbmMuIHN1cHBvcnRAZm1vZGUuY24uIDE4NjA3MDA3MDczLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUEFUSDovaG9tZS9yeWFuL3dvcmtzcGFjZS9ub3ZhL25vdmEtYWRtaW4vZGlzdC9mbW9kZS1uZy9lc20yMDIyL2xpYi9haWdjL3ZvaWNlL2luZGV4Lm1qcw==`
10
-
1
+ export * from "./fmode-voice.service";
2
+ export * from "./audio.player";
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9mbW9kZS1uZy9zcmMvbGliL2FpZ2Mvdm9pY2UvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyx1QkFBdUIsQ0FBQTtBQUNyQyxjQUFjLGdCQUFnQixDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSBcIi4vZm1vZGUtdm9pY2Uuc2VydmljZVwiXG5leHBvcnQgKiBmcm9tIFwiLi9hdWRpby5wbGF5ZXJcIiJdfQ==