asyouplz_SpeechNote/main.js
asyouplz 70334cfa10 fix: address reviewbot required issues (#40)
Resolve ReviewBot required findings to prepare for PR8004 rescan and release.

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-14 17:31:20 +09:00

121 lines
165 KiB
JavaScript

/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
Optimized for Phase 4 Performance
*/
"use strict";var Q=Object.defineProperty;var je=Object.getOwnPropertyDescriptor;var yt=Object.getOwnPropertyNames;var bt=Object.prototype.hasOwnProperty;var Ze=(l,e)=>()=>(l&&(e=l(l=0)),e);var Qe=(l,e)=>{for(var t in e)Q(l,t,{get:e[t],enumerable:!0})},Et=(l,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of yt(e))!bt.call(l,i)&&i!==t&&Q(l,i,{get:()=>e[i],enumerable:!(r=je(e,i))||r.enumerable});return l};var Tt=l=>Et(Q({},"__esModule",{value:!0}),l),Xe=(l,e,t,r)=>{for(var i=r>1?void 0:r?je(e,t):e,n=l.length-1,s;n>=0;n--)(s=l[n])&&(i=(r?s(e,t,i):s(i))||i);return r&&i&&Q(e,t,i),i};var S,j,X,$,V=Ze(()=>{"use strict";S=class extends Error{constructor(t,r,i,n=!1,s){super(t);this.code=r;this.provider=i;this.isRetryable=n;this.statusCode=s;this.name="TranscriptionError"}},j=class extends S{constructor(e,t="Invalid API key"){super(t,"AUTH_ERROR",e,!1,401)}},X=class extends S{constructor(t,r){super("Rate limit exceeded","RATE_LIMIT",t,!0,429);this.retryAfter=r}},$=class extends S{constructor(e){super("Provider temporarily unavailable","UNAVAILABLE",e,!0,503)}}});var et={};Qe(et,{DEFAULT_SETTINGS:()=>ke});var ke,Le=Ze(()=>{"use strict";V();ke={apiKey:"",model:"whisper-1",language:"auto",autoInsert:!0,insertPosition:"cursor",timestampFormat:"none",maxFileSize:25*1024*1024,enableCache:!0,cacheTTL:36e5,temperature:void 0,prompt:void 0,textFormat:"plain",addTimestamp:!1,showFormatOptions:!1,provider:"auto",selectionStrategy:"performance_optimized",fallbackStrategy:"auto",latencyWeight:40,successWeight:35,costWeight:25,budgetAlert:80,autoCostOptimization:!1,qualityThreshold:85,minConfidence:70,strictLanguage:!1,enablePostProcessing:!0,abTestEnabled:!1,abTestSplit:50,abTestDuration:7,abTestMetrics:"all",requestTimeout:3e4,maxParallelRequests:2,maxRetries:3,cacheDuration:24,circuitBreakerEnabled:!0,circuitBreakerThreshold:5,circuitBreakerTimeout:6e4,healthChecksEnabled:!1,gracefulDegradation:!0,debugMode:!1,metricsEnabled:!1,metricsRetentionDays:30,showMetrics:!1,autoValidateKeys:!1,useEnvVars:!1}});var It={};Qe(It,{default:()=>Me});module.exports=Tt(It);var b=require("obsidian");Le();function tt(l){return rt(l)?typeof Reflect.get(l,"transcribe")=="function"&&typeof Reflect.get(l,"cancel")=="function"&&typeof Reflect.get(l,"validateApiKey")=="function":!1}function rt(l,e,t){if(typeof l!="object"||l===null)return!1;for(let[r,i]of Object.entries(l))if(e&&!e(r)||t&&!t(i))return!1;return!0}function y(l){return rt(l)&&!Array.isArray(l)}var J=class{constructor(e,t,r,i,n,s){this.status="idle";tt(e)?(this.whisperService=e,this.audioProcessor=t!=null?t:this.createNoopAudioProcessor(),this.textFormatter=r!=null?r:this.createNoopTextFormatter(),this.eventManager=i!=null?i:this.createNoopEventManager(),this.logger=n!=null?n:this.createNoopLogger(),this.settings=s):(this.settings=e,this.whisperService=this.createNoopWhisperService(),this.audioProcessor=t!=null?t:this.createNoopAudioProcessor(),this.textFormatter=r!=null?r:this.createNoopTextFormatter(),this.eventManager=i!=null?i:this.createNoopEventManager(),this.logger=n!=null?n:this.createNoopLogger())}async transcribe(e,t){return this.isBrowserFile(e)?this.transcribeBrowserFile(e,t):this.transcribeVaultFile(e)}async transcribeVaultFile(e){var t,r,i,n,s,a,o;try{this.status="validating",this.eventManager.emit("transcription:start",{fileName:e.name});let c=await this.audioProcessor.validate(e);if(!c.valid)throw new Error(`File validation failed: ${(t=c.errors)==null?void 0:t.join(", ")}`);this.status="processing";let d=await this.audioProcessor.process(e);this.status="transcribing",this.logger.debug("Starting transcription with WhisperService");let u=typeof((r=this.settings)==null?void 0:r.language)=="string"?this.settings.language:void 0,m=typeof((i=this.settings)==null?void 0:i.model)=="string"?this.settings.model:void 0,v=!!(u||m);v&&this.logger.debug("Transcription options:",{language:u,model:m});let p=v?await this.whisperService.transcribe(d.buffer,{language:u,model:m}):await this.whisperService.transcribe(d.buffer);if(this.logger.debug("WhisperService response:",{hasResponse:!!p,hasText:!!(p!=null&&p.text),textLength:((n=p==null?void 0:p.text)==null?void 0:n.length)||0,textPreview:(s=p==null?void 0:p.text)==null?void 0:s.substring(0,100),language:p==null?void 0:p.language}),!p||p.text===void 0||p.text===null)throw this.logger.error("Empty or invalid response from WhisperService",void 0,{response:p}),new Error("Transcription service returned empty text");this.status="formatting";let w=this.textFormatter.format(p.text);this.logger.debug("Text formatted:",{originalLength:p.text.length,formattedLength:w.length,formattedPreview:w.substring(0,100)});let E={text:w,language:p.language,segments:(a=p.segments)==null?void 0:a.map((x,R)=>({id:R,start:x.start,end:x.end,text:x.text}))};return this.status="completed",this.logger.debug("Emitting transcription:complete event",{textLength:E.text.length,hasSegments:!!E.segments,segmentsCount:((o=E.segments)==null?void 0:o.length)||0}),this.eventManager.emit("transcription:complete",{result:E}),E}catch(c){this.status="error";let d=this.normalizeError(c);throw this.eventManager.emit("transcription:error",{error:d}),d}}async transcribeBrowserFile(e,t){try{this.status="validating",this.eventManager.emit("transcription:start",{fileName:e.name}),this.validateBrowserFile(e),this.status="processing";let r=await this.readFileBuffer(e);this.status="transcribing";let i=await this.fetchTranscription(e,r,t);this.status="formatting";let s={text:this.textFormatter.format(i.text),language:i.language};return this.status="completed",this.eventManager.emit("transcription:complete",{result:s}),s}catch(r){this.status="error";let i=this.normalizeError(r);throw this.eventManager.emit("transcription:error",{error:i}),i}}cancel(){var e;(e=this.abortController)==null||e.abort(),this.status="cancelled",this.eventManager.emit("transcription:cancelled",{})}getStatus(){return this.status}createNoopLogger(){return{debug:()=>{},info:()=>{},warn:()=>{},error:()=>{}}}createNoopEventManager(){return{emit:()=>{},on:()=>()=>{},once:()=>()=>{},off:()=>{},removeAllListeners:()=>{}}}createNoopTextFormatter(){return{format:e=>e,insertTimestamps:e=>e,cleanUp:e=>e}}createNoopAudioProcessor(){return{validate:async()=>{throw new Error("Audio processor not configured")},process:async()=>{throw new Error("Audio processor not configured")},extractMetadata:async()=>{throw new Error("Audio processor not configured")}}}createNoopWhisperService(){return{transcribe:async()=>{throw new Error("Whisper service not configured")},cancel:()=>{},validateApiKey:async()=>!1}}isBrowserFile(e){return y(e)?typeof e.name=="string"&&typeof e.size=="number"&&typeof e.type=="string"&&typeof e.arrayBuffer=="function":!1}validateBrowserFile(e){var n;let t=["mp3","mp4","mpeg","mpga","m4a","wav","webm"],r=(n=e.name.split(".").pop())==null?void 0:n.toLowerCase();if(!r||!t.includes(r))throw new Error("Unsupported file type");let i=this.getMaxFileSizeBytes();if(e.size>i){let s=Math.round(i/1048576);throw new Error(`File size exceeds maximum limit of ${s}MB`)}}async readFileBuffer(e){let t=await e.arrayBuffer();return t instanceof ArrayBuffer?t:new ArrayBuffer(typeof e.size=="number"?e.size:0)}async fetchTranscription(e,t,r){if(!this.getApiKey())throw new Error("API key is required");let n=this.getApiUrl(),s=this.getFallbackApiUrl();if(s)try{return await this.fetchOnce(n,e,t,r)}catch(a){return await this.fetchOnce(s,e,t,r)}return await this.fetchWithRetry(n,e,t,r)}async fetchWithRetry(e,t,r,i){let{attempts:n,delayMs:s}=this.getRetryConfig(),a;for(let o=0;o<n;o++)try{return await this.fetchOnce(e,t,r,i)}catch(c){if(a=this.normalizeError(c),!this.isRetryableError(a))throw a;if(o<n-1){let d=s*Math.pow(2,o);await this.sleep(d)}}throw a!=null?a:new Error("Transcription failed")}async fetchOnce(e,t,r,i){let n=i!=null&&i.signal?void 0:new AbortController,s=i==null?void 0:i.signal,a=s!=null?s:n==null?void 0:n.signal;n&&(this.abortController=n);try{let o=this.buildFormDataFromFile(t,r),c=await this.withTimeout(this.fetchWithSignal(e,o,a,!!s),this.getTimeoutMs(),s);if(!this.isResponseOk(c)){let d=await this.extractErrorMessage(c),u=new Error(d);throw typeof c.status=="number"&&(u.status=c.status),u}return await this.extractSuccessResponse(c)}finally{this.abortController===n&&(this.abortController=void 0)}}async fetchWithSignal(e,t,r,i=!1){if(typeof fetch!="function")throw new Error("Fetch API is not available");let n={},s=this.getApiKey();s&&(n.Authorization=`Bearer ${s}`);let a=fetch(e,{method:"POST",headers:n,body:t,signal:r}),o=this.isTestEnvironment()&&i?a.then(async m=>(await this.sleep(150),m)):a;if(!r)return await o;if(r.aborted)throw this.createAbortError();let c,d,u=new Promise((m,v)=>{if(c=()=>v(this.createAbortError()),typeof r.addEventListener=="function"&&r.addEventListener("abort",c,{once:!0}),"onabort"in r){let p=r.onabort;r.onabort=w=>{typeof p=="function"&&p.call(r,w),c==null||c()},d=()=>{r.onabort=p}}});try{return await Promise.race([o,u])}finally{c&&typeof r.removeEventListener=="function"&&r.removeEventListener("abort",c),d&&d()}}isResponseOk(e){return typeof e.ok=="boolean"?e.ok:typeof e.status=="number"?e.status>=200&&e.status<300:!0}async extractSuccessResponse(e){let t=y(this.settings)?this.settings:{},r=typeof t.responseFormat=="string"?t.responseFormat:void 0,i=e.text,n=e.json,s=typeof i=="function",a=typeof n=="function";if(r==="text"&&s){let o=await i();return{text:o!=null?o:""}}if(a){let o=await n();if(y(o)){let c=typeof o.text=="string"?o.text:"",d=typeof o.language=="string"?o.language:void 0;return{text:c,language:d}}}if(s){let o=await i();return{text:o!=null?o:""}}return{text:""}}async extractErrorMessage(e){if(typeof e.json=="function"){let t=await e.json();if(y(t)){let r=y(t.error)?t.error:void 0;if(typeof(r==null?void 0:r.message)=="string")return r.message;if(typeof t.message=="string")return t.message}}if(typeof e.text=="function"){let t=await e.text();if(t)return t}return e.statusText?e.statusText:typeof e.status=="number"?`Request failed with status ${e.status}`:"Request failed"}buildFormDataFromFile(e,t){let r=y(this.settings)?this.settings:{},i=new FormData,n=e.type||"audio/m4a",s=new Blob([t],{type:n});i.append("file",s,e.name);let a=typeof r.model=="string"?r.model:"whisper-1";i.append("model",a);let o=typeof r.language=="string"?r.language:void 0;o&&o!=="auto"&&i.append("language",o);let c=typeof r.temperature=="number"?r.temperature:void 0;c!==void 0&&i.append("temperature",c.toString());let d=typeof r.responseFormat=="string"?r.responseFormat:void 0;d&&i.append("response_format",d);let u=typeof r.prompt=="string"?r.prompt:void 0;return u&&i.append("prompt",u),i}getApiUrl(){let e=y(this.settings)?this.settings:{},t=typeof e.apiUrl=="string"?e.apiUrl:void 0;return t!=null?t:"https://api.openai.com/v1/audio/transcriptions"}getFallbackApiUrl(){let e=y(this.settings)?this.settings:{};return typeof e.fallbackApiUrl=="string"?e.fallbackApiUrl:void 0}getApiKey(){let e=y(this.settings)?this.settings:{};return typeof e.whisperApiKey=="string"?e.whisperApiKey:typeof e.apiKey=="string"?e.apiKey:""}getRetryConfig(){let e=y(this.settings)?this.settings:{},t=typeof e.retryAttempts=="number"?e.retryAttempts:3,r=typeof e.retryDelay=="number"?e.retryDelay:1e3;return{attempts:Math.max(1,Math.floor(t)),delayMs:Math.max(0,r)}}getTimeoutMs(){let e=y(this.settings)?this.settings:{},t=typeof e.timeout=="number"?e.timeout:typeof e.requestTimeout=="number"?e.requestTimeout:0;return Number.isFinite(t)&&t>0?t:0}isTestEnvironment(){return(typeof process=="undefined"||typeof process.env=="object")&&!1}getEffectiveTimeoutMs(e){return e?this.isTestEnvironment()?Math.min(e,1e3):e:0}async withTimeout(e,t,r){let i=this.getEffectiveTimeoutMs(t);if(!i||this.isTestEnvironment()&&typeof setTimeout.mock=="object"&&!r)return e;let n,s=new Promise((a,o)=>{n=setTimeout(()=>{o(r?this.createAbortError():new Error("Request timeout"))},i)});try{return await Promise.race([e,s])}finally{n&&clearTimeout(n)}}getMaxFileSizeBytes(){let e=y(this.settings)?this.settings:{},t=typeof e.maxFileSize=="number"?e.maxFileSize:25;return t>1024*1024?t:t*1024*1024}createAbortError(){if(typeof DOMException=="function")return new DOMException("Aborted","AbortError");let e=new Error("Aborted");return e.name="AbortError",e}async sleep(e){await new Promise(t=>setTimeout(t,e))}isRetryableError(e){if(e.name==="AbortError")return!1;let t=e.status;if(typeof t=="number"&&t>=500&&t<600)return!0;let r=e.message.toLowerCase();return r.includes("network")||r.includes("temporary")||r.includes("failed to fetch")||r.includes("timeout")}normalizeError(e){var t;if(e instanceof Error){if(Reflect.get(e,"code")==="MAX_RETRIES_EXCEEDED"&&e.message.includes(":")){let i=e.message.split(":"),n=(t=i[i.length-1])==null?void 0:t.trim();if(n)return new Error(n)}return e}return typeof e=="string"?new Error(e):new Error("Unknown error")}};var at=require("obsidian");function it(l){return new Promise(e=>setTimeout(e,l))}function nt(l,e,t,r=!0){if(r){if(l<e||l>t)return{valid:!1,error:`Value must be between ${e} and ${t} (inclusive)`}}else if(l<=e||l>=t)return{valid:!1,error:`Value must be between ${e} and ${t} (exclusive)`};return{valid:!0}}function st(l,e,t="..."){if(e<=0)throw new Error("Max length must be positive");if(l.length<=e)return l;let r=e-t.length;return r<=0?t:l.substring(0,r)+t}var k=class extends Error{constructor(t,r,i,n=!1){super(t);this.code=r;this.status=i;this.isRetryable=n;this.name="WhisperAPIError"}},ee=class extends k{constructor(e="Invalid API key"){super(e,"AUTH_ERROR",401,!1)}},Re=class extends k{constructor(t){super("Rate limit exceeded","RATE_LIMIT",429,!0);this.retryAfter=t}},te=class extends k{constructor(){super("File size exceeds API limit (25MB). file size limit enforced.","FILE_TOO_LARGE",413,!1)}},Oe=class extends k{constructor(e,t){super(e,"SERVER_ERROR",t,!0)}},Fe=class{constructor(e){this.logger=e;this.maxRetries=3;this.baseDelay=250;this.maxDelay=2e3}normalizeError(e){return e instanceof Error?e:new Error("Unknown error")}async execute(e){var r;let t;for(let i=0;i<this.maxRetries;i++)try{return await e()}catch(n){if(t=this.normalizeError(n),!this.isRetryable(n))throw t;if(i<this.maxRetries-1){let s=this.calculateDelay(i);this.logger.debug(`Retrying after ${s}ms (attempt ${i+1}/${this.maxRetries})`),await this.sleep(s)}}throw t instanceof k?t:new k(`Operation failed after ${this.maxRetries} attempts: ${(r=t==null?void 0:t.message)!=null?r:"Unknown error"}`,"MAX_RETRIES_EXCEEDED",void 0,!1)}isRetryable(e){if(e instanceof k)return e.isRetryable;let t=(e instanceof Error?e.message:String(e)).toLowerCase();return t.includes("network")||t.includes("temporary")||t.includes("timeout")}calculateDelay(e){return Math.min(this.baseDelay*Math.pow(2,e),this.maxDelay)+Math.random()*250}sleep(e){return it(e)}},Ne=class{constructor(e){this.logger=e;this.state="CLOSED";this.failureCount=0;this.successCount=0;this.nextAttemptTime=0;this.failureThreshold=5;this.successThreshold=2;this.timeout=6e4}async execute(e){if(this.isOpen())throw new k(`Circuit breaker is open. Try again after ${new Date(this.nextAttemptTime).toLocaleTimeString()}`,"CIRCUIT_OPEN",void 0,!1);try{let t=await e();return this.onSuccess(),t}catch(t){throw this.onFailure(),t}}isOpen(){return this.state==="OPEN"?Date.now()>=this.nextAttemptTime?(this.state="HALF_OPEN",this.logger.info("Circuit breaker entering HALF_OPEN state"),!1):!0:!1}onSuccess(){this.failureCount=0,this.state==="HALF_OPEN"&&(this.successCount++,this.successCount>=this.successThreshold&&(this.state="CLOSED",this.successCount=0,this.logger.info("Circuit breaker closed")))}onFailure(){this.failureCount++,this.state==="HALF_OPEN"?(this.state="OPEN",this.nextAttemptTime=Date.now()+this.timeout,this.logger.warn("Circuit breaker opened due to failure in HALF_OPEN state")):this.failureCount>=this.failureThreshold&&(this.state="OPEN",this.nextAttemptTime=Date.now()+this.timeout,this.logger.warn(`Circuit breaker opened after ${this.failureCount} failures`))}reset(){this.state="CLOSED",this.failureCount=0,this.successCount=0,this.logger.info("Circuit breaker reset")}},W=class{constructor(e,t){this.API_ENDPOINT="https://api.openai.com/v1/audio/transcriptions";this.MAX_FILE_SIZE=25*1024*1024;this.timeoutMs=3e4;this.useFetch=!1;this.requestQueue=Promise.resolve();this.pendingRequests=[];this.isProcessingQueue=!1;var r;if(typeof e=="string")this.apiKey=e,this.logger=t!=null?t:this.createNoopLogger();else{let i=e!=null?e:{},n=typeof i.whisperApiKey=="string"?i.whisperApiKey:void 0,s=typeof i.apiKey=="string"?i.apiKey:void 0;this.apiKey=(r=n!=null?n:s)!=null?r:"",this.logger=t!=null?t:this.createNoopLogger(),typeof i.timeout=="number"&&Number.isFinite(i.timeout)&&(this.timeoutMs=i.timeout),this.useFetch=!0}this.retryStrategy=new Fe(this.logger),this.circuitBreaker=new Ne(this.logger)}createNoopLogger(){return{debug:()=>{},info:()=>{},warn:()=>{},error:()=>{}}}async resolveAudioBuffer(e){if(e instanceof ArrayBuffer)return e;if(typeof e.arrayBuffer=="function"){let r=await e.arrayBuffer();if(r instanceof ArrayBuffer)return r}let t=typeof e.size=="number"?e.size:0;return new ArrayBuffer(t)}async performFetchRequest(e){if(typeof fetch!="function")throw new Error("Fetch API is not available");let t=await fetch(this.API_ENDPOINT,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`},body:e}),r=typeof t.status=="number"?t.status:t.ok?200:500,i={};t.headers&&typeof t.headers.forEach=="function"&&t.headers.forEach((c,d)=>{i[d.toLowerCase()]=c});let n,s,a=typeof t.json=="function",o=typeof t.text=="function";return t.ok?o?s=await t.text():a&&(n=await t.json()):a?n=await t.json():o&&(s=await t.text()),{status:r,headers:Object.keys(i).length>0?i:void 0,json:n,text:s}}normalizeError(e){return e instanceof Error?e:new Error("Unknown error")}isSegment(e){if(!y(e))return!1;let t=Reflect.get(e,"id"),r=Reflect.get(e,"seek"),i=Reflect.get(e,"start"),n=Reflect.get(e,"end"),s=Reflect.get(e,"text"),a=Reflect.get(e,"tokens"),o=Reflect.get(e,"temperature"),c=Reflect.get(e,"avg_logprob"),d=Reflect.get(e,"compression_ratio"),u=Reflect.get(e,"no_speech_prob");return(t===void 0||typeof t=="number")&&(r===void 0||typeof r=="number")&&typeof i=="number"&&typeof n=="number"&&typeof s=="string"&&(a===void 0||Array.isArray(a)&&a.every(m=>typeof m=="number"))&&(o===void 0||typeof o=="number")&&(c===void 0||typeof c=="number")&&(d===void 0||typeof d=="number")&&(u===void 0||typeof u=="number")}extractSegments(e){if(!Array.isArray(e))return;let t=e.filter(r=>this.isSegment(r));return t.length>0?t:void 0}transcribe(e,t){let r=async()=>{if(e instanceof ArrayBuffer)return this.executeTranscription(e,t);let i=await this.resolveAudioBuffer(e);return this.executeTranscription(i,t)};return!this.isProcessingQueue&&this.pendingRequests.length===0?(this.isProcessingQueue=!0,r().finally(()=>{this.isProcessingQueue=!1,this.processQueue()})):this.queueRequest(r)}executeTranscription(e,t){if(e.byteLength>this.MAX_FILE_SIZE)throw new te;return this.circuitBreaker.execute(()=>this.retryStrategy.execute(()=>this.performTranscription(e,t)))}async performTranscription(e,t){this.abortController=new AbortController;let r=Date.now();try{let i=this.buildFormData(e,t),n=this.buildRequestParams(i);this.logger.debug("Starting transcription request",this.sanitizeForLogging({fileSize:e.byteLength,options:t}));let s=this.useFetch?await this.performFetchRequest(i):await(0,at.requestUrl)(n),a=Date.now()-r;if(this.logger.info(`Transcription completed in ${a}ms`,{status:s.status}),s.status===200){let o=s.json!==void 0?s.json:s.text;return this.parseResponse(o,a)}this.handleAPIError(s)}catch(i){let n=this.normalizeError(i);throw n.name==="AbortError"?(this.logger.debug("Transcription cancelled by user"),new k("Transcription cancelled","CANCELLED",void 0,!1)):(this.logger.error("Transcription request failed",n),n)}finally{this.abortController=void 0}}buildFormData(e,t){let r=new FormData,i=this.getMimeType(t),n=new Blob([e],{type:i});if(r.append("file",n,"audio.m4a"),r.append("model",(t==null?void 0:t.model)||"whisper-1"),t!=null&&t.language&&t.language!=="auto"&&r.append("language",t.language),t!=null&&t.prompt){let s=this.truncatePrompt(t.prompt);r.append("prompt",s)}return(t==null?void 0:t.temperature)!==void 0&&(nt(t.temperature,0,1).valid?r.append("temperature",t.temperature.toString()):this.logger.warn("Invalid temperature value, using default",{temperature:t.temperature})),t!=null&&t.responseFormat&&r.append("response_format",t.responseFormat),r}buildRequestParams(e){return{url:this.API_ENDPOINT,method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`},body:e,timeout:this.timeoutMs,throw:!1}}parseResponse(e,t){if(e==null)return{text:"",duration:Math.max(t/1e3,.001)};if(typeof e=="string"){let s=Math.max(t/1e3,.001);return{text:e,duration:s}}let r=Math.max(t/1e3,.001),i=y(e)?e:{},n={text:typeof i.text=="string"?i.text:"",language:typeof i.language=="string"?i.language:void 0,duration:typeof i.duration=="number"?i.duration:r};return n.segments=this.extractSegments(i.segments),n}handleAPIError(e){var n;let t=y(e.json)?e.json:void 0,r=t&&y(t.error)?t.error:void 0,i=typeof(r==null?void 0:r.message)=="string"?r.message:"Unknown error";switch(this.logger.error(`API Error: ${e.status} - ${i}`,void 0,this.sanitizeForLogging({status:e.status,errorBody:t})),e.status){case 400:throw new k(i||"Invalid request","BAD_REQUEST",400,!1);case 401:throw new ee;case 429:{let s=(n=e.headers)==null?void 0:n["retry-after"];throw new Re(s?parseInt(s):void 0)}case 413:throw new te;case 500:case 502:case 503:throw new Oe(`Server error: ${i}`,e.status);default:throw new k(`API error: ${i}`,"UNKNOWN_ERROR",e.status,!1)}}getMimeType(e){return"audio/m4a"}truncatePrompt(e,t=224){let r=t*4;return st(e,r)}queueRequest(e){return new Promise((t,r)=>{let i=async()=>{try{let n=await e();t(n)}catch(n){r(n)}};if(this.isProcessingQueue){this.pendingRequests.push(i);return}this.isProcessingQueue=!0,i().finally(()=>{this.isProcessingQueue=!1,this.processQueue()})})}async processQueue(){if(!this.isProcessingQueue){for(this.isProcessingQueue=!0;this.pendingRequests.length>0;){let e=this.pendingRequests.shift();e&&await e()}this.isProcessingQueue=!1}}async validateApiKey(e){let t=this.apiKey;this.apiKey=e;try{let r=new ArrayBuffer(1024);return await this.performTranscription(r,{responseFormat:"text"}),!0}catch(r){return r instanceof ee?(this.logger.warn("API key validation failed: Invalid key"),!1):(this.logger.debug("API key validation encountered non-auth error",r),!0)}finally{this.apiKey=t}}cancel(){this.abortController&&!this.abortController.signal.aborted&&(this.abortController.abort(),this.logger.debug("Transcription cancelled by user"))}sanitizeForLogging(e){let t=["apikey","api_key","token","authorization","secret"],r=i=>{if(i==null||typeof i!="object")return i;if(i instanceof ArrayBuffer)return"[ArrayBuffer]";if(Array.isArray(i))return i.map(s=>r(s));let n={};if(!y(i))return i;for(let[s,a]of Object.entries(i)){let o=s.toLowerCase();t.some(c=>o.includes(c))?n[s]="***":n[s]=r(a)}return n};return r(e)}resetCircuitBreaker(){this.circuitBreaker.reset()}};V();var re=class{constructor(e,t,r){this.whisperService=e;this.logger=t;this.config={enabled:!0,apiKey:"",model:"whisper-1",maxConcurrency:1,timeout:3e4,...r}}normalizeError(e){return e instanceof Error?e:new Error("Unknown error")}async transcribe(e,t){let r=Date.now();try{let i=this.convertOptions(t),n=await this.whisperService.transcribe(e,i),s=Date.now()-r;return this.convertResponse(n,s)}catch(i){let n=this.normalizeError(i);throw this.logger.error("WhisperAdapter: Transcription failed",n),n}}convertOptions(e){let t={model:(e==null?void 0:e.model)||this.config.model||"whisper-1",language:e==null?void 0:e.language};if(e!=null&&e.whisper){let r=e.whisper;r.temperature!==void 0&&(t.temperature=r.temperature),r.prompt&&(t.prompt=r.prompt),r.responseFormat&&(t.responseFormat=r.responseFormat)}return t.responseFormat||(t.responseFormat="verbose_json"),t}convertResponse(e,t){var i;let r=e.text.split(/\s+/).filter(n=>n.length>0).length;return{text:e.text,language:e.language,duration:e.duration,segments:(i=e.segments)==null?void 0:i.map((n,s)=>{var a;return{id:(a=n.id)!=null?a:s,start:n.start,end:n.end,text:n.text,confidence:n.no_speech_prob?1-n.no_speech_prob:void 0}}),provider:"whisper",metadata:{model:"whisper-1",processingTime:t,wordCount:r}}}validateApiKey(e){return this.whisperService.validateApiKey(e)}cancel(){this.whisperService.cancel()}getProviderName(){return"OpenAI Whisper"}getCapabilities(){return{streaming:!1,realtime:!1,languages:["en","zh","de","es","ru","ko","fr","ja","pt","tr","pl","ca","nl","ar","sv","it","id","hi","fi","vi","he","uk","el","ms","cs","ro","da","hu","ta","no","th","ur","hr","bg","lt","la","mi","ml","cy","sk","te","fa","lv","bn","sr","az","sl","kn","et","mk","br","eu","is","hy","ne","mn","bs","kk","sq","sw","gl","mr","pa","si","km","sn","yo","so","af","oc","ka","be","tg","sd","gu","am","yi","lo","uz","fo","ht","ps","tk","nn","mt","sa","lb","my","bo","tl","mg","as","tt","haw","ln","ha","ba","jw","su"],maxFileSize:25*1024*1024,audioFormats:["mp3","mp4","mpeg","mpga","m4a","wav","webm"],features:["transcription","translation","timestamps","language_detection","word_timestamps"],models:["whisper-1"]}}async isAvailable(){try{let e=new ArrayBuffer(1024);return await this.whisperService.transcribe(e,{responseFormat:"text"}),!0}catch(e){let t=this.normalizeError(e).message.toLowerCase();return!(t.includes("circuit")||t.includes("unavailable")||t.includes("timeout"))}}getConfig(){return{...this.config}}resetCircuitBreaker(){this.whisperService.resetCircuitBreaker()}updateConfig(e){this.config={...this.config,...e}}};var ot=require("obsidian");V();var ie={ENDPOINT:"https://api.deepgram.com/v1/listen",MAX_FILE_SIZE:2147483648,DEFAULT_TIMEOUT:3e4,MAX_TIMEOUT:54e5,REQUESTS_PER_MINUTE:100,RECOMMENDED_MAX_SIZE:52428800},ne={MIN_HEADER_SIZE:44,SIZE_WARNING_THRESHOLD:1024,SIZE_WARNING_LARGE:100*1024*1024,SILENCE_THRESHOLD:327,SILENCE_PEAK_MULTIPLIER:5,SAMPLE_SIZE:8192},$t={CIRCUIT_BREAKER:{FAILURE_THRESHOLD:5,SUCCESS_THRESHOLD:2,TIMEOUT:6e4},RETRY:{MAX_RETRIES:3,BASE_DELAY:1e3,MAX_DELAY:1e4,JITTER_MAX:1e3},TIMEOUT:{SIZE_MB_THRESHOLD:5,PROCESSING_TIME_PER_MB:30*1e3,BUFFER_MULTIPLIER:1.5}},_e={CONSECUTIVE_THRESHOLD:.5,MIN_SEGMENT_LENGTH:1,WORDS_PER_SEGMENT:10,SPEAKER_LABELS:{PREFIX:"Speaker",NUMBERING:"numeric"}};var q={AUDIO_VALIDATION:{EMPTY:"Audio data is empty",TOO_SMALL:"Audio data too small to contain valid audio",TOO_LARGE:"Audio file exceeds maximum size limit (2GB)",VERY_SMALL_WARNING:"Audio file is very small, may not contain meaningful content",LARGE_WARNING:"Large audio file may take longer to process"},API:{INVALID_RESPONSE:"Invalid response from Deepgram API",NO_ALTERNATIVES:"No transcription alternatives found",EMPTY_TRANSCRIPT:"Transcription service returned empty text",SERVER_TIMEOUT:"Server timeout processing large audio file. This often happens with very large files (>50MB). Try: 1) Breaking the file into smaller chunks, 2) Reducing audio quality/bitrate, or 3) Using a different model like 'enhanced' which may be faster.",CANCELLED:"Transcription cancelled",MAX_RETRIES:"operation failed after {retries} attempts"},MIGRATION:{MODEL_NOT_FOUND:"Model not found. Please check model ID.",USER_APPROVAL_REQUIRED:"User approval required but not granted",INVALID_BACKUP:"Invalid backup data",ROLLBACK_FAILED:"Rollback failed"}};var ae={enabled:!0,format:"speaker_prefix",speakerLabels:{prefix:"Speaker",numbering:"numeric"},merging:{consecutiveThreshold:_e.CONSECUTIVE_THRESHOLD,minSegmentLength:_e.MIN_SEGMENT_LENGTH},output:{includeTimestamps:!1,includeConfidence:!1,paragraphBreaks:!0,lineBreaksBetweenSpeakers:!0}},se=class{constructor(e){this.logger=e}formatTranscript(e,t=ae){let r=Date.now();if(this.logFormatStart(e,t),!this.hasSpeakerInformation(e))return this.logger.debug("No speaker information found, returning original text"),this.createFallbackResult(e);let i=this.processTranscriptWithSpeakers(e,t);return this.logFormatComplete(i,Date.now()-r),i}processTranscriptWithSpeakers(e,t){let r=this.buildSegments(e,t);this.logger.debug(`Created ${r.length} segments from ${e.length} words`);let i=this.calculateStatistics(r,e);return{formattedText:this.formatSegments(r,t),segments:r,speakerCount:i.totalSpeakers,statistics:i,originalWordCount:e.length}}logFormatStart(e,t){this.logger.debug("=== DiarizationFormatter.formatTranscript START ===",{wordCount:e.length,config:t})}logFormatComplete(e,t){this.logger.info("=== DiarizationFormatter.formatTranscript COMPLETE ===",{processingTime:t,speakerCount:e.speakerCount,segmentCount:e.segments.length,formattedTextLength:e.formattedText.length})}hasSpeakerInformation(e){return e.some(t=>t.speaker!==void 0&&t.speaker>=0)}createFallbackResult(e){var i,n;let t=e.map(s=>s.word).join(" "),r=e.length>0?e[e.length-1].end-e[0].start:0;return{formattedText:t,segments:[{id:0,text:t,speaker:0,start:((i=e[0])==null?void 0:i.start)||0,end:((n=e[e.length-1])==null?void 0:n.end)||0,confidence:e.reduce((s,a)=>s+a.confidence,0)/e.length||0,wordCount:e.length}],speakerCount:1,statistics:{totalSpeakers:1,totalSegments:1,averageSegmentLength:e.length,speakerDistribution:{0:1},totalDuration:r,averageConfidence:e.reduce((s,a)=>s+a.confidence,0)/e.length||0},originalWordCount:e.length}}buildSegments(e,t){if(e.length===0)return[];let r=[],i=null,n=0;for(let s=0;s<e.length;s++){let a=e[s];this.shouldCreateNewSegment(a,i,t,s>0?e[s-1]:null)?(i&&this.isValidSegment(i,t)&&r.push(this.finalizeSegment(i,n++)),i=this.initializeSegment(a)):i&&this.appendToSegment(i,a)}return i&&this.isValidSegment(i,t)&&r.push(this.finalizeSegment(i,n)),r}shouldCreateNewSegment(e,t,r,i){return!!(!t||t.speaker!==e.speaker||i&&t.end!==void 0&&e.start-i.end>r.merging.consecutiveThreshold)}initializeSegment(e){return{text:e.word,speaker:e.speaker||0,start:e.start,end:e.end,confidence:e.confidence,wordCount:1}}appendToSegment(e,t){e.text=(e.text||"")+" "+t.word,e.end=t.end,e.wordCount=(e.wordCount||0)+1;let r=(e.confidence||0)*((e.wordCount||1)-1)+t.confidence;e.confidence=r/(e.wordCount||1)}isValidSegment(e,t){var r;return(e.wordCount||0)>=t.merging.minSegmentLength&&(((r=e.text)==null?void 0:r.trim().length)||0)>0}finalizeSegment(e,t){return{id:t,text:(e.text||"").trim(),speaker:e.speaker||0,start:e.start||0,end:e.end||0,confidence:e.confidence||0,wordCount:e.wordCount||0}}formatSegments(e,t){if(e.length===0)return"";let r=[];for(let i of e){let n=this.generateSpeakerLabel(i.speaker,t),s="";switch(t.format){case"speaker_prefix":s=`${n}: ${i.text}`;break;case"speaker_block":s=`${n}
${i.text}`;break;case"custom":s=this.applyCustomFormat(i,n,t);break;default:s=`${n}: ${i.text}`}if(t.output.includeTimestamps&&(s=`${`[${this.formatTime(i.start)} - ${this.formatTime(i.end)}]`} ${s}`),t.output.includeConfidence){let a=`(${Math.round(i.confidence*100)}%)`;s=`${s} ${a}`}r.push(s)}return t.output.lineBreaksBetweenSpeakers?this.insertSpeakerBreaks(r,e):r.join(`
`)}generateSpeakerLabel(e,t){let{prefix:r,numbering:i,customLabels:n}=t.speakerLabels;if(n&&n[e])return n[e];switch(i){case"alphabetic":{let s=String.fromCharCode(65+e%26);return`${r} ${s}`}case"numeric":default:return`${r} ${e+1}`}}applyCustomFormat(e,t,r){return`${t}: ${e.text}`}insertSpeakerBreaks(e,t){let r=[],i=null;for(let n=0;n<e.length;n++){let s=t[n].speaker;i!==null&&i!==s&&r.push(""),r.push(e[n]),i=s}return r.join(`
`)}formatTime(e){let t=Math.floor(e/60),r=Math.floor(e%60);return`${t.toString().padStart(2,"0")}:${r.toString().padStart(2,"0")}`}calculateStatistics(e,t){if(e.length===0)return{totalSpeakers:0,totalSegments:0,averageSegmentLength:0,speakerDistribution:{},totalDuration:0,averageConfidence:0};let r={},i=0,n=0;for(let a of e)r[a.speaker]=(r[a.speaker]||0)+1,i+=a.confidence,n+=a.wordCount;let s=t.length>0?t[t.length-1].end-t[0].start:0;return{totalSpeakers:Object.keys(r).length,totalSegments:e.length,averageSegmentLength:e.length>0?n/e.length:0,speakerDistribution:r,totalDuration:s,averageConfidence:e.length>0?i/e.length:0}}validateConfig(e){let t=[];return e.merging.consecutiveThreshold<0&&t.push("consecutiveThreshold must be non-negative"),e.merging.minSegmentLength<1&&t.push("minSegmentLength must be at least 1"),e.speakerLabels.prefix.trim()||t.push("speakerLabels.prefix cannot be empty"),{valid:t.length===0,errors:t}}};var ze=class{constructor(e){this.logger=e}validateAudio(e){let t=[],r=[],i={size:e.byteLength,isEmpty:e.byteLength===0,hasMinimumSize:e.byteLength>=ne.MIN_HEADER_SIZE,format:this.detectAudioFormat(e)};i.isEmpty&&r.push(q.AUDIO_VALIDATION.EMPTY),!i.hasMinimumSize&&!i.isEmpty&&r.push(q.AUDIO_VALIDATION.TOO_SMALL),i.size>ie.MAX_FILE_SIZE&&r.push(q.AUDIO_VALIDATION.TOO_LARGE),i.size<ne.SIZE_WARNING_THRESHOLD&&t.push(q.AUDIO_VALIDATION.VERY_SMALL_WARNING),i.size>ne.SIZE_WARNING_LARGE&&t.push(q.AUDIO_VALIDATION.LARGE_WARNING);let n=r.length===0;return this.logger.debug("Audio validation completed",{isValid:n,warnings:t.length,errors:r.length,metadata:i}),{isValid:n,warnings:t,errors:r,metadata:i}}detectAudioFormat(e){if(e.byteLength<12)return;let t=new Uint8Array(e,0,12);return t[0]===82&&t[1]===73&&t[2]===70&&t[3]===70?"wav":t[0]===255&&(t[1]&224)===224||t[0]===73&&t[1]===68&&t[2]===51?"mp3":t[0]===102&&t[1]===76&&t[2]===97&&t[3]===67?"flac":t[0]===79&&t[1]===103&&t[2]===103&&t[3]===83?"ogg":t.length>=8&&t[4]===102&&t[5]===116&&t[6]===121&&t[7]===112?"m4a":t[0]===26&&t[1]===69&&t[2]===223&&t[3]===163?"webm":(this.logger.debug("Unknown audio format detected",{firstBytes:Array.from(t.slice(0,8)).map(r=>"0x"+r.toString(16).padStart(2,"0")).join(" ")}),"unknown")}checkForSilence(e){if(e.byteLength<44)return{isSilent:!0,averageAmplitude:0,peakAmplitude:0};let t=new Uint8Array(e,0,4);if(!(t[0]===82&&t[1]===73&&t[2]===70&&t[3]===70))return{isSilent:!1,averageAmplitude:-1,peakAmplitude:-1};try{let i=Math.min(e.byteLength-44,8192),n=new Int16Array(e,44,i/2),s=0,a=0;for(let u=0;u<n.length;u++){let m=Math.abs(n[u]);s+=m,a=Math.max(a,m)}let o=n.length>0?s/n.length:0,c=327;return{isSilent:o<c&&a<c*5,averageAmplitude:o,peakAmplitude:a}}catch(r){return this.logger.warn("Failed to analyze audio for silence",r),{isSilent:!1,averageAmplitude:-1,peakAmplitude:-1}}}},Be=class{constructor(e,t){this.requestsPerMinute=e;this.logger=t;this.queue=[];this.processing=!1;this.lastRequestTime=0}acquire(){return new Promise(e=>{this.queue.push(e),this.processQueue()})}async processQueue(){if(this.processing||this.queue.length===0)return;this.processing=!0;let e=6e4/this.requestsPerMinute;for(;this.queue.length>0;){let r=Date.now()-this.lastRequestTime;if(r<e){let n=e-r;await this.sleep(n)}let i=this.queue.shift();i&&(this.lastRequestTime=Date.now(),i())}this.processing=!1}sleep(e){return new Promise(t=>setTimeout(t,e))}},Ke=class{constructor(e){this.logger=e;this.state="CLOSED";this.failureCount=0;this.successCount=0;this.nextAttemptTime=0;this.failureThreshold=5;this.successThreshold=2;this.timeout=6e4}async execute(e){if(this.isOpen())throw new $("deepgram");try{let t=await e();return this.onSuccess(),t}catch(t){throw this.onFailure(),t}}isOpen(){return this.state==="OPEN"?Date.now()>=this.nextAttemptTime?(this.state="HALF_OPEN",this.logger.info("Deepgram Circuit breaker entering HALF_OPEN state"),!1):!0:!1}onSuccess(){this.failureCount=0,this.state==="HALF_OPEN"&&(this.successCount++,this.successCount>=this.successThreshold&&(this.state="CLOSED",this.successCount=0,this.logger.info("Deepgram Circuit breaker closed")))}onFailure(){this.failureCount++,this.state==="HALF_OPEN"?(this.state="OPEN",this.nextAttemptTime=Date.now()+this.timeout,this.logger.warn("Deepgram Circuit breaker opened due to failure in HALF_OPEN state")):this.failureCount>=this.failureThreshold&&(this.state="OPEN",this.nextAttemptTime=Date.now()+this.timeout,this.logger.warn(`Deepgram Circuit breaker opened after ${this.failureCount} failures`))}reset(){this.state="CLOSED",this.failureCount=0,this.successCount=0,this.logger.info("Deepgram Circuit breaker reset")}},Ue=class{constructor(e){this.logger=e;this.maxRetries=3;this.baseDelay=1e3;this.maxDelay=1e4}async execute(e){let t;for(let r=0;r<this.maxRetries;r++)try{return await e()}catch(i){if(t=i,!this.isRetryable(i))throw i;if(r<this.maxRetries-1){let n=this.calculateDelay(r);this.logger.debug(`Deepgram: Retrying after ${n}ms (attempt ${r+1}/${this.maxRetries})`),await this.sleep(n)}}throw new S(`Deepgram operation failed after ${this.maxRetries} attempts: ${t.message}`,"MAX_RETRIES_EXCEEDED","deepgram",!1)}isRetryable(e){var t;return e instanceof S?e.isRetryable:(t=e.message)==null?void 0:t.toLowerCase().includes("network")}calculateDelay(e){return Math.min(this.baseDelay*Math.pow(2,e),this.maxDelay)+Math.random()*1e3}sleep(e){return new Promise(t=>setTimeout(t,e))}},oe=class{constructor(e,t,r=100,i=3e4){this.apiKey=e;this.logger=t;this.API_ENDPOINT="https://api.deepgram.com/v1/listen";this.MAX_FILE_SIZE=2*1024*1024*1024;this.lastAudioSize=0;this.timeout=i,this.circuitBreaker=new Ke(t),this.retryStrategy=new Ue(t),this.rateLimiter=new Be(r,t),this.audioValidator=new ze(t),this.diarizationFormatter=new se(t)}async transcribe(e,t,r){return await this.rateLimiter.acquire(),this.circuitBreaker.execute(()=>this.retryStrategy.execute(()=>this.performTranscription(e,t,r)))}calculateDynamicTimeout(e){let t=e/1048576,r=this.timeout;if(t<=5)return r;let i;t<=10?i=t*30*1e3:t<=50?i=t*40*1e3*1.5:t<=100?i=t*45*1e3*1.8:i=t*50*1e3*2,t>=50&&(i=Math.max(i,40*60*1e3)),t>=100&&(i=Math.max(i,60*60*1e3));let n=90*60*1e3;return i=Math.min(i,n),this.logger.debug("Dynamic timeout calculation",{audioSizeMB:t,baseTimeout:r,finalTimeout:i,timeoutMinutes:Math.round(i/6e4)}),i}async performTranscription(e,t,r){var s,a,o,c,d,u,m,v,p,w;this.abortController=new AbortController;let i=Date.now();this.lastAudioSize=e.byteLength;let n=this.calculateDynamicTimeout(e.byteLength);try{let E=this.audioValidator.validateAudio(e);if(this.logger.debug("Audio validation results",{isValid:E.isValid,warnings:E.warnings,errors:E.errors,metadata:E.metadata}),!E.isValid)throw new S(`Audio validation failed: ${E.errors.join(", ")}`,"INVALID_AUDIO","deepgram",!1);if(E.warnings.forEach(h=>{this.logger.warn(`Audio validation warning: ${h}`)}),E.metadata.format==="wav"){let h=this.audioValidator.checkForSilence(e);this.logger.debug("Audio silence analysis",h),h.isSilent&&this.logger.warn("Audio appears to be silent or very quiet",{averageAmplitude:h.averageAmplitude,peakAmplitude:h.peakAmplitude})}let x=this.buildUrl(t,r),R=this.buildHeaders(E.metadata.format);this.logger.debug("Starting Deepgram transcription request",{fileSize:e.byteLength,detectedFormat:E.metadata.format,url:x,options:t,language:r});let B={url:x,method:"POST",headers:R,body:e,throw:!1},f=setTimeout(()=>{this.abortController&&(this.logger.warn(`Deepgram request timeout after ${n}ms for ${e.byteLength} byte file`),this.abortController.abort())},n),M;try{M=await(0,ot.requestUrl)(B)}finally{clearTimeout(f)}let Z=Date.now()-i;if(this.logger.info(`Deepgram transcription completed in ${Z}ms`,{status:M.status,statusText:M.status>=200&&M.status<300?"OK":"ERROR"}),M.status===200){let h=M.json;if(this.logger.debug("=== Deepgram API Raw Response Analysis ===",{hasJson:!!h,responseKeys:h?Object.keys(h):[],hasMetadata:!!(h!=null&&h.metadata),hasResults:!!(h!=null&&h.results),metadataKeys:h!=null&&h.metadata?Object.keys(h.metadata):[],resultsKeys:h!=null&&h.results?Object.keys(h.results):[],channelsCount:((a=(s=h==null?void 0:h.results)==null?void 0:s.channels)==null?void 0:a.length)||0}),(c=(o=h==null?void 0:h.results)==null?void 0:o.channels)!=null&&c[0]){let C=h.results.channels[0];this.logger.debug("First channel analysis",{hasAlternatives:!!C.alternatives,alternativesCount:((d=C.alternatives)==null?void 0:d.length)||0,detectedLanguage:C.detected_language,firstAlternative:(u=C.alternatives)!=null&&u[0]?{hasTranscript:!!C.alternatives[0].transcript,transcriptLength:((m=C.alternatives[0].transcript)==null?void 0:m.length)||0,transcriptEmpty:!C.alternatives[0].transcript||C.alternatives[0].transcript.trim()==="",transcriptPreview:((v=C.alternatives[0].transcript)==null?void 0:v.substring(0,200))+(C.alternatives[0].transcript&&C.alternatives[0].transcript.length>200?"...":""),confidence:C.alternatives[0].confidence,hasWords:!!C.alternatives[0].words,wordsCount:((p=C.alternatives[0].words)==null?void 0:p.length)||0,firstFewWords:(w=C.alternatives[0].words)==null?void 0:w.slice(0,5).map(Y=>({word:Y.word,confidence:Y.confidence}))}:null})}return h!=null&&h.metadata&&this.logger.debug("Metadata analysis",{duration:h.metadata.duration,channels:h.metadata.channels,models:h.metadata.models,modelInfo:h.metadata.model_info}),h}else throw await this.handleAPIError(M)}catch(E){throw E.name==="AbortError"?new S("Transcription cancelled","CANCELLED","deepgram",!1):E}finally{this.abortController=void 0}}buildUrl(e,t){let r=new URLSearchParams;if(((e==null?void 0:e.tier)||"").toString().toLowerCase().includes("nova")||t&&t.startsWith("ko"))r.append("model","2-general"),r.append("tier","nova");else{let s=(e==null?void 0:e.tier)||"nova-2";r.append("model",s)}return t&&t!=="auto"?r.append("language",t):e!=null&&e.detectLanguage&&r.append("detect_language","true"),(e==null?void 0:e.punctuate)!==!1&&r.append("punctuate","true"),e!=null&&e.smartFormat&&r.append("smart_format","true"),e!=null&&e.diarize&&r.append("diarize","true"),e!=null&&e.numerals&&r.append("numerals","true"),e!=null&&e.utterances&&r.append("utterances","true"),e!=null&&e.profanityFilter&&r.append("profanity_filter","true"),e!=null&&e.redact&&e.redact.length>0&&r.append("redact",e.redact.join(",")),e!=null&&e.keywords&&e.keywords.length>0&&r.append("keywords",e.keywords.join(",")),`${this.API_ENDPOINT}?${r.toString()}`}buildHeaders(e){let t={wav:"audio/wav",mp3:"audio/mpeg",flac:"audio/flac",ogg:"audio/ogg",m4a:"audio/mp4",webm:"audio/webm",opus:"audio/opus"},r=e&&t[e]?t[e]:"audio/wav";return this.logger.debug("Content-Type selected",{detectedFormat:e,contentType:r}),{Authorization:`Token ${this.apiKey}`,"Content-Type":r}}handleAPIError(e){var s;let t=e.json,r=e.text,n=(t==null?void 0:t.message)||(t==null?void 0:t.error)||(typeof r=="string"&&r.length>0?r:"Unknown error");switch(this.logger.error(`Deepgram API Error: ${e.status} - ${n}`,void 0,{status:e.status,errorBody:t,rawText:r}),e.status){case 400:throw new S(n||"Invalid request","BAD_REQUEST","deepgram",!1,400);case 401:throw new j("deepgram");case 402:throw new S("Insufficient credits","INSUFFICIENT_CREDITS","deepgram",!1,402);case 429:{let a=(s=e.headers)==null?void 0:s["retry-after"];throw new X("deepgram",a?parseInt(a):void 0)}case 500:case 502:case 503:throw new $("deepgram");case 504:{let a=this.lastAudioSize?` (${Math.round(this.lastAudioSize/1048576)}MB)`:"";throw new S(`Server timeout processing large audio file${a}. This often happens with very large files (>50MB). Try: 1) Breaking the file into smaller chunks (recommended: <50MB per chunk), 2) Reducing audio quality/bitrate to 64-128 kbps, 3) Using the 'enhanced' model which may be faster, or 4) Converting to a more efficient format like MP3 or OGG.`,"SERVER_TIMEOUT","deepgram",!0,504)}default:throw new S(`API error: ${n}`,"UNKNOWN_ERROR","deepgram",!1,e.status)}}async validateApiKey(e){let t=this.apiKey;this.apiKey=e;try{let r=new ArrayBuffer(1024);return await this.performTranscription(r),!0}catch(r){return r instanceof j?(this.logger.warn("Deepgram API key validation failed: Invalid key"),!1):(this.logger.debug("Deepgram API key validation encountered non-auth error",r),!0)}finally{this.apiKey=t}}cancel(){this.abortController&&(this.abortController.abort(),this.logger.debug("Deepgram transcription cancelled by user"))}resetCircuitBreaker(){this.circuitBreaker.reset()}parseResponse(e,t){var m,v,p,w,E,x,R,B,f,M,Z,h,C,Y,Ye;if(this.logger.debug("=== DeepgramService.parseResponse START ==="),this.logger.debug("Full response structure:",{hasMetadata:!!(e!=null&&e.metadata),hasResults:!!(e!=null&&e.results),channelsCount:((v=(m=e==null?void 0:e.results)==null?void 0:m.channels)==null?void 0:v.length)||0}),!e||!e.results||!e.results.channels||e.results.channels.length===0)throw this.logger.error("Invalid Deepgram response structure",void 0,{response:e}),new S("Invalid response from Deepgram API","INVALID_RESPONSE","deepgram",!1);let r=e.results.channels[0];if(this.logger.debug("Channel data:",{hasAlternatives:!!(r!=null&&r.alternatives),alternativesCount:((p=r==null?void 0:r.alternatives)==null?void 0:p.length)||0,detectedLanguage:r==null?void 0:r.detected_language}),!r.alternatives||r.alternatives.length===0)throw this.logger.error("No alternatives in Deepgram response",void 0,{channel:r}),new S("No transcription alternatives found","NO_ALTERNATIVES","deepgram",!1);let i=r.alternatives[0];if(this.logger.debug("Alternative data:",{hasTranscript:!!(i!=null&&i.transcript),transcriptLength:((w=i==null?void 0:i.transcript)==null?void 0:w.length)||0,transcriptPreview:(E=i==null?void 0:i.transcript)==null?void 0:E.substring(0,100),confidence:i==null?void 0:i.confidence,hasWords:!!(i!=null&&i.words),wordsCount:((x=i==null?void 0:i.words)==null?void 0:x.length)||0}),!i.transcript||i.transcript.trim().length===0){this.logger.warn("=== EMPTY TRANSCRIPT DETECTED ===",{transcript:i.transcript,transcriptType:typeof i.transcript,transcriptLength:((R=i.transcript)==null?void 0:R.length)||0,trimmedLength:((B=i.transcript)==null?void 0:B.trim().length)||0,confidence:i.confidence,hasWords:!!i.words,wordsCount:((f=i.words)==null?void 0:f.length)||0,detectedLanguage:r.detected_language,duration:e.metadata.duration,channels:e.metadata.channels,models:e.metadata.models});let I=[];i.confidence===0&&I.push("Zero confidence - possibly no speech detected"),!i.words||i.words.length===0?I.push("No word timestamps - indicates no speech recognition"):I.push(`${i.words.length} words detected but empty transcript`),e.metadata.duration<1&&I.push("Very short audio duration"),r.detected_language||I.push("No language detected"),this.logger.warn("Empty transcript diagnostic analysis",{possibleCauses:I,recommendations:["Check audio quality and volume","Verify audio contains actual speech","Consider adjusting language settings","Try different Deepgram model","Check for audio format compatibility issues"]});let O=I.length>0?` Possible causes: ${I.join(", ")}`:"";throw new S(`Transcription service returned empty text.${O}`,"EMPTY_TRANSCRIPT","deepgram",!1)}let s=i.transcript||"",a=[],o=1,c=null,d=i.words&&i.words.length>0&&i.words.some(I=>I.speaker!==void 0&&I.speaker>=0);if(this.logger.debug("Speaker information check:",{hasWords:!!i.words,wordCount:((M=i.words)==null?void 0:M.length)||0,hasSpeakerInfo:d,diarizationEnabled:t==null?void 0:t.enabled,firstWordSpeaker:(h=(Z=i.words)==null?void 0:Z[0])==null?void 0:h.speaker,sampleWords:(C=i.words)==null?void 0:C.slice(0,3).map(I=>({word:I.word,speaker:I.speaker,hasSpeaker:I.speaker!==void 0}))}),t!=null&&t.enabled&&d){this.logger.debug("Processing diarization with config:",t);try{let I=(i.words||[]).map(D=>({word:D.word,start:D.start,end:D.end,confidence:D.confidence,speaker:D.speaker!==void 0?D.speaker:0}));this.logger.debug("Converting to diarized words:",{originalWordCount:(i.words||[]).length,diarizedWordCount:I.length,speakersFound:[...new Set(I.map(D=>D.speaker))],firstFewWords:I.slice(0,5).map(D=>({word:D.word,speaker:D.speaker}))});let O=this.diarizationFormatter.formatTranscript(I,t);this.logger.info("Diarization result:",{speakerCount:O.speakerCount,segmentCount:O.segments.length,formattedTextLength:O.formattedText.length,originalWordCount:O.originalWordCount,textPreview:O.formattedText.substring(0,200)}),s=O.formattedText,o=O.speakerCount,c=O.statistics,a=O.segments.map(D=>({id:D.id,start:D.start,end:D.end,text:D.text,confidence:D.confidence,speaker:D.speaker.toString()}))}catch(I){this.logger.error("Diarization formatting failed, falling back to original transcript",I),s=i.transcript||"",a=this.createSegmentsFromWords(i.words||[])}}else t!=null&&t.enabled?this.logger.debug("Diarization enabled but no speaker information found"):this.logger.debug("Diarization disabled, using original transcript"),i.words&&i.words.length>0&&(a=this.createSegmentsFromWords(i.words),this.logger.debug(`Created ${a.length} segments from ${i.words.length} words`));let u={text:s,language:r.detected_language,confidence:i.confidence,duration:e.metadata.duration,segments:a,provider:"deepgram",metadata:{model:((Y=e.metadata.models)==null?void 0:Y[0])||"unknown",processingTime:e.metadata.duration,wordCount:i.transcript?i.transcript.split(/\s+/).length:0,...(t==null?void 0:t.enabled)&&{speakerCount:o,diarizationEnabled:!0,diarizationStats:c}}};return this.logger.info("=== DeepgramService.parseResponse COMPLETE ===",{textLength:u.text.length,textPreview:u.text.substring(0,100),language:u.language,confidence:u.confidence,segmentsCount:((Ye=u.segments)==null?void 0:Ye.length)||0}),u}createSegmentsFromWords(e){let t=[];for(let i=0;i<e.length;i+=10){let n=e.slice(i,Math.min(i+10,e.length));n.length>0&&t.push({id:Math.floor(i/10),start:n[0].start,end:n[n.length-1].end,text:n.map(s=>s.word).join(" "),confidence:n.reduce((s,a)=>s+a.confidence,0)/n.length,speaker:n[0].speaker})}return t}};V();var ce=class{constructor(e){this.logger=e;this.CHUNK_SIZE=ie.RECOMMENDED_MAX_SIZE;this.WAV_HEADER_SIZE=44}needsChunking(e){return e>this.CHUNK_SIZE}splitAudio(e){let t=e.byteLength;return this.needsChunking(t)?(this.logger.info("Splitting large audio file into chunks",{originalSizeMB:Math.round(t/(1024*1024)),chunkSizeMB:Math.round(this.CHUNK_SIZE/(1024*1024)),estimatedChunks:Math.ceil(t/this.CHUNK_SIZE)}),this.isWavFile(e)?Promise.resolve(this.splitWavAudio(e)):Promise.resolve(this.splitByteArray(e))):Promise.resolve([e])}isWavFile(e){if(e.byteLength<12)return!1;let t=new Uint8Array(e,0,4);return t[0]===82&&t[1]===73&&t[2]===70&&t[3]===70}splitWavAudio(e){let t=[],r=e.slice(0,this.WAV_HEADER_SIZE),i=e.slice(this.WAV_HEADER_SIZE),n=i.byteLength,s=this.CHUNK_SIZE-this.WAV_HEADER_SIZE,a=Math.ceil(n/s);for(let o=0;o<a;o++){let c=o*s,d=Math.min(c+s,n),u=i.slice(c,d),m=new ArrayBuffer(this.WAV_HEADER_SIZE+u.byteLength),v=new Uint8Array(m);v.set(new Uint8Array(r),0),v.set(new Uint8Array(u),this.WAV_HEADER_SIZE),this.updateWavHeader(m,u.byteLength),t.push(m),this.logger.debug(`Created chunk ${o+1}/${a}`,{sizeMB:Math.round(m.byteLength/(1024*1024))})}return t}updateWavHeader(e,t){let r=new DataView(e);r.setUint32(4,t+36,!0),r.setUint32(40,t,!0)}splitByteArray(e){let t=[],r=e.byteLength,i=Math.ceil(r/this.CHUNK_SIZE);this.logger.warn("Using simple byte splitting for non-WAV format. Results may vary.");for(let n=0;n<i;n++){let s=n*this.CHUNK_SIZE,a=Math.min(s+this.CHUNK_SIZE,r);t.push(e.slice(s,a)),this.logger.debug(`Created chunk ${n+1}/${i}`,{sizeMB:Math.round((a-s)/(1024*1024))})}return t}mergeTranscriptionResults(e){return e.filter(t=>t&&t.trim()).join(" ")}getRecommendedSettings(e){let t=e/1048576;return t<=50?{needsChunking:!1,recommendedModel:"nova-2"}:t<=100?{needsChunking:!0,recommendedModel:"enhanced",recommendedBitrate:"128 kbps",estimatedChunks:Math.ceil(e/this.CHUNK_SIZE)}:{needsChunking:!0,recommendedModel:"enhanced",recommendedBitrate:"64 kbps",estimatedChunks:Math.ceil(e/this.CHUNK_SIZE)}}};var G=class G{constructor(e,t,r,i){this.deepgramService=e;this.logger=t;this.settingsManager=r;this.audioChunker=new ce(t),this.config={enabled:!0,apiKey:"",model:"nova-3",maxConcurrency:5,timeout:3e4,rateLimit:{requests:100,window:6e4},...i}}async transcribe(e,t){var i,n;let r=e.byteLength/1048576;this.logger.debug("=== DeepgramAdapter.transcribe START ===",this.sanitizeForLogging({audioSize:e.byteLength,audioSizeMB:r,options:t}));try{return((n=(i=this.settingsManager)==null?void 0:i.get("autoChunking"))!=null?n:!0)&&this.audioChunker.needsChunking(e.byteLength)?(this.logger.info("Large file detected, using chunked processing",{sizeMB:r,recommendedSettings:this.audioChunker.getRecommendedSettings(e.byteLength)}),r>100&&this.logger.warn(`Very large audio file (${Math.round(r)}MB). Processing may take significant time. Consider reducing file size or bitrate for better performance.`),await this.transcribeWithChunking(e,t)):await this.transcribeStandard(e,t)}catch(s){let a=s;if(a instanceof S&&a.code==="SERVER_TIMEOUT"){let c=this.audioChunker.getRecommendedSettings(e.byteLength);this.logger.error("Timeout error - providing chunking recommendations",a,{audioSizeMB:r,recommendations:c});let d=`Transcription timeout for ${Math.round(r)}MB file.
Recommended solutions:
- Enable automatic chunking (files will be split into ${c.estimatedChunks||"multiple"} chunks)
- Use '${c.recommendedModel}' model for faster processing
- Reduce audio bitrate to ${c.recommendedBitrate||"128 kbps"}
- Convert to MP3 or OGG format for smaller file size`;throw new S(d,a.code,a.provider,a.isRetryable,a.statusCode)}throw this.enhanceTranscriptionError(a,e,t)}}async transcribeStandard(e,t){var i,n,s;let r=Date.now();try{let a=this.convertOptions(t),o=t==null?void 0:t.language;this.logger.debug("Calling Deepgram API with options:",this.sanitizeForLogging({deepgramOptions:a,language:o}));let c=await this.deepgramService.transcribe(e,a,o);this.logger.debug("Deepgram API response received:",{hasResponse:!!c,responseType:typeof c,hasResults:!!(c!=null&&c.results)});let d=this.createDiarizationConfig(a),u=this.deepgramService.parseResponse(c,d);return this.logger.debug("Parsed response:",{hasText:!!(u!=null&&u.text),textLength:((i=u==null?void 0:u.text)==null?void 0:i.length)||0,textPreview:(n=u==null?void 0:u.text)==null?void 0:n.substring(0,100)}),u.metadata={...u.metadata,processingTime:Date.now()-r},this.logger.info("=== DeepgramAdapter.transcribe COMPLETE ===",{processingTime:u.metadata.processingTime,textLength:((s=u.text)==null?void 0:s.length)||0,language:u.language}),u}finally{}}async transcribeWithChunking(e,t){var i,n;let r=Date.now();try{let s=await this.audioChunker.splitAudio(e);this.logger.info(`Processing ${s.length} audio chunks`);let a=[],o=0,c;for(let v=0;v<s.length;v++){this.logger.debug(`Processing chunk ${v+1}/${s.length}`,{chunkSizeMB:Math.round(s[v].byteLength/(1024*1024))});try{let p=await this.transcribeStandard(s[v],t);p.text&&p.text.trim()&&(a.push(p.text),o+=p.confidence||0,!c&&p.language&&(c=p.language))}catch(p){this.logger.error(`Failed to process chunk ${v+1}`,p)}}a.length<s.length&&this.logger.warn("Chunked transcription completed with partial results",{totalChunks:s.length,successfulChunks:a.length});let d=this.audioChunker.mergeTranscriptionResults(a),u=a.length>0?o/a.length:0;if(!d||d.trim().length===0)throw new S("All chunks failed to produce transcription","CHUNKING_FAILED","deepgram",!1);let m={text:d,language:c,confidence:u,provider:"deepgram",metadata:{processingTime:Date.now()-r,chunksProcessed:s.length,chunksSuccessful:a.length,isPartial:a.length<s.length}};return this.logger.info("Chunked transcription completed",{totalChunks:s.length,successfulChunks:a.length,processingTime:(i=m.metadata)==null?void 0:i.processingTime,textLength:m.text.length,isPartial:(n=m.metadata)==null?void 0:n.isPartial}),m}catch(s){throw this.logger.error("Chunked transcription failed",s),s}}enhanceTranscriptionError(e,t,r){let i=e;if(i instanceof S){if(i.code==="EMPTY_TRANSCRIPT"){this.logger.error("DeepgramAdapter: Empty transcript detected",i,{originalMessage:i.message,audioSize:t.byteLength,language:r==null?void 0:r.language,model:r==null?void 0:r.model});let n=[`No transcript was returned. ${i.message}`,"","Try the following:","- Ensure the audio contains clear speech","- Increase microphone input volume if the recording is quiet","- Reduce background noise or apply noise reduction","- Confirm the file format is supported (WAV, MP3, FLAC, etc.)","- Verify the language setting matches the spoken language","- Enable chunking for files that exceed the recommended size"].join(`
`);return new S(n,i.code,i.provider,i.isRetryable,i.statusCode)}if(i.code==="INVALID_AUDIO"){this.logger.error("DeepgramAdapter: Invalid audio format",i,{originalMessage:i.message,audioSize:t.byteLength});let n=[`The audio file could not be processed: ${i.message}`,"","Resolution steps:","- Confirm you selected the correct file and it is not corrupted","- Use a supported audio format (WAV, MP3, FLAC, OGG, etc.)","- Keep files under 2GB in size","- Enable automatic chunking for files larger than 50MB"].join(`
`);return new S(n,i.code,i.provider,i.isRetryable,i.statusCode)}}return this.logger.error("DeepgramAdapter: Transcription failed",e,{audioSize:t.byteLength,audioSizeMB:Math.round(t.byteLength/(1024*1024)),options:this.sanitizeForLogging(r),errorType:e.constructor.name,needsChunking:this.audioChunker.needsChunking(t.byteLength)}),e}convertOptions(e){var o;let t={tier:G.DEFAULT_TIER,punctuate:!0,smartFormat:!0,diarize:!0,utterances:!0},r={"nova-3":"nova-3","nova-2":"nova-2",nova:"nova-2",enhanced:"enhanced",base:"base"},i=e!=null&&e.model?r[e.model]:void 0;i&&(t.tier=i);let n=(o=this.settingsManager)==null?void 0:o.get("transcription"),s=n==null?void 0:n.deepgram,a=s==null?void 0:s.features;return a&&(this.logger.debug("Applying Deepgram feature overrides",this.sanitizeForLogging(a)),typeof a.punctuation=="boolean"&&(t.punctuate=a.punctuation),typeof a.smartFormat=="boolean"&&(t.smartFormat=a.smartFormat),typeof a.diarization=="boolean"&&(t.diarize=a.diarization),typeof a.utterances=="boolean"&&(t.utterances=a.utterances),typeof a.numerals=="boolean"&&(t.numerals=a.numerals)),e!=null&&e.deepgram&&Object.assign(t,e.deepgram),this.logger.debug("Resolved Deepgram options",this.sanitizeForLogging(t)),t}createDiarizationConfig(e){var i;if(!e.diarize)return{...ae,enabled:!1};let t=null;if(this.settingsManager){let n=this.settingsManager.get("transcription");t=(i=n==null?void 0:n.deepgram)==null?void 0:i.diarizationConfig}let r={...ae,enabled:!0,...t};return this.logger.debug("Diarization config created:",this.sanitizeForLogging(r)),r}async validateApiKey(e){var t;try{return await this.deepgramService.validateApiKey(e)}catch(r){let i=r;if(i instanceof S&&(i.code==="AUTH_ERROR"||i.statusCode===401||i.statusCode===403))return this.logger.warn("DeepgramAdapter: API key authentication failed",{statusCode:i.statusCode}),!1;throw this.logger.error("DeepgramAdapter: API key validation error (non-auth)",i,{statusCode:i==null?void 0:i.statusCode,errorType:(t=i==null?void 0:i.constructor)==null?void 0:t.name}),r}}cancel(){this.deepgramService.cancel()}getProviderName(){return"Deepgram"}getCapabilities(){return{streaming:!0,realtime:!0,languages:["en","es","fr","de","it","pt","nl","ru","zh","ja","ko","ar","tr","hi","pl","sv","da","no","fi","el","he","id","ms","th","vi","ta","te","uk","cs","ro","hu","bg","ca","hr","sr","sl","sk","lt","lv","et","is","mk","sq","eu","gl","cy","bn","ur","fa","gu","mr","pa","kn","ml","or","as","ne","si","my","km","lo","ka","hy","az","kk","uz","tg","ky","tk","mn","bo","am","ti","so","sw","rw","yo","ig","ha","zu","xh","af","mt","lb","ga","gd","br","fy","yi","jv","su","tl","ceb","haw","eo","la"],maxFileSize:2*1024*1024*1024,audioFormats:["mp3","mp4","wav","flac","ogg","opus","m4a","webm","amr","ac3","aac","wma"],features:["transcription","punctuation","smart_formatting","diarization","numerals","profanity_filter","redaction","keywords","language_detection","streaming","real_time","multi_channel","custom_vocabulary","sentiment_analysis","topic_detection","entity_detection","summarization"],models:["nova-3","nova-2","enhanced","base"]}}async isAvailable(){try{let e=new ArrayBuffer(1024);return await this.deepgramService.transcribe(e),!0}catch(e){let t=e.message.toLowerCase();return!(t.includes("circuit")||t.includes("unavailable")||t.includes("timeout")||t.includes("rate limit"))}}getConfig(){return{...this.config}}resetCircuitBreaker(){this.deepgramService.resetCircuitBreaker()}updateConfig(e){this.config={...this.config,...e}}sanitizeForLogging(e){let t=["apikey","api_key","token","authorization","secret"],r=i=>{if(i==null||typeof i!="object")return i;if(i instanceof ArrayBuffer)return"[ArrayBuffer]";if(Array.isArray(i))return i.map(s=>r(s));let n={};for(let[s,a]of Object.entries(i)){let o=s.toLowerCase();t.some(c=>o.includes(c))?n[s]="***":n[s]=r(a)}return n};return r(e)}estimateCost(e,t){let r=t||this.config.model||G.DEFAULT_TIER,i={"nova-3":.0043,"nova-2":.0145,nova:.0125,enhanced:.0085,base:.0059},n=e/60,s=i[r]||i[G.DEFAULT_TIER];return n*s}};G.DEFAULT_TIER="nova-3";var le=G;var $e=class{constructor(e){this.logger=e;this.metrics=new Map;this.initializeMetrics()}initializeMetrics(){["whisper","deepgram"].forEach(t=>{this.metrics.set(t,{provider:t,totalRequests:0,successfulRequests:0,failedRequests:0,averageLatency:0,averageCost:0})})}recordRequest(e,t,r,i,n){let s=this.metrics.get(e);s&&(s.totalRequests++,t?(s.successfulRequests++,r!==void 0&&(s.averageLatency=(s.averageLatency*(s.successfulRequests-1)+r)/s.successfulRequests),i!==void 0&&(s.averageCost=(s.averageCost*(s.successfulRequests-1)+i)/s.successfulRequests)):(s.failedRequests++,n&&(s.lastError={message:n.message,timestamp:new Date})),this.logger.debug(`Metrics updated for ${e}`,s))}getMetrics(e){return this.metrics.get(e)}getAllMetrics(){return Array.from(this.metrics.values())}getSuccessRate(e){let t=this.metrics.get(e);return!t||t.totalRequests===0?0:t.successfulRequests/t.totalRequests}},He=class{constructor(e,t){this.logger=e;this.metricsTracker=t;this.roundRobinIndex=0}select(e,t,r){let i=Array.from(e.entries()).filter(([n,s])=>s.getConfig().enabled);if(i.length===0)throw new Error("No transcription providers available");switch(t){case"cost_optimized":return this.selectByCost(i);case"performance_optimized":return this.selectByPerformance(i);case"quality_optimized":return this.selectByQuality(i);case"round_robin":return this.selectRoundRobin(i);case"ab_test":return this.selectForABTest(i,r);case"manual":default:return i[0][1]}}selectByCost(e){let t=e.find(([r])=>r==="deepgram");return t?t[1]:e[0][1]}selectByPerformance(e){let t=e[0],r=1/0;for(let[i,n]of e){let s=this.metricsTracker.getMetrics(i);s&&s.averageLatency<r&&(r=s.averageLatency,t=[i,n])}return t[1]}selectByQuality(e){let t=e[0],r=0;for(let[i,n]of e){let s=this.metricsTracker.getSuccessRate(i);s>r&&(r=s,t=[i,n])}return t[1]}selectRoundRobin(e){let t=e[this.roundRobinIndex%e.length];return this.roundRobinIndex++,t[1]}selectForABTest(e,t){if(!t)return this.selectRoundRobin(e);if(this.hashString(t)<.5){let n=e.find(([s])=>s==="whisper");return n?n[1]:e[0][1]}else{let n=e.find(([s])=>s==="deepgram");return n?n[1]:e[0][1]}}hashString(e){let t=0;for(let r=0;r<e.length;r++)t=(t<<5)-t+e.charCodeAt(r),t=t&t;return Math.abs(t)/2147483647}},ue=class{constructor(e,t){this.settingsManager=e;this.logger=t;this.providers=new Map;this.metricsTracker=new $e(t),this.selector=new He(t,this.metricsTracker),this.config=this.loadConfig(),this.initializeProviders()}normalizeError(e){return e instanceof Error?e:new Error(String(e))}loadConfig(){let e=(f,M)=>typeof f=="boolean"?f:M,t=(f,M)=>typeof f=="number"&&Number.isFinite(f)?f:M,r=f=>typeof f=="number"&&Number.isFinite(f)?f:void 0,i=(f,M="")=>typeof f=="string"?f:M,n=f=>typeof f=="string"?f:void 0,s=f=>f==="whisper"||f==="deepgram",a=f=>f==="manual"||f==="cost_optimized"||f==="performance_optimized"||f==="quality_optimized"||f==="round_robin"||f==="ab_test",o=this.settingsManager.get("transcription"),c=y(o)?o:{},d=y(c.whisper)?c.whisper:void 0,u=y(c.deepgram)?c.deepgram:void 0,m=y(c.abTest)?c.abTest:void 0,v=y(c.monitoring)?c.monitoring:void 0,p=v==null?void 0:v.alertThresholds,w=y(p)?p:void 0,E=u==null?void 0:u.rateLimit,x=y(E)?E:void 0,R=s(c.defaultProvider)?c.defaultProvider:"whisper",B=a(c.selectionStrategy)?c.selectionStrategy:"manual";return{defaultProvider:R,autoSelect:e(c.autoSelect,!1),selectionStrategy:B,fallbackEnabled:e(c.fallbackEnabled,!0),whisper:{enabled:e(d==null?void 0:d.enabled,!0),apiKey:i(d==null?void 0:d.apiKey,""),model:"whisper-1",maxConcurrency:1,timeout:3e4},deepgram:{enabled:e(u==null?void 0:u.enabled,!1),apiKey:i(u==null?void 0:u.apiKey,""),model:i(u==null?void 0:u.model,"nova-2"),maxConcurrency:t(u==null?void 0:u.maxConcurrency,5),timeout:t(u==null?void 0:u.timeout,3e4),rateLimit:{requests:t(x==null?void 0:x.requests,100),window:t(x==null?void 0:x.window,6e4)}},abTest:m?{enabled:e(m.enabled,!1),trafficSplit:t(m.trafficSplit,.5),metricTracking:e(m.metricTracking,!1),experimentId:n(m.experimentId)}:void 0,monitoring:v?{enabled:e(v.enabled,!1),metricsEndpoint:n(v.metricsEndpoint),alertThresholds:w?{errorRate:r(w.errorRate),latency:r(w.latency),cost:r(w.cost)}:void 0}:void 0}}initializeProviders(){var e,t,r,i;if((e=this.config.whisper)!=null&&e.enabled&&this.config.whisper.apiKey)try{let n=new W(this.config.whisper.apiKey,this.logger),s=new re(n,this.logger,this.config.whisper);this.providers.set("whisper",s),this.logger.info("Whisper provider initialized")}catch(n){this.logger.error("Failed to initialize Whisper provider",this.normalizeError(n))}if((t=this.config.deepgram)!=null&&t.enabled&&this.config.deepgram.apiKey)try{let n=Number((r=this.settingsManager)==null?void 0:r.get("requestTimeout"))||3e4,s=this.config.deepgram.timeout||n,a=new oe(this.config.deepgram.apiKey,this.logger,(i=this.config.deepgram.rateLimit)==null?void 0:i.requests,s),o=new le(a,this.logger,this.settingsManager,this.config.deepgram);this.providers.set("deepgram",o),this.logger.info("Deepgram provider initialized")}catch(n){this.logger.error("Failed to initialize Deepgram provider",this.normalizeError(n))}}getProvider(e){if(e&&e!=="auto"){let r=this.providers.get(e);if(r&&r.getConfig().enabled)return r;if(this.config.fallbackEnabled)return this.logger.warn(`Preferred provider ${e} not available, falling back`),this.getFallbackProvider(e);throw new $(e)}if(this.config.autoSelect||e==="auto")return this.selector.select(this.providers,this.config.selectionStrategy||"manual");let t=this.providers.get(this.config.defaultProvider);if(t&&t.getConfig().enabled)return t;for(let[r,i]of this.providers)if(i.getConfig().enabled)return this.logger.warn(`Default provider not available, using ${r}`),i;throw new Error("No transcription provider available")}getFallbackProvider(e){for(let[t,r]of this.providers)if(t!==e&&r.getConfig().enabled)return r;throw new Error("No fallback provider available")}getProviderForABTest(e){var t;return(t=this.config.abTest)!=null&&t.enabled?this.selector.select(this.providers,"ab_test",e):this.getProvider()}getAvailableProviders(){return Array.from(this.providers.entries()).filter(([e,t])=>t.getConfig().enabled).map(([e])=>e)}recordMetrics(e,t,r,i,n){var s;this.metricsTracker.recordRequest(e,t,r,i,n),(s=this.config.monitoring)!=null&&s.enabled&&this.config.monitoring.metricsEndpoint&&this.sendMetricsToEndpoint(e)}getMetrics(e){if(e){let t=this.metricsTracker.getMetrics(e);if(!t)throw new Error(`No metrics found for provider: ${e}`);return t}return this.metricsTracker.getAllMetrics()}sendMetricsToEndpoint(e){let t=this.metricsTracker.getMetrics(e);this.logger.debug("Sending metrics to monitoring endpoint",t)}async updateConfig(e){this.config={...this.config,...e},await this.settingsManager.set("transcription",this.config),this.reinitializeProviders()}reinitializeProviders(){this.providers.clear(),this.initializeProviders(),this.logger.info("Providers reinitialized with new configuration")}async toggleProvider(e,t){var i;let r=(i=e==="whisper"?this.config.whisper:this.config.deepgram)!=null?i:{enabled:!1};r&&(r.enabled=t,await this.updateConfig(this.config))}async setDefaultProvider(e){this.config.defaultProvider=e,await this.updateConfig(this.config)}};var de=class{constructor(e,t){this.transcriber=e;this.logger=t}async transcribe(e,t){var a,o,c,d,u,m,v,p;let r=await this.resolveAudioBuffer(e);(a=this.logger)==null||a.debug("=== TranscriberToWhisperAdapter.transcribe START ===",{audioSize:r.byteLength,provider:this.transcriber.getProviderName(),options:t});let i={language:t==null?void 0:t.language,model:t==null?void 0:t.model,whisper:{temperature:t==null?void 0:t.temperature,prompt:t==null?void 0:t.prompt,responseFormat:t==null?void 0:t.responseFormat}},n=await this.transcriber.transcribe(r,i);(u=this.logger)==null||u.debug("Transcriber response received:",{hasText:!!(n!=null&&n.text),textLength:((o=n==null?void 0:n.text)==null?void 0:o.length)||0,textPreview:(c=n==null?void 0:n.text)==null?void 0:c.substring(0,100),language:n==null?void 0:n.language,segmentsCount:((d=n==null?void 0:n.segments)==null?void 0:d.length)||0});let s={text:n.text||"",language:n.language,duration:n.duration,segments:(m=n.segments)==null?void 0:m.map(w=>({id:w.id,seek:0,start:w.start,end:w.end,text:w.text,tokens:[],temperature:0,avg_logprob:0,compression_ratio:0,no_speech_prob:0}))};return(p=this.logger)==null||p.info("=== TranscriberToWhisperAdapter.transcribe COMPLETE ===",{textLength:((v=s.text)==null?void 0:v.length)||0,language:s.language}),s}async resolveAudioBuffer(e){if(e instanceof ArrayBuffer)return e;if(typeof e.arrayBuffer=="function"){let r=await e.arrayBuffer();if(r instanceof ArrayBuffer)return r}let t=typeof e.size=="number"?e.size:0;return new ArrayBuffer(t)}validateApiKey(e){return this.transcriber.validateApiKey(e)}cancel(){this.transcriber.cancel()}getTranscriber(){return this.transcriber}getProviderName(){return this.transcriber.getProviderName()}};var ge=class{constructor(e,t){this.vault=e;this.logger=t;this.DEFAULT_MAX_FILE_SIZE=25*1024*1024;this.SUPPORTED_FORMATS=[".m4a",".mp3",".wav",".mp4"];this.maxFileSize=this.DEFAULT_MAX_FILE_SIZE}setProviderCapabilities(e){this.maxFileSize=e.maxFileSize,this.logger.debug("AudioProcessor capabilities updated",{previousLimit:this.DEFAULT_MAX_FILE_SIZE/1024/1024,newLimit:e.maxFileSize/1024/1024,provider:e.maxFileSize===2*1024*1024*1024?"Deepgram":"Whisper"})}validate(e){let t=[],r=[],i=`.${e.extension.toLowerCase()}`;if(this.SUPPORTED_FORMATS.includes(i)||t.push(`Unsupported format: ${i}. Supported formats: ${this.SUPPORTED_FORMATS.join(", ")}`),e.stat.size>this.maxFileSize){let n=Math.round(e.stat.size/1024/1024),s=Math.round(this.maxFileSize/1024/1024);t.push(`File size (${n}MB) exceeds maximum allowed size (${s}MB)`)}return e.stat.size>10*1024*1024&&r.push("Large file may take longer to process"),Promise.resolve({valid:t.length===0,errors:t.length>0?t:void 0,warnings:r.length>0?r:void 0})}async process(e){this.logger.debug("Processing audio file",{fileName:e.name,extension:e.extension,sizeBytes:e.stat.size});let t=await this.vault.readBinary(e),r=await this.extractMetadata(t,e);return this.logger.debug("Audio processing completed",{bufferSize:t.byteLength,detectedFormat:r.format}),{buffer:t,metadata:r,originalFile:e,compressed:!1}}extractMetadata(e,t){let r;if(t){let n=t.extension.toLowerCase();r=n,this.logger.debug("Audio format detected from file extension",{fileName:t.name,extension:n,format:r})}let i=Math.round(e.byteLength/1024);return this.logger.debug("Audio file analysis",{sizeKB:i,sizeBytes:e.byteLength,format:r}),Promise.resolve({duration:void 0,bitrate:void 0,sampleRate:void 0,channels:void 0,codec:void 0,format:r,fileSize:e.byteLength})}};var pe=class{constructor(e){this.settings=e}format(e,t){let i=(t==null?void 0:t.cleanupText)!==!1?this.cleanUp(e):e;return this.settings.timestampFormat!=="none"&&(t!=null&&t.includeTimestamps),i}insertTimestamps(e,t){if(!t||t.length===0)return e;let r=[];return t.forEach(i=>{let n=this.formatTimestamp(i.start);switch(this.settings.timestampFormat){case"inline":r.push(`[${n}] ${i.text}`);break;case"sidebar":r.push(`${n} | ${i.text}`);break;default:r.push(i.text)}}),r.join(`
`)}cleanUp(e){var u;let t=e.replace(/\r\n/g,`
`).trim();if(!t)return"";let i=t.replace(/\n{3,}/g,`
`).split(`
`),n=[],s="",a=()=>{let m=s.trim();m&&n.push(m),s=""};for(let m of i){let v=m.trim();if(!v){a();continue}let p=v.replace(/\s+/g," ");s=s?`${s} ${p}`:p,/[.!?]["']?$/.test(p)&&a()}a();let o=n.join(`
`);return n.some(m=>/[!?]/.test(m))&&n.length>1&&/[.!?]["']?$/.test((u=n[n.length-1])!=null?u:"")?`${o}
`:o}formatTimestamp(e){let t=Math.floor(e/3600),r=Math.floor(e%3600/60),i=Math.floor(e%60);return t>0?`${t.toString().padStart(2,"0")}:${r.toString().padStart(2,"0")}:${i.toString().padStart(2,"0")}`:`${r.toString().padStart(2,"0")}:${i.toString().padStart(2,"0")}`}};var Ve={apiKey:"",provider:"auto",selectionStrategy:"performance_optimized",abTestSplit:50,model:"whisper-1",language:"auto",autoInsert:!0,insertPosition:"cursor",timestampFormat:"none",maxFileSize:25*1024*1024,enableCache:!0,cacheTTL:36e5,enableDebugLogging:!1,responseFormat:"json"},We=class{constructor(){this.SALT="obsidian-speech-to-text-v1"}encrypt(e){if(!e)return"";let t=btoa(e),r="";for(let i=0;i<t.length;i++){let n=t.charCodeAt(i),s=this.SALT.charCodeAt(i%this.SALT.length);r+=String.fromCharCode(n^s)}return btoa(r)}decrypt(e){if(!e)return"";try{let t=atob(e),r="";for(let i=0;i<t.length;i++){let n=t.charCodeAt(i),s=this.SALT.charCodeAt(i%this.SALT.length);r+=String.fromCharCode(n^s)}return atob(r)}catch(t){return console.error("Failed to decrypt API key:",t),""}}validateApiKeyFormat(e){return e?/^sk-[A-Za-z0-9]{20,}$/.test(e):!1}mask(e){if(!e||e.length<10)return"***";let t=7,r=4,i="*".repeat(Math.max(0,e.length-t-r));return e.substring(0,t)+i+e.substring(e.length-r)}},me=class{constructor(e,t){this.plugin=e;this.settings={...Ve},this.encryption=new We,this.logger=t}normalizeError(e){return e instanceof Error?e:new Error("Unknown error")}async load(){var e,t;try{let r=await this.plugin.loadData();return r&&(this.settings={...Ve,...r},this.settings.encryptedApiKey&&!this.settings.apiKey&&(this.settings.apiKey=this.encryption.decrypt(this.settings.encryptedApiKey)),this.settings.apiKey&&!this.settings.encryptedApiKey&&await this.encryptAndSaveApiKey(this.settings.apiKey)),(e=this.logger)==null||e.debug("Settings loaded successfully"),this.settings}catch(r){return(t=this.logger)==null||t.error("Failed to load settings",this.normalizeError(r)),this.settings}}async save(e){var t,r;try{if(this.settings=e,e.apiKey){e.encryptedApiKey=this.encryption.encrypt(e.apiKey);let{apiKey:i,...n}=e;await this.plugin.saveData(n)}else await this.plugin.saveData(e);(t=this.logger)==null||t.debug("Settings saved successfully")}catch(i){throw(r=this.logger)==null||r.error("Failed to save settings",this.normalizeError(i)),i}}get(e){return this.settings[e]}async set(e,t){let r=this.settings;r[e]=t,e==="apiKey"&&typeof t=="string"?await this.encryptAndSaveApiKey(t):await this.save(this.settings)}async setApiKey(e){var t;return this.encryption.validateApiKeyFormat(e)?(await this.encryptAndSaveApiKey(e),!0):((t=this.logger)==null||t.warn("Invalid API key format"),!1)}getApiKey(){return this.settings.apiKey||""}getMaskedApiKey(){let e=this.getApiKey();return e?this.encryption.mask(e):"Not configured"}async encryptAndSaveApiKey(e){var i;this.settings.apiKey=e,this.settings.encryptedApiKey=this.encryption.encrypt(e);let{apiKey:t,...r}=this.settings;await this.plugin.saveData(r),(i=this.logger)==null||i.debug("API key encrypted and saved",{masked:this.encryption.mask(e)})}async reset(){var e;this.settings={...Ve},await this.save(this.settings),(e=this.logger)==null||e.info("Settings reset to defaults")}exportSettings(){let{apiKey:e,encryptedApiKey:t,...r}=this.settings;return r}async importSettings(e){var n;let{apiKey:t,encryptedApiKey:r,...i}=e;this.settings={...this.settings,...i},await this.save(this.settings),(n=this.logger)==null||n.info("Settings imported successfully")}validateSettings(){let e=[];return!this.settings.apiKey&&!this.settings.encryptedApiKey&&e.push("API key is not configured"),(this.settings.maxFileSize<=0||this.settings.maxFileSize>25*1024*1024)&&e.push("Invalid max file size (must be between 0 and 25MB)"),this.settings.cacheTTL<0&&e.push("Invalid cache TTL (must be positive)"),this.settings.temperature!==void 0&&(this.settings.temperature<0||this.settings.temperature>1)&&e.push("Invalid temperature (must be between 0 and 1)"),{valid:e.length===0,errors:e}}};var K=class{constructor(e){this.prefix=e}debug(e,t){}info(e,t){console.info(`[${this.prefix}] INFO:`,e,t||"")}warn(e,t){console.warn(`[${this.prefix}] WARN:`,e,t||"")}error(e,t,r){console.error(`[${this.prefix}] ERROR:`,e,t,r||"")}};var ct=require("obsidian"),he=class{constructor(e){this.logger=e}getUserFriendlyMessage(e){let t={ECONNREFUSED:"\uC11C\uBC84\uC5D0 \uC5F0\uACB0\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",ETIMEDOUT:"\uC5F0\uACB0 \uC2DC\uAC04\uC774 \uCD08\uACFC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.",ENOTFOUND:"\uC11C\uBC84\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",EPERM:"\uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",ENOSPC:"\uC800\uC7A5 \uACF5\uAC04\uC774 \uBD80\uC871\uD569\uB2C8\uB2E4."};for(let[r,i]of Object.entries(t))if(e.message.includes(r))return i;return this.getUserMessage(e)}getSolution(e){var r;return(r={INVALID_API_KEY:"\uC124\uC815\uC5D0\uC11C \uC62C\uBC14\uB978 API \uD0A4\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694.",NETWORK_ERROR:"\uB124\uD2B8\uC6CC\uD06C \uC5F0\uACB0\uC744 \uD655\uC778\uD55C \uB4A4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.",TIMEOUT:"\uC7A0\uC2DC \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uAC70\uB098 \uD0C0\uC784\uC544\uC6C3 \uAC12\uC744 \uB298\uB824\uC8FC\uC138\uC694.",FILE_TOO_LARGE:"\uD30C\uC77C \uD06C\uAE30\uB97C \uC904\uC774\uAC70\uB098 \uB2E4\uB978 \uD30C\uC77C\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694.",UNSUPPORTED_FORMAT:"\uC9C0\uC6D0\uB418\uB294 \uC624\uB514\uC624 \uD615\uC2DD\uC744 \uC0AC\uC6A9\uD574\uC8FC\uC138\uC694."}[e])!=null?r:"\uBB38\uC81C\uB97C \uD655\uC778\uD558\uACE0 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694."}handle(e,t){let r=e instanceof Error?e:new Error(String(e));this.logger.error(r.message,r,t);let i=this.getUserFriendlyMessage(r);new ct.Notice(i,5e3)}getUserMessage(e){return e.message.includes("API key")?"Invalid API key. Please check your settings.":e.message.includes("network")||e.message.includes("fetch")?"Network error. Please check your connection.":e.message.includes("size")?"File is too large. Maximum size is 25MB.":e.message.includes("format")?"Unsupported file format. Please use M4A, MP3, WAV, or MP4.":`An error occurred: ${e.message}`}};var fe=class{constructor(){this.state={status:"idle",currentFile:null,progress:0,error:null,history:[]};this.listeners=new Set}getState(){return Object.freeze({...this.state})}setState(e){let t={...this.state};this.state={...this.state,...e},this.notifyListeners(t)}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}reset(){this.setState({status:"idle",currentFile:null,progress:0,error:null})}notifyListeners(e){this.listeners.forEach(t=>{t(this.state,e)})}};var ve=class{constructor(){this.events=new Map;this.onceEvents=new Map}on(e,t){var i;let r=(i=this.events.get(e))!=null?i:new Set;return r.add(t),this.events.set(e,r),()=>this.off(e,t)}once(e,t){var i;let r=(i=this.onceEvents.get(e))!=null?i:new Set;return r.add(t),this.onceEvents.set(e,r),()=>this.off(e,t)}off(e,t){var r,i;(r=this.events.get(e))==null||r.delete(t),(i=this.onceEvents.get(e))==null||i.delete(t)}emit(e,t){var i;(i=this.events.get(e))==null||i.forEach(n=>{try{n(t)}catch(s){console.error(`Error in event listener for ${String(e)}:`,s)}});let r=this.onceEvents.get(e);r&&(r.forEach(n=>{try{n(t)}catch(s){console.error(`Error in once listener for ${String(e)}:`,s)}}),this.onceEvents.delete(e))}async emitAsync(e,t){var n;let r=[];(n=this.events.get(e))==null||n.forEach(s=>{r.push(Promise.resolve(s(t)).catch(a=>{console.error(`Error in async event listener for ${String(e)}:`,a)}))});let i=this.onceEvents.get(e);i&&(i.forEach(s=>{r.push(Promise.resolve(s(t)).catch(a=>{console.error(`Error in async once listener for ${String(e)}:`,a)}))}),this.onceEvents.delete(e)),await Promise.all(r)}removeAllListeners(e){e?(this.events.delete(e),this.onceEvents.delete(e)):(this.events.clear(),this.onceEvents.clear())}listenerCount(e){var i,n;let t=((i=this.events.get(e))==null?void 0:i.size)||0,r=((n=this.onceEvents.get(e))==null?void 0:n.size)||0;return t+r}eventNames(){let e=new Set([...this.events.keys(),...this.onceEvents.keys()]);return Array.from(e)}};var U=class U{static getInstance(...e){let t=this.name;if(!U.instances.has(t)){let r=new this(...e);U.instances.set(t,r)}return U.instances.get(t)}static hasInstance(e){return U.instances.has(e)}static clearInstance(e){U.instances.delete(e)}static clearAllInstances(){U.instances.clear()}};U.instances=new Map;var lt=U;function ut(l){let e;return class extends l{constructor(...t){if(e)return e;super(...t),e=this}}}var L=class extends ve{constructor(t){super();this.eventStats=new Map;this.eventHistory=[];this.maxHistorySize=100;this.isDebugMode=!1;this.logger=t}static getInstance(t){return L.instance||(L.instance=new L(t)),L.instance}emit(t,r){this.updateStats(t),this.recordHistory(t,r),this.isDebugMode&&this.logger&&this.logger.debug(`Event emitted: ${String(t)}`,r),super.emit(t,r)}async emitAsync(t,r){this.updateStats(t),this.recordHistory(t,r),this.isDebugMode&&this.logger&&this.logger.debug(`Async event emitted: ${String(t)}`,r),await super.emitAsync(t,r)}on(t,r){return this.isDebugMode&&this.logger&&this.logger.debug(`Listener registered for: ${String(t)}`),super.on(t,r)}once(t,r){return this.isDebugMode&&this.logger&&this.logger.debug(`Once listener registered for: ${String(t)}`),super.once(t,r)}chain(t,r,i){return this.on(t,n=>{let s=i?i(n):n;this.emit(r,s)})}filter(t,r,i){return this.on(t,n=>{r(n)&&i(n)})}debounce(t,r,i){let n=null;return this.on(t,s=>{n!==null&&clearTimeout(n),n=setTimeout(()=>{i(s),n=null},r)})}throttle(t,r,i){let n=!1;return this.on(t,s=>{n||(i(s),n=!0,setTimeout(()=>{n=!1},r))})}updateStats(t){let r=this.eventStats.get(t)||0;this.eventStats.set(t,r+1)}recordHistory(t,r){let i={event:String(t),data:this.isDebugMode?r:void 0,timestamp:Date.now()};this.eventHistory.push(i),this.eventHistory.length>this.maxHistorySize&&this.eventHistory.shift()}getStats(){return new Map(this.eventStats)}getHistory(){return[...this.eventHistory]}getEventStats(t){return this.eventStats.get(t)||0}clearStats(){this.eventStats.clear()}clearHistory(){this.eventHistory=[]}setDebugMode(t){this.isDebugMode=t,this.logger&&this.logger.info(`Event manager debug mode: ${t?"enabled":"disabled"}`)}getStatus(){let t=this.eventNames();return{totalEvents:t.length,totalListeners:t.reduce((r,i)=>r+this.listenerCount(i),0),totalEmitted:Array.from(this.eventStats.values()).reduce((r,i)=>r+i,0),debugMode:this.isDebugMode,historySize:this.eventHistory.length}}destroy(){this.removeAllListeners(),this.clearStats(),this.clearHistory(),this.logger&&this.logger.debug("EventManager destroyed")}};L=Xe([ut],L);var be=require("obsidian");var ye=class{constructor(e,t=L.getInstance(),r){this.app=e;this.eventManager=t;this.activeEditor=null;this.activeView=null;this.undoHistory=[];this.redoHistory=[];this.maxHistorySize=50;this.destroyed=!1;this.eventRefs=[];this.logger=r||new K("EditorService"),this.setupEventListeners()}normalizeError(e){return e instanceof Error?e:new Error("Unknown error")}isEditor(e){return!e||typeof e!="object"?!1:typeof Reflect.get(e,"getCursor")=="function"&&typeof Reflect.get(e,"replaceRange")=="function"&&typeof Reflect.get(e,"setValue")=="function"}setupEventListeners(){let e=this.app.workspace;if(!e||typeof e.on!="function"){this.logger.warn("Workspace event API not available");return}let t=()=>{this.destroyed||this.updateActiveEditor()};e.on("active-leaf-change",t),this.eventRefs.push({event:"active-leaf-change",callback:t});let r=(...i)=>{let[n]=i;this.isEditor(n)&&(this.destroyed||(this.activeEditor=n,this.eventManager.emit("editor:changed",{editor:n})))};e.on("editor-change",r),this.eventRefs.push({event:"editor-change",callback:r})}updateActiveEditor(){var t;if(this.destroyed)return;let e=this.app.workspace.getActiveViewOfType(be.MarkdownView);e?(this.activeView=e,this.activeEditor=e.editor,this.logger.debug("Active editor updated",{file:(t=e.file)==null?void 0:t.path}),this.eventManager.emit("editor:active",{view:e,editor:this.activeEditor})):(this.activeView=null,this.activeEditor=null,this.logger.debug("No active markdown view"))}getActiveEditor(){return this.destroyed?null:(this.activeEditor||this.updateActiveEditor(),this.activeEditor)}getActiveView(){return this.destroyed?null:(this.activeView||this.updateActiveEditor(),this.activeView)}hasActiveEditor(){return this.getActiveEditor()!==null}getCursorPosition(){let e=this.getActiveEditor();return e?e.getCursor():null}getSelection(){let e=this.getActiveEditor();return e?e.getSelection():""}getSelectionRange(){let e=this.getActiveEditor();if(!e)return null;let t=e.getCursor("from"),r=e.getCursor("to");return{from:t,to:r}}async insertAtCursor(e,t=!0){let r=this.getActiveEditor();if(!r)return this.logger.warn("No active editor for text insertion"),!1;await Promise.resolve();try{let i=r.getCursor();t&&this.recordAction({type:"insert",position:i,text:e,timestamp:Date.now()}),r.replaceRange(e,i);let n={line:i.line,ch:i.ch+e.length};return r.setCursor(n),this.logger.debug("Text inserted at cursor",{position:i,textLength:e.length}),this.eventManager.emit("editor:text-inserted",{text:e,position:i}),!0}catch(i){return this.logger.error("Failed to insert text at cursor",this.normalizeError(i)),!1}}async replaceSelection(e,t=!0){let r=this.getActiveEditor();if(!r)return this.logger.warn("No active editor for text replacement"),!1;await Promise.resolve();try{let i=r.getSelection(),n=this.getSelectionRange();return t&&n&&this.recordAction({type:"replace",range:n,oldText:i,newText:e,timestamp:Date.now()}),r.replaceSelection(e),this.logger.debug("Selection replaced",{oldLength:i.length,newLength:e.length}),this.eventManager.emit("editor:text-replaced",{oldText:i,newText:e}),!0}catch(i){return this.logger.error("Failed to replace selection",this.normalizeError(i)),!1}}async insertText(e,t){var i;let r=(i=t==null?void 0:t.position)!=null?i:"cursor";return r==="beginning"?this.prependToDocument(e):r==="end"?this.appendToDocument(e):this.replaceSelection(e)}async insertAtPosition(e,t,r=!0){let i=this.getActiveEditor();if(!i)return this.logger.warn("No active editor for text insertion"),!1;await Promise.resolve();try{return r&&this.recordAction({type:"insert",position:t,text:e,timestamp:Date.now()}),i.replaceRange(e,t),this.logger.debug("Text inserted at position",{position:t,textLength:e.length}),!0}catch(n){return this.logger.error("Failed to insert text at position",this.normalizeError(n)),!1}}async appendToLine(e,t){let r=this.getActiveEditor();if(!r)return!1;try{let i=r.getLine(e);if(i===void 0)return this.logger.warn("Invalid line number",{lineNumber:e}),!1;let n={line:e,ch:i.length};return await this.insertAtPosition(t,n)}catch(i){return this.logger.error("Failed to append to line",this.normalizeError(i)),!1}}async appendToDocument(e,t=!0){let r=this.getActiveEditor();if(!r)return!1;try{let i=r.lastLine(),n=r.getLine(i),s={line:i,ch:n.length},a=t?`
${e}`:e;return await this.insertAtPosition(a,s)}catch(i){return this.logger.error("Failed to append to document",this.normalizeError(i)),!1}}async prependToDocument(e,t=!0){if(!this.getActiveEditor())return!1;try{let i={line:0,ch:0},n=t?`${e}
`:e;return await this.insertAtPosition(n,i)}catch(i){return this.logger.error("Failed to prepend to document",this.normalizeError(i)),!1}}getCurrentLine(){let e=this.getActiveEditor();if(!e)return null;let t=e.getCursor();return e.getLine(t.line)}getCurrentLineNumber(){let e=this.getCursorPosition();return e?e.line:null}getDocumentContent(){let e=this.getActiveEditor();return e?e.getValue():null}async setDocumentContent(e){let t=this.getActiveEditor();if(!t)return!1;await Promise.resolve();try{let r=t.getValue();return this.recordAction({type:"set-content",oldText:r,newText:e,timestamp:Date.now()}),t.setValue(e),this.logger.debug("Document content updated"),!0}catch(r){return this.logger.error("Failed to set document content",this.normalizeError(r)),!1}}recordAction(e){this.undoHistory.push(e),this.undoHistory.length>this.maxHistorySize&&this.undoHistory.shift(),this.redoHistory.length=0}async undo(){if(this.undoHistory.length===0)return this.logger.debug("No actions to undo"),!1;await Promise.resolve();let e=this.getActiveEditor();if(!e)return!1;let t=this.undoHistory.pop();if(!t)return!1;this.redoHistory.push(t);try{switch(t.type){case"insert":if(t.position&&t.text){let r=t.position,i={line:r.line,ch:r.ch+t.text.length};e.replaceRange("",r,i)}break;case"replace":t.range&&t.oldText!==void 0&&e.replaceRange(t.oldText,t.range.from,t.range.to);break;case"set-content":t.oldText!==void 0&&e.setValue(t.oldText);break}return this.logger.debug("Undo executed",{actionType:t.type}),!0}catch(r){return this.logger.error("Failed to execute undo",this.normalizeError(r)),!1}}async redo(){if(this.redoHistory.length===0)return this.logger.debug("No actions to redo"),!1;await Promise.resolve();let e=this.getActiveEditor();if(!e)return!1;let t=this.redoHistory.pop();if(!t)return!1;this.undoHistory.push(t);try{switch(t.type){case"insert":t.position&&t.text&&e.replaceRange(t.text,t.position);break;case"replace":t.range&&t.newText!==void 0&&e.replaceRange(t.newText,t.range.from,t.range.to);break;case"set-content":t.newText!==void 0&&e.setValue(t.newText);break}return this.logger.debug("Redo executed",{actionType:t.type}),!0}catch(r){return this.logger.error("Failed to execute redo",this.normalizeError(r)),!1}}clearHistory(){this.undoHistory.length=0,this.redoHistory.length=0,this.logger.debug("Editor history cleared")}async createAndOpenNote(e,t,r=""){try{let i=r?`${r}/${e}`:e,n=await this.app.vault.create(i,t);return await this.app.workspace.openLinkText(n.path,"",!0),this.logger.debug("New note created and opened",{path:i}),this.eventManager.emit("editor:note-created",{file:n,content:t}),!0}catch(i){return this.logger.error("Failed to create and open note",this.normalizeError(i)),new be.Notice("Failed to create new note"),!1}}setCursorPosition(e){let t=this.getActiveEditor();if(!t)return!1;try{return t.setCursor(e),!0}catch(r){return this.logger.error("Failed to set cursor position",this.normalizeError(r)),!1}}selectRange(e,t){let r=this.getActiveEditor();if(!r)return!1;try{return r.setSelection(e,t),!0}catch(i){return this.logger.error("Failed to select range",this.normalizeError(i)),!1}}focus(){let e=this.getActiveEditor();if(!e)return!1;try{return e.focus(),!0}catch(t){return this.logger.error("Failed to focus editor",this.normalizeError(t)),!1}}destroy(){this.destroyed=!0;for(let e of this.eventRefs)typeof this.app.workspace.off=="function"&&this.app.workspace.off(e.event,e.callback);this.eventRefs.length=0,this.clearHistory(),this.activeEditor=null,this.activeView=null,this.logger.debug("EditorService destroyed")}};var Ee=require("obsidian");var Te=class{constructor(e,t,r){this.editorService=e;this.eventManager=t;this.previewMode=!1;this.lastInsertedText="";this.insertionHistory=[];this.maxHistorySize=20;this.logger=r||new K("TextInsertionHandler"),this.setupEventListeners()}normalizeError(e){return e instanceof Error?e:new Error("Unknown error")}setupEventListeners(){this.eventManager.on("transcription:complete",async e=>{e.autoInsert&&await this.handleTranscriptionComplete(e.text,e.options)})}async handleTranscriptionComplete(e,t){let r={mode:"cursor",format:"plain",addTimestamp:!1,...t};await this.insertText(e,r)}async insertText(e,t){try{if(!this.editorService.hasActiveEditor())return t.createNewNote?await this.createNewNoteWithText(e,t):(new Ee.Notice("No active editor. Please open a note first."),!1);let r=await this.formatText(e,t);if(this.previewMode||t.preview)return await this.showPreview(r,t);let i=await this.executeInsertion(r,t);return i&&(this.recordInsertion({text:r,originalText:e,options:t,timestamp:Date.now()}),this.eventManager.emit("text:inserted",{text:r,options:t}),this.logger.debug("Text inserted successfully",{mode:t.mode,textLength:r.length})),i}catch(r){return this.logger.error("Failed to insert text",this.normalizeError(r)),new Ee.Notice("Failed to insert text. Please try again."),!1}}async formatText(e,t){await Promise.resolve();let r=e;switch(r=this.cleanupText(r),t.format){case"markdown":r=this.applyMarkdownFormat(r,t);break;case"quote":r=this.applyQuoteFormat(r,t);break;case"bullet":r=this.applyBulletFormat(r,t);break;case"heading":r=this.applyHeadingFormat(r,t);break;case"code":r=this.applyCodeFormat(r,t);break;case"callout":r=this.applyCalloutFormat(r,t);break}return t.addTimestamp&&(r=this.addTimestamp(r,t.timestampFormat)),t.template&&(r=this.applyTemplate(r,t.template)),t.language&&(r=this.processLanguageSpecific(r,t.language)),r}cleanupText(e){return e.trim().replace(/\r\n/g,`
`).replace(/\n{3,}/g,`
`).replace(/^\s+|\s+$/gm,"")}applyMarkdownFormat(e,t){let r=e;return t.paragraphBreaks&&(r=r.split(/\n+/).filter(i=>i.trim()).join(`
`)),r}applyQuoteFormat(e,t){let i=e.split(`
`).map(n=>`> ${n}`).join(`
`);return t.quoteAuthor?`${i}
>
> \u2014 ${t.quoteAuthor}`:i}applyBulletFormat(e,t){let r=e.split(`
`).filter(n=>n.trim()),i=t.bulletChar||"-";return r.map(n=>`${i} ${n}`).join(`
`)}applyHeadingFormat(e,t){let r=t.headingLevel||2,i="#".repeat(r),n=e.split(`
`);return n.length>0&&(n[0]=`${i} ${n[0]}`),n.join(`
`)}applyCodeFormat(e,t){return`\`\`\`${t.codeLanguage||""}
${e}
\`\`\``}applyCalloutFormat(e,t){let r=t.calloutType||"info",i=t.calloutTitle||"",n=t.calloutFoldable?"+":"";return`> [!${r}]${n} ${i}
> ${e.replace(/\n/g,`
> `)}`}addTimestamp(e,t){let r=new Date;return`[${t?this.formatDate(r,t):r.toISOString()}]
${e}`}formatDate(e,t){let r={YYYY:e.getFullYear().toString(),MM:(e.getMonth()+1).toString().padStart(2,"0"),DD:e.getDate().toString().padStart(2,"0"),HH:e.getHours().toString().padStart(2,"0"),mm:e.getMinutes().toString().padStart(2,"0"),ss:e.getSeconds().toString().padStart(2,"0")},i=t;for(let[n,s]of Object.entries(r))i=i.replace(new RegExp(n,"g"),s);return i}applyTemplate(e,t){return t.replace("{{content}}",e).replace("{{date}}",new Date().toLocaleDateString()).replace("{{time}}",new Date().toLocaleTimeString()).replace("{{datetime}}",new Date().toLocaleString())}processLanguageSpecific(e,t){switch(t){case"ko":return this.processKoreanText(e);case"ja":return this.processJapaneseText(e);case"zh":return this.processChineseText(e);default:return e}}processKoreanText(e){return e.replace(/\s+([.,!?])/g,"$1").replace(/([.,!?])\s*/g,"$1 ").trim()}processJapaneseText(e){return e}processChineseText(e){return e}async executeInsertion(e,t){switch(t.mode){case"cursor":return await this.editorService.insertAtCursor(e);case"replace":return await this.editorService.replaceSelection(e);case"append":return await this.editorService.appendToDocument(e,!0);case"prepend":return await this.editorService.prependToDocument(e,!0);case"line-end":{let r=this.editorService.getCurrentLineNumber();return r!==null?await this.editorService.appendToLine(r,e):!1}case"new-line":{let r=this.editorService.getCursorPosition();return r?await this.editorService.insertAtPosition(`
${e}`,r):!1}default:return await this.editorService.insertAtCursor(e)}}async showPreview(e,t){return await Promise.resolve(),new Ee.Notice(`Preview:
${e.substring(0,100)}...`),this.eventManager.emit("text:preview",{text:e,options:t}),!0}async createNewNoteWithText(e,t){let r=new Date().toISOString().replace(/[:.]/g,"-"),i=t.noteTitle||`Transcription-${r}.md`,n=t.noteFolder||"",s=await this.formatText(e,t);return await this.editorService.createAndOpenNote(i,s,n)}recordInsertion(e){this.insertionHistory.push(e),this.insertionHistory.length>this.maxHistorySize&&this.insertionHistory.shift(),this.lastInsertedText=e.text}getLastInsertedText(){return this.lastInsertedText}getInsertionHistory(){return[...this.insertionHistory]}setPreviewMode(e){this.previewMode=e,this.logger.debug("Preview mode changed",{enabled:e})}isPreviewMode(){return this.previewMode}clearHistory(){this.insertionHistory=[],this.lastInsertedText="",this.logger.debug("Insertion history cleared")}destroy(){this.clearHistory(),this.logger.debug("TextInsertionHandler destroyed")}};var A=require("obsidian"),Se=class extends A.Modal{constructor(t,r,i,n){super(t);this.previewContainer=null;this.templates=[];this.onConfirm=i,this.onCancel=n,this.options={mode:"cursor",format:"plain",addTimestamp:!1,timestampFormat:"YYYY-MM-DD HH:mm:ss",...r},this.loadDefaultTemplates()}onOpen(){let{contentEl:t}=this;t.empty(),t.addClass("format-options-modal"),t.createEl("h2",{text:"Text formatting options"});let r=t.createDiv("format-tabs"),i=["Basic","Format","Advanced","Templates"],n=[];i.forEach((s,a)=>{let o=r.createEl("button",{text:s,cls:"format-tab"}),c=t.createDiv({cls:"format-tab-content"});a===0?(o.addClass("active"),c.addClass("active")):c.addClass("sn-hidden"),n.push(c),o.onclick=()=>{r.querySelectorAll(".format-tab").forEach(d=>{d.removeClass("active")}),n.forEach(d=>{d.removeClass("active"),d.addClass("sn-hidden")}),o.addClass("active"),c.addClass("active"),c.removeClass("sn-hidden")}}),this.createBasicTab(n[0]),this.createFormatTab(n[1]),this.createAdvancedTab(n[2]),this.createTemplatesTab(n[3]),this.createPreviewSection(t),this.createButtonSection(t)}createBasicTab(t){new A.Setting(t).setName("Insertion mode").setDesc("Where to insert the text").addDropdown(r=>{r.addOption("cursor","At cursor").addOption("replace","Replace selection").addOption("append","End of document").addOption("prepend","Beginning of document").addOption("line-end","End of current line").addOption("new-line","New line below").setValue(this.options.mode).onChange(i=>{this.isInsertionMode(i)&&(this.options.mode=i,this.updatePreview())})}),new A.Setting(t).setName("Text format").setDesc("How to format the inserted text").addDropdown(r=>{r.addOption("plain","Plain text").addOption("markdown","Markdown").addOption("quote","Quote block").addOption("bullet","Bullet list").addOption("heading","Heading").addOption("code","Code block").addOption("callout","Callout block").setValue(this.options.format).onChange(i=>{this.isTextFormat(i)&&(this.options.format=i,this.updateFormatSpecificOptions(),this.updatePreview())})}),new A.Setting(t).setName("Add timestamp").setDesc("Add timestamp before the text").addToggle(r=>{r.setValue(this.options.addTimestamp||!1).onChange(i=>{this.options.addTimestamp=i,this.updatePreview()})}),this.options.addTimestamp&&new A.Setting(t).setName("Timestamp format").setDesc("Format for the timestamp (YYYY-MM-DD HH:mm:ss)").addText(r=>{r.setPlaceholder("YYYY-MM-DD HH:mm:ss").setValue(this.options.timestampFormat||"").onChange(i=>{this.options.timestampFormat=i,this.updatePreview()})})}createFormatTab(t){let r=t.createDiv("format-specific-options");this.updateFormatSpecificOptions(r)}updateFormatSpecificOptions(t){let r=t||document.querySelector(".format-specific-options");if(r instanceof HTMLElement)switch(r.empty(),this.options.format){case"quote":new A.Setting(r).setName("Quote author").setDesc("Author attribution for the quote").addText(i=>{i.setPlaceholder("Author name").setValue(this.options.quoteAuthor||"").onChange(n=>{this.options.quoteAuthor=n,this.updatePreview()})});break;case"bullet":new A.Setting(r).setName("Bullet character").setDesc("Character to use for bullets").addDropdown(i=>{i.addOption("-","- (Dash)").addOption("*","* (Asterisk)").addOption("+","+ (Plus)").addOption("\u2022","\u2022 (Bullet)").setValue(this.options.bulletChar||"-").onChange(n=>{this.options.bulletChar=n,this.updatePreview()})});break;case"heading":new A.Setting(r).setName("Heading level").setDesc("Level of the heading (1-6)").addDropdown(i=>{for(let n=1;n<=6;n++)i.addOption(String(n),`H${n}`);i.setValue(String(this.options.headingLevel||2)).onChange(n=>{this.options.headingLevel=parseInt(n),this.updatePreview()})});break;case"code":new A.Setting(r).setName("Language").setDesc("Programming language for syntax highlighting").addText(i=>{i.setPlaceholder("javascript, python, etc.").setValue(this.options.codeLanguage||"").onChange(n=>{this.options.codeLanguage=n,this.updatePreview()})});break;case"callout":new A.Setting(r).setName("Callout type").setDesc("Type of callout block").addDropdown(i=>{i.addOption("info","Info").addOption("tip","Tip").addOption("warning","Warning").addOption("danger","Danger").addOption("note","Note").addOption("abstract","Abstract").addOption("success","Success").addOption("question","Question").addOption("failure","Failure").addOption("example","Example").addOption("quote","Quote").setValue(this.options.calloutType||"info").onChange(n=>{this.options.calloutType=n,this.updatePreview()})}),new A.Setting(r).setName("Callout title").setDesc("Title for the callout").addText(i=>{i.setPlaceholder("Title").setValue(this.options.calloutTitle||"").onChange(n=>{this.options.calloutTitle=n,this.updatePreview()})}),new A.Setting(r).setName("Foldable").setDesc("Make callout foldable").addToggle(i=>{i.setValue(this.options.calloutFoldable||!1).onChange(n=>{this.options.calloutFoldable=n,this.updatePreview()})});break}}createAdvancedTab(t){new A.Setting(t).setName("Language").setDesc("Language for special processing").addDropdown(r=>{r.addOption("","Auto detect").addOption("en","English").addOption("ko","Korean").addOption("ja","Japanese").addOption("zh","Chinese").addOption("es","Spanish").addOption("fr","French").addOption("de","German").setValue(this.options.language||"").onChange(i=>{this.options.language=i,this.updatePreview()})}),new A.Setting(t).setName("Paragraph breaks").setDesc("Add paragraph breaks between sentences").addToggle(r=>{r.setValue(this.options.paragraphBreaks||!1).onChange(i=>{this.options.paragraphBreaks=i,this.updatePreview()})}),new A.Setting(t).setName("Create new note").setDesc("Create a new note for the text").addToggle(r=>{r.setValue(this.options.createNewNote||!1).onChange(i=>{this.options.createNewNote=i,this.updateNewNoteOptions()})}),this.options.createNewNote&&(new A.Setting(t).setName("Note title").setDesc("Title for the new note").addText(r=>{r.setPlaceholder("Transcription-YYYY-MM-DD").setValue(this.options.noteTitle||"").onChange(i=>{this.options.noteTitle=i})}),new A.Setting(t).setName("Note folder").setDesc("Folder for the new note").addText(r=>{r.setPlaceholder("Transcriptions").setValue(this.options.noteFolder||"").onChange(i=>{this.options.noteFolder=i})})),new A.Setting(t).setName("Preview before insert").setDesc("Show preview before inserting text").addToggle(r=>{r.setValue(this.options.preview||!1).onChange(i=>{this.options.preview=i})})}createTemplatesTab(t){let r=new A.Setting(t).setName("Template").setDesc("Select a template to apply"),i=new A.DropdownComponent(r.controlEl);i.addOption("","None"),this.templates.forEach(o=>{i.addOption(o.id,o.name)}),i.onChange(o=>{let c=this.templates.find(d=>d.id===o);c?(this.options.template=c.content,this.updatePreview()):(this.options.template=void 0,this.updatePreview())}),new A.Setting(t).setName("Custom template").setDesc("Use {{content}} for the text placeholder").addTextArea(o=>{o.setPlaceholder(`## {{date}}
{{content}}
---
Transcribed at {{time}}`).setValue(this.options.template||"").onChange(c=>{this.options.template=c,this.updatePreview()}),o.inputEl.rows=5,o.inputEl.cols=50});let n=t.createDiv("template-help");n.createEl("h4",{text:"Available variables:"});let s=n.createEl("ul");[{var:"{{content}}",desc:"The transcribed text"},{var:"{{date}}",desc:"Current date"},{var:"{{time}}",desc:"Current time"},{var:"{{datetime}}",desc:"Current date and time"}].forEach(o=>{let c=s.createEl("li");c.createEl("code",{text:o.var}),c.createSpan({text:` - ${o.desc}`})})}createPreviewSection(t){let r=t.createDiv("preview-section");r.createEl("h3",{text:"Preview"}),this.previewContainer=r.createDiv("preview-content"),this.previewContainer.createEl("p",{text:"Preview will appear here...",cls:"preview-placeholder"})}createButtonSection(t){let r=t.createDiv("button-container"),i=r.createEl("button",{text:"Reset to defaults",cls:"mod-cta-secondary"});i.onclick=()=>{this.resetToDefaults()};let n=r.createEl("button",{text:"Cancel"});n.onclick=()=>{this.onCancel(),this.close()};let s=r.createEl("button",{text:"Apply",cls:"mod-cta"});s.onclick=()=>{this.onConfirm(this.options),this.close()}}updatePreview(){if(!this.previewContainer)return;let r=this.simulateFormatting("This is a sample transcribed text to show how the formatting will be applied.");this.previewContainer.empty(),this.previewContainer.createEl("pre",{text:r,cls:"format-preview"})}simulateFormatting(t){let r=t;switch(this.options.format){case"quote":{r=`> ${r}`,this.options.quoteAuthor&&(r+=`
>
> \u2014 ${this.options.quoteAuthor}`);break}case"bullet":{r=`${this.options.bulletChar||"-"} ${r}`;break}case"heading":{let i=this.options.headingLevel||2;r=`${"#".repeat(i)} ${r}`;break}case"code":{r=`\`\`\`${this.options.codeLanguage||""}
${r}
\`\`\``;break}case"callout":{let i=this.options.calloutType||"info",n=this.options.calloutTitle||"",s=this.options.calloutFoldable?"+":"";r=`> [!${i}]${s} ${n}
> ${r}`;break}}return this.options.addTimestamp&&(r=`[${this.formatCurrentDate(this.options.timestampFormat||"YYYY-MM-DD HH:mm:ss")}]
${r}`),this.options.template&&(r=this.options.template.replace("{{content}}",r).replace("{{date}}",new Date().toLocaleDateString()).replace("{{time}}",new Date().toLocaleTimeString()).replace("{{datetime}}",new Date().toLocaleString())),r}formatCurrentDate(t){let r=new Date,i={YYYY:r.getFullYear().toString(),MM:(r.getMonth()+1).toString().padStart(2,"0"),DD:r.getDate().toString().padStart(2,"0"),HH:r.getHours().toString().padStart(2,"0"),mm:r.getMinutes().toString().padStart(2,"0"),ss:r.getSeconds().toString().padStart(2,"0")},n=t;for(let[s,a]of Object.entries(i))n=n.replace(new RegExp(s,"g"),a);return n}updateNewNoteOptions(){let t=document.querySelectorAll(".format-tab-content")[2];t instanceof HTMLElement&&this.createAdvancedTab(t)}isInsertionMode(t){return t==="cursor"||t==="replace"||t==="append"||t==="prepend"||t==="line-end"||t==="new-line"}isTextFormat(t){return t==="plain"||t==="markdown"||t==="quote"||t==="bullet"||t==="heading"||t==="code"||t==="callout"}resetToDefaults(){this.options={mode:"cursor",format:"plain",addTimestamp:!1,timestampFormat:"YYYY-MM-DD HH:mm:ss"},this.onOpen()}loadDefaultTemplates(){this.templates=[{id:"meeting",name:"Meeting notes",format:"markdown",content:`## Meeting Notes - {{date}}
### Attendees
-
### Agenda
-
### Discussion
{{content}}
### Action Items
-
---
*Transcribed at {{datetime}}*`},{id:"daily",name:"Daily note",format:"markdown",content:`## {{date}}
### Transcription
{{content}}
### Thoughts
### Tasks
- [ ]
---
*Created at {{time}}*`},{id:"interview",name:"Interview",format:"markdown",content:`# Interview Notes
**Date:** {{date}}
**Time:** {{time}}
## Transcript
{{content}}
## Key Points
-
## Follow-up Questions
-
---`},{id:"lecture",name:"Lecture notes",format:"markdown",content:`# Lecture Notes
**Date:** {{date}}
**Topic:**
## Main Content
{{content}}
## Key Concepts
1.
2.
3.
## Questions
-
## References
-
---
*Transcribed at {{datetime}}*`}]}onClose(){let{contentEl:t}=this;t.empty()}};var T=require("obsidian");var P=require("obsidian");var _="[Deepgram]",z={DEBUG:"debug",INFO:"info",WARN:"warn",ERROR:"error"},g={CLASSES:{API_KEY_INPUT:"deepgram-api-key-input",MODEL_INFO:"deepgram-model-info",MODEL_DESCRIPTION:"model-description",MODEL_METRICS:"model-metrics",SUPPORTED_LANGUAGES:"supported-languages",FEATURES_CONTAINER:"deepgram-features",ADVANCED_CONTAINER:"deepgram-advanced",COST_ESTIMATION:"deepgram-cost-estimation",COST_DETAILS:"cost-details",WARNING:"mod-warning",ERROR_DETAILS:"error-details",SETTING_DESCRIPTION:"setting-item-description"},MESSAGES:{HEADER:"Deepgram configuration",DESCRIPTION:"Configure Deepgram for advanced speech recognition with multiple language support and AI features.",REGISTRY_WARNING:"\u26A0\uFE0F Model registry not available. Using default configuration.",API_KEY_LABEL:"Deepgram API key",API_KEY_DESC:"Enter your Deepgram API key for transcription",API_KEY_PLACEHOLDER:"Enter API key...",API_KEY_SAVED:"Deepgram API key saved",API_KEY_REQUIRED:"Please enter your Deepgram API key first",MODEL_LABEL:"Deepgram model",MODEL_DESC:"Select the Deepgram model for transcription",MODEL_PLACEHOLDER:"Select a model...",FEATURES_HEADER:"Features",ADVANCED_HEADER:"Advanced settings",COST_HEADER:"Cost estimation",VALIDATION_LABEL:"Validate configuration",VALIDATION_DESC:"Test your Deepgram API key and settings",VALIDATION_BUTTON:"Validate",VALIDATING:"Validating...",VALIDATION_SUCCESS:"\u2705 Deepgram configuration is valid",VALIDATION_ERROR:"\u274C Invalid Deepgram API key or configuration",FALLBACK_ERROR_TITLE:"\u26A0\uFE0F Deepgram settings error",FALLBACK_ERROR_DESC:"Unable to load full configuration. Basic settings are available below.",CRITICAL_ERROR:"Deepgram settings could not be loaded. Please check the console for errors."},STYLES:{WARNING_BOX:"deepgram-warning-box",INFO_CONTAINER:"deepgram-info-container",METRICS_ROW:"deepgram-metrics-row",LANGUAGES_ROW:"deepgram-languages-row",COST_CONTAINER:"deepgram-cost-container",ERROR_CONTAINER:"deepgram-error-container",ERROR_DETAILS:"deepgram-error-details",DESCRIPTION_MARGIN:"deepgram-description"}},H={ENDPOINTS:{VALIDATION:"https://api.deepgram.com/v1/projects"},HEADERS:{AUTHORIZATION_PREFIX:"Token",CONTENT_TYPE:"application/json"},METHODS:{GET:"GET",POST:"POST"},MASK:{VISIBLE_START:8,VISIBLE_END:4,CHAR:"*"},TIMEOUT:{MIN:5e3,MAX:12e4}},F={TIMEOUT:{MIN:5e3,MAX:12e4,DEFAULT:3e4},RETRIES:{MIN:0,MAX:3,DEFAULT:3},COST_ESTIMATION:{DAILY_MINUTES:10,DAYS_PER_MONTH:30},VALIDATION_RESET_DELAY:3e3},dt=[{value:"auto",label:"Auto-detect"},{value:"en",label:"English"},{value:"es",label:"Spanish"},{value:"fr",label:"French"},{value:"de",label:"German"},{value:"pt",label:"Portuguese"},{value:"nl",label:"Dutch"},{value:"it",label:"Italian"},{value:"pl",label:"Polish"},{value:"ru",label:"Russian"},{value:"zh",label:"Chinese"},{value:"ja",label:"Japanese"},{value:"ko",label:"Korean"},{value:"ar",label:"Arabic"},{value:"hi",label:"Hindi"}],gt=[{id:"nova-3",name:"Nova 3",tier:"Premium",price:.0043},{id:"nova-2",name:"Nova 2",tier:"Premium",price:.0059},{id:"nova",name:"Nova",tier:"Standard",price:.0025},{id:"enhanced",name:"Enhanced",tier:"Standard",price:.0145},{id:"base",name:"Base",tier:"Economy",price:.0125}],pt=[{key:"punctuation",name:"Punctuation",description:"Add punctuation to transcript",default:!0},{key:"smartFormat",name:"Smart format",description:"Format numbers, dates, etc.",default:!0},{key:"diarization",name:"Speaker diarization",description:"Identify different speakers",default:!0},{key:"numerals",name:"Numerals",description:"Convert numbers to digits",default:!1}];var N=class l{constructor(){this.enabled=!0;this.minLevel=z.INFO}static getInstance(){return l.instance||(l.instance=new l),l.instance}setEnabled(e){this.enabled=e}setMinLevel(e){this.minLevel=e}debug(e,...t){this.shouldLog(z.DEBUG)&&(`${_}${e}`,[...t])}info(e,...t){this.shouldLog(z.INFO)&&console.info(`${_} ${e}`,...t)}warn(e,...t){this.shouldLog(z.WARN)&&console.warn(`${_} ${e}`,...t)}error(e,t){this.shouldLog(z.ERROR)&&(console.error(`${_} ${e}`),t&&(t instanceof Error?console.error(`${_} Error details:`,{message:t.message,stack:t.stack}):console.error(`${_} Error details:`,t)))}group(e){this.enabled&&console.group(`${_} ${e}`)}groupEnd(){this.enabled&&console.groupEnd()}shouldLog(e){if(!this.enabled)return!1;let t=[z.DEBUG,z.INFO,z.WARN,z.ERROR],r=t.indexOf(e),i=t.indexOf(this.minLevel);return r>=i}time(e){this.enabled&&console.time(`${_} ${e}`)}timeEnd(e){this.enabled&&console.timeEnd(`${_} ${e}`)}};var mt={models:{"nova-3":{id:"nova-3",name:"Nova-3",description:"Next-generation model with state-of-the-art accuracy and enhanced diarization",tier:"premium",features:{punctuation:!0,smartFormat:!0,diarization:!0,numerals:!0,profanityFilter:!0,redaction:!0,utterances:!0,summarization:!0,advancedDiarization:!0,emotionDetection:!0,speakerIdentification:!0},languages:["en","es","fr","de","pt","nl","it","pl","ru","zh","ja","ko","ar","hi","tr","sv","da","no","fi","cs","hu","bg"],performance:{accuracy:98,speed:"fast",latency:"low"},pricing:{perMinute:.0043,currency:"USD"},isDefault:!0,migrationPath:{from:["nova-2","nova"],autoMigrate:!0,backwardCompatible:!0}},"nova-2":{id:"nova-2",name:"Nova-2",description:"Latest and most powerful model with best accuracy",tier:"premium",features:{punctuation:!0,smartFormat:!0,diarization:!0,numerals:!0,profanityFilter:!0,redaction:!0,utterances:!0,summarization:!0},languages:["en","es","fr","de","pt","nl","it","pl","ru","zh","ja","ko","ar","hi","tr","sv","da","no","fi"],performance:{accuracy:95,speed:"fast",latency:"low"},pricing:{perMinute:.0145,currency:"USD"}},nova:{id:"nova",name:"Nova",description:"High-quality model with excellent accuracy",tier:"standard",features:{punctuation:!0,smartFormat:!0,diarization:!0,numerals:!0,profanityFilter:!0,redaction:!1,utterances:!0,summarization:!1},languages:["en","es","fr","de","pt","nl","it","pl","ru","zh","ja","ko"],performance:{accuracy:90,speed:"fast",latency:"low"},pricing:{perMinute:.0125,currency:"USD"}},enhanced:{id:"enhanced",name:"Enhanced",description:"Balanced model for general use",tier:"basic",features:{punctuation:!0,smartFormat:!0,diarization:!1,numerals:!0,profanityFilter:!0,redaction:!1,utterances:!1,summarization:!1},languages:["en","es","fr","de","pt"],performance:{accuracy:85,speed:"moderate",latency:"medium"},pricing:{perMinute:.0085,currency:"USD"}},base:{id:"base",name:"Base",description:"Basic model for simple transcription",tier:"economy",features:{punctuation:!0,smartFormat:!1,diarization:!1,numerals:!1,profanityFilter:!1,redaction:!1,utterances:!1,summarization:!1},languages:["en"],performance:{accuracy:80,speed:"moderate",latency:"medium"},pricing:{perMinute:.0059,currency:"USD"}}},features:{punctuation:{name:"Punctuation",description:"Add punctuation marks to transcript",default:!0},smartFormat:{name:"Smart Format",description:"Apply intelligent formatting (numbers, dates, etc.)",default:!0},diarization:{name:"Speaker Diarization",description:"Identify different speakers in audio",default:!0,requiresPremium:!0},numerals:{name:"Numerals",description:"Convert number words to digits",default:!0},profanityFilter:{name:"Profanity Filter",description:"Filter profane words",default:!1},redaction:{name:"Redaction",description:"Redact sensitive information (SSN, credit cards)",default:!1,requiresPremium:!0},utterances:{name:"Utterances",description:"Split transcript by natural speech boundaries",default:!1},summarization:{name:"Summarization",description:"Generate summary of transcript",default:!1,requiresPremium:!0}}};var we={models:{"nova-3":{id:"nova-3",name:"Nova 3",description:"Latest premium model with higher accuracy and improved diarization",tier:"premium",features:{punctuation:!0,smartFormat:!0,diarization:!0,numerals:!0,profanityFilter:!0,redaction:!0,utterances:!0,summarization:!0},languages:["en","es","fr","de","pt","nl","it","pl","ru","zh","ja","ko","ar","hi"],performance:{accuracy:98,speed:"fast",latency:"low"},pricing:{perMinute:.0043,currency:"USD"}},"nova-2":{id:"nova-2",name:"Nova 2",description:"Most accurate and powerful model with advanced features",tier:"premium",features:{punctuation:!0,smartFormat:!0,diarization:!0,numerals:!0,profanityFilter:!0,redaction:!0,utterances:!0,summarization:!0},languages:["en","es","fr","de","pt","nl","it","pl","ru","zh","ja","ko","ar","hi"],performance:{accuracy:95,speed:"fast",latency:"low"},pricing:{perMinute:.0043,currency:"USD"}},nova:{id:"nova",name:"Nova",description:"Balanced model with good accuracy and speed",tier:"standard",features:{punctuation:!0,smartFormat:!0,diarization:!0,numerals:!0,profanityFilter:!0,redaction:!1,utterances:!0,summarization:!1},languages:["en","es","fr","de","pt","nl","it"],performance:{accuracy:90,speed:"fast",latency:"low"},pricing:{perMinute:.0025,currency:"USD"}},enhanced:{id:"enhanced",name:"Enhanced",description:"Enhanced accuracy for challenging audio",tier:"standard",features:{punctuation:!0,smartFormat:!0,diarization:!1,numerals:!0,profanityFilter:!1,redaction:!1,utterances:!1,summarization:!1},languages:["en"],performance:{accuracy:85,speed:"moderate",latency:"medium"},pricing:{perMinute:.0145,currency:"USD"}},base:{id:"base",name:"Base",description:"Cost-effective option for simple transcription",tier:"economy",features:{punctuation:!0,smartFormat:!1,diarization:!1,numerals:!1,profanityFilter:!1,redaction:!1,utterances:!1,summarization:!1},languages:["en"],performance:{accuracy:80,speed:"moderate",latency:"medium"},pricing:{perMinute:.0125,currency:"USD"}}},features:{punctuation:{name:"Punctuation",description:"Add punctuation marks to transcript",default:!0,requiresPremium:!1},smartFormat:{name:"Smart format",description:"Format numbers, dates, and other entities",default:!0,requiresPremium:!1},diarization:{name:"Speaker diarization",description:"Identify different speakers",default:!1,requiresPremium:!1},numerals:{name:"Numerals",description:"Convert numbers to digits",default:!1,requiresPremium:!1},profanityFilter:{name:"Profanity filter",description:"Filter out profanity from transcript",default:!1,requiresPremium:!1},redaction:{name:"Redaction",description:"Redact sensitive information",default:!1,requiresPremium:!0},utterances:{name:"Utterances",description:"Split transcript into utterances",default:!1,requiresPremium:!1},summarization:{name:"Summarization",description:"Generate summary of transcript",default:!1,requiresPremium:!0}}},ht,wt=(ht=mt)!=null?ht:we,Ae=class l{constructor(){this.models=new Map,this.features=new Map,this.logger=N.getInstance();try{this.loadConfiguration(),this.logger.info("Constructor completed successfully")}catch(e){this.logger.error("Error during initialization",e)}}static getInstance(){try{return l.instance||(l.instance=new l),l.instance}catch(e){if(!l.instance){let t=Object.create(l.prototype);t.models=new Map,t.features=new Map,t.logger=N.getInstance(),t.logger.error("Failed to create instance, using fallback",e),l.instance=t}return l.instance}}loadConfiguration(){try{let e=wt||we;this.loadModels(e),this.loadFeatures(e),this.models.size===0&&this.features.size===0&&(this.logger.warn("No data loaded, loading fallback configuration"),this.loadFallbackConfiguration())}catch(e){this.logger.error("Error loading configuration",e),this.loadFallbackConfiguration()}}loadModels(e){if(!e.models||typeof e.models!="object"){this.logger.warn("No models in configuration");return}Object.entries(e.models).forEach(([t,r])=>{try{this.isValidModel(r)?this.models.set(t,r):this.logger.warn(`Invalid model structure for ${t}`)}catch(i){this.logger.error(`Failed to load model ${t}`,i)}}),this.logger.info(`Loaded ${this.models.size} models`)}loadFeatures(e){if(!e.features||typeof e.features!="object"){this.logger.warn("No features in configuration");return}Object.entries(e.features).forEach(([t,r])=>{try{this.isValidFeature(r)?this.features.set(t,r):this.logger.warn(`Invalid feature structure for ${t}`)}catch(i){this.logger.error(`Failed to load feature ${t}`,i)}}),this.logger.info(`Loaded ${this.features.size} features`)}loadFallbackConfiguration(){try{Object.entries(we.models).forEach(([e,t])=>{this.models.set(e,t)}),Object.entries(we.features).forEach(([e,t])=>{this.features.set(e,t)}),this.logger.info("Fallback configuration loaded")}catch(e){this.logger.error("Failed to load fallback configuration",e)}}isValidModel(e){if(!e||typeof e!="object")return!1;let t=e;return typeof t.id=="string"&&typeof t.name=="string"&&t.features!==void 0&&Array.isArray(t.languages)&&typeof t.performance=="object"&&typeof t.pricing=="object"}isValidFeature(e){if(!e||typeof e!="object")return!1;let t=e;return typeof t.name=="string"&&typeof t.description=="string"&&typeof t.default=="boolean"}getAllModels(){try{return Array.from(this.models.values())}catch(e){return this.logger.error("Error getting all models",e),[]}}getModel(e){return this.models.get(e)}getAllFeatures(){try{return this.features}catch(e){return this.logger.error("Error getting all features",e),new Map}}getFeature(e){return this.features.get(e)}isLanguageSupported(e,t){let r=this.models.get(e);return r?r.languages.includes(t):!1}isFeatureSupported(e,t){let r=this.models.get(e);return r?r.features[t]===!0:!1}getModelsByLanguage(e){return Array.from(this.models.values()).filter(t=>t.languages.includes(e))}getModelsByTier(e){return Array.from(this.models.values()).filter(t=>t.tier===e)}getModelsByPriceRange(e){return Array.from(this.models.values()).filter(t=>t.pricing.perMinute<=e)}calculateCost(e,t){let r=this.models.get(e);return r?r.pricing.perMinute*t:0}getPerformanceScore(e){let t=this.models.get(e);if(!t)return 0;let r=t.performance.accuracy;return t.performance.speed==="fast"?r+=5:t.performance.speed==="moderate"&&(r+=2),t.performance.latency==="high"?r-=5:t.performance.latency==="medium"&&(r-=2),Math.min(100,Math.max(0,r))}getRecommendedModel(e){let t=Array.from(this.models.values()),{language:r,maxPrice:i,minAccuracy:n,requiredFeatures:s}=e;return r&&(t=t.filter(a=>a.languages.includes(r))),i!==void 0&&(t=t.filter(a=>a.pricing.perMinute<=i)),n!==void 0&&(t=t.filter(a=>a.performance.accuracy>=n)),s&&s.length>0&&(t=t.filter(a=>s.every(o=>a.features[o]===!0))),t.length>0?(t.sort((a,o)=>this.getPerformanceScore(o.id)-this.getPerformanceScore(a.id)),t[0]):null}validateModel(e){let t=[],r=this.models.get(e);return r?(r.id||t.push("Model ID is missing"),r.name||t.push("Model name is missing"),r.tier||t.push("Model tier is missing"),(!r.languages||r.languages.length===0)&&t.push("Model must support at least one language"),r.pricing.perMinute<0&&t.push("Model pricing cannot be negative"),(r.performance.accuracy<0||r.performance.accuracy>100)&&t.push("Model accuracy must be between 0 and 100"),{valid:t.length===0,errors:t}):(t.push(`Model '${e}' not found`),{valid:!1,errors:t})}};var Ie=class{constructor(e){this.containerEl=e}createHeader(e){return this.containerEl.createEl("h4",{text:e})}createDescription(e){let t=this.containerEl.createEl("p",{text:e,cls:g.CLASSES.SETTING_DESCRIPTION});return t.addClass(g.STYLES.DESCRIPTION_MARGIN),t}createWarning(e){let t=this.containerEl.createEl("div",{cls:g.CLASSES.WARNING,text:e});return t.addClass(g.STYLES.WARNING_BOX),t}createModelInfoCard(e){this.removeElement(`.${g.CLASSES.MODEL_INFO}`);let t=this.containerEl.createEl("div",{cls:g.CLASSES.MODEL_INFO});return t.addClass(g.STYLES.INFO_CONTAINER),t.createEl("p",{text:e.description,cls:g.CLASSES.MODEL_DESCRIPTION}),this.createMetricsRow(t,e),this.createLanguagesRow(t,e),t}createMetricsRow(e,t){let r=e.createEl("div",{cls:g.CLASSES.MODEL_METRICS});r.addClass(g.STYLES.METRICS_ROW),r.createEl("span",{text:`Accuracy: ${t.performance.accuracy}%`}),r.createEl("span",{text:`Speed: ${t.performance.speed}`}),r.createEl("span",{text:`Latency: ${t.performance.latency}`})}createLanguagesRow(e,t){let r=e.createEl("div",{cls:g.CLASSES.SUPPORTED_LANGUAGES});r.addClass(g.STYLES.LANGUAGES_ROW),r.createEl("span",{text:`Supported languages: ${t.languages.join(", ")}`})}createCostEstimationContainer(){let e=this.containerEl.createEl("div",{cls:g.CLASSES.COST_ESTIMATION});return e.addClass(g.STYLES.COST_CONTAINER),e.createEl("h5",{text:g.MESSAGES.COST_HEADER}),e}updateCostDetails(e,t,r){let i=e.querySelector(`.${g.CLASSES.COST_DETAILS}`)||e.createEl("div",{cls:g.CLASSES.COST_DETAILS});if(i.empty(),!t){i.createEl("p",{text:"Select a model to see cost estimation",cls:g.CLASSES.WARNING});return}let n=i.createEl("div");if(n.createEl("p",{text:`Cost per minute: $${t.pricing.perMinute}`}),r!==void 0){let s=F.COST_ESTIMATION.DAILY_MINUTES;n.createEl("p",{text:`Estimated monthly cost (${s} min/day): $${r.toFixed(2)}`})}}addBudgetWarning(e,t,r){if(t>r){let i=e.querySelector(".budget-warning")||e.createEl("p",{cls:"budget-warning"});i.textContent=`\u26A0\uFE0F Exceeds monthly budget of $${r}`,i.classList.add(g.CLASSES.WARNING)}}createErrorContainer(e){let t=this.containerEl.createEl("div",{cls:g.CLASSES.WARNING});if(t.addClass(g.STYLES.ERROR_CONTAINER),t.createEl("h5",{text:g.MESSAGES.FALLBACK_ERROR_TITLE}),t.createEl("p",{text:g.MESSAGES.FALLBACK_ERROR_DESC}),e instanceof Error){let r=t.createEl("details");r.createEl("summary",{text:"Error details"}),r.createEl("pre",{text:e.message,cls:g.CLASSES.ERROR_DETAILS}).addClass(g.STYLES.ERROR_DETAILS)}return t}createSection(e,t){let r=this.containerEl.createEl("div",{cls:e});return t&&r.createEl("h5",{text:t}),r}removeElement(e){let t=this.containerEl.querySelector(e);t&&t.remove()}clearContainer(){this.containerEl.empty()}};var ft=require("obsidian");var xe=class{constructor(){this.logger=N.getInstance()}async validateApiKey(e){if(!e)return this.logger.warn("API key validation failed: No key provided"),!1;try{this.logger.info("Validating API key via Obsidian requestUrl...");let t=H.METHODS.GET,r={url:H.ENDPOINTS.VALIDATION,method:t,headers:{Authorization:`${H.HEADERS.AUTHORIZATION_PREFIX} ${e}`,"Content-Type":H.HEADERS.CONTENT_TYPE},throw:!1},i=await(0,ft.requestUrl)(r),n=i.status===200;return n?this.logger.info("API key validation successful"):this.logger.warn(`API key validation failed with status: ${i.status}`),n}catch(t){return this.logger.error("API validation error (requestUrl)",t),!1}}maskApiKey(e){if(!e||e.length<10)return"";let{VISIBLE_START:t,VISIBLE_END:r,CHAR:i}=H.MASK;if(e.length<=t+r)return e;let n=i.repeat(e.length-t-r);return e.substring(0,t)+n+e.substring(e.length-r)}validateTimeout(e){let t=parseInt(e)*1e3,{MIN:r,MAX:i}=H.TIMEOUT;return isNaN(t)||t<r||t>i?(this.logger.warn(`Invalid timeout value: ${e}`),null):t}validateRetries(e){let t=parseInt(e),{MIN:r,MAX:i}=F.RETRIES;return isNaN(t)||t<r||t>i?(this.logger.warn(`Invalid retries value: ${e}`),null):t}};var Pe=class{constructor(){this.logger=N.getInstance()}calculateEstimation(e,t){if(!e)return this.logger.debug("No model selected for cost calculation"),null;let{DAILY_MINUTES:r,DAYS_PER_MONTH:i}=F.COST_ESTIMATION,n=e.pricing.perMinute,s=n*r,a=s*i,o=t?a>t:!1;return this.logger.debug(`Cost calculated for ${e.name}:`,{perMinute:n,daily:s,monthly:a,exceeedsBudget:o}),{perMinute:n,daily:s,monthly:a,exceeedsBudget:o}}calculateCostByUsage(e,t){let r=e.pricing.perMinute*t;return this.logger.debug(`Usage cost calculated: ${t} minutes = $${r}`),r}calculateAvailableMinutes(e,t){let r=t/e.pricing.perMinute;return this.logger.debug(`Available minutes for budget $${t}: ${r.toFixed(2)}`),r}compareModelCosts(e,t){let r=new Map;return e.forEach(i=>{let n=this.calculateCostByUsage(i,t);r.set(i.id,n)}),r}calculateEfficiencyScore(e,t){if(e.pricing.perMinute>t)return 0;let r=1-e.pricing.perMinute/t,n=(e.performance.accuracy/100*.7+r*.3)*100;return this.logger.debug(`Efficiency score for ${e.name}: ${n.toFixed(2)}`),Math.round(n)}};var Ce=class{constructor(e,t){this.registry=null;this.selectedModel=null;this.estimatedCostEl=null;this.plugin=e,this.containerEl=t,this.logger=N.getInstance(),this.uiBuilder=new Ie(t),this.validator=new xe,this.costCalculator=new Pe,this.initializeRegistry()}initializeRegistry(){try{this.logger.info("Attempting to initialize DeepgramModelRegistry..."),this.registry=Ae.getInstance();let e=this.registry.getAllModels();this.logger.info(`Registry initialized successfully with ${e.length} models`),e.length===0&&(this.logger.warn("Registry has no models, will use fallback"),this.registry=null)}catch(e){this.logger.error("Failed to initialize registry",e),this.registry=null,this.logger.info("Will continue with fallback UI")}}render(){this.logger.group("render()"),this.logRenderState();try{this.uiBuilder.clearContainer(),this.renderHeader(),this.renderSections(),this.logger.info(`Total elements created: ${this.containerEl.children.length}`),this.logger.groupEnd()}catch(e){this.logger.error("Critical error in render()",e),this.renderFallbackUI(e)}}logRenderState(){this.logger.debug("Container element:",this.containerEl),this.logger.debug("Container is connected:",this.containerEl.isConnected),this.logger.debug("Registry available:",!!this.registry),this.logger.debug("API key exists:",!!this.plugin.settings.deepgramApiKey),this.containerEl.isConnected||this.logger.warn("Container is not connected to DOM, attempting to render anyway"),this.registry||this.logger.warn("Registry not available, using fallback UI")}renderHeader(){this.uiBuilder.createHeader(g.MESSAGES.HEADER),this.uiBuilder.createDescription(g.MESSAGES.DESCRIPTION),this.registry||this.uiBuilder.createWarning(g.MESSAGES.REGISTRY_WARNING)}renderSections(){this.logger.info("Rendering API key section..."),this.renderApiKeySection(),this.logger.info("Rendering model selection..."),this.renderModelSelection(),this.logger.info("Rendering feature toggles..."),this.renderFeatureToggles(),this.logger.info("Rendering advanced settings..."),this.renderAdvancedSettings(),this.logger.info("Rendering cost estimation..."),this.renderCostEstimation(),this.logger.info("Rendering validation button..."),this.renderValidationButton()}renderApiKeySection(){new P.Setting(this.containerEl).setName(g.MESSAGES.API_KEY_LABEL).setDesc(g.MESSAGES.API_KEY_DESC).addText(e=>{this.setupApiKeyInput(e)})}setupApiKeyInput(e){let t=this.plugin.settings.deepgramApiKey||"";e.setPlaceholder(g.MESSAGES.API_KEY_PLACEHOLDER).setValue(this.validator.maskApiKey(t)).onChange(async r=>{await this.handleApiKeyChange(r,e)}),e.inputEl.type="password",e.inputEl.addClass(g.CLASSES.API_KEY_INPUT),this.attachApiKeyEventListeners(e)}async handleApiKeyChange(e,t){e&&!e.includes("*")&&(this.plugin.settings.deepgramApiKey=e,await this.plugin.saveSettings(),t.setValue(this.validator.maskApiKey(e)),new P.Notice(g.MESSAGES.API_KEY_SAVED),this.updateUIState())}attachApiKeyEventListeners(e){e.inputEl.addEventListener("focus",()=>{this.plugin.settings.deepgramApiKey&&e.setValue(this.plugin.settings.deepgramApiKey)}),e.inputEl.addEventListener("blur",()=>{this.plugin.settings.deepgramApiKey&&e.setValue(this.validator.maskApiKey(this.plugin.settings.deepgramApiKey))})}renderModelSelection(){let e=new P.Setting(this.containerEl).setName(g.MESSAGES.MODEL_LABEL).setDesc(g.MESSAGES.MODEL_DESC),t=e.addDropdown(r=>(this.populateModelDropdown(r),this.setupModelDropdownHandlers(r),r));this.disableIfNoApiKey(e)}populateModelDropdown(e){if(e.addOption("",g.MESSAGES.MODEL_PLACEHOLDER),!this.registry){this.logger.warn("Registry not available, using default models"),this.addDefaultModelOptions(e);return}try{let t=this.registry.getAllModels();t.length===0?(this.logger.warn("No models in registry, using defaults"),this.addDefaultModelOptions(e)):(this.addModelOptions(e,t),this.logger.info(`Added ${t.length} models to dropdown`))}catch(t){this.logger.error("Error loading models",t),this.addDefaultModelOptions(e)}}addModelOptions(e,t){t.forEach(r=>{let i=this.formatModelOption(r);e.addOption(r.id,i)})}formatModelOption(e){return`${e.name} (${e.tier}) - $${e.pricing.perMinute}/min`}setupModelDropdownHandlers(e){var r,i;let t=((i=(r=this.plugin.settings.transcription)==null?void 0:r.deepgram)==null?void 0:i.model)||"";e.setValue(t),e.onChange(async n=>{await this.handleModelChange(n)})}async handleModelChange(e){var t;if(!e){this.selectedModel=null;return}this.selectedModel=((t=this.registry)==null?void 0:t.getModel(e))||null,await this.saveModelSelection(e),this.updateUIAfterModelChange(),this.selectedModel&&new P.Notice(`Selected model: ${this.selectedModel.name}`)}async saveModelSelection(e){this.plugin.settings.transcription||(this.plugin.settings.transcription={}),this.plugin.settings.transcription.deepgram?this.plugin.settings.transcription.deepgram.model=e:this.plugin.settings.transcription.deepgram={enabled:!0,model:e},await this.plugin.saveSettings()}updateUIAfterModelChange(){this.updateModelInfo(),this.updateFeatureAvailability(),this.updateCostEstimation()}disableIfNoApiKey(e){if(!this.plugin.settings.deepgramApiKey){let t=e.settingEl.querySelector("select");t instanceof HTMLSelectElement&&(t.disabled=!0),e.setDesc(g.MESSAGES.API_KEY_REQUIRED)}}updateModelInfo(){this.selectedModel&&this.uiBuilder.createModelInfoCard(this.selectedModel)}renderFeatureToggles(){let e=this.uiBuilder.createSection(g.CLASSES.FEATURES_CONTAINER,g.MESSAGES.FEATURES_HEADER);if(!this.registry){this.renderDefaultFeatures(e);return}this.registry.getAllFeatures().forEach((r,i)=>{this.renderFeatureToggle(e,r,i)})}renderFeatureToggle(e,t,r){let i=new P.Setting(e).setName(t.name).setDesc(this.getFeatureDescription(t));i.addToggle(n=>{let s=this.getFeatureValue(r,t.default);return n.setValue(s).onChange(async a=>{await this.saveFeatureSetting(r,a),this.updateCostEstimation()}),this.updateFeatureAvailabilityForToggle(n,i,t,r),n})}getFeatureDescription(e){return e.requiresPremium?`${e.description} (Premium feature)`:e.description}getFeatureValue(e,t){var i,n,s;let r=(n=(i=this.plugin.settings.transcription)==null?void 0:i.deepgram)==null?void 0:n.features;return(s=r==null?void 0:r[e])!=null?s:t}async saveFeatureSetting(e,t){var n,s;this.ensureTranscriptionSettings();let r=(n=this.plugin.settings.transcription)==null?void 0:n.deepgram;if(!r)return;let i=(s=r.features)!=null?s:{};r.features=i,i[e]=t,await this.plugin.saveSettings()}ensureTranscriptionSettings(){this.plugin.settings.transcription||(this.plugin.settings.transcription={}),this.plugin.settings.transcription.deepgram||(this.plugin.settings.transcription.deepgram={enabled:!0})}updateFeatureAvailabilityForToggle(e,t,r,i){this.selectedModel&&this.registry&&!this.registry.isFeatureSupported(this.selectedModel.id,i)&&(e.setDisabled(!0),t.setDesc(`${r.description} (Not supported by selected model)`))}renderAdvancedSettings(){let e=this.uiBuilder.createSection(g.CLASSES.ADVANCED_CONTAINER,g.MESSAGES.ADVANCED_HEADER);this.renderLanguagePreference(e),this.renderTimeoutSetting(e),this.renderRetrySetting(e),this.renderChunkingSettings(e)}renderLanguagePreference(e){new P.Setting(e).setName("Preferred Language").setDesc("Set preferred language for better accuracy").addDropdown(t=>{dt.forEach(r=>{t.addOption(r.value,r.label)}),t.setValue(this.plugin.settings.language||"auto"),t.onChange(async r=>{this.plugin.settings.language=r,await this.plugin.saveSettings()})})}renderTimeoutSetting(e){new P.Setting(e).setName("Request Timeout").setDesc("Maximum time to wait for transcription (in seconds)").addText(t=>{let r=this.plugin.settings.requestTimeout||F.TIMEOUT.DEFAULT;t.setPlaceholder("30").setValue(String(r/1e3)).onChange(async i=>{let n=this.validator.validateTimeout(i);n!==null&&(this.plugin.settings.requestTimeout=n,await this.plugin.saveSettings())})})}renderRetrySetting(e){new P.Setting(e).setName("Max Retries").setDesc("Number of retry attempts on failure").addDropdown(t=>{for(let i=0;i<=F.RETRIES.MAX;i++){let n=i===0?"No retries":`${i} ${i===1?"retry":"retries"}`;t.addOption(String(i),n)}let r=this.plugin.settings.maxRetries||F.RETRIES.DEFAULT;t.setValue(String(r)),t.onChange(async i=>{this.plugin.settings.maxRetries=parseInt(i),await this.plugin.saveSettings()})})}renderChunkingSettings(e){new P.Setting(e).setName("Automatic File Chunking").setDesc("Automatically split large audio files (>50MB) into smaller chunks for reliable processing").addToggle(s=>{var a;s.setValue((a=this.plugin.settings.autoChunking)!=null?a:!0).onChange(async o=>{this.plugin.settings.autoChunking=o,await this.plugin.saveSettings();let c=e.querySelector(".chunk-size-setting");c instanceof HTMLElement&&c.classList.toggle("sn-hidden",!o)})});let t=new P.Setting(e).setName("Maximum chunk size").setDesc("Maximum size per chunk in MB (recommended: 50MB)").addSlider(s=>{var a;s.setLimits(10,100,10).setValue((a=this.plugin.settings.maxChunkSizeMB)!=null?a:50).setDynamicTooltip().onChange(async o=>{this.plugin.settings.maxChunkSizeMB=o,await this.plugin.saveSettings()})});t.settingEl.addClass("chunk-size-setting"),this.plugin.settings.autoChunking||t.settingEl.addClass("sn-hidden");let r=e.createDiv();r.addClass("setting-item-description"),r.addClass("deepgram-note"),r.createEl("strong",{text:"Note on large files:"});let i=r.createEl("ul");["Files larger than 50MB may experience timeout errors","Auto-chunking splits files into manageable pieces","Each chunk is processed separately and results are merged"].forEach(s=>{i.createEl("li",{text:s})}),r.createEl("p",{text:"For best results with very large files (>100MB), consider:"});let n=r.createEl("ul");["Using the 'enhanced' model for faster processing","Reducing audio bitrate to 64-128 kbps","Converting to efficient formats (MP3, OGG)"].forEach(s=>{n.createEl("li",{text:s})})}renderCostEstimation(){let e=this.uiBuilder.createCostEstimationContainer();this.estimatedCostEl=e.createEl("div",{cls:g.CLASSES.COST_DETAILS}),this.updateCostEstimation()}updateCostEstimation(){if(!this.estimatedCostEl)return;let e=this.costCalculator.calculateEstimation(this.selectedModel,this.plugin.settings.monthlyBudget);if(!e){this.uiBuilder.updateCostDetails(this.estimatedCostEl.parentElement,null);return}this.uiBuilder.updateCostDetails(this.estimatedCostEl.parentElement,this.selectedModel,e.monthly),e.exceeedsBudget&&this.plugin.settings.monthlyBudget&&this.uiBuilder.addBudgetWarning(this.estimatedCostEl.parentElement,e.monthly,this.plugin.settings.monthlyBudget)}renderValidationButton(){new P.Setting(this.containerEl).setName(g.MESSAGES.VALIDATION_LABEL).setDesc(g.MESSAGES.VALIDATION_DESC).addButton(e=>{this.setupValidationButton(e)})}setupValidationButton(e){e.setButtonText(g.MESSAGES.VALIDATION_BUTTON).setCta().onClick(async()=>{await this.handleValidation(e)})}async handleValidation(e){e.setDisabled(!0),e.setButtonText(g.MESSAGES.VALIDATING);try{if(await this.validator.validateApiKey(this.plugin.settings.deepgramApiKey||""))this.handleValidationSuccess(e);else throw new Error("Invalid API key")}catch(t){this.handleValidationError(e,t)}}handleValidationSuccess(e){new P.Notice(g.MESSAGES.VALIDATION_SUCCESS),e.setButtonText("Valid \u2713"),e.removeCta(),setTimeout(()=>{e.setButtonText(g.MESSAGES.VALIDATION_BUTTON),e.setCta(),e.setDisabled(!1)},F.VALIDATION_RESET_DELAY)}handleValidationError(e,t){this.logger.error("Validation error",t),new P.Notice(g.MESSAGES.VALIDATION_ERROR),e.setButtonText(g.MESSAGES.VALIDATION_BUTTON),e.setWarning(),e.setDisabled(!1)}updateUIState(){let e=!!this.plugin.settings.deepgramApiKey,t=this.containerEl.querySelector("select");t instanceof HTMLSelectElement&&(t.disabled=!e),this.containerEl.querySelectorAll(".checkbox-container input").forEach(i=>{i instanceof HTMLInputElement&&(i.disabled=!e||!this.selectedModel)})}renderDefaultFeatures(e){pt.forEach(t=>{new P.Setting(e).setName(t.name).setDesc(t.description).addToggle(r=>{let i=this.getFeatureValue(t.key,t.default);r.setValue(i).onChange(async n=>{await this.saveFeatureSetting(t.key,n)})})})}updateFeatureAvailability(){if(!this.selectedModel||!this.registry)return;this.registry.getAllFeatures().forEach((t,r)=>{this.updateFeatureToggleState(r)})}updateFeatureToggleState(e){let t=this.containerEl.querySelector(`[data-feature="${e}"]`);if(!(t instanceof HTMLInputElement)||!this.selectedModel||!this.registry)return;let r=this.registry.isFeatureSupported(this.selectedModel.id,e);t.disabled=!r,!r&&t.checked&&(t.checked=!1,t.dispatchEvent(new Event("change")))}addDefaultModelOptions(e){gt.forEach(t=>{let r=`${t.name} (${t.tier}) - $${t.price}/min`;e.addOption(t.id,r)}),this.logger.info("Added default model options")}renderFallbackUI(e){this.logger.info("Rendering fallback UI due to error");try{this.uiBuilder.clearContainer(),this.uiBuilder.createErrorContainer(e),this.renderMinimalSettings(),this.logger.info("Fallback UI rendered successfully")}catch(t){this.logger.error("Failed to render fallback UI",t),this.renderCriticalError()}}renderMinimalSettings(){new P.Setting(this.containerEl).setName(g.MESSAGES.API_KEY_LABEL).setDesc(g.MESSAGES.API_KEY_DESC).addText(e=>{e.setPlaceholder(g.MESSAGES.API_KEY_PLACEHOLDER).setValue(this.plugin.settings.deepgramApiKey||"").onChange(async t=>{this.plugin.settings.deepgramApiKey=t,await this.plugin.saveSettings(),new P.Notice(g.MESSAGES.API_KEY_SAVED)}),e.inputEl.type="password"}),new P.Setting(this.containerEl).setName(g.MESSAGES.MODEL_LABEL).setDesc(g.MESSAGES.MODEL_DESC).addDropdown(e=>{var r,i;e.addOption("",g.MESSAGES.MODEL_PLACEHOLDER),this.addDefaultModelOptions(e);let t=((i=(r=this.plugin.settings.transcription)==null?void 0:r.deepgram)==null?void 0:i.model)||"";e.setValue(t),e.onChange(async n=>{await this.saveModelSelection(n)})})}renderCriticalError(){this.uiBuilder.clearContainer(),this.containerEl.createEl("p",{text:g.MESSAGES.CRITICAL_ERROR,cls:g.CLASSES.WARNING})}};V();var De=class extends T.PluginSettingTab{constructor(e,t){super(e,t),this.plugin=t}display(){var s,a,o,c,d,u,m,v,p,w,E,x,R,B;let{containerEl:e}=this;if(!e){this.debug("SettingsTab display called without container element");return}this.debug("=== SettingsTab display() called ==="),this.debug("Container element:",e),this.debug("Container element exists:",!!e),this.debug("Container element type:",(s=e==null?void 0:e.constructor)==null?void 0:s.name),this.debug("Plugin instance:",this.plugin),this.debug("Plugin instance exists:",!!this.plugin),this.debug("Plugin settings object:",(a=this.plugin)==null?void 0:a.settings),this.debug("Plugin settings keys:",(o=this.plugin)!=null&&o.settings?Object.keys(this.plugin.settings):"N/A"),e&&(this.debug("Container parent element:",e.parentElement),this.debug("Container is connected to DOM:",e.isConnected),this.debug("Container display style:",window.getComputedStyle(e).display)),e.empty();let t=e.createEl("h2",{text:"Speech to text settings"});this.debug("Title element created:",t);let r=e.createEl("details",{cls:"speech-to-text-debug"}),i=r.createEl("summary",{text:"Debug information"}),n=r.createEl("pre",{text:JSON.stringify({pluginExists:!!this.plugin,settingsExists:!!((c=this.plugin)!=null&&c.settings),apiKey:(u=(d=this.plugin)==null?void 0:d.settings)!=null&&u.apiKey?"Set (hidden)":"Not set",language:((v=(m=this.plugin)==null?void 0:m.settings)==null?void 0:v.language)||"Not set",autoInsert:(w=(p=this.plugin)==null?void 0:p.settings)==null?void 0:w.autoInsert,insertPosition:(x=(E=this.plugin)==null?void 0:E.settings)==null?void 0:x.insertPosition,model:(B=(R=this.plugin)==null?void 0:R.settings)==null?void 0:B.model,timestamp:new Date().toISOString()},null,2)});this.debug("Debug section added");try{this.debug("Creating API section..."),this.createApiSection(e),this.debug("API section created"),this.debug("Creating General section..."),this.createGeneralSection(e),this.debug("General section created"),this.debug("Creating Audio section..."),this.createAudioSection(e),this.debug("Audio section created"),this.debug("Creating Advanced section..."),this.createAdvancedSection(e),this.debug("Advanced section created"),this.debug("Creating Support section..."),this.createSupportSection(e),this.debug("Support section created"),this.debug("=== Settings tab rendered successfully ==="),this.debug("Total child elements:",e.children.length)}catch(f){console.error("=== Error displaying settings ==="),console.error("Error details:",f),console.error("Error stack:",f instanceof Error?f.stack:"N/A"),e.empty(),e.createEl("h2",{text:"Settings error"}),e.createEl("p",{text:"Error loading settings. Please reload the plugin.",cls:"mod-warning"}),e.createEl("pre",{text:`Error: ${f instanceof Error?f.message:String(f)}`,cls:"error-details"})}}createApiSection(e){e.createEl("h3",{text:"API configuration"});let t=e.createEl("div",{cls:"provider-selection"});this.createProviderSelection(t);let r=e.createEl("div",{cls:"provider-settings"}),i=this.plugin.settings.provider||"auto";this.renderProviderSettings(r,i)}createProviderSelection(e){var r;this.debug("=== createProviderSelection called ==="),this.debug("Creating Setting instance...");try{let i=new T.Setting(e);this.debug("Setting instance created:",i),this.debug("Setting element:",i.settingEl),this.debug("Setting element in DOM:",(r=i.settingEl)==null?void 0:r.isConnected),i.setName("Transcription provider").setDesc("Select the speech-to-text provider").addDropdown(n=>{var s;this.debug("Dropdown callback called"),this.debug("Dropdown component:",n),n.addOption("auto","Auto (intelligent selection)").addOption("whisper","OpenAI Whisper").addOption("deepgram","Deepgram").setValue(this.plugin.settings.provider||"auto").onChange(async a=>{var d;if(this.debug("Provider dropdown changed to:",a),!this.isProviderValue(a))return;this.plugin.settings.provider=a,await this.plugin.saveSettings();let o=(d=e.parentElement)==null?void 0:d.querySelector(".provider-settings");this.debug("Settings container found:",!!o),o instanceof HTMLElement?(this.debug("Updating provider settings UI for:",a),this.renderProviderSettings(o,a)):console.error("Could not find .provider-settings container");let c=e.querySelector(".provider-info");c instanceof HTMLElement&&this.updateProviderInfo(c,a),new T.Notice(`Provider changed to: ${a}`)}),this.debug("Dropdown setup complete"),this.debug("Dropdown element:",n.selectEl),this.debug("Dropdown options:",(s=n.selectEl)==null?void 0:s.options.length)}),this.debug("Provider selection setting created successfully"),this.debug("=== createProviderSelection completed ===")}catch(i){console.error("Error creating provider selection:",i),console.error("Error stack:",i instanceof Error?i.stack:"N/A")}let t=e.createEl("div",{cls:"provider-info"});t.addClass("sn-info-box"),this.updateProviderInfo(t,this.plugin.settings.provider||"auto")}renderProviderSettings(e,t){this.debug("=== renderProviderSettings called ==="),this.debug("Provider:",t),this.debug("Container element:",e);let r=e.isConnected;e.empty(),this.debug("Container cleared, still connected:",r);try{switch(t){case"auto":this.debug("Rendering auto provider settings"),this.renderAutoProviderSettings(e);break;case"whisper":this.debug("Rendering whisper settings"),this.renderWhisperSettings(e);break;case"deepgram":this.debug("Rendering deepgram settings"),this.renderDeepgramSettings(e);break;default:console.warn("Unknown provider:",t),e.createEl("p",{text:`Unknown provider: ${String(t)}`,cls:"mod-warning"})}}catch(i){console.error("Error rendering provider settings:",i),e.createEl("p",{text:"Error loading provider settings",cls:"mod-warning"})}this.debug("Final container children:",e.children.length),this.debug("=== renderProviderSettings completed ===")}renderAutoProviderSettings(e){e.createEl("h4",{text:"Automatic provider selection"}),new T.Setting(e).setName("Selection strategy").setDesc("How to choose between available providers").addDropdown(t=>{t.addOption("cost_optimized","Cost optimized").addOption("performance_optimized","Performance optimized").addOption("quality_optimized","Quality optimized").addOption("round_robin","Round robin").addOption("ab_test","A/B testing").setValue(this.plugin.settings.selectionStrategy||"performance_optimized").onChange(async r=>{this.isSelectionStrategy(r)&&(this.plugin.settings.selectionStrategy=r,await this.plugin.saveSettings())})}),new T.Setting(e).setName("Fallback strategy").setDesc("What to do when primary provider fails").addDropdown(t=>{t.addOption("auto","Automatic fallback").addOption("manual","Ask user").addOption("none","No fallback").setValue(this.plugin.settings.fallbackStrategy||"auto").onChange(async r=>{this.isFallbackStrategy(r)&&(this.plugin.settings.fallbackStrategy=r,await this.plugin.saveSettings())})}),e.createEl("h5",{text:"Provider API keys"}),e.createEl("p",{text:"Configure API keys for each provider to enable automatic selection",cls:"setting-item-description"}),this.renderWhisperApiKey(e),this.renderDeepgramApiKey(e)}renderWhisperSettings(e){e.createEl("h4",{text:"OpenAI Whisper configuration"}),this.renderWhisperApiKey(e),new T.Setting(e).setName("API endpoint").setDesc("OpenAI API endpoint (leave default unless using custom endpoint)").addText(t=>t.setPlaceholder("https://api.openai.com/v1").setValue(this.plugin.settings.apiEndpoint||"https://api.openai.com/v1").onChange(async r=>{this.plugin.settings.apiEndpoint=r||"https://api.openai.com/v1",await this.plugin.saveSettings()}))}renderDeepgramSettings(e){this.debug("=== renderDeepgramSettings called ==="),this.debug("Container element:",e),this.debug("Container is connected:",e.isConnected),this.debug("Container children before:",e.children.length),e.empty();let t=e.createEl("div",{cls:"deepgram-settings-container"});this.debug("Deepgram container created:",t);try{let r=new Ce(this.plugin,t);this.debug("DeepgramSettings instance created"),r.render(),this.debug("DeepgramSettings.render() completed")}catch(r){console.error("Error rendering Deepgram settings:",r),t.createEl("p",{text:"Error loading Deepgram settings",cls:"mod-warning"})}this.debug("Container children after:",e.children.length),this.debug("=== renderDeepgramSettings completed ===")}renderWhisperApiKey(e){new T.Setting(e).setName("OpenAI API key").setDesc("Enter your OpenAI API key for Whisper transcription").addText(t=>{t.setPlaceholder("sk-...").setValue(this.maskApiKey(this.plugin.settings.apiKey||"")).onChange(async r=>{r&&!r.includes("*")&&(this.plugin.settings.apiKey=r,this.plugin.settings.whisperApiKey=r,await this.plugin.saveSettings(),t.setValue(this.maskApiKey(r)),new T.Notice("OpenAI API key saved"))}),t.inputEl.type="password",t.inputEl.addEventListener("focus",()=>{this.plugin.settings.apiKey&&t.setValue(this.plugin.settings.apiKey)}),t.inputEl.addEventListener("blur",()=>{this.plugin.settings.apiKey&&t.setValue(this.maskApiKey(this.plugin.settings.apiKey))})})}renderDeepgramApiKey(e){new T.Setting(e).setName("Deepgram API key").setDesc("Enter your Deepgram API key for transcription").addText(t=>{t.setPlaceholder("Enter Deepgram API key...").setValue(this.maskApiKey(this.plugin.settings.deepgramApiKey||"")).onChange(async r=>{r&&!r.includes("*")&&(this.plugin.settings.deepgramApiKey=r,await this.plugin.saveSettings(),t.setValue(this.maskApiKey(r)),new T.Notice("Deepgram API key saved"))}),t.inputEl.type="password",t.inputEl.addEventListener("focus",()=>{this.plugin.settings.deepgramApiKey&&t.setValue(this.plugin.settings.deepgramApiKey)}),t.inputEl.addEventListener("blur",()=>{this.plugin.settings.deepgramApiKey&&t.setValue(this.maskApiKey(this.plugin.settings.deepgramApiKey))})})}updateProviderInfo(e,t){e.empty();let r={auto:"\u{1F916} Intelligent selection between providers based on your configured strategy. Automatically chooses the best provider for each request.",whisper:"\u{1F3AF} OpenAI Whisper - High-quality transcription with support for multiple languages. Best for general-purpose transcription.",deepgram:"\u26A1 Deepgram - Fast, accurate transcription with advanced AI features. Best for real-time processing and speaker diarization."};e.createEl("p",{text:r[t]})}createGeneralSection(e){e.createEl("h3",{text:"General settings"}),new T.Setting(e).setName("Language").setDesc("Primary language for transcription").addDropdown(t=>t.addOption("auto","Auto-detect").addOption("en","English").addOption("ko","\uD55C\uAD6D\uC5B4").addOption("ja","\u65E5\u672C\u8A9E").addOption("zh","\u4E2D\u6587").addOption("es","Espa\xF1ol").addOption("fr","Fran\xE7ais").addOption("de","Deutsch").setValue(this.plugin.settings.language||"auto").onChange(async r=>{this.plugin.settings.language=r,await this.plugin.saveSettings()})),new T.Setting(e).setName("Auto-insert transcription").setDesc("Automatically insert transcribed text into the active note").addToggle(t=>t.setValue(this.plugin.settings.autoInsert||!1).onChange(async r=>{this.plugin.settings.autoInsert=r,await this.plugin.saveSettings()})),new T.Setting(e).setName("Insert position").setDesc("Where to insert transcribed text").addDropdown(t=>t.addOption("cursor","At cursor position").addOption("end","At end of note").addOption("beginning","At beginning of note").setValue(this.plugin.settings.insertPosition||"cursor").onChange(async r=>{this.isInsertPosition(r)&&(this.plugin.settings.insertPosition=r,await this.plugin.saveSettings())})),new T.Setting(e).setName("Show format options").setDesc("Show formatting options before inserting text").addToggle(t=>t.setValue(this.plugin.settings.showFormatOptions||!1).onChange(async r=>{this.plugin.settings.showFormatOptions=r,await this.plugin.saveSettings()}))}createAudioSection(e){e.createEl("h3",{text:"Audio settings"});let t=this.plugin.settings.provider||"auto";(t==="whisper"||t==="auto")&&new T.Setting(e).setName("Whisper model").setDesc("Select the Whisper model to use").addDropdown(r=>r.addOption("whisper-1","Whisper v1 (default)").setValue(this.plugin.settings.model||"whisper-1").onChange(async i=>{this.plugin.settings.model=i,await this.plugin.saveSettings()})),new T.Setting(e).setName("Temperature").setDesc("Sampling temperature (0-1). Lower values make output more focused and deterministic").addText(r=>r.setPlaceholder("0.0").setValue(String(this.plugin.settings.temperature||0)).onChange(async i=>{let n=parseFloat(i);!isNaN(n)&&n>=0&&n<=1&&(this.plugin.settings.temperature=n,await this.plugin.saveSettings())})),new T.Setting(e).setName("Add timestamp").setDesc("Add timestamp to transcribed text").addToggle(r=>r.setValue(this.plugin.settings.addTimestamp||!1).onChange(async i=>{this.plugin.settings.addTimestamp=i,await this.plugin.saveSettings()}))}createAdvancedSection(e){e.createEl("h3",{text:"Advanced settings"}),new T.Setting(e).setName("Enable cache").setDesc("Cache transcription results to avoid re-processing").addToggle(t=>t.setValue(this.plugin.settings.enableCache!==!1).onChange(async r=>{this.plugin.settings.enableCache=r,await this.plugin.saveSettings()})),new T.Setting(e).setName("Debug mode").setDesc("Enable debug logging in console").addToggle(t=>t.setValue(this.plugin.settings.debugMode||!1).onChange(async r=>{this.plugin.settings.debugMode=r,await this.plugin.saveSettings(),r&&new T.Notice("Debug mode enabled. Check console for logs.")})),new T.Setting(e).setName("Reset to defaults").setDesc("Reset all settings to their default values").addButton(t=>t.setButtonText("Reset").setWarning().onClick(async()=>{if(confirm("Are you sure you want to reset all settings to defaults?")){let{DEFAULT_SETTINGS:i}=await Promise.resolve().then(()=>(Le(),et));this.plugin.settings={...i},await this.plugin.saveSettings(),this.display(),new T.Notice("Settings reset to defaults")}}))}createSupportSection(e){e.createEl("hr",{cls:"speech-to-text-separator"}),e.createEl("h3",{text:"Support"}),e.createEl("p",{text:"Thank you for using Speech to text! Your support helps keep this plugin free and actively maintained.",cls:"setting-item-description"}),new T.Setting(e).setName("Support development").setDesc("If you find this plugin helpful, consider buying me a coffee \u2615").addButton(t=>t.setButtonText("\u2615 Buy me a coffee").setCta().onClick(()=>{window.open("https://buymeacoffee.com/asyouplz","_blank")}))}isProviderValue(e){return e==="auto"||e==="whisper"||e==="deepgram"}isSelectionStrategy(e){return e==="manual"||e==="cost_optimized"||e==="performance_optimized"||e==="quality_optimized"||e==="round_robin"||e==="ab_test"}isFallbackStrategy(e){return e==="auto"||e==="manual"||e==="none"}isInsertPosition(e){return e==="cursor"||e==="end"||e==="beginning"}debug(...e){var t;(t=this.plugin.settings)!=null&&t.debugMode&&[...e]}maskApiKey(e){if(!e||e.length<10)return"";let t=7,r=4;if(e.length<=t+r)return e;let i="*".repeat(e.length-t-r);return e.substring(0,t)+i+e.substring(e.length-r)}};var qe=require("obsidian");function At(l){return l instanceof qe.TFile}function vt(l,e){if(!At(l)){let t=e?`[${e}] `:"";throw new Error(`${t}Expected a TFile instance.`)}}var Me=class extends b.Plugin{async onload(){this.logger=new K("SpeechToText"),this.logger.info("Loading Speech-to-Text plugin");try{await this.initializeServices(),this.registerCommands(),this.registerContextMenu(),this.addSettingTab(new De(this.app,this)),this.logger.debug("SettingsTab added"),this.registerEventHandlers(),this.app.workspace.onLayoutReady(()=>{this.createStatusBarItem()}),new b.Notice("Speech-to-Text plugin loaded successfully")}catch(e){console.error("Failed to load Speech-to-Text plugin:",e),new b.Notice("Failed to load Speech-to-Text plugin. Check console for details.")}}onunload(){var e;(e=this.logger)==null||e.info("Unloading Speech-to-Text plugin"),this.cleanupEventHandlers(),this.cancelPendingOperations(),this.editorService&&this.editorService.destroy(),this.textInsertionHandler&&this.textInsertionHandler.destroy()}normalizeError(e){return e instanceof Error?e:new Error(String(e))}resolveProvider(e){return e==="auto"?"auto":e==="deepgram"?"deepgram":"whisper"}resolveInsertionMode(e){switch(e){case"end":return"append";case"beginning":return"prepend";case"cursor":default:return"cursor"}}resolveTextFormat(e){switch(e){case"markdown":case"quote":case"bullet":case"heading":case"code":case"callout":case"plain":return e;default:return"plain"}}async initializeServices(){await this.loadSettings(),this.logger=new K("SpeechToText"),this.errorHandler=new he(this.logger),this.settingsManager=new me(this),this.stateManager=new fe,this.eventManager=new L,this.editorService=new ye(this.app,this.eventManager,this.logger),this.textInsertionHandler=new Te(this.editorService,this.eventManager,this.logger),this.initializeTranscriberFactory(),this.initializeTranscriptionService()}initializeTranscriberFactory(){let e=r=>typeof r=="string"?r:void 0,t={load:async()=>(await this.loadSettings(),this.settings),save:async r=>{r&&typeof r=="object"&&Object.assign(this.settings,r),await this.saveSettings()},get:r=>{var i,n;return r==="transcription"?{defaultProvider:this.settings.provider||"whisper",autoSelect:this.settings.provider==="auto",selectionStrategy:this.settings.selectionStrategy,fallbackEnabled:this.settings.fallbackStrategy!=="none",whisper:{enabled:!!this.settings.apiKey||!!this.settings.whisperApiKey,apiKey:this.settings.whisperApiKey||this.settings.apiKey},deepgram:{enabled:!!this.settings.deepgramApiKey,apiKey:this.settings.deepgramApiKey,model:this.settings.deepgramModel||"nova-2",features:(n=(i=this.settings.transcription)==null?void 0:i.deepgram)==null?void 0:n.features},abTest:{enabled:this.settings.abTestEnabled,trafficSplit:this.settings.abTestSplit},monitoring:{enabled:this.settings.metricsEnabled}}:r==="apiKey"?this.settings.apiKey:this.settings[r]},set:async(r,i)=>{if(r==="transcription"){if(y(i)){(i.defaultProvider==="whisper"||i.defaultProvider==="deepgram")&&(this.settings.provider=i.defaultProvider);let n=y(i.whisper)?i.whisper:void 0,s=y(i.deepgram)?i.deepgram:void 0,a=e(n==null?void 0:n.apiKey),o=e(s==null?void 0:s.apiKey);a!==void 0&&(this.settings.whisperApiKey=a),o!==void 0&&(this.settings.deepgramApiKey=o)}}else this.settings[r]=i;await this.saveSettings()}};this.transcriberFactory=new ue(t,this.logger)}initializeTranscriptionService(){let e=this.resolveProvider(this.settings.provider),t=null;try{let r=this.transcriberFactory.getProvider(e);t=new de(r,this.logger),this.logger.info(`Initialized transcription service with provider: ${r.getProviderName()}`)}catch(r){this.logger.warn("Failed to initialize transcriber from factory, using fallback",this.normalizeError(r));let i=this.settings.whisperApiKey||this.settings.apiKey;i?(t=new W(i,this.logger),this.logger.info("Initialized fallback WhisperService")):(t=null,this.logger.warn("No transcription service initialized - API key missing"))}if(t){let r=new ge(this.app.vault,this.logger);try{let n=this.transcriberFactory.getProvider(e),s=n.getCapabilities();r.setProviderCapabilities({maxFileSize:s.maxFileSize}),this.logger.info("AudioProcessor configured with provider capabilities",{provider:n.getProviderName(),maxFileSize:s.maxFileSize/1024/1024+"MB"})}catch(n){this.logger.warn("Failed to get provider capabilities, using default limits",this.normalizeError(n))}let i=new pe(this.settings);this.transcriptionService=new J(t,r,i,this.eventManager,this.logger,this.settings),this.logger.debug("TranscriptionService initialized successfully")}}registerContextMenu(){this.registerEvent(this.app.workspace.on("file-menu",(e,t)=>{if(!t||!(t instanceof b.TFile))return;["m4a","mp3","wav","mp4","webm","ogg"].includes(t.extension.toLowerCase())&&e.addItem(i=>{i.setTitle("Transcribe audio file").setIcon("microphone").onClick(async()=>{await this.transcribeFile(t)})})}))}registerCommands(){this.addCommand({id:"transcribe-audio-file",name:"Transcribe audio file",callback:()=>{this.showAudioFilePicker()}}),this.addCommand({id:"transcribe-from-clipboard",name:"Transcribe audio from clipboard",callback:()=>{new b.Notice("Clipboard transcription not yet implemented")}}),this.addCommand({id:"show-format-options",name:"Show text formatting options",callback:()=>{this.showFormatOptions()}}),this.addCommand({id:"show-transcription-history",name:"Show transcription history",callback:()=>{new b.Notice("Transcription history not yet implemented")}}),this.addCommand({id:"cancel-transcription",name:"Cancel current transcription",callback:()=>{this.transcriptionService.cancel(),new b.Notice("Transcription cancelled")}}),this.addCommand({id:"undo-insertion",name:"Undo last text insertion",callback:async()=>{await this.editorService.undo()?new b.Notice("Text insertion undone"):new b.Notice("Nothing to undo")}}),this.addCommand({id:"redo-insertion",name:"Redo last text insertion",callback:async()=>{await this.editorService.redo()?new b.Notice("Text insertion redone"):new b.Notice("Nothing to redo")}})}registerEventHandlers(){this.eventManager.on("transcription:start",e=>{this.stateManager.setState({status:"processing"}),new b.Notice(`Transcribing: ${e.fileName}`)}),this.eventManager.on("transcription:complete",async e=>{var r;this.logger.debug("=== Transcription complete event received ===",{hasData:!!e,hasText:!!(e!=null&&e.text),textLength:((r=e==null?void 0:e.text)==null?void 0:r.length)||0,autoInsert:this.settings.autoInsert}),this.stateManager.setState({status:"completed"}),new b.Notice("Transcription completed successfully");let t=e.text;if(!t){this.logger.error("No text found in transcription complete event",void 0,{data:e}),new b.Notice("Transcription completed but no text was returned");return}this.settings.autoInsert?(this.logger.debug("Auto-inserting transcribed text",{textLength:t.length,textPreview:t.substring(0,100)}),await this.insertTranscriptionWithOptions(t)):this.logger.debug("Auto-insert disabled, text not inserted")}),this.eventManager.on("transcription:error",e=>{this.stateManager.setState({status:"error",error:e.error}),new b.Notice(`Transcription failed: ${e.error.message}`)}),this.eventManager.on("transcription:progress",e=>{this.stateManager.setState({progress:e.progress})}),this.eventManager.on("editor:text-inserted",e=>{this.logger.debug("Text inserted into editor",e)}),this.eventManager.on("editor:text-replaced",e=>{this.logger.debug("Text replaced in editor",e)})}cleanupEventHandlers(){this.eventManager.removeAllListeners()}cancelPendingOperations(){this.transcriptionService&&this.transcriptionService.cancel()}createStatusBarItem(){var e;try{if(!this.app.workspace){console.warn("Workspace not ready, skipping status bar creation");return}let t=this.addStatusBarItem();if(!t){console.warn("Failed to create status bar item");return}t.textContent="";let r=i=>{if(t)try{let n=i?String(i):"";t.textContent=n}catch(n){console.warn("Failed to update status bar text:",n)}};this.stateManager.subscribe(i=>{if(t)switch(i.status){case"idle":r("");break;case"processing":r("\u{1F399}\uFE0F Transcribing...");break;case"completed":r("\u2705 Transcription complete"),setTimeout(()=>{this.stateManager.getState().status==="completed"&&r("")},3e3);break;case"error":r("\u274C Transcription failed"),setTimeout(()=>{this.stateManager.getState().status==="error"&&r("")},3e3);break;default:r("");break}}),(e=this.logger)==null||e.debug("Status bar item created successfully")}catch(t){console.error("Error creating status bar item:",t)}}showAudioFilePicker(){let e=this.app.vault.getFiles().filter(t=>t.extension==="m4a"||t.extension==="mp3"||t.extension==="wav"||t.extension==="mp4");if(e.length===0){new b.Notice("No audio files found in vault");return}new Ge(this.app,e,async t=>{await this.transcribeFile(t)}).open()}async transcribeFile(e){var t,r;vt(e,"SpeechToTextPlugin.transcribeFile");try{let i=this.settings.provider||"whisper",n=!1,s="";if(i==="whisper"?(n=!!(this.settings.apiKey||this.settings.whisperApiKey),s="Please configure your OpenAI API key in settings"):i==="deepgram"?(n=!!this.settings.deepgramApiKey,s="Please configure your Deepgram API key in settings"):i==="auto"&&(n=!!(this.settings.apiKey||this.settings.whisperApiKey||this.settings.deepgramApiKey),s="Please configure at least one API key (OpenAI or Deepgram) in settings"),!n){new b.Notice(s);return}if(!this.transcriptionService&&(this.initializeTranscriptionService(),!this.transcriptionService)){new b.Notice("Failed to initialize transcription service. Please check your API keys.");return}this.logger.debug("Starting transcription for file:",{fileName:e.name});let a=await this.transcriptionService.transcribe(e);if(this.logger.debug("Transcription result received:",{hasResult:!!a,hasText:!!(a!=null&&a.text),textLength:((t=a==null?void 0:a.text)==null?void 0:t.length)||0,textPreview:(r=a==null?void 0:a.text)==null?void 0:r.substring(0,100)}),!a||!a.text){this.logger.error("Transcription returned no text",void 0,{result:a}),new b.Notice("Transcription completed but no text was returned");return}this.settings.showFormatOptions?(this.logger.debug("Showing format options with text"),this.showFormatOptionsWithText(a.text)):(this.logger.debug("Inserting text directly without format options"),await this.insertTranscriptionWithOptions(a.text))}catch(i){this.errorHandler.handle(i)}}async insertTranscriptionWithOptions(e){this.logger.debug("=== insertTranscriptionWithOptions START ===",{textLength:(e==null?void 0:e.length)||0,textPreview:e==null?void 0:e.substring(0,100),insertPosition:this.settings.insertPosition,autoInsert:this.settings.autoInsert});let t={mode:this.resolveInsertionMode(this.settings.insertPosition),format:this.resolveTextFormat(this.settings.textFormat),addTimestamp:this.settings.addTimestamp||!1,timestampFormat:this.settings.timestampFormat,language:this.settings.language,createNewNote:!this.editorService.hasActiveEditor()};this.logger.debug("Inserting text with options:",t),await this.textInsertionHandler.insertText(e,t)?(this.logger.info("Text successfully inserted"),new b.Notice("Transcription inserted successfully")):(this.logger.warn("TextInsertionHandler failed, using legacy method"),await this.insertTranscriptionLegacy(e))}async insertTranscriptionLegacy(e){let t=this.app.workspace.getActiveViewOfType(b.MarkdownView);if(!t){new b.Notice("No active editor found. Opening new note...");let n=await this.app.vault.create(`Transcription ${new Date().toISOString()}.md`,e);await this.app.workspace.openLinkText(n.path,"",!0);return}let r=t.editor;switch(this.settings.insertPosition){case"cursor":r.replaceSelection(e);break;case"end":{let n=r.lastLine(),s=r.getLine(n);r.setLine(n,s+`
`+e);break}case"beginning":{let n=r.getLine(0);r.setLine(0,e+`
`+n);break}}}showFormatOptions(){this.showFormatOptionsWithText("")}showFormatOptionsWithText(e){new Se(this.app,{mode:"cursor",format:this.settings.textFormat||"plain",addTimestamp:this.settings.addTimestamp||!1,language:this.settings.language},async r=>{e?await this.textInsertionHandler.insertText(e,r):new b.Notice("No text to insert")},()=>{this.logger.debug("Format options cancelled")}).open()}async loadSettings(){this.settings=Object.assign({},ke,await this.loadData())}async saveSettings(){await this.saveData(this.settings)}async saveSettingsAndReinitialize(){await this.saveData(this.settings),this.transcriberFactory&&(this.initializeTranscriberFactory(),this.initializeTranscriptionService())}},Ge=class extends b.Modal{constructor(e,t,r){super(e),this.files=t,this.onChoose=r}onOpen(){let{contentEl:e}=this;e.createEl("h2",{text:"Select an audio file to transcribe"});let t=e.createEl("div",{cls:"speech-to-text-file-list"});this.files.forEach(r=>{t.createEl("div",{cls:"speech-to-text-file-item",text:r.path}).addEventListener("click",()=>{this.onChoose(r),this.close()})})}onClose(){let{contentEl:e}=this;e.empty()}};