From a4298d444f937ae9fd1fe246bb013870f9f4f0e1 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 10 Sep 2025 16:27:35 +0700 Subject: [PATCH] update view message --- .../composer-bot-extensions/content.js | 12 +- .../src/api/message-api.service.ts | 47 ++++- composer-bot-extensions/src/features/app.ts | 23 +++ composer-bot-extensions/src/interfate.d.ts | 2 +- .../src/services/content.service.ts | 5 +- .../src/services/teams-chat.service.ts | 35 +++- server/package-lock.json | 56 ++++-- server/package.json | 3 + server/src/entities/message.entity.ts | 2 +- server/src/features/is-base64.ts | 14 ++ server/src/features/is-url.ts | 10 + .../messages/dtos/create-bulk-message.dto.ts | 5 +- .../messages/dtos/create-message.dto.ts | 2 +- .../src/modules/messages/messages.service.ts | 181 +++++++++++++++--- server/src/modules/messages/zulip.service.ts | 102 +++++++++- server/test.png | 0 .../tmp/1757489923980-3pmx.octet-stream.jpg | Bin 0 -> 32756 bytes server/tmp/1757490053884-nt5w8y.png | Bin 0 -> 32756 bytes 18 files changed, 428 insertions(+), 71 deletions(-) create mode 100644 server/src/features/is-base64.ts create mode 100644 server/src/features/is-url.ts create mode 100644 server/test.png create mode 100644 server/tmp/1757489923980-3pmx.octet-stream.jpg create mode 100644 server/tmp/1757490053884-nt5w8y.png diff --git a/composer-bot-extensions/composer-bot-extensions/content.js b/composer-bot-extensions/composer-bot-extensions/content.js index a49b048..9f7b563 100644 --- a/composer-bot-extensions/composer-bot-extensions/content.js +++ b/composer-bot-extensions/composer-bot-extensions/content.js @@ -1,6 +1,6 @@ -const q={GET_CONVERSATIONS:"messages.get-conversations",GET_CONVERSATION:"messages.get-conversation",RECEIVE_CONVERSATIONS:"messages.receive-conversations",RECEIVE_CONVERSATION:"messages.receive-conversation",SEND_MESSAGE:"messages.send-messsage",REPLY_MESSAGE:"messages.reply-messsage"};function ft(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var ae={exports:{}},Se;function dt(){return Se||(Se=1,function(t){var e=Object.prototype.hasOwnProperty,n="~";function r(){}Object.create&&(r.prototype=Object.create(null),new r().__proto__||(n=!1));function s(f,c,u){this.fn=f,this.context=c,this.once=u||!1}function o(f,c,u,d,m){if(typeof u!="function")throw new TypeError("The listener must be a function");var g=new s(u,d||f,m),p=n?n+c:c;return f._events[p]?f._events[p].fn?f._events[p]=[f._events[p],g]:f._events[p].push(g):(f._events[p]=g,f._eventsCount++),f}function i(f,c){--f._eventsCount===0?f._events=new r:delete f._events[c]}function a(){this._events=new r,this._eventsCount=0}a.prototype.eventNames=function(){var c=[],u,d;if(this._eventsCount===0)return c;for(d in u=this._events)e.call(u,d)&&c.push(n?d.slice(1):d);return Object.getOwnPropertySymbols?c.concat(Object.getOwnPropertySymbols(u)):c},a.prototype.listeners=function(c){var u=n?n+c:c,d=this._events[u];if(!d)return[];if(d.fn)return[d.fn];for(var m=0,g=d.length,p=new Array(g);mglobalThis.DOMException===void 0?new mt(t):new DOMException(t),Re=t=>{const e=t.reason===void 0?Te("This operation was aborted."):t.reason;return e instanceof Error?e:Te(e)};function yt(t,e){const{milliseconds:n,fallback:r,message:s,customTimers:o={setTimeout,clearTimeout}}=e;let i,a;const c=new Promise((u,d)=>{if(typeof n!="number"||Math.sign(n)!==1)throw new TypeError(`Expected \`milliseconds\` to be a positive number, got \`${n}\``);if(e.signal){const{signal:g}=e;g.aborted&&d(Re(g)),a=()=>{d(Re(g))},g.addEventListener("abort",a,{once:!0})}if(n===Number.POSITIVE_INFINITY){t.then(u,d);return}const m=new De;i=o.setTimeout.call(void 0,()=>{if(r){try{u(r())}catch(g){d(g)}return}typeof t.cancel=="function"&&t.cancel(),s===!1?u():s instanceof Error?d(s):(m.message=s??`Promise timed out after ${n} milliseconds`,d(m))},n),(async()=>{try{u(await t)}catch(g){d(g)}})()}).finally(()=>{c.clear(),a&&e.signal&&e.signal.removeEventListener("abort",a)});return c.clear=()=>{o.clearTimeout.call(void 0,i),i=void 0},c}function gt(t,e,n){let r=0,s=t.length;for(;s>0;){const o=Math.trunc(s/2);let i=r+o;n(t[i],e)<=0?(r=++i,s-=o+1):s=o}return r}class wt{#e=[];enqueue(e,n){n={priority:0,...n};const r={priority:n.priority,id:n.id,run:e};if(this.size===0||this.#e[this.size-1].priority>=n.priority){this.#e.push(r);return}const s=gt(this.#e,r,(o,i)=>i.priority-o.priority);this.#e.splice(s,0,r)}setPriority(e,n){const r=this.#e.findIndex(o=>o.id===e);if(r===-1)throw new ReferenceError(`No promise function with the id "${e}" exists in the queue.`);const[s]=this.#e.splice(r,1);this.enqueue(s.run,{priority:n,id:e})}dequeue(){return this.#e.shift()?.run}filter(e){return this.#e.filter(n=>n.priority===e.priority).map(n=>n.run)}get size(){return this.#e.length}}class Et extends pt{#e;#i;#o=0;#h;#a;#p=0;#n;#c;#t;#m;#r=0;#l;#s;#y;#E=1n;timeout;constructor(e){if(super(),e={carryoverConcurrencyCount:!1,intervalCap:Number.POSITIVE_INFINITY,interval:0,concurrency:Number.POSITIVE_INFINITY,autoStart:!0,queueClass:wt,...e},!(typeof e.intervalCap=="number"&&e.intervalCap>=1))throw new TypeError(`Expected \`intervalCap\` to be a number from 1 and up, got \`${e.intervalCap?.toString()??""}\` (${typeof e.intervalCap})`);if(e.interval===void 0||!(Number.isFinite(e.interval)&&e.interval>=0))throw new TypeError(`Expected \`interval\` to be a finite number >= 0, got \`${e.interval?.toString()??""}\` (${typeof e.interval})`);this.#e=e.carryoverConcurrencyCount,this.#i=e.intervalCap===Number.POSITIVE_INFINITY||e.interval===0,this.#h=e.intervalCap,this.#a=e.interval,this.#t=new e.queueClass,this.#m=e.queueClass,this.concurrency=e.concurrency,this.timeout=e.timeout,this.#y=e.throwOnTimeout===!0,this.#s=e.autoStart===!1}get#b(){return this.#i||this.#o{this.#R()},n)),!0}return!1}#u(){if(this.#t.size===0)return this.#n&&clearInterval(this.#n),this.#n=void 0,this.emit("empty"),this.#r===0&&this.emit("idle"),!1;if(!this.#s){const e=!this.#v;if(this.#b&&this.#S){const n=this.#t.dequeue();return n?(this.emit("active"),n(),e&&this.#g(),!0):!1}}return!1}#g(){this.#i||this.#n!==void 0||(this.#n=setInterval(()=>{this.#w()},this.#a),this.#p=Date.now()+this.#a)}#w(){this.#o===0&&this.#r===0&&this.#n&&(clearInterval(this.#n),this.#n=void 0),this.#o=this.#e?this.#r:0,this.#f()}#f(){for(;this.#u(););}get concurrency(){return this.#l}set concurrency(e){if(!(typeof e=="number"&&e>=1))throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${e}\` (${typeof e})`);this.#l=e,this.#f()}async#_(e){return new Promise((n,r)=>{e.addEventListener("abort",()=>{r(e.reason)},{once:!0})})}setPriority(e,n){this.#t.setPriority(e,n)}async add(e,n={}){return n.id??=(this.#E++).toString(),n={timeout:this.timeout,throwOnTimeout:this.#y,...n},new Promise((r,s)=>{this.#t.enqueue(async()=>{this.#r++,this.#o++;try{n.signal?.throwIfAborted();let o=e({signal:n.signal});n.timeout&&(o=yt(Promise.resolve(o),{milliseconds:n.timeout})),n.signal&&(o=Promise.race([o,this.#_(n.signal)]));const i=await o;r(i),this.emit("completed",i)}catch(o){if(o instanceof De&&!n.throwOnTimeout){r();return}s(o),this.emit("error",o)}finally{this.#T()}},n),this.emit("add"),this.#u()})}async addAll(e,n){return Promise.all(e.map(async r=>this.add(r,n)))}start(){return this.#s?(this.#s=!1,this.#f(),this):this}pause(){this.#s=!0}clear(){this.#t=new this.#m}async onEmpty(){this.#t.size!==0&&await this.#d("empty")}async onSizeLessThan(e){this.#t.sizethis.#t.size{const s=()=>{n&&!n()||(this.off(e,s),r())};this.on(e,s)})}get size(){return this.#t.size}sizeBy(e){return this.#t.filter(e).length}get pending(){return this.#r}get isPaused(){return this.#s}}const D=new Et({concurrency:1});function qe(t,e){return function(){return t.apply(e,arguments)}}const{toString:bt}=Object.prototype,{getPrototypeOf:ge}=Object,{iterator:te,toStringTag:Ue}=Symbol,ne=(t=>e=>{const n=bt.call(e);return t[n]||(t[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),O=t=>(t=t.toLowerCase(),e=>ne(e)===t),re=t=>e=>typeof e===t,{isArray:H}=Array,V=re("undefined");function z(t){return t!==null&&!V(t)&&t.constructor!==null&&!V(t.constructor)&&_(t.constructor.isBuffer)&&t.constructor.isBuffer(t)}const He=O("ArrayBuffer");function St(t){let e;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?e=ArrayBuffer.isView(t):e=t&&t.buffer&&He(t.buffer),e}const Tt=re("string"),_=re("function"),je=re("number"),J=t=>t!==null&&typeof t=="object",Rt=t=>t===!0||t===!1,X=t=>{if(ne(t)!=="object")return!1;const e=ge(t);return(e===null||e===Object.prototype||Object.getPrototypeOf(e)===null)&&!(Ue in t)&&!(te in t)},vt=t=>{if(!J(t)||z(t))return!1;try{return Object.keys(t).length===0&&Object.getPrototypeOf(t)===Object.prototype}catch{return!1}},_t=O("Date"),Ct=O("File"),At=O("Blob"),Ot=O("FileList"),xt=t=>J(t)&&_(t.pipe),Nt=t=>{let e;return t&&(typeof FormData=="function"&&t instanceof FormData||_(t.append)&&((e=ne(t))==="formdata"||e==="object"&&_(t.toString)&&t.toString()==="[object FormData]"))},Pt=O("URLSearchParams"),[It,Mt,Lt,kt]=["ReadableStream","Request","Response","Headers"].map(O),Ft=t=>t.trim?t.trim():t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function K(t,e,{allOwnKeys:n=!1}={}){if(t===null||typeof t>"u")return;let r,s;if(typeof t!="object"&&(t=[t]),H(t))for(r=0,s=t.length;r0;)if(s=n[r],e===s.toLowerCase())return s;return null}const k=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,Ve=t=>!V(t)&&t!==k;function fe(){const{caseless:t}=Ve(this)&&this||{},e={},n=(r,s)=>{const o=t&&$e(e,s)||s;X(e[o])&&X(r)?e[o]=fe(e[o],r):X(r)?e[o]=fe({},r):H(r)?e[o]=r.slice():e[o]=r};for(let r=0,s=arguments.length;r(K(e,(s,o)=>{n&&_(s)?t[o]=qe(s,n):t[o]=s},{allOwnKeys:r}),t),Dt=t=>(t.charCodeAt(0)===65279&&(t=t.slice(1)),t),qt=(t,e,n,r)=>{t.prototype=Object.create(e.prototype,r),t.prototype.constructor=t,Object.defineProperty(t,"super",{value:e.prototype}),n&&Object.assign(t.prototype,n)},Ut=(t,e,n,r)=>{let s,o,i;const a={};if(e=e||{},t==null)return e;do{for(s=Object.getOwnPropertyNames(t),o=s.length;o-- >0;)i=s[o],(!r||r(i,t,e))&&!a[i]&&(e[i]=t[i],a[i]=!0);t=n!==!1&&ge(t)}while(t&&(!n||n(t,e))&&t!==Object.prototype);return e},Ht=(t,e,n)=>{t=String(t),(n===void 0||n>t.length)&&(n=t.length),n-=e.length;const r=t.indexOf(e,n);return r!==-1&&r===n},jt=t=>{if(!t)return null;if(H(t))return t;let e=t.length;if(!je(e))return null;const n=new Array(e);for(;e-- >0;)n[e]=t[e];return n},$t=(t=>e=>t&&e instanceof t)(typeof Uint8Array<"u"&&ge(Uint8Array)),Vt=(t,e)=>{const r=(t&&t[te]).call(t);let s;for(;(s=r.next())&&!s.done;){const o=s.value;e.call(t,o[0],o[1])}},zt=(t,e)=>{let n;const r=[];for(;(n=t.exec(e))!==null;)r.push(n);return r},Jt=O("HTMLFormElement"),Kt=t=>t.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,r,s){return r.toUpperCase()+s}),ve=(({hasOwnProperty:t})=>(e,n)=>t.call(e,n))(Object.prototype),Wt=O("RegExp"),ze=(t,e)=>{const n=Object.getOwnPropertyDescriptors(t),r={};K(n,(s,o)=>{let i;(i=e(s,o,t))!==!1&&(r[o]=i||s)}),Object.defineProperties(t,r)},Gt=t=>{ze(t,(e,n)=>{if(_(t)&&["arguments","caller","callee"].indexOf(n)!==-1)return!1;const r=t[n];if(_(r)){if(e.enumerable=!1,"writable"in e){e.writable=!1;return}e.set||(e.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},Xt=(t,e)=>{const n={},r=s=>{s.forEach(o=>{n[o]=!0})};return H(t)?r(t):r(String(t).split(e)),n},Qt=()=>{},Yt=(t,e)=>t!=null&&Number.isFinite(t=+t)?t:e;function Zt(t){return!!(t&&_(t.append)&&t[Ue]==="FormData"&&t[te])}const en=t=>{const e=new Array(10),n=(r,s)=>{if(J(r)){if(e.indexOf(r)>=0)return;if(z(r))return r;if(!("toJSON"in r)){e[s]=r;const o=H(r)?[]:{};return K(r,(i,a)=>{const f=n(i,s+1);!V(f)&&(o[a]=f)}),e[s]=void 0,o}}return r};return n(t,0)},tn=O("AsyncFunction"),nn=t=>t&&(J(t)||_(t))&&_(t.then)&&_(t.catch),Je=((t,e)=>t?setImmediate:e?((n,r)=>(k.addEventListener("message",({source:s,data:o})=>{s===k&&o===n&&r.length&&r.shift()()},!1),s=>{r.push(s),k.postMessage(n,"*")}))(`axios@${Math.random()}`,[]):n=>setTimeout(n))(typeof setImmediate=="function",_(k.postMessage)),rn=typeof queueMicrotask<"u"?queueMicrotask.bind(k):typeof process<"u"&&process.nextTick||Je,sn=t=>t!=null&&_(t[te]),l={isArray:H,isArrayBuffer:He,isBuffer:z,isFormData:Nt,isArrayBufferView:St,isString:Tt,isNumber:je,isBoolean:Rt,isObject:J,isPlainObject:X,isEmptyObject:vt,isReadableStream:It,isRequest:Mt,isResponse:Lt,isHeaders:kt,isUndefined:V,isDate:_t,isFile:Ct,isBlob:At,isRegExp:Wt,isFunction:_,isStream:xt,isURLSearchParams:Pt,isTypedArray:$t,isFileList:Ot,forEach:K,merge:fe,extend:Bt,trim:Ft,stripBOM:Dt,inherits:qt,toFlatObject:Ut,kindOf:ne,kindOfTest:O,endsWith:Ht,toArray:jt,forEachEntry:Vt,matchAll:zt,isHTMLForm:Jt,hasOwnProperty:ve,hasOwnProp:ve,reduceDescriptors:ze,freezeMethods:Gt,toObjectSet:Xt,toCamelCase:Kt,noop:Qt,toFiniteNumber:Yt,findKey:$e,global:k,isContextDefined:Ve,isSpecCompliantForm:Zt,toJSONObject:en,isAsyncFn:tn,isThenable:nn,setImmediate:Je,asap:rn,isIterable:sn};function w(t,e,n,r,s){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack,this.message=t,this.name="AxiosError",e&&(this.code=e),n&&(this.config=n),r&&(this.request=r),s&&(this.response=s,this.status=s.status?s.status:null)}l.inherits(w,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:l.toJSONObject(this.config),code:this.code,status:this.status}}});const Ke=w.prototype,We={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach(t=>{We[t]={value:t}});Object.defineProperties(w,We);Object.defineProperty(Ke,"isAxiosError",{value:!0});w.from=(t,e,n,r,s,o)=>{const i=Object.create(Ke);return l.toFlatObject(t,i,function(f){return f!==Error.prototype},a=>a!=="isAxiosError"),w.call(i,t.message,e,n,r,s),i.cause=t,i.name=t.name,o&&Object.assign(i,o),i};const on=null;function de(t){return l.isPlainObject(t)||l.isArray(t)}function Ge(t){return l.endsWith(t,"[]")?t.slice(0,-2):t}function _e(t,e,n){return t?t.concat(e).map(function(s,o){return s=Ge(s),!n&&o?"["+s+"]":s}).join(n?".":""):e}function an(t){return l.isArray(t)&&!t.some(de)}const cn=l.toFlatObject(l,{},null,function(e){return/^is[A-Z]/.test(e)});function se(t,e,n){if(!l.isObject(t))throw new TypeError("target must be an object");e=e||new FormData,n=l.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(y,h){return!l.isUndefined(h[y])});const r=n.metaTokens,s=n.visitor||u,o=n.dots,i=n.indexes,f=(n.Blob||typeof Blob<"u"&&Blob)&&l.isSpecCompliantForm(e);if(!l.isFunction(s))throw new TypeError("visitor must be a function");function c(p){if(p===null)return"";if(l.isDate(p))return p.toISOString();if(l.isBoolean(p))return p.toString();if(!f&&l.isBlob(p))throw new w("Blob is not supported. Use a Buffer instead.");return l.isArrayBuffer(p)||l.isTypedArray(p)?f&&typeof Blob=="function"?new Blob([p]):Buffer.from(p):p}function u(p,y,h){let b=p;if(p&&!h&&typeof p=="object"){if(l.endsWith(y,"{}"))y=r?y:y.slice(0,-2),p=JSON.stringify(p);else if(l.isArray(p)&&an(p)||(l.isFileList(p)||l.endsWith(y,"[]"))&&(b=l.toArray(p)))return y=Ge(y),b.forEach(function(E,A){!(l.isUndefined(E)||E===null)&&e.append(i===!0?_e([y],A,o):i===null?y:y+"[]",c(E))}),!1}return de(p)?!0:(e.append(_e(h,y,o),c(p)),!1)}const d=[],m=Object.assign(cn,{defaultVisitor:u,convertValue:c,isVisitable:de});function g(p,y){if(!l.isUndefined(p)){if(d.indexOf(p)!==-1)throw Error("Circular reference detected in "+y.join("."));d.push(p),l.forEach(p,function(b,S){(!(l.isUndefined(b)||b===null)&&s.call(e,b,l.isString(S)?S.trim():S,y,m))===!0&&g(b,y?y.concat(S):[S])}),d.pop()}}if(!l.isObject(t))throw new TypeError("data must be an object");return g(t),e}function Ce(t){const e={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(t).replace(/[!'()~]|%20|%00/g,function(r){return e[r]})}function we(t,e){this._pairs=[],t&&se(t,this,e)}const Xe=we.prototype;Xe.append=function(e,n){this._pairs.push([e,n])};Xe.toString=function(e){const n=e?function(r){return e.call(this,r,Ce)}:Ce;return this._pairs.map(function(s){return n(s[0])+"="+n(s[1])},"").join("&")};function ln(t){return encodeURIComponent(t).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function Qe(t,e,n){if(!e)return t;const r=n&&n.encode||ln;l.isFunction(n)&&(n={serialize:n});const s=n&&n.serialize;let o;if(s?o=s(e,n):o=l.isURLSearchParams(e)?e.toString():new we(e,n).toString(r),o){const i=t.indexOf("#");i!==-1&&(t=t.slice(0,i)),t+=(t.indexOf("?")===-1?"?":"&")+o}return t}class Ae{constructor(){this.handlers=[]}use(e,n,r){return this.handlers.push({fulfilled:e,rejected:n,synchronous:r?r.synchronous:!1,runWhen:r?r.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(e){l.forEach(this.handlers,function(r){r!==null&&e(r)})}}const Ye={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},un=typeof URLSearchParams<"u"?URLSearchParams:we,fn=typeof FormData<"u"?FormData:null,dn=typeof Blob<"u"?Blob:null,hn={isBrowser:!0,classes:{URLSearchParams:un,FormData:fn,Blob:dn},protocols:["http","https","file","blob","url","data"]},Ee=typeof window<"u"&&typeof document<"u",he=typeof navigator=="object"&&navigator||void 0,pn=Ee&&(!he||["ReactNative","NativeScript","NS"].indexOf(he.product)<0),mn=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",yn=Ee&&window.location.href||"http://localhost",gn=Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:Ee,hasStandardBrowserEnv:pn,hasStandardBrowserWebWorkerEnv:mn,navigator:he,origin:yn},Symbol.toStringTag,{value:"Module"})),v={...gn,...hn};function wn(t,e){return se(t,new v.classes.URLSearchParams,{visitor:function(n,r,s,o){return v.isNode&&l.isBuffer(n)?(this.append(r,n.toString("base64")),!1):o.defaultVisitor.apply(this,arguments)},...e})}function En(t){return l.matchAll(/\w+|\[(\w*)]/g,t).map(e=>e[0]==="[]"?"":e[1]||e[0])}function bn(t){const e={},n=Object.keys(t);let r;const s=n.length;let o;for(r=0;r=n.length;return i=!i&&l.isArray(s)?s.length:i,f?(l.hasOwnProp(s,i)?s[i]=[s[i],r]:s[i]=r,!a):((!s[i]||!l.isObject(s[i]))&&(s[i]=[]),e(n,r,s[i],o)&&l.isArray(s[i])&&(s[i]=bn(s[i])),!a)}if(l.isFormData(t)&&l.isFunction(t.entries)){const n={};return l.forEachEntry(t,(r,s)=>{e(En(r),s,n,0)}),n}return null}function Sn(t,e,n){if(l.isString(t))try{return(e||JSON.parse)(t),l.trim(t)}catch(r){if(r.name!=="SyntaxError")throw r}return(n||JSON.stringify)(t)}const W={transitional:Ye,adapter:["xhr","http","fetch"],transformRequest:[function(e,n){const r=n.getContentType()||"",s=r.indexOf("application/json")>-1,o=l.isObject(e);if(o&&l.isHTMLForm(e)&&(e=new FormData(e)),l.isFormData(e))return s?JSON.stringify(Ze(e)):e;if(l.isArrayBuffer(e)||l.isBuffer(e)||l.isStream(e)||l.isFile(e)||l.isBlob(e)||l.isReadableStream(e))return e;if(l.isArrayBufferView(e))return e.buffer;if(l.isURLSearchParams(e))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();let a;if(o){if(r.indexOf("application/x-www-form-urlencoded")>-1)return wn(e,this.formSerializer).toString();if((a=l.isFileList(e))||r.indexOf("multipart/form-data")>-1){const f=this.env&&this.env.FormData;return se(a?{"files[]":e}:e,f&&new f,this.formSerializer)}}return o||s?(n.setContentType("application/json",!1),Sn(e)):e}],transformResponse:[function(e){const n=this.transitional||W.transitional,r=n&&n.forcedJSONParsing,s=this.responseType==="json";if(l.isResponse(e)||l.isReadableStream(e))return e;if(e&&l.isString(e)&&(r&&!this.responseType||s)){const i=!(n&&n.silentJSONParsing)&&s;try{return JSON.parse(e)}catch(a){if(i)throw a.name==="SyntaxError"?w.from(a,w.ERR_BAD_RESPONSE,this,null,this.response):a}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:v.classes.FormData,Blob:v.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};l.forEach(["delete","get","head","post","put","patch"],t=>{W.headers[t]={}});const Tn=l.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),Rn=t=>{const e={};let n,r,s;return t&&t.split(` -`).forEach(function(i){s=i.indexOf(":"),n=i.substring(0,s).trim().toLowerCase(),r=i.substring(s+1).trim(),!(!n||e[n]&&Tn[n])&&(n==="set-cookie"?e[n]?e[n].push(r):e[n]=[r]:e[n]=e[n]?e[n]+", "+r:r)}),e},Oe=Symbol("internals");function $(t){return t&&String(t).trim().toLowerCase()}function Q(t){return t===!1||t==null?t:l.isArray(t)?t.map(Q):String(t)}function vn(t){const e=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(t);)e[r[1]]=r[2];return e}const _n=t=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(t.trim());function ce(t,e,n,r,s){if(l.isFunction(r))return r.call(this,e,n);if(s&&(e=n),!!l.isString(e)){if(l.isString(r))return e.indexOf(r)!==-1;if(l.isRegExp(r))return r.test(e)}}function Cn(t){return t.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(e,n,r)=>n.toUpperCase()+r)}function An(t,e){const n=l.toCamelCase(" "+e);["get","set","has"].forEach(r=>{Object.defineProperty(t,r+n,{value:function(s,o,i){return this[r].call(this,e,s,o,i)},configurable:!0})})}let C=class{constructor(e){e&&this.set(e)}set(e,n,r){const s=this;function o(a,f,c){const u=$(f);if(!u)throw new Error("header name must be a non-empty string");const d=l.findKey(s,u);(!d||s[d]===void 0||c===!0||c===void 0&&s[d]!==!1)&&(s[d||f]=Q(a))}const i=(a,f)=>l.forEach(a,(c,u)=>o(c,u,f));if(l.isPlainObject(e)||e instanceof this.constructor)i(e,n);else if(l.isString(e)&&(e=e.trim())&&!_n(e))i(Rn(e),n);else if(l.isObject(e)&&l.isIterable(e)){let a={},f,c;for(const u of e){if(!l.isArray(u))throw TypeError("Object iterator must return a key-value pair");a[c=u[0]]=(f=a[c])?l.isArray(f)?[...f,u[1]]:[f,u[1]]:u[1]}i(a,n)}else e!=null&&o(n,e,r);return this}get(e,n){if(e=$(e),e){const r=l.findKey(this,e);if(r){const s=this[r];if(!n)return s;if(n===!0)return vn(s);if(l.isFunction(n))return n.call(this,s,r);if(l.isRegExp(n))return n.exec(s);throw new TypeError("parser must be boolean|regexp|function")}}}has(e,n){if(e=$(e),e){const r=l.findKey(this,e);return!!(r&&this[r]!==void 0&&(!n||ce(this,this[r],r,n)))}return!1}delete(e,n){const r=this;let s=!1;function o(i){if(i=$(i),i){const a=l.findKey(r,i);a&&(!n||ce(r,r[a],a,n))&&(delete r[a],s=!0)}}return l.isArray(e)?e.forEach(o):o(e),s}clear(e){const n=Object.keys(this);let r=n.length,s=!1;for(;r--;){const o=n[r];(!e||ce(this,this[o],o,e,!0))&&(delete this[o],s=!0)}return s}normalize(e){const n=this,r={};return l.forEach(this,(s,o)=>{const i=l.findKey(r,o);if(i){n[i]=Q(s),delete n[o];return}const a=e?Cn(o):String(o).trim();a!==o&&delete n[o],n[a]=Q(s),r[a]=!0}),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){const n=Object.create(null);return l.forEach(this,(r,s)=>{r!=null&&r!==!1&&(n[s]=e&&l.isArray(r)?r.join(", "):r)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([e,n])=>e+": "+n).join(` -`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...n){const r=new this(e);return n.forEach(s=>r.set(s)),r}static accessor(e){const r=(this[Oe]=this[Oe]={accessors:{}}).accessors,s=this.prototype;function o(i){const a=$(i);r[a]||(An(s,i),r[a]=!0)}return l.isArray(e)?e.forEach(o):o(e),this}};C.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);l.reduceDescriptors(C.prototype,({value:t},e)=>{let n=e[0].toUpperCase()+e.slice(1);return{get:()=>t,set(r){this[n]=r}}});l.freezeMethods(C);function le(t,e){const n=this||W,r=e||n,s=C.from(r.headers);let o=r.data;return l.forEach(t,function(a){o=a.call(n,o,s.normalize(),e?e.status:void 0)}),s.normalize(),o}function et(t){return!!(t&&t.__CANCEL__)}function j(t,e,n){w.call(this,t??"canceled",w.ERR_CANCELED,e,n),this.name="CanceledError"}l.inherits(j,w,{__CANCEL__:!0});function tt(t,e,n){const r=n.config.validateStatus;!n.status||!r||r(n.status)?t(n):e(new w("Request failed with status code "+n.status,[w.ERR_BAD_REQUEST,w.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))}function On(t){const e=/^([-+\w]{1,25})(:?\/\/|:)/.exec(t);return e&&e[1]||""}function xn(t,e){t=t||10;const n=new Array(t),r=new Array(t);let s=0,o=0,i;return e=e!==void 0?e:1e3,function(f){const c=Date.now(),u=r[o];i||(i=c),n[s]=f,r[s]=c;let d=o,m=0;for(;d!==s;)m+=n[d++],d=d%t;if(s=(s+1)%t,s===o&&(o=(o+1)%t),c-i{n=u,s=null,o&&(clearTimeout(o),o=null),t(...c)};return[(...c)=>{const u=Date.now(),d=u-n;d>=r?i(c,u):(s=c,o||(o=setTimeout(()=>{o=null,i(s)},r-d)))},()=>s&&i(s)]}const Z=(t,e,n=3)=>{let r=0;const s=xn(50,250);return Nn(o=>{const i=o.loaded,a=o.lengthComputable?o.total:void 0,f=i-r,c=s(f),u=i<=a;r=i;const d={loaded:i,total:a,progress:a?i/a:void 0,bytes:f,rate:c||void 0,estimated:c&&a&&u?(a-i)/c:void 0,event:o,lengthComputable:a!=null,[e?"download":"upload"]:!0};t(d)},n)},xe=(t,e)=>{const n=t!=null;return[r=>e[0]({lengthComputable:n,total:t,loaded:r}),e[1]]},Ne=t=>(...e)=>l.asap(()=>t(...e)),Pn=v.hasStandardBrowserEnv?((t,e)=>n=>(n=new URL(n,v.origin),t.protocol===n.protocol&&t.host===n.host&&(e||t.port===n.port)))(new URL(v.origin),v.navigator&&/(msie|trident)/i.test(v.navigator.userAgent)):()=>!0,In=v.hasStandardBrowserEnv?{write(t,e,n,r,s,o){const i=[t+"="+encodeURIComponent(e)];l.isNumber(n)&&i.push("expires="+new Date(n).toGMTString()),l.isString(r)&&i.push("path="+r),l.isString(s)&&i.push("domain="+s),o===!0&&i.push("secure"),document.cookie=i.join("; ")},read(t){const e=document.cookie.match(new RegExp("(^|;\\s*)("+t+")=([^;]*)"));return e?decodeURIComponent(e[3]):null},remove(t){this.write(t,"",Date.now()-864e5)}}:{write(){},read(){return null},remove(){}};function Mn(t){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t)}function Ln(t,e){return e?t.replace(/\/?\/$/,"")+"/"+e.replace(/^\/+/,""):t}function nt(t,e,n){let r=!Mn(e);return t&&(r||n==!1)?Ln(t,e):e}const Pe=t=>t instanceof C?{...t}:t;function B(t,e){e=e||{};const n={};function r(c,u,d,m){return l.isPlainObject(c)&&l.isPlainObject(u)?l.merge.call({caseless:m},c,u):l.isPlainObject(u)?l.merge({},u):l.isArray(u)?u.slice():u}function s(c,u,d,m){if(l.isUndefined(u)){if(!l.isUndefined(c))return r(void 0,c,d,m)}else return r(c,u,d,m)}function o(c,u){if(!l.isUndefined(u))return r(void 0,u)}function i(c,u){if(l.isUndefined(u)){if(!l.isUndefined(c))return r(void 0,c)}else return r(void 0,u)}function a(c,u,d){if(d in e)return r(c,u);if(d in t)return r(void 0,c)}const f={url:o,method:o,data:o,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,responseEncoding:i,validateStatus:a,headers:(c,u,d)=>s(Pe(c),Pe(u),d,!0)};return l.forEach(Object.keys({...t,...e}),function(u){const d=f[u]||s,m=d(t[u],e[u],u);l.isUndefined(m)&&d!==a||(n[u]=m)}),n}const rt=t=>{const e=B({},t);let{data:n,withXSRFToken:r,xsrfHeaderName:s,xsrfCookieName:o,headers:i,auth:a}=e;e.headers=i=C.from(i),e.url=Qe(nt(e.baseURL,e.url,e.allowAbsoluteUrls),t.params,t.paramsSerializer),a&&i.set("Authorization","Basic "+btoa((a.username||"")+":"+(a.password?unescape(encodeURIComponent(a.password)):"")));let f;if(l.isFormData(n)){if(v.hasStandardBrowserEnv||v.hasStandardBrowserWebWorkerEnv)i.setContentType(void 0);else if((f=i.getContentType())!==!1){const[c,...u]=f?f.split(";").map(d=>d.trim()).filter(Boolean):[];i.setContentType([c||"multipart/form-data",...u].join("; "))}}if(v.hasStandardBrowserEnv&&(r&&l.isFunction(r)&&(r=r(e)),r||r!==!1&&Pn(e.url))){const c=s&&o&&In.read(o);c&&i.set(s,c)}return e},kn=typeof XMLHttpRequest<"u",Fn=kn&&function(t){return new Promise(function(n,r){const s=rt(t);let o=s.data;const i=C.from(s.headers).normalize();let{responseType:a,onUploadProgress:f,onDownloadProgress:c}=s,u,d,m,g,p;function y(){g&&g(),p&&p(),s.cancelToken&&s.cancelToken.unsubscribe(u),s.signal&&s.signal.removeEventListener("abort",u)}let h=new XMLHttpRequest;h.open(s.method.toUpperCase(),s.url,!0),h.timeout=s.timeout;function b(){if(!h)return;const E=C.from("getAllResponseHeaders"in h&&h.getAllResponseHeaders()),R={data:!a||a==="text"||a==="json"?h.responseText:h.response,status:h.status,statusText:h.statusText,headers:E,config:t,request:h};tt(function(P){n(P),y()},function(P){r(P),y()},R),h=null}"onloadend"in h?h.onloadend=b:h.onreadystatechange=function(){!h||h.readyState!==4||h.status===0&&!(h.responseURL&&h.responseURL.indexOf("file:")===0)||setTimeout(b)},h.onabort=function(){h&&(r(new w("Request aborted",w.ECONNABORTED,t,h)),h=null)},h.onerror=function(){r(new w("Network Error",w.ERR_NETWORK,t,h)),h=null},h.ontimeout=function(){let A=s.timeout?"timeout of "+s.timeout+"ms exceeded":"timeout exceeded";const R=s.transitional||Ye;s.timeoutErrorMessage&&(A=s.timeoutErrorMessage),r(new w(A,R.clarifyTimeoutError?w.ETIMEDOUT:w.ECONNABORTED,t,h)),h=null},o===void 0&&i.setContentType(null),"setRequestHeader"in h&&l.forEach(i.toJSON(),function(A,R){h.setRequestHeader(R,A)}),l.isUndefined(s.withCredentials)||(h.withCredentials=!!s.withCredentials),a&&a!=="json"&&(h.responseType=s.responseType),c&&([m,p]=Z(c,!0),h.addEventListener("progress",m)),f&&h.upload&&([d,g]=Z(f),h.upload.addEventListener("progress",d),h.upload.addEventListener("loadend",g)),(s.cancelToken||s.signal)&&(u=E=>{h&&(r(!E||E.type?new j(null,t,h):E),h.abort(),h=null)},s.cancelToken&&s.cancelToken.subscribe(u),s.signal&&(s.signal.aborted?u():s.signal.addEventListener("abort",u)));const S=On(s.url);if(S&&v.protocols.indexOf(S)===-1){r(new w("Unsupported protocol "+S+":",w.ERR_BAD_REQUEST,t));return}h.send(o||null)})},Bn=(t,e)=>{const{length:n}=t=t?t.filter(Boolean):[];if(e||n){let r=new AbortController,s;const o=function(c){if(!s){s=!0,a();const u=c instanceof Error?c:this.reason;r.abort(u instanceof w?u:new j(u instanceof Error?u.message:u))}};let i=e&&setTimeout(()=>{i=null,o(new w(`timeout ${e} of ms exceeded`,w.ETIMEDOUT))},e);const a=()=>{t&&(i&&clearTimeout(i),i=null,t.forEach(c=>{c.unsubscribe?c.unsubscribe(o):c.removeEventListener("abort",o)}),t=null)};t.forEach(c=>c.addEventListener("abort",o));const{signal:f}=r;return f.unsubscribe=()=>l.asap(a),f}},Dn=function*(t,e){let n=t.byteLength;if(n{const s=qn(t,e);let o=0,i,a=f=>{i||(i=!0,r&&r(f))};return new ReadableStream({async pull(f){try{const{done:c,value:u}=await s.next();if(c){a(),f.close();return}let d=u.byteLength;if(n){let m=o+=d;n(m)}f.enqueue(new Uint8Array(u))}catch(c){throw a(c),c}},cancel(f){return a(f),s.return()}},{highWaterMark:2})},oe=typeof fetch=="function"&&typeof Request=="function"&&typeof Response=="function",st=oe&&typeof ReadableStream=="function",Hn=oe&&(typeof TextEncoder=="function"?(t=>e=>t.encode(e))(new TextEncoder):async t=>new Uint8Array(await new Response(t).arrayBuffer())),ot=(t,...e)=>{try{return!!t(...e)}catch{return!1}},jn=st&&ot(()=>{let t=!1;const e=new Request(v.origin,{body:new ReadableStream,method:"POST",get duplex(){return t=!0,"half"}}).headers.has("Content-Type");return t&&!e}),Me=64*1024,pe=st&&ot(()=>l.isReadableStream(new Response("").body)),ee={stream:pe&&(t=>t.body)};oe&&(t=>{["text","arrayBuffer","blob","formData","stream"].forEach(e=>{!ee[e]&&(ee[e]=l.isFunction(t[e])?n=>n[e]():(n,r)=>{throw new w(`Response type '${e}' is not supported`,w.ERR_NOT_SUPPORT,r)})})})(new Response);const $n=async t=>{if(t==null)return 0;if(l.isBlob(t))return t.size;if(l.isSpecCompliantForm(t))return(await new Request(v.origin,{method:"POST",body:t}).arrayBuffer()).byteLength;if(l.isArrayBufferView(t)||l.isArrayBuffer(t))return t.byteLength;if(l.isURLSearchParams(t)&&(t=t+""),l.isString(t))return(await Hn(t)).byteLength},Vn=async(t,e)=>{const n=l.toFiniteNumber(t.getContentLength());return n??$n(e)},zn=oe&&(async t=>{let{url:e,method:n,data:r,signal:s,cancelToken:o,timeout:i,onDownloadProgress:a,onUploadProgress:f,responseType:c,headers:u,withCredentials:d="same-origin",fetchOptions:m}=rt(t);c=c?(c+"").toLowerCase():"text";let g=Bn([s,o&&o.toAbortSignal()],i),p;const y=g&&g.unsubscribe&&(()=>{g.unsubscribe()});let h;try{if(f&&jn&&n!=="get"&&n!=="head"&&(h=await Vn(u,r))!==0){let R=new Request(e,{method:"POST",body:r,duplex:"half"}),N;if(l.isFormData(r)&&(N=R.headers.get("content-type"))&&u.setContentType(N),R.body){const[P,G]=xe(h,Z(Ne(f)));r=Ie(R.body,Me,P,G)}}l.isString(d)||(d=d?"include":"omit");const b="credentials"in Request.prototype;p=new Request(e,{...m,signal:g,method:n.toUpperCase(),headers:u.normalize().toJSON(),body:r,duplex:"half",credentials:b?d:void 0});let S=await fetch(p,m);const E=pe&&(c==="stream"||c==="response");if(pe&&(a||E&&y)){const R={};["status","statusText","headers"].forEach(be=>{R[be]=S[be]});const N=l.toFiniteNumber(S.headers.get("content-length")),[P,G]=a&&xe(N,Z(Ne(a),!0))||[];S=new Response(Ie(S.body,Me,P,()=>{G&&G(),y&&y()}),R)}c=c||"text";let A=await ee[l.findKey(ee,c)||"text"](S,t);return!E&&y&&y(),await new Promise((R,N)=>{tt(R,N,{data:A,headers:C.from(S.headers),status:S.status,statusText:S.statusText,config:t,request:p})})}catch(b){throw y&&y(),b&&b.name==="TypeError"&&/Load failed|fetch/i.test(b.message)?Object.assign(new w("Network Error",w.ERR_NETWORK,t,p),{cause:b.cause||b}):w.from(b,b&&b.code,t,p)}}),me={http:on,xhr:Fn,fetch:zn};l.forEach(me,(t,e)=>{if(t){try{Object.defineProperty(t,"name",{value:e})}catch{}Object.defineProperty(t,"adapterName",{value:e})}});const Le=t=>`- ${t}`,Jn=t=>l.isFunction(t)||t===null||t===!1,it={getAdapter:t=>{t=l.isArray(t)?t:[t];const{length:e}=t;let n,r;const s={};for(let o=0;o`adapter ${a} `+(f===!1?"is not supported by the environment":"is not available in the build"));let i=e?o.length>1?`since : -`+o.map(Le).join(` -`):" "+Le(o[0]):"as no adapter specified";throw new w("There is no suitable adapter to dispatch the request "+i,"ERR_NOT_SUPPORT")}return r},adapters:me};function ue(t){if(t.cancelToken&&t.cancelToken.throwIfRequested(),t.signal&&t.signal.aborted)throw new j(null,t)}function ke(t){return ue(t),t.headers=C.from(t.headers),t.data=le.call(t,t.transformRequest),["post","put","patch"].indexOf(t.method)!==-1&&t.headers.setContentType("application/x-www-form-urlencoded",!1),it.getAdapter(t.adapter||W.adapter)(t).then(function(r){return ue(t),r.data=le.call(t,t.transformResponse,r),r.headers=C.from(r.headers),r},function(r){return et(r)||(ue(t),r&&r.response&&(r.response.data=le.call(t,t.transformResponse,r.response),r.response.headers=C.from(r.response.headers))),Promise.reject(r)})}const at="1.11.0",ie={};["object","boolean","number","function","string","symbol"].forEach((t,e)=>{ie[t]=function(r){return typeof r===t||"a"+(e<1?"n ":" ")+t}});const Fe={};ie.transitional=function(e,n,r){function s(o,i){return"[Axios v"+at+"] Transitional option '"+o+"'"+i+(r?". "+r:"")}return(o,i,a)=>{if(e===!1)throw new w(s(i," has been removed"+(n?" in "+n:"")),w.ERR_DEPRECATED);return n&&!Fe[i]&&(Fe[i]=!0,console.warn(s(i," has been deprecated since v"+n+" and will be removed in the near future"))),e?e(o,i,a):!0}};ie.spelling=function(e){return(n,r)=>(console.warn(`${r} is likely a misspelling of ${e}`),!0)};function Kn(t,e,n){if(typeof t!="object")throw new w("options must be an object",w.ERR_BAD_OPTION_VALUE);const r=Object.keys(t);let s=r.length;for(;s-- >0;){const o=r[s],i=e[o];if(i){const a=t[o],f=a===void 0||i(a,o,t);if(f!==!0)throw new w("option "+o+" must be "+f,w.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new w("Unknown option "+o,w.ERR_BAD_OPTION)}}const Y={assertOptions:Kn,validators:ie},x=Y.validators;let F=class{constructor(e){this.defaults=e||{},this.interceptors={request:new Ae,response:new Ae}}async request(e,n){try{return await this._request(e,n)}catch(r){if(r instanceof Error){let s={};Error.captureStackTrace?Error.captureStackTrace(s):s=new Error;const o=s.stack?s.stack.replace(/^.+\n/,""):"";try{r.stack?o&&!String(r.stack).endsWith(o.replace(/^.+\n.+\n/,""))&&(r.stack+=` -`+o):r.stack=o}catch{}}throw r}}_request(e,n){typeof e=="string"?(n=n||{},n.url=e):n=e||{},n=B(this.defaults,n);const{transitional:r,paramsSerializer:s,headers:o}=n;r!==void 0&&Y.assertOptions(r,{silentJSONParsing:x.transitional(x.boolean),forcedJSONParsing:x.transitional(x.boolean),clarifyTimeoutError:x.transitional(x.boolean)},!1),s!=null&&(l.isFunction(s)?n.paramsSerializer={serialize:s}:Y.assertOptions(s,{encode:x.function,serialize:x.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),Y.assertOptions(n,{baseUrl:x.spelling("baseURL"),withXsrfToken:x.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let i=o&&l.merge(o.common,o[n.method]);o&&l.forEach(["delete","get","head","post","put","patch","common"],p=>{delete o[p]}),n.headers=C.concat(i,o);const a=[];let f=!0;this.interceptors.request.forEach(function(y){typeof y.runWhen=="function"&&y.runWhen(n)===!1||(f=f&&y.synchronous,a.unshift(y.fulfilled,y.rejected))});const c=[];this.interceptors.response.forEach(function(y){c.push(y.fulfilled,y.rejected)});let u,d=0,m;if(!f){const p=[ke.bind(this),void 0];for(p.unshift(...a),p.push(...c),m=p.length,u=Promise.resolve(n);d{if(!r._listeners)return;let o=r._listeners.length;for(;o-- >0;)r._listeners[o](s);r._listeners=null}),this.promise.then=s=>{let o;const i=new Promise(a=>{r.subscribe(a),o=a}).then(s);return i.cancel=function(){r.unsubscribe(o)},i},e(function(o,i,a){r.reason||(r.reason=new j(o,i,a),n(r.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const n=this._listeners.indexOf(e);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const e=new AbortController,n=r=>{e.abort(r)};return this.subscribe(n),e.signal.unsubscribe=()=>this.unsubscribe(n),e.signal}static source(){let e;return{token:new ct(function(s){e=s}),cancel:e}}};function Gn(t){return function(n){return t.apply(null,n)}}function Xn(t){return l.isObject(t)&&t.isAxiosError===!0}const ye={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(ye).forEach(([t,e])=>{ye[e]=t});function lt(t){const e=new F(t),n=qe(F.prototype.request,e);return l.extend(n,F.prototype,e,{allOwnKeys:!0}),l.extend(n,e,null,{allOwnKeys:!0}),n.create=function(s){return lt(B(t,s))},n}const T=lt(W);T.Axios=F;T.CanceledError=j;T.CancelToken=Wn;T.isCancel=et;T.VERSION=at;T.toFormData=se;T.AxiosError=w;T.Cancel=T.CanceledError;T.all=function(e){return Promise.all(e)};T.spread=Gn;T.isAxiosError=Xn;T.mergeConfig=B;T.AxiosHeaders=C;T.formToJSON=t=>Ze(l.isHTMLForm(t)?new FormData(t):t);T.getAdapter=it.getAdapter;T.HttpStatusCode=ye;T.default=T;const{Axios:or,AxiosError:ir,CanceledError:ar,isCancel:cr,CancelToken:lr,VERSION:ur,all:fr,Cancel:dr,isAxiosError:hr,spread:pr,toFormData:mr,AxiosHeaders:yr,HttpStatusCode:gr,formToJSON:wr,getAdapter:Er,mergeConfig:br}=T,U=T.create({baseURL:"https://notable-recently-seagull.ngrok-free.app/api/v1/",headers:{"Content-Type":"application/json"}});class Qn{async sendSingleMessage(e){try{const{data:n}=await U.post("/messages",e);return console.log("[NestJS] Response (single):",n),n}catch(n){throw console.error("[NestJS] Error (single):",n),n}}async sendBulkMessages(e){try{const{data:n}=await U.post("/messages/bulk",{data:e});return console.log("[NestJS] Response (bulk):",n),n}catch(n){throw console.error("[NestJS] Error (bulk):",n),n}}async createAndSendToZulip(e){try{const{data:n}=await U.post("/messages/create-and-send",{data:e});return console.log("[NestJS] Response (create and send):",n),n}catch(n){throw console.error("[NestJS] Error (create and send):",n),n}}async sendLog(e){try{const{data:n}=await U.post("/messages/logs",e);return console.log("[NestJS] Response (logs):",n),n}catch(n){throw console.error("[NestJS] Error (logs):",n),n}}}const M=new Qn;class Yn{MY_NAME="Apactech com";lastMessage;initialHistories=[];elTags={container_scroll:"/html/body/div[1]/div/div/div/div[5]/div[1]/div[1]/div[2]/div[1]/div[1]/div",conatainer_conversations:"/html/body/div[1]/div/div/div/div[5]/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[1]",container_chat:'[data-testid="message-wrapper"]',root_id:'[aria-selected="true"] [id^="chat-list-item"]',room_name:'[data-tid="chat-title"]',close_reply_btn:'[data-track-action-scenario="messageQuotedReplyDismissed"]',reply_btn:'[aria-label="Reply"]',chat_input:'[placeholder="Type a message"]'};getCurrentRoomInfo(){const e=document.querySelector(this.elTags.root_id)?.id?.replace("chat-list-item_",""),n=document.querySelector(this.elTags.room_name)?.innerText;return{room_id:e,room_name:n}}_getMessageByEl(e){if(!e)return"";let n=e.innerText||"";const r=e.querySelector("img[data-gallery-src]");if(r)return r.getAttribute("data-gallery-src")||"";const o=Array.from(e.querySelectorAll("img[itemtype]")).map(i=>i.getAttribute("alt")||"").filter(Boolean);return o.length&&(n+=o.join("")),n.trim()}parseMessageElement(e,n=!1){const r=e.querySelector(n?".fui-ChatMyMessage__timestamp":".fui-ChatMessage__timestamp"),s=e.querySelector(n?".fui-ChatMyMessage__author":".fui-ChatMessage__author");if(!r)return null;const o=r.getAttribute("datetime");if(!o)return null;const i=Number.isNaN(r.id.replace("timestamp-",""))?new Date(o).getTime():Number(r.id.replace("timestamp-","")),a=document.querySelector(`#content-${i}`),{room_id:f,room_name:c}=this.getCurrentRoomInfo();return{name:s?.innerText,message:this._getMessageByEl(a),time:i,room_id:f,room_name:c,date_time:new Date(o).getTime()}}extractAllMessages(){const e=Array.from(document.querySelectorAll(".fui-ChatMyMessage")).map(r=>this.parseMessageElement(r,!0)).filter(r=>r!==null),n=Array.from(document.querySelectorAll(".fui-ChatMessage")).map(r=>this.parseMessageElement(r,!1)).filter(r=>r!==null);return console.log({myMessages:e,otherMessages:n}),[...e,...n].sort((r,s)=>r.time-s.time)}handleNewMessage(e){console.log("%c[New incoming message]","color: #007acc;",e)}async detectNewMessages(){const e=this.extractAllMessages(),n=e.findIndex(o=>o.time===this.lastMessage?.time),r=e.slice(n+1);if(r.length===0){console.log("[Monitor] No new messages...");return}const s=r[0];return this.lastMessage=e.pop(),s}async start(e=1e4){console.log("[Monitor] Starting..."),this.initialHistories=this.extractAllMessages(),this.lastMessage=this.initialHistories.pop(),setInterval(async()=>await this.detectNewMessages(),e)}async _getConversationsInfo(e=this.elTags.conatainer_conversations){const n=document.evaluate(e,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;return n?Array.from(n.children).filter(o=>o.getAttribute("role")==="none").map(o=>{const i=o.id||null,a=`title-chat-list-item_${i}`,c=document.getElementById(a)?.innerText||null;let u=null;return i?.includes("@thread.skype")?u="group":i?.includes("@oneToOne.skype")?u="personal":u="group",{id:i,name:c,type:u}}):(console.log("Không tìm thấy phần tử theo XPath."),M.sendLog({type:"error",message:`Not found selector: ${e}`}),[])}async _scrollToBottomByXPath(e=this.elTags.container_scroll,n){const{maxStableRounds:r=5,delay:s=300,maxScrolls:o=100}=n||{},i=document.evaluate(e,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;if(!i){console.warn("❌ Không tìm thấy phần tử với XPath:",e),M.sendLog({type:"error",message:`Not found selector: ${e}`});return}return new Promise(a=>{let f=-1,c=0,u=0;const d=setInterval(()=>{const m=i.scrollHeight;i.scrollTop=m,m===f?c++:(c=0,f=m),u++,(c>=r||u>=o)&&(clearInterval(d),a())},s)})}async handleGetConversations(){return await this._scrollToBottomByXPath(),this._getConversationsInfo()}}class Zn{axios=null;constructor(){this.axios=T.create({baseURL:"MyCoolApp",headers:{"Content-Type":"application/json"}})}async send(e){if(!this.axios)return null;const{data:n}=await this.axios({method:"POST",url:"type",data:{message:e}});return n}}const Be=new Zn;function I(t){return new Promise(e=>setTimeout(e,t))}class er{async index(e){try{const{data:n}=await U({url:"conversations",params:e});return console.log("[NestJS] Response (conversation-index):",n),n}catch(n){throw console.error("[NestJS] Error (conversation-index):",n),n}}async getConversationByPrefix(){try{const{data:e}=await U({url:"conversations/prefix",method:"POST"});return console.log("[NestJS] Response (conversation-prefix):",e),e}catch(e){throw console.error("[NestJS] Error (conversation-prefix):",e),e}}}const tr=new er;class nr{service;port;constructor(e){this.service=new Yn,this.port=e}_forceHeightObserver;getElementByXPath(e){return document.evaluate(e,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue}forceHeight(e,n="100px"){if(!e)return;e.style.setProperty("height",n,"important"),e.style.setProperty("resize","none","important");const r=()=>{e.style.setProperty("height",n,"important")};e.addEventListener("focus",r),e.addEventListener("input",r),e.addEventListener("blur",r);const s=new MutationObserver(()=>{e.style.setProperty("height",n,"important")});s.observe(e,{attributes:!0,attributeFilter:["style"]}),this._forceHeightObserver=s}_clickToConversation(e){const n=document.getElementById(`chat-list-item_${e}`);return n&&(n.scrollIntoView({behavior:"smooth",block:"center"}),setTimeout(()=>n.click(),200)),n?.click()}async _waitForMessagesToAppear(e=1e4){return new Promise((n,r)=>{const s=document.getElementById("chat-pane-list");let o=null;if(!s)return r(new Error("#chat-pane-list not found"));const i=()=>Array.from(s.children),a=()=>{const c=i();c.length>0&&(f.disconnect(),o&&clearTimeout(o),n(c))},f=new MutationObserver(()=>{a()});f.observe(s,{childList:!0,subtree:!0}),a(),o=setTimeout(()=>{f.disconnect(),r(new Error("Timeout waiting for chat messages to appear"))},e)})}async _waitForNewMessages(e,n=1e4){return new Promise((r,s)=>{const o=document.getElementById("chat-pane-list");if(!o)return s(new Error("#chat-pane-list not found"));const i=()=>Array.from(o.children),a=new Set(e);let f=null;const c=new MutationObserver(()=>{const d=i().filter(m=>!a.has(m));d.length>0&&(c.disconnect(),f&&clearTimeout(f),r(d))});c.observe(o,{childList:!0,subtree:!0}),f=setTimeout(()=>{c.disconnect(),s(new Error("Timeout waiting for new messages"))},n)})}async _waitToloadMessages(e=300){return new Promise(n=>{const r=document.getElementById("chat-pane-list");if(!r)throw new Error("#chat-pane-list not found");let s=null,o=[];const i=new MutationObserver(()=>{s&&clearTimeout(s),o=Array.from(r.children),s=setTimeout(()=>{i.disconnect(),n(o)},e)});i.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0})})}_getTypeGeo(){const e=document.querySelector(".ck-placeholder");if(e){const n=e.getBoundingClientRect();return{top:n.top,left:n.left,right:n.right,bottom:n.bottom,width:n.width,height:n.height}}return null}async _rightClickMessage(e){const n=this.service.elTags.container_chat,r=`content-${e}`,s=30,o=200;let i=0,a=document.querySelector(n);if(!a){console.error("Wrapper not found:",n),await M.sendLog({type:"error",message:`Not found selector: ${n}`});return}let f=document.querySelector(`#${r}`);for(;!f&&i{const r=document.querySelector(e);r?(r.scrollIntoView({behavior:"auto",block:"center"}),setTimeout(()=>{r?.click(),n(!0)},100)):(console.warn("Không tìm thấy phần tử:",e),n(!1))})}async getConversations(e){D.add(async()=>{console.log("[Queue] Handling GET_CONVERSATIONS");const n=await this.service.handleGetConversations();this.port.postMessage({type:"socket-response",event:q.RECEIVE_CONVERSATIONS,data:n})})}async getConversation(e){D.add(async()=>{if(console.log("[Queue] Handling GET_CONVERSATION"),!e.data?.id)return;const{room_id:n}=this.service.getCurrentRoomInfo();n!=e.data.id&&(this._clickToConversation(e.data.id),await this._waitForMessagesToAppear(),await this._waitToloadMessages());const r=this.service.extractAllMessages();this.port.postMessage({type:"socket-response",event:q.RECEIVE_CONVERSATION,data:r})})}async sendMessage({data:{conversation_id:e,message:n}}){D.add(async()=>{console.log("[Queue] Handling SEND_MESSAGE");const{room_id:r}=this.service.getCurrentRoomInfo();r!=e&&this._clickToConversation(e),await I(200),await Be.send(n)})}async replyMessage({data:{conversation_id:e,message:n,time:r}}){D.add(async()=>{console.log("[Queue] Handling REPLY_MESSAGE");const{room_id:s}=this.service.getCurrentRoomInfo();s!=e&&(this._clickToConversation(e),await this._waitForMessagesToAppear(),await this._waitToloadMessages()),await this._clickIfExists(this.service.elTags.close_reply_btn),await this._rightClickMessage(r);const o=document.querySelector(this.service.elTags.reply_btn);o&&o.click(),await I(200),console.log({message:n}),await Be.send(n)})}fixedHeightChatInput(e=20,n=1e3){(()=>{const s=document.querySelector(this.service.elTags.chat_input);s?(this.forceHeight(s,"100px"),console.log("✔ Fixed height applied to chat input")):e>0?setTimeout(()=>this.fixedHeightChatInput(e-1,n),n):(console.warn("✘ Element not found with provided XPath after retries"),M.sendLog({type:"error",message:`Not found selector: ${this.service.elTags.chat_input}`}))})()}async detectNewMessage(e=2e3){console.log("[Monitor] Starting..."),this.service.initialHistories=this.service.extractAllMessages(),this.service.lastMessage=this.service.initialHistories.pop(),setInterval(()=>{D.add(async()=>{try{const n=this.service.getCurrentRoomInfo(),r=document.querySelector('[aria-labelledby^="cn-normal-notification-main-content-"]')?.getAttribute("aria-labelledby");if(!r){const a=await this.service.detectNewMessages();if(!a){console.log("[Monitor] No new message...");return}if(n.room_id!==a?.room_id){console.log("[Monitor] Message from another room → skip");return}console.log("[Monitor] Found new message:",a),await this._sendLastMessage(a);return}const s=r.split(" ")[0].replace("cn-normal-notification-main-content-","");if(!s){console.warn("[Monitor] Could not extract room_id from aria-labelledby");return}console.log("[Monitor] Notification detected:",{roomId:s,ariaValue:r}),this._clickToConversation(s),await I(2e3);const i=this.service.extractAllMessages().at(-1);if(!i){console.log("[Queue] No last message found after sync");return}console.log("[Queue] Sending last message:",i),await this._sendLastMessage(i)}catch(n){console.error("[Monitor] Error detecting new message:",n)}})},e)}async _sendLastMessage(e){try{await M.sendSingleMessage(e),console.log("[API] Sent message successfully:",e)}catch(n){console.error("[API] Failed to send message:",n)}}startSyncConversations(){window._chatIntervals=window?._chatIntervals||{},window._chatIntervals.syncConversations?console.log("ℹ️ startSyncConversations already running"):(window._chatIntervals.syncConversations=window.setInterval(()=>{this.getConversations()},6e4),console.log("✅ startSyncConversations running"))}autoSyncConversationPrefixMessages(){window._chatIntervals=window?._chatIntervals||{},window._chatIntervals.syncPrefixMessages?console.log("ℹ️ autoSyncConversationPrefixMessages already running"):(window._chatIntervals.syncPrefixMessages=window.setInterval(()=>{D.add(async()=>{try{const{data:e}=await tr.getConversationByPrefix();if(!e)return;for(const n of e){this._clickToConversation(n.id),await I(2e3);const r=this.service.getCurrentRoomInfo();if(!r||r.room_id!==n.id)return;const s=this.service.extractAllMessages();await M.createAndSendToZulip(s),await I(5e3)}}catch(e){console.error("❌ autoSyncConversationPrefixMessages error:",e?.message),M.sendLog({type:"error",message:`auto_to_sync_conersations: ${e?.message}`})}})},3e4),console.log("✅ autoSyncConversationPrefixMessages running with PQueue"))}}const ut=chrome.runtime.connect({name:"message"}),L=new nr(ut);ut.onMessage.addListener(t=>{if(console.log({msg:t}),L.fixedHeightChatInput(),t.type==="socket")switch(t.event){case q.GET_CONVERSATIONS:{L.getConversations(t);break}case q.GET_CONVERSATION:{L.getConversation(t);break}case q.SEND_MESSAGE:{L.sendMessage(t);break}case q.REPLY_MESSAGE:{L.replyMessage(t);break}}});L.startSyncConversations();L.autoSyncConversationPrefixMessages(); +const U={GET_CONVERSATIONS:"messages.get-conversations",GET_CONVERSATION:"messages.get-conversation",RECEIVE_CONVERSATIONS:"messages.receive-conversations",RECEIVE_CONVERSATION:"messages.receive-conversation",SEND_MESSAGE:"messages.send-messsage",REPLY_MESSAGE:"messages.reply-messsage"};function ht(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var ae={exports:{}},Se;function pt(){return Se||(Se=1,function(t){var e=Object.prototype.hasOwnProperty,n="~";function r(){}Object.create&&(r.prototype=Object.create(null),new r().__proto__||(n=!1));function s(f,c,u){this.fn=f,this.context=c,this.once=u||!1}function o(f,c,u,d,m){if(typeof u!="function")throw new TypeError("The listener must be a function");var g=new s(u,d||f,m),p=n?n+c:c;return f._events[p]?f._events[p].fn?f._events[p]=[f._events[p],g]:f._events[p].push(g):(f._events[p]=g,f._eventsCount++),f}function i(f,c){--f._eventsCount===0?f._events=new r:delete f._events[c]}function a(){this._events=new r,this._eventsCount=0}a.prototype.eventNames=function(){var c=[],u,d;if(this._eventsCount===0)return c;for(d in u=this._events)e.call(u,d)&&c.push(n?d.slice(1):d);return Object.getOwnPropertySymbols?c.concat(Object.getOwnPropertySymbols(u)):c},a.prototype.listeners=function(c){var u=n?n+c:c,d=this._events[u];if(!d)return[];if(d.fn)return[d.fn];for(var m=0,g=d.length,p=new Array(g);mglobalThis.DOMException===void 0?new gt(t):new DOMException(t),Re=t=>{const e=t.reason===void 0?Te("This operation was aborted."):t.reason;return e instanceof Error?e:Te(e)};function wt(t,e){const{milliseconds:n,fallback:r,message:s,customTimers:o={setTimeout,clearTimeout}}=e;let i,a;const c=new Promise((u,d)=>{if(typeof n!="number"||Math.sign(n)!==1)throw new TypeError(`Expected \`milliseconds\` to be a positive number, got \`${n}\``);if(e.signal){const{signal:g}=e;g.aborted&&d(Re(g)),a=()=>{d(Re(g))},g.addEventListener("abort",a,{once:!0})}if(n===Number.POSITIVE_INFINITY){t.then(u,d);return}const m=new qe;i=o.setTimeout.call(void 0,()=>{if(r){try{u(r())}catch(g){d(g)}return}typeof t.cancel=="function"&&t.cancel(),s===!1?u():s instanceof Error?d(s):(m.message=s??`Promise timed out after ${n} milliseconds`,d(m))},n),(async()=>{try{u(await t)}catch(g){d(g)}})()}).finally(()=>{c.clear(),a&&e.signal&&e.signal.removeEventListener("abort",a)});return c.clear=()=>{o.clearTimeout.call(void 0,i),i=void 0},c}function bt(t,e,n){let r=0,s=t.length;for(;s>0;){const o=Math.trunc(s/2);let i=r+o;n(t[i],e)<=0?(r=++i,s-=o+1):s=o}return r}class Et{#e=[];enqueue(e,n){n={priority:0,...n};const r={priority:n.priority,id:n.id,run:e};if(this.size===0||this.#e[this.size-1].priority>=n.priority){this.#e.push(r);return}const s=bt(this.#e,r,(o,i)=>i.priority-o.priority);this.#e.splice(s,0,r)}setPriority(e,n){const r=this.#e.findIndex(o=>o.id===e);if(r===-1)throw new ReferenceError(`No promise function with the id "${e}" exists in the queue.`);const[s]=this.#e.splice(r,1);this.enqueue(s.run,{priority:n,id:e})}dequeue(){return this.#e.shift()?.run}filter(e){return this.#e.filter(n=>n.priority===e.priority).map(n=>n.run)}get size(){return this.#e.length}}class St extends yt{#e;#i;#o=0;#h;#a;#p=0;#n;#c;#t;#m;#r=0;#l;#s;#y;#b=1n;timeout;constructor(e){if(super(),e={carryoverConcurrencyCount:!1,intervalCap:Number.POSITIVE_INFINITY,interval:0,concurrency:Number.POSITIVE_INFINITY,autoStart:!0,queueClass:Et,...e},!(typeof e.intervalCap=="number"&&e.intervalCap>=1))throw new TypeError(`Expected \`intervalCap\` to be a number from 1 and up, got \`${e.intervalCap?.toString()??""}\` (${typeof e.intervalCap})`);if(e.interval===void 0||!(Number.isFinite(e.interval)&&e.interval>=0))throw new TypeError(`Expected \`interval\` to be a finite number >= 0, got \`${e.interval?.toString()??""}\` (${typeof e.interval})`);this.#e=e.carryoverConcurrencyCount,this.#i=e.intervalCap===Number.POSITIVE_INFINITY||e.interval===0,this.#h=e.intervalCap,this.#a=e.interval,this.#t=new e.queueClass,this.#m=e.queueClass,this.concurrency=e.concurrency,this.timeout=e.timeout,this.#y=e.throwOnTimeout===!0,this.#s=e.autoStart===!1}get#E(){return this.#i||this.#o{this.#R()},n)),!0}return!1}#u(){if(this.#t.size===0)return this.#n&&clearInterval(this.#n),this.#n=void 0,this.emit("empty"),this.#r===0&&this.emit("idle"),!1;if(!this.#s){const e=!this.#v;if(this.#E&&this.#S){const n=this.#t.dequeue();return n?(this.emit("active"),n(),e&&this.#g(),!0):!1}}return!1}#g(){this.#i||this.#n!==void 0||(this.#n=setInterval(()=>{this.#w()},this.#a),this.#p=Date.now()+this.#a)}#w(){this.#o===0&&this.#r===0&&this.#n&&(clearInterval(this.#n),this.#n=void 0),this.#o=this.#e?this.#r:0,this.#f()}#f(){for(;this.#u(););}get concurrency(){return this.#l}set concurrency(e){if(!(typeof e=="number"&&e>=1))throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${e}\` (${typeof e})`);this.#l=e,this.#f()}async#_(e){return new Promise((n,r)=>{e.addEventListener("abort",()=>{r(e.reason)},{once:!0})})}setPriority(e,n){this.#t.setPriority(e,n)}async add(e,n={}){return n.id??=(this.#b++).toString(),n={timeout:this.timeout,throwOnTimeout:this.#y,...n},new Promise((r,s)=>{this.#t.enqueue(async()=>{this.#r++,this.#o++;try{n.signal?.throwIfAborted();let o=e({signal:n.signal});n.timeout&&(o=wt(Promise.resolve(o),{milliseconds:n.timeout})),n.signal&&(o=Promise.race([o,this.#_(n.signal)]));const i=await o;r(i),this.emit("completed",i)}catch(o){if(o instanceof qe&&!n.throwOnTimeout){r();return}s(o),this.emit("error",o)}finally{this.#T()}},n),this.emit("add"),this.#u()})}async addAll(e,n){return Promise.all(e.map(async r=>this.add(r,n)))}start(){return this.#s?(this.#s=!1,this.#f(),this):this}pause(){this.#s=!0}clear(){this.#t=new this.#m}async onEmpty(){this.#t.size!==0&&await this.#d("empty")}async onSizeLessThan(e){this.#t.sizethis.#t.size{const s=()=>{n&&!n()||(this.off(e,s),r())};this.on(e,s)})}get size(){return this.#t.size}sizeBy(e){return this.#t.filter(e).length}get pending(){return this.#r}get isPaused(){return this.#s}}const D=new St({concurrency:1});function I(t){return new Promise(e=>setTimeout(e,t))}async function ve(t){const n=await(await fetch(t)).blob();return new Promise((r,s)=>{const o=new FileReader;o.onloadend=()=>{typeof o.result=="string"?r(o.result.split(",")[1]):s("Không thể đọc dữ liệu ảnh")},o.onerror=s,o.readAsDataURL(n)})}function _e(t){return t.startsWith("blob:")}function He(t,e){return function(){return t.apply(e,arguments)}}const{toString:Tt}=Object.prototype,{getPrototypeOf:ge}=Object,{iterator:te,toStringTag:je}=Symbol,ne=(t=>e=>{const n=Tt.call(e);return t[n]||(t[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),O=t=>(t=t.toLowerCase(),e=>ne(e)===t),re=t=>e=>typeof e===t,{isArray:H}=Array,V=re("undefined");function z(t){return t!==null&&!V(t)&&t.constructor!==null&&!V(t.constructor)&&_(t.constructor.isBuffer)&&t.constructor.isBuffer(t)}const $e=O("ArrayBuffer");function Rt(t){let e;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?e=ArrayBuffer.isView(t):e=t&&t.buffer&&$e(t.buffer),e}const vt=re("string"),_=re("function"),Ve=re("number"),J=t=>t!==null&&typeof t=="object",_t=t=>t===!0||t===!1,X=t=>{if(ne(t)!=="object")return!1;const e=ge(t);return(e===null||e===Object.prototype||Object.getPrototypeOf(e)===null)&&!(je in t)&&!(te in t)},At=t=>{if(!J(t)||z(t))return!1;try{return Object.keys(t).length===0&&Object.getPrototypeOf(t)===Object.prototype}catch{return!1}},Ct=O("Date"),Ot=O("File"),xt=O("Blob"),Nt=O("FileList"),Pt=t=>J(t)&&_(t.pipe),It=t=>{let e;return t&&(typeof FormData=="function"&&t instanceof FormData||_(t.append)&&((e=ne(t))==="formdata"||e==="object"&&_(t.toString)&&t.toString()==="[object FormData]"))},Mt=O("URLSearchParams"),[Lt,kt,Ft,Bt]=["ReadableStream","Request","Response","Headers"].map(O),Dt=t=>t.trim?t.trim():t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function K(t,e,{allOwnKeys:n=!1}={}){if(t===null||typeof t>"u")return;let r,s;if(typeof t!="object"&&(t=[t]),H(t))for(r=0,s=t.length;r0;)if(s=n[r],e===s.toLowerCase())return s;return null}const k=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,Je=t=>!V(t)&&t!==k;function fe(){const{caseless:t}=Je(this)&&this||{},e={},n=(r,s)=>{const o=t&&ze(e,s)||s;X(e[o])&&X(r)?e[o]=fe(e[o],r):X(r)?e[o]=fe({},r):H(r)?e[o]=r.slice():e[o]=r};for(let r=0,s=arguments.length;r(K(e,(s,o)=>{n&&_(s)?t[o]=He(s,n):t[o]=s},{allOwnKeys:r}),t),qt=t=>(t.charCodeAt(0)===65279&&(t=t.slice(1)),t),Ht=(t,e,n,r)=>{t.prototype=Object.create(e.prototype,r),t.prototype.constructor=t,Object.defineProperty(t,"super",{value:e.prototype}),n&&Object.assign(t.prototype,n)},jt=(t,e,n,r)=>{let s,o,i;const a={};if(e=e||{},t==null)return e;do{for(s=Object.getOwnPropertyNames(t),o=s.length;o-- >0;)i=s[o],(!r||r(i,t,e))&&!a[i]&&(e[i]=t[i],a[i]=!0);t=n!==!1&&ge(t)}while(t&&(!n||n(t,e))&&t!==Object.prototype);return e},$t=(t,e,n)=>{t=String(t),(n===void 0||n>t.length)&&(n=t.length),n-=e.length;const r=t.indexOf(e,n);return r!==-1&&r===n},Vt=t=>{if(!t)return null;if(H(t))return t;let e=t.length;if(!Ve(e))return null;const n=new Array(e);for(;e-- >0;)n[e]=t[e];return n},zt=(t=>e=>t&&e instanceof t)(typeof Uint8Array<"u"&&ge(Uint8Array)),Jt=(t,e)=>{const r=(t&&t[te]).call(t);let s;for(;(s=r.next())&&!s.done;){const o=s.value;e.call(t,o[0],o[1])}},Kt=(t,e)=>{let n;const r=[];for(;(n=t.exec(e))!==null;)r.push(n);return r},Wt=O("HTMLFormElement"),Gt=t=>t.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,r,s){return r.toUpperCase()+s}),Ae=(({hasOwnProperty:t})=>(e,n)=>t.call(e,n))(Object.prototype),Xt=O("RegExp"),Ke=(t,e)=>{const n=Object.getOwnPropertyDescriptors(t),r={};K(n,(s,o)=>{let i;(i=e(s,o,t))!==!1&&(r[o]=i||s)}),Object.defineProperties(t,r)},Qt=t=>{Ke(t,(e,n)=>{if(_(t)&&["arguments","caller","callee"].indexOf(n)!==-1)return!1;const r=t[n];if(_(r)){if(e.enumerable=!1,"writable"in e){e.writable=!1;return}e.set||(e.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},Yt=(t,e)=>{const n={},r=s=>{s.forEach(o=>{n[o]=!0})};return H(t)?r(t):r(String(t).split(e)),n},Zt=()=>{},en=(t,e)=>t!=null&&Number.isFinite(t=+t)?t:e;function tn(t){return!!(t&&_(t.append)&&t[je]==="FormData"&&t[te])}const nn=t=>{const e=new Array(10),n=(r,s)=>{if(J(r)){if(e.indexOf(r)>=0)return;if(z(r))return r;if(!("toJSON"in r)){e[s]=r;const o=H(r)?[]:{};return K(r,(i,a)=>{const f=n(i,s+1);!V(f)&&(o[a]=f)}),e[s]=void 0,o}}return r};return n(t,0)},rn=O("AsyncFunction"),sn=t=>t&&(J(t)||_(t))&&_(t.then)&&_(t.catch),We=((t,e)=>t?setImmediate:e?((n,r)=>(k.addEventListener("message",({source:s,data:o})=>{s===k&&o===n&&r.length&&r.shift()()},!1),s=>{r.push(s),k.postMessage(n,"*")}))(`axios@${Math.random()}`,[]):n=>setTimeout(n))(typeof setImmediate=="function",_(k.postMessage)),on=typeof queueMicrotask<"u"?queueMicrotask.bind(k):typeof process<"u"&&process.nextTick||We,an=t=>t!=null&&_(t[te]),l={isArray:H,isArrayBuffer:$e,isBuffer:z,isFormData:It,isArrayBufferView:Rt,isString:vt,isNumber:Ve,isBoolean:_t,isObject:J,isPlainObject:X,isEmptyObject:At,isReadableStream:Lt,isRequest:kt,isResponse:Ft,isHeaders:Bt,isUndefined:V,isDate:Ct,isFile:Ot,isBlob:xt,isRegExp:Xt,isFunction:_,isStream:Pt,isURLSearchParams:Mt,isTypedArray:zt,isFileList:Nt,forEach:K,merge:fe,extend:Ut,trim:Dt,stripBOM:qt,inherits:Ht,toFlatObject:jt,kindOf:ne,kindOfTest:O,endsWith:$t,toArray:Vt,forEachEntry:Jt,matchAll:Kt,isHTMLForm:Wt,hasOwnProperty:Ae,hasOwnProp:Ae,reduceDescriptors:Ke,freezeMethods:Qt,toObjectSet:Yt,toCamelCase:Gt,noop:Zt,toFiniteNumber:en,findKey:ze,global:k,isContextDefined:Je,isSpecCompliantForm:tn,toJSONObject:nn,isAsyncFn:rn,isThenable:sn,setImmediate:We,asap:on,isIterable:an};function w(t,e,n,r,s){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack,this.message=t,this.name="AxiosError",e&&(this.code=e),n&&(this.config=n),r&&(this.request=r),s&&(this.response=s,this.status=s.status?s.status:null)}l.inherits(w,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:l.toJSONObject(this.config),code:this.code,status:this.status}}});const Ge=w.prototype,Xe={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach(t=>{Xe[t]={value:t}});Object.defineProperties(w,Xe);Object.defineProperty(Ge,"isAxiosError",{value:!0});w.from=(t,e,n,r,s,o)=>{const i=Object.create(Ge);return l.toFlatObject(t,i,function(f){return f!==Error.prototype},a=>a!=="isAxiosError"),w.call(i,t.message,e,n,r,s),i.cause=t,i.name=t.name,o&&Object.assign(i,o),i};const cn=null;function de(t){return l.isPlainObject(t)||l.isArray(t)}function Qe(t){return l.endsWith(t,"[]")?t.slice(0,-2):t}function Ce(t,e,n){return t?t.concat(e).map(function(s,o){return s=Qe(s),!n&&o?"["+s+"]":s}).join(n?".":""):e}function ln(t){return l.isArray(t)&&!t.some(de)}const un=l.toFlatObject(l,{},null,function(e){return/^is[A-Z]/.test(e)});function se(t,e,n){if(!l.isObject(t))throw new TypeError("target must be an object");e=e||new FormData,n=l.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(y,h){return!l.isUndefined(h[y])});const r=n.metaTokens,s=n.visitor||u,o=n.dots,i=n.indexes,f=(n.Blob||typeof Blob<"u"&&Blob)&&l.isSpecCompliantForm(e);if(!l.isFunction(s))throw new TypeError("visitor must be a function");function c(p){if(p===null)return"";if(l.isDate(p))return p.toISOString();if(l.isBoolean(p))return p.toString();if(!f&&l.isBlob(p))throw new w("Blob is not supported. Use a Buffer instead.");return l.isArrayBuffer(p)||l.isTypedArray(p)?f&&typeof Blob=="function"?new Blob([p]):Buffer.from(p):p}function u(p,y,h){let E=p;if(p&&!h&&typeof p=="object"){if(l.endsWith(y,"{}"))y=r?y:y.slice(0,-2),p=JSON.stringify(p);else if(l.isArray(p)&&ln(p)||(l.isFileList(p)||l.endsWith(y,"[]"))&&(E=l.toArray(p)))return y=Qe(y),E.forEach(function(b,C){!(l.isUndefined(b)||b===null)&&e.append(i===!0?Ce([y],C,o):i===null?y:y+"[]",c(b))}),!1}return de(p)?!0:(e.append(Ce(h,y,o),c(p)),!1)}const d=[],m=Object.assign(un,{defaultVisitor:u,convertValue:c,isVisitable:de});function g(p,y){if(!l.isUndefined(p)){if(d.indexOf(p)!==-1)throw Error("Circular reference detected in "+y.join("."));d.push(p),l.forEach(p,function(E,S){(!(l.isUndefined(E)||E===null)&&s.call(e,E,l.isString(S)?S.trim():S,y,m))===!0&&g(E,y?y.concat(S):[S])}),d.pop()}}if(!l.isObject(t))throw new TypeError("data must be an object");return g(t),e}function Oe(t){const e={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(t).replace(/[!'()~]|%20|%00/g,function(r){return e[r]})}function we(t,e){this._pairs=[],t&&se(t,this,e)}const Ye=we.prototype;Ye.append=function(e,n){this._pairs.push([e,n])};Ye.toString=function(e){const n=e?function(r){return e.call(this,r,Oe)}:Oe;return this._pairs.map(function(s){return n(s[0])+"="+n(s[1])},"").join("&")};function fn(t){return encodeURIComponent(t).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function Ze(t,e,n){if(!e)return t;const r=n&&n.encode||fn;l.isFunction(n)&&(n={serialize:n});const s=n&&n.serialize;let o;if(s?o=s(e,n):o=l.isURLSearchParams(e)?e.toString():new we(e,n).toString(r),o){const i=t.indexOf("#");i!==-1&&(t=t.slice(0,i)),t+=(t.indexOf("?")===-1?"?":"&")+o}return t}class xe{constructor(){this.handlers=[]}use(e,n,r){return this.handlers.push({fulfilled:e,rejected:n,synchronous:r?r.synchronous:!1,runWhen:r?r.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(e){l.forEach(this.handlers,function(r){r!==null&&e(r)})}}const et={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},dn=typeof URLSearchParams<"u"?URLSearchParams:we,hn=typeof FormData<"u"?FormData:null,pn=typeof Blob<"u"?Blob:null,mn={isBrowser:!0,classes:{URLSearchParams:dn,FormData:hn,Blob:pn},protocols:["http","https","file","blob","url","data"]},be=typeof window<"u"&&typeof document<"u",he=typeof navigator=="object"&&navigator||void 0,yn=be&&(!he||["ReactNative","NativeScript","NS"].indexOf(he.product)<0),gn=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",wn=be&&window.location.href||"http://localhost",bn=Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:be,hasStandardBrowserEnv:yn,hasStandardBrowserWebWorkerEnv:gn,navigator:he,origin:wn},Symbol.toStringTag,{value:"Module"})),v={...bn,...mn};function En(t,e){return se(t,new v.classes.URLSearchParams,{visitor:function(n,r,s,o){return v.isNode&&l.isBuffer(n)?(this.append(r,n.toString("base64")),!1):o.defaultVisitor.apply(this,arguments)},...e})}function Sn(t){return l.matchAll(/\w+|\[(\w*)]/g,t).map(e=>e[0]==="[]"?"":e[1]||e[0])}function Tn(t){const e={},n=Object.keys(t);let r;const s=n.length;let o;for(r=0;r=n.length;return i=!i&&l.isArray(s)?s.length:i,f?(l.hasOwnProp(s,i)?s[i]=[s[i],r]:s[i]=r,!a):((!s[i]||!l.isObject(s[i]))&&(s[i]=[]),e(n,r,s[i],o)&&l.isArray(s[i])&&(s[i]=Tn(s[i])),!a)}if(l.isFormData(t)&&l.isFunction(t.entries)){const n={};return l.forEachEntry(t,(r,s)=>{e(Sn(r),s,n,0)}),n}return null}function Rn(t,e,n){if(l.isString(t))try{return(e||JSON.parse)(t),l.trim(t)}catch(r){if(r.name!=="SyntaxError")throw r}return(n||JSON.stringify)(t)}const W={transitional:et,adapter:["xhr","http","fetch"],transformRequest:[function(e,n){const r=n.getContentType()||"",s=r.indexOf("application/json")>-1,o=l.isObject(e);if(o&&l.isHTMLForm(e)&&(e=new FormData(e)),l.isFormData(e))return s?JSON.stringify(tt(e)):e;if(l.isArrayBuffer(e)||l.isBuffer(e)||l.isStream(e)||l.isFile(e)||l.isBlob(e)||l.isReadableStream(e))return e;if(l.isArrayBufferView(e))return e.buffer;if(l.isURLSearchParams(e))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();let a;if(o){if(r.indexOf("application/x-www-form-urlencoded")>-1)return En(e,this.formSerializer).toString();if((a=l.isFileList(e))||r.indexOf("multipart/form-data")>-1){const f=this.env&&this.env.FormData;return se(a?{"files[]":e}:e,f&&new f,this.formSerializer)}}return o||s?(n.setContentType("application/json",!1),Rn(e)):e}],transformResponse:[function(e){const n=this.transitional||W.transitional,r=n&&n.forcedJSONParsing,s=this.responseType==="json";if(l.isResponse(e)||l.isReadableStream(e))return e;if(e&&l.isString(e)&&(r&&!this.responseType||s)){const i=!(n&&n.silentJSONParsing)&&s;try{return JSON.parse(e)}catch(a){if(i)throw a.name==="SyntaxError"?w.from(a,w.ERR_BAD_RESPONSE,this,null,this.response):a}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:v.classes.FormData,Blob:v.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};l.forEach(["delete","get","head","post","put","patch"],t=>{W.headers[t]={}});const vn=l.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),_n=t=>{const e={};let n,r,s;return t&&t.split(` +`).forEach(function(i){s=i.indexOf(":"),n=i.substring(0,s).trim().toLowerCase(),r=i.substring(s+1).trim(),!(!n||e[n]&&vn[n])&&(n==="set-cookie"?e[n]?e[n].push(r):e[n]=[r]:e[n]=e[n]?e[n]+", "+r:r)}),e},Ne=Symbol("internals");function $(t){return t&&String(t).trim().toLowerCase()}function Q(t){return t===!1||t==null?t:l.isArray(t)?t.map(Q):String(t)}function An(t){const e=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(t);)e[r[1]]=r[2];return e}const Cn=t=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(t.trim());function ce(t,e,n,r,s){if(l.isFunction(r))return r.call(this,e,n);if(s&&(e=n),!!l.isString(e)){if(l.isString(r))return e.indexOf(r)!==-1;if(l.isRegExp(r))return r.test(e)}}function On(t){return t.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(e,n,r)=>n.toUpperCase()+r)}function xn(t,e){const n=l.toCamelCase(" "+e);["get","set","has"].forEach(r=>{Object.defineProperty(t,r+n,{value:function(s,o,i){return this[r].call(this,e,s,o,i)},configurable:!0})})}let A=class{constructor(e){e&&this.set(e)}set(e,n,r){const s=this;function o(a,f,c){const u=$(f);if(!u)throw new Error("header name must be a non-empty string");const d=l.findKey(s,u);(!d||s[d]===void 0||c===!0||c===void 0&&s[d]!==!1)&&(s[d||f]=Q(a))}const i=(a,f)=>l.forEach(a,(c,u)=>o(c,u,f));if(l.isPlainObject(e)||e instanceof this.constructor)i(e,n);else if(l.isString(e)&&(e=e.trim())&&!Cn(e))i(_n(e),n);else if(l.isObject(e)&&l.isIterable(e)){let a={},f,c;for(const u of e){if(!l.isArray(u))throw TypeError("Object iterator must return a key-value pair");a[c=u[0]]=(f=a[c])?l.isArray(f)?[...f,u[1]]:[f,u[1]]:u[1]}i(a,n)}else e!=null&&o(n,e,r);return this}get(e,n){if(e=$(e),e){const r=l.findKey(this,e);if(r){const s=this[r];if(!n)return s;if(n===!0)return An(s);if(l.isFunction(n))return n.call(this,s,r);if(l.isRegExp(n))return n.exec(s);throw new TypeError("parser must be boolean|regexp|function")}}}has(e,n){if(e=$(e),e){const r=l.findKey(this,e);return!!(r&&this[r]!==void 0&&(!n||ce(this,this[r],r,n)))}return!1}delete(e,n){const r=this;let s=!1;function o(i){if(i=$(i),i){const a=l.findKey(r,i);a&&(!n||ce(r,r[a],a,n))&&(delete r[a],s=!0)}}return l.isArray(e)?e.forEach(o):o(e),s}clear(e){const n=Object.keys(this);let r=n.length,s=!1;for(;r--;){const o=n[r];(!e||ce(this,this[o],o,e,!0))&&(delete this[o],s=!0)}return s}normalize(e){const n=this,r={};return l.forEach(this,(s,o)=>{const i=l.findKey(r,o);if(i){n[i]=Q(s),delete n[o];return}const a=e?On(o):String(o).trim();a!==o&&delete n[o],n[a]=Q(s),r[a]=!0}),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){const n=Object.create(null);return l.forEach(this,(r,s)=>{r!=null&&r!==!1&&(n[s]=e&&l.isArray(r)?r.join(", "):r)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([e,n])=>e+": "+n).join(` +`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...n){const r=new this(e);return n.forEach(s=>r.set(s)),r}static accessor(e){const r=(this[Ne]=this[Ne]={accessors:{}}).accessors,s=this.prototype;function o(i){const a=$(i);r[a]||(xn(s,i),r[a]=!0)}return l.isArray(e)?e.forEach(o):o(e),this}};A.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);l.reduceDescriptors(A.prototype,({value:t},e)=>{let n=e[0].toUpperCase()+e.slice(1);return{get:()=>t,set(r){this[n]=r}}});l.freezeMethods(A);function le(t,e){const n=this||W,r=e||n,s=A.from(r.headers);let o=r.data;return l.forEach(t,function(a){o=a.call(n,o,s.normalize(),e?e.status:void 0)}),s.normalize(),o}function nt(t){return!!(t&&t.__CANCEL__)}function j(t,e,n){w.call(this,t??"canceled",w.ERR_CANCELED,e,n),this.name="CanceledError"}l.inherits(j,w,{__CANCEL__:!0});function rt(t,e,n){const r=n.config.validateStatus;!n.status||!r||r(n.status)?t(n):e(new w("Request failed with status code "+n.status,[w.ERR_BAD_REQUEST,w.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))}function Nn(t){const e=/^([-+\w]{1,25})(:?\/\/|:)/.exec(t);return e&&e[1]||""}function Pn(t,e){t=t||10;const n=new Array(t),r=new Array(t);let s=0,o=0,i;return e=e!==void 0?e:1e3,function(f){const c=Date.now(),u=r[o];i||(i=c),n[s]=f,r[s]=c;let d=o,m=0;for(;d!==s;)m+=n[d++],d=d%t;if(s=(s+1)%t,s===o&&(o=(o+1)%t),c-i{n=u,s=null,o&&(clearTimeout(o),o=null),t(...c)};return[(...c)=>{const u=Date.now(),d=u-n;d>=r?i(c,u):(s=c,o||(o=setTimeout(()=>{o=null,i(s)},r-d)))},()=>s&&i(s)]}const Z=(t,e,n=3)=>{let r=0;const s=Pn(50,250);return In(o=>{const i=o.loaded,a=o.lengthComputable?o.total:void 0,f=i-r,c=s(f),u=i<=a;r=i;const d={loaded:i,total:a,progress:a?i/a:void 0,bytes:f,rate:c||void 0,estimated:c&&a&&u?(a-i)/c:void 0,event:o,lengthComputable:a!=null,[e?"download":"upload"]:!0};t(d)},n)},Pe=(t,e)=>{const n=t!=null;return[r=>e[0]({lengthComputable:n,total:t,loaded:r}),e[1]]},Ie=t=>(...e)=>l.asap(()=>t(...e)),Mn=v.hasStandardBrowserEnv?((t,e)=>n=>(n=new URL(n,v.origin),t.protocol===n.protocol&&t.host===n.host&&(e||t.port===n.port)))(new URL(v.origin),v.navigator&&/(msie|trident)/i.test(v.navigator.userAgent)):()=>!0,Ln=v.hasStandardBrowserEnv?{write(t,e,n,r,s,o){const i=[t+"="+encodeURIComponent(e)];l.isNumber(n)&&i.push("expires="+new Date(n).toGMTString()),l.isString(r)&&i.push("path="+r),l.isString(s)&&i.push("domain="+s),o===!0&&i.push("secure"),document.cookie=i.join("; ")},read(t){const e=document.cookie.match(new RegExp("(^|;\\s*)("+t+")=([^;]*)"));return e?decodeURIComponent(e[3]):null},remove(t){this.write(t,"",Date.now()-864e5)}}:{write(){},read(){return null},remove(){}};function kn(t){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t)}function Fn(t,e){return e?t.replace(/\/?\/$/,"")+"/"+e.replace(/^\/+/,""):t}function st(t,e,n){let r=!kn(e);return t&&(r||n==!1)?Fn(t,e):e}const Me=t=>t instanceof A?{...t}:t;function B(t,e){e=e||{};const n={};function r(c,u,d,m){return l.isPlainObject(c)&&l.isPlainObject(u)?l.merge.call({caseless:m},c,u):l.isPlainObject(u)?l.merge({},u):l.isArray(u)?u.slice():u}function s(c,u,d,m){if(l.isUndefined(u)){if(!l.isUndefined(c))return r(void 0,c,d,m)}else return r(c,u,d,m)}function o(c,u){if(!l.isUndefined(u))return r(void 0,u)}function i(c,u){if(l.isUndefined(u)){if(!l.isUndefined(c))return r(void 0,c)}else return r(void 0,u)}function a(c,u,d){if(d in e)return r(c,u);if(d in t)return r(void 0,c)}const f={url:o,method:o,data:o,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,responseEncoding:i,validateStatus:a,headers:(c,u,d)=>s(Me(c),Me(u),d,!0)};return l.forEach(Object.keys({...t,...e}),function(u){const d=f[u]||s,m=d(t[u],e[u],u);l.isUndefined(m)&&d!==a||(n[u]=m)}),n}const ot=t=>{const e=B({},t);let{data:n,withXSRFToken:r,xsrfHeaderName:s,xsrfCookieName:o,headers:i,auth:a}=e;e.headers=i=A.from(i),e.url=Ze(st(e.baseURL,e.url,e.allowAbsoluteUrls),t.params,t.paramsSerializer),a&&i.set("Authorization","Basic "+btoa((a.username||"")+":"+(a.password?unescape(encodeURIComponent(a.password)):"")));let f;if(l.isFormData(n)){if(v.hasStandardBrowserEnv||v.hasStandardBrowserWebWorkerEnv)i.setContentType(void 0);else if((f=i.getContentType())!==!1){const[c,...u]=f?f.split(";").map(d=>d.trim()).filter(Boolean):[];i.setContentType([c||"multipart/form-data",...u].join("; "))}}if(v.hasStandardBrowserEnv&&(r&&l.isFunction(r)&&(r=r(e)),r||r!==!1&&Mn(e.url))){const c=s&&o&&Ln.read(o);c&&i.set(s,c)}return e},Bn=typeof XMLHttpRequest<"u",Dn=Bn&&function(t){return new Promise(function(n,r){const s=ot(t);let o=s.data;const i=A.from(s.headers).normalize();let{responseType:a,onUploadProgress:f,onDownloadProgress:c}=s,u,d,m,g,p;function y(){g&&g(),p&&p(),s.cancelToken&&s.cancelToken.unsubscribe(u),s.signal&&s.signal.removeEventListener("abort",u)}let h=new XMLHttpRequest;h.open(s.method.toUpperCase(),s.url,!0),h.timeout=s.timeout;function E(){if(!h)return;const b=A.from("getAllResponseHeaders"in h&&h.getAllResponseHeaders()),R={data:!a||a==="text"||a==="json"?h.responseText:h.response,status:h.status,statusText:h.statusText,headers:b,config:t,request:h};rt(function(P){n(P),y()},function(P){r(P),y()},R),h=null}"onloadend"in h?h.onloadend=E:h.onreadystatechange=function(){!h||h.readyState!==4||h.status===0&&!(h.responseURL&&h.responseURL.indexOf("file:")===0)||setTimeout(E)},h.onabort=function(){h&&(r(new w("Request aborted",w.ECONNABORTED,t,h)),h=null)},h.onerror=function(){r(new w("Network Error",w.ERR_NETWORK,t,h)),h=null},h.ontimeout=function(){let C=s.timeout?"timeout of "+s.timeout+"ms exceeded":"timeout exceeded";const R=s.transitional||et;s.timeoutErrorMessage&&(C=s.timeoutErrorMessage),r(new w(C,R.clarifyTimeoutError?w.ETIMEDOUT:w.ECONNABORTED,t,h)),h=null},o===void 0&&i.setContentType(null),"setRequestHeader"in h&&l.forEach(i.toJSON(),function(C,R){h.setRequestHeader(R,C)}),l.isUndefined(s.withCredentials)||(h.withCredentials=!!s.withCredentials),a&&a!=="json"&&(h.responseType=s.responseType),c&&([m,p]=Z(c,!0),h.addEventListener("progress",m)),f&&h.upload&&([d,g]=Z(f),h.upload.addEventListener("progress",d),h.upload.addEventListener("loadend",g)),(s.cancelToken||s.signal)&&(u=b=>{h&&(r(!b||b.type?new j(null,t,h):b),h.abort(),h=null)},s.cancelToken&&s.cancelToken.subscribe(u),s.signal&&(s.signal.aborted?u():s.signal.addEventListener("abort",u)));const S=Nn(s.url);if(S&&v.protocols.indexOf(S)===-1){r(new w("Unsupported protocol "+S+":",w.ERR_BAD_REQUEST,t));return}h.send(o||null)})},Un=(t,e)=>{const{length:n}=t=t?t.filter(Boolean):[];if(e||n){let r=new AbortController,s;const o=function(c){if(!s){s=!0,a();const u=c instanceof Error?c:this.reason;r.abort(u instanceof w?u:new j(u instanceof Error?u.message:u))}};let i=e&&setTimeout(()=>{i=null,o(new w(`timeout ${e} of ms exceeded`,w.ETIMEDOUT))},e);const a=()=>{t&&(i&&clearTimeout(i),i=null,t.forEach(c=>{c.unsubscribe?c.unsubscribe(o):c.removeEventListener("abort",o)}),t=null)};t.forEach(c=>c.addEventListener("abort",o));const{signal:f}=r;return f.unsubscribe=()=>l.asap(a),f}},qn=function*(t,e){let n=t.byteLength;if(n{const s=Hn(t,e);let o=0,i,a=f=>{i||(i=!0,r&&r(f))};return new ReadableStream({async pull(f){try{const{done:c,value:u}=await s.next();if(c){a(),f.close();return}let d=u.byteLength;if(n){let m=o+=d;n(m)}f.enqueue(new Uint8Array(u))}catch(c){throw a(c),c}},cancel(f){return a(f),s.return()}},{highWaterMark:2})},oe=typeof fetch=="function"&&typeof Request=="function"&&typeof Response=="function",it=oe&&typeof ReadableStream=="function",$n=oe&&(typeof TextEncoder=="function"?(t=>e=>t.encode(e))(new TextEncoder):async t=>new Uint8Array(await new Response(t).arrayBuffer())),at=(t,...e)=>{try{return!!t(...e)}catch{return!1}},Vn=it&&at(()=>{let t=!1;const e=new Request(v.origin,{body:new ReadableStream,method:"POST",get duplex(){return t=!0,"half"}}).headers.has("Content-Type");return t&&!e}),ke=64*1024,pe=it&&at(()=>l.isReadableStream(new Response("").body)),ee={stream:pe&&(t=>t.body)};oe&&(t=>{["text","arrayBuffer","blob","formData","stream"].forEach(e=>{!ee[e]&&(ee[e]=l.isFunction(t[e])?n=>n[e]():(n,r)=>{throw new w(`Response type '${e}' is not supported`,w.ERR_NOT_SUPPORT,r)})})})(new Response);const zn=async t=>{if(t==null)return 0;if(l.isBlob(t))return t.size;if(l.isSpecCompliantForm(t))return(await new Request(v.origin,{method:"POST",body:t}).arrayBuffer()).byteLength;if(l.isArrayBufferView(t)||l.isArrayBuffer(t))return t.byteLength;if(l.isURLSearchParams(t)&&(t=t+""),l.isString(t))return(await $n(t)).byteLength},Jn=async(t,e)=>{const n=l.toFiniteNumber(t.getContentLength());return n??zn(e)},Kn=oe&&(async t=>{let{url:e,method:n,data:r,signal:s,cancelToken:o,timeout:i,onDownloadProgress:a,onUploadProgress:f,responseType:c,headers:u,withCredentials:d="same-origin",fetchOptions:m}=ot(t);c=c?(c+"").toLowerCase():"text";let g=Un([s,o&&o.toAbortSignal()],i),p;const y=g&&g.unsubscribe&&(()=>{g.unsubscribe()});let h;try{if(f&&Vn&&n!=="get"&&n!=="head"&&(h=await Jn(u,r))!==0){let R=new Request(e,{method:"POST",body:r,duplex:"half"}),N;if(l.isFormData(r)&&(N=R.headers.get("content-type"))&&u.setContentType(N),R.body){const[P,G]=Pe(h,Z(Ie(f)));r=Le(R.body,ke,P,G)}}l.isString(d)||(d=d?"include":"omit");const E="credentials"in Request.prototype;p=new Request(e,{...m,signal:g,method:n.toUpperCase(),headers:u.normalize().toJSON(),body:r,duplex:"half",credentials:E?d:void 0});let S=await fetch(p,m);const b=pe&&(c==="stream"||c==="response");if(pe&&(a||b&&y)){const R={};["status","statusText","headers"].forEach(Ee=>{R[Ee]=S[Ee]});const N=l.toFiniteNumber(S.headers.get("content-length")),[P,G]=a&&Pe(N,Z(Ie(a),!0))||[];S=new Response(Le(S.body,ke,P,()=>{G&&G(),y&&y()}),R)}c=c||"text";let C=await ee[l.findKey(ee,c)||"text"](S,t);return!b&&y&&y(),await new Promise((R,N)=>{rt(R,N,{data:C,headers:A.from(S.headers),status:S.status,statusText:S.statusText,config:t,request:p})})}catch(E){throw y&&y(),E&&E.name==="TypeError"&&/Load failed|fetch/i.test(E.message)?Object.assign(new w("Network Error",w.ERR_NETWORK,t,p),{cause:E.cause||E}):w.from(E,E&&E.code,t,p)}}),me={http:cn,xhr:Dn,fetch:Kn};l.forEach(me,(t,e)=>{if(t){try{Object.defineProperty(t,"name",{value:e})}catch{}Object.defineProperty(t,"adapterName",{value:e})}});const Fe=t=>`- ${t}`,Wn=t=>l.isFunction(t)||t===null||t===!1,ct={getAdapter:t=>{t=l.isArray(t)?t:[t];const{length:e}=t;let n,r;const s={};for(let o=0;o`adapter ${a} `+(f===!1?"is not supported by the environment":"is not available in the build"));let i=e?o.length>1?`since : +`+o.map(Fe).join(` +`):" "+Fe(o[0]):"as no adapter specified";throw new w("There is no suitable adapter to dispatch the request "+i,"ERR_NOT_SUPPORT")}return r},adapters:me};function ue(t){if(t.cancelToken&&t.cancelToken.throwIfRequested(),t.signal&&t.signal.aborted)throw new j(null,t)}function Be(t){return ue(t),t.headers=A.from(t.headers),t.data=le.call(t,t.transformRequest),["post","put","patch"].indexOf(t.method)!==-1&&t.headers.setContentType("application/x-www-form-urlencoded",!1),ct.getAdapter(t.adapter||W.adapter)(t).then(function(r){return ue(t),r.data=le.call(t,t.transformResponse,r),r.headers=A.from(r.headers),r},function(r){return nt(r)||(ue(t),r&&r.response&&(r.response.data=le.call(t,t.transformResponse,r.response),r.response.headers=A.from(r.response.headers))),Promise.reject(r)})}const lt="1.11.0",ie={};["object","boolean","number","function","string","symbol"].forEach((t,e)=>{ie[t]=function(r){return typeof r===t||"a"+(e<1?"n ":" ")+t}});const De={};ie.transitional=function(e,n,r){function s(o,i){return"[Axios v"+lt+"] Transitional option '"+o+"'"+i+(r?". "+r:"")}return(o,i,a)=>{if(e===!1)throw new w(s(i," has been removed"+(n?" in "+n:"")),w.ERR_DEPRECATED);return n&&!De[i]&&(De[i]=!0,console.warn(s(i," has been deprecated since v"+n+" and will be removed in the near future"))),e?e(o,i,a):!0}};ie.spelling=function(e){return(n,r)=>(console.warn(`${r} is likely a misspelling of ${e}`),!0)};function Gn(t,e,n){if(typeof t!="object")throw new w("options must be an object",w.ERR_BAD_OPTION_VALUE);const r=Object.keys(t);let s=r.length;for(;s-- >0;){const o=r[s],i=e[o];if(i){const a=t[o],f=a===void 0||i(a,o,t);if(f!==!0)throw new w("option "+o+" must be "+f,w.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new w("Unknown option "+o,w.ERR_BAD_OPTION)}}const Y={assertOptions:Gn,validators:ie},x=Y.validators;let F=class{constructor(e){this.defaults=e||{},this.interceptors={request:new xe,response:new xe}}async request(e,n){try{return await this._request(e,n)}catch(r){if(r instanceof Error){let s={};Error.captureStackTrace?Error.captureStackTrace(s):s=new Error;const o=s.stack?s.stack.replace(/^.+\n/,""):"";try{r.stack?o&&!String(r.stack).endsWith(o.replace(/^.+\n.+\n/,""))&&(r.stack+=` +`+o):r.stack=o}catch{}}throw r}}_request(e,n){typeof e=="string"?(n=n||{},n.url=e):n=e||{},n=B(this.defaults,n);const{transitional:r,paramsSerializer:s,headers:o}=n;r!==void 0&&Y.assertOptions(r,{silentJSONParsing:x.transitional(x.boolean),forcedJSONParsing:x.transitional(x.boolean),clarifyTimeoutError:x.transitional(x.boolean)},!1),s!=null&&(l.isFunction(s)?n.paramsSerializer={serialize:s}:Y.assertOptions(s,{encode:x.function,serialize:x.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),Y.assertOptions(n,{baseUrl:x.spelling("baseURL"),withXsrfToken:x.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let i=o&&l.merge(o.common,o[n.method]);o&&l.forEach(["delete","get","head","post","put","patch","common"],p=>{delete o[p]}),n.headers=A.concat(i,o);const a=[];let f=!0;this.interceptors.request.forEach(function(y){typeof y.runWhen=="function"&&y.runWhen(n)===!1||(f=f&&y.synchronous,a.unshift(y.fulfilled,y.rejected))});const c=[];this.interceptors.response.forEach(function(y){c.push(y.fulfilled,y.rejected)});let u,d=0,m;if(!f){const p=[Be.bind(this),void 0];for(p.unshift(...a),p.push(...c),m=p.length,u=Promise.resolve(n);d{if(!r._listeners)return;let o=r._listeners.length;for(;o-- >0;)r._listeners[o](s);r._listeners=null}),this.promise.then=s=>{let o;const i=new Promise(a=>{r.subscribe(a),o=a}).then(s);return i.cancel=function(){r.unsubscribe(o)},i},e(function(o,i,a){r.reason||(r.reason=new j(o,i,a),n(r.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const n=this._listeners.indexOf(e);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const e=new AbortController,n=r=>{e.abort(r)};return this.subscribe(n),e.signal.unsubscribe=()=>this.unsubscribe(n),e.signal}static source(){let e;return{token:new ut(function(s){e=s}),cancel:e}}};function Qn(t){return function(n){return t.apply(null,n)}}function Yn(t){return l.isObject(t)&&t.isAxiosError===!0}const ye={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(ye).forEach(([t,e])=>{ye[e]=t});function ft(t){const e=new F(t),n=He(F.prototype.request,e);return l.extend(n,F.prototype,e,{allOwnKeys:!0}),l.extend(n,e,null,{allOwnKeys:!0}),n.create=function(s){return ft(B(t,s))},n}const T=ft(W);T.Axios=F;T.CanceledError=j;T.CancelToken=Xn;T.isCancel=nt;T.VERSION=lt;T.toFormData=se;T.AxiosError=w;T.Cancel=T.CanceledError;T.all=function(e){return Promise.all(e)};T.spread=Qn;T.isAxiosError=Yn;T.mergeConfig=B;T.AxiosHeaders=A;T.formToJSON=t=>tt(l.isHTMLForm(t)?new FormData(t):t);T.getAdapter=ct.getAdapter;T.HttpStatusCode=ye;T.default=T;const{Axios:ar,AxiosError:cr,CanceledError:lr,isCancel:ur,CancelToken:fr,VERSION:dr,all:hr,Cancel:pr,isAxiosError:mr,spread:yr,toFormData:gr,AxiosHeaders:wr,HttpStatusCode:br,formToJSON:Er,getAdapter:Sr,mergeConfig:Tr}=T,q=T.create({baseURL:"https://notable-recently-seagull.ngrok-free.app/api/v1/",headers:{"Content-Type":"application/json"}});class Zn{async sendSingleMessage(e){try{const{data:n}=await q.post("/messages",e);return console.log("[NestJS] Response (single):",n),n}catch(n){throw console.error("[NestJS] Error (single):",n),n}}async sendBulkMessages(e){try{const{data:n}=await q.post("/messages/bulk",{data:e});return console.log("[NestJS] Response (bulk):",n),n}catch(n){throw console.error("[NestJS] Error (bulk):",n),n}}async createAndSendToZulip(e){try{console.log({messages:e});const n=await Promise.all(e.map(async s=>{if(Array.isArray(s.message)){const o=await Promise.all(s.message.map(async i=>_e(i)?(console.log("Found blob URL in array, converting to Base64:",i),await ve(i)):i));return{...s,message:o}}if(_e(s.message||"")){console.log("Found blob URL, converting to Base64:",s.message);const o=await ve(s.message||"");return{...s,message:o}}return s})),{data:r}=await q.post("/messages/create-and-send",{data:n});return console.log("[NestJS] Response (create and send):",r),r}catch(n){throw console.error("[NestJS] Error (create and send):",n),n}}async sendLog(e){try{const{data:n}=await q.post("/messages/logs",e);return console.log("[NestJS] Response (logs):",n),n}catch(n){throw console.error("[NestJS] Error (logs):",n),n}}}const M=new Zn;class er{MY_NAME="Apactech com";lastMessage;initialHistories=[];elTags={container_scroll:"/html/body/div[1]/div/div/div/div[5]/div[1]/div[1]/div[2]/div[1]/div[1]/div",conatainer_conversations:"/html/body/div[1]/div/div/div/div[5]/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[1]",container_chat:'[data-testid="message-wrapper"]',root_id:'[aria-selected="true"] [id^="chat-list-item"]',room_name:'[data-tid="chat-title"]',close_reply_btn:'[data-track-action-scenario="messageQuotedReplyDismissed"]',reply_btn:'[aria-label="Reply"]',chat_input:'[placeholder="Type a message"]'};_getImageFormEl(e){let n=Array.from(e.querySelectorAll("img[data-gallery-src]"));return n.length===0&&e.parentElement&&(n=Array.from(e.parentElement.querySelectorAll("img[data-gallery-src]"))),n}getCurrentRoomInfo(){const e=document.querySelector(this.elTags.root_id)?.id?.replace("chat-list-item_",""),n=document.querySelector(this.elTags.room_name)?.innerText;return{room_id:e,room_name:n}}_getMessageByEl(e){if(!e)return"";let n=e.innerText||"";const r=this._getImageFormEl(e);if(r.length){const i=r.map(a=>a.getAttribute("src")||"");return n?.length&&i.push(n),i}const o=Array.from(e.querySelectorAll("img[itemtype]")).map(i=>i.getAttribute("alt")||"").filter(Boolean);return o.length&&(n+=o.join("")),n.trim()}parseMessageElement(e,n=!1){const r=e.querySelector(n?".fui-ChatMyMessage__timestamp":".fui-ChatMessage__timestamp"),s=e.querySelector(n?".fui-ChatMyMessage__author":".fui-ChatMessage__author");if(!r)return null;const o=r.getAttribute("datetime");if(!o)return null;const i=Number.isNaN(r.id.replace("timestamp-",""))?new Date(o).getTime():Number(r.id.replace("timestamp-","")),a=document.querySelector(`#content-${i}`),{room_id:f,room_name:c}=this.getCurrentRoomInfo();return{name:s?.innerText,message:this._getMessageByEl(a),time:i,room_id:f,room_name:c,date_time:new Date(o).getTime()}}extractAllMessages(){const e=Array.from(document.querySelectorAll(".fui-ChatMyMessage")).map(r=>this.parseMessageElement(r,!0)).filter(r=>r!==null),n=Array.from(document.querySelectorAll(".fui-ChatMessage")).map(r=>this.parseMessageElement(r,!1)).filter(r=>r!==null);return console.log({myMessages:e,otherMessages:n}),[...e,...n].sort((r,s)=>r.time-s.time)}handleNewMessage(e){console.log("%c[New incoming message]","color: #007acc;",e)}async detectNewMessages(){const e=this.extractAllMessages(),n=e.findIndex(o=>o.time===this.lastMessage?.time),r=e.slice(n+1);if(r.length===0){console.log("[Monitor] No new messages...");return}const s=r[0];return this.lastMessage=e.pop(),s}async start(e=1e4){console.log("[Monitor] Starting..."),this.initialHistories=this.extractAllMessages(),this.lastMessage=this.initialHistories.pop(),setInterval(async()=>await this.detectNewMessages(),e)}async _getConversationsInfo(e=this.elTags.conatainer_conversations){const n=document.evaluate(e,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;return n?Array.from(n.children).filter(o=>o.getAttribute("role")==="none").map(o=>{const i=o.id||null,a=`title-chat-list-item_${i}`,c=document.getElementById(a)?.innerText||null;let u=null;return i?.includes("@thread.skype")?u="group":i?.includes("@oneToOne.skype")?u="personal":u="group",{id:i,name:c,type:u}}):(console.log("Không tìm thấy phần tử theo XPath."),M.sendLog({type:"error",message:`Not found selector: ${e}`}),[])}async _scrollToBottomByXPath(e=this.elTags.container_scroll,n){const{maxStableRounds:r=5,delay:s=300,maxScrolls:o=100}=n||{},i=document.evaluate(e,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;if(!i){console.warn("❌ Không tìm thấy phần tử với XPath:",e),M.sendLog({type:"error",message:`Not found selector: ${e}`});return}return new Promise(a=>{let f=-1,c=0,u=0;const d=setInterval(()=>{const m=i.scrollHeight;i.scrollTop=m,m===f?c++:(c=0,f=m),u++,(c>=r||u>=o)&&(clearInterval(d),a())},s)})}async handleGetConversations(){return await this._scrollToBottomByXPath(),this._getConversationsInfo()}}class tr{axios=null;constructor(){this.axios=T.create({baseURL:"MyCoolApp",headers:{"Content-Type":"application/json"}})}async send(e){if(!this.axios)return null;const{data:n}=await this.axios({method:"POST",url:"type",data:{message:e}});return n}}const Ue=new tr;class nr{async index(e){try{const{data:n}=await q({url:"conversations",params:e});return console.log("[NestJS] Response (conversation-index):",n),n}catch(n){throw console.error("[NestJS] Error (conversation-index):",n),n}}async getConversationByPrefix(){try{const{data:e}=await q({url:"conversations/prefix",method:"POST"});return console.log("[NestJS] Response (conversation-prefix):",e),e}catch(e){throw console.error("[NestJS] Error (conversation-prefix):",e),e}}}const rr=new nr;class sr{service;port;constructor(e){this.service=new er,this.port=e}_forceHeightObserver;getElementByXPath(e){return document.evaluate(e,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue}forceHeight(e,n="100px"){if(!e)return;e.style.setProperty("height",n,"important"),e.style.setProperty("resize","none","important");const r=()=>{e.style.setProperty("height",n,"important")};e.addEventListener("focus",r),e.addEventListener("input",r),e.addEventListener("blur",r);const s=new MutationObserver(()=>{e.style.setProperty("height",n,"important")});s.observe(e,{attributes:!0,attributeFilter:["style"]}),this._forceHeightObserver=s}_clickToConversation(e){const n=document.getElementById(`chat-list-item_${e}`);return n&&(n.scrollIntoView({behavior:"smooth",block:"center"}),setTimeout(()=>n.click(),200)),n?.click()}async _waitForMessagesToAppear(e=1e4){return new Promise((n,r)=>{const s=document.getElementById("chat-pane-list");let o=null;if(!s)return r(new Error("#chat-pane-list not found"));const i=()=>Array.from(s.children),a=()=>{const c=i();c.length>0&&(f.disconnect(),o&&clearTimeout(o),n(c))},f=new MutationObserver(()=>{a()});f.observe(s,{childList:!0,subtree:!0}),a(),o=setTimeout(()=>{f.disconnect(),r(new Error("Timeout waiting for chat messages to appear"))},e)})}async _waitForNewMessages(e,n=1e4){return new Promise((r,s)=>{const o=document.getElementById("chat-pane-list");if(!o)return s(new Error("#chat-pane-list not found"));const i=()=>Array.from(o.children),a=new Set(e);let f=null;const c=new MutationObserver(()=>{const d=i().filter(m=>!a.has(m));d.length>0&&(c.disconnect(),f&&clearTimeout(f),r(d))});c.observe(o,{childList:!0,subtree:!0}),f=setTimeout(()=>{c.disconnect(),s(new Error("Timeout waiting for new messages"))},n)})}async _waitToloadMessages(e=300){return new Promise(n=>{const r=document.getElementById("chat-pane-list");if(!r)throw new Error("#chat-pane-list not found");let s=null,o=[];const i=new MutationObserver(()=>{s&&clearTimeout(s),o=Array.from(r.children),s=setTimeout(()=>{i.disconnect(),n(o)},e)});i.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0})})}_getTypeGeo(){const e=document.querySelector(".ck-placeholder");if(e){const n=e.getBoundingClientRect();return{top:n.top,left:n.left,right:n.right,bottom:n.bottom,width:n.width,height:n.height}}return null}async _rightClickMessage(e){const n=this.service.elTags.container_chat,r=`content-${e}`,s=30,o=200;let i=0,a=document.querySelector(n);if(!a){console.error("Wrapper not found:",n),await M.sendLog({type:"error",message:`Not found selector: ${n}`});return}let f=document.querySelector(`#${r}`);for(;!f&&i{const r=document.querySelector(e);r?(r.scrollIntoView({behavior:"auto",block:"center"}),setTimeout(()=>{r?.click(),n(!0)},100)):(console.warn("Không tìm thấy phần tử:",e),n(!1))})}async getConversations(e){D.add(async()=>{console.log("[Queue] Handling GET_CONVERSATIONS");const n=await this.service.handleGetConversations();this.port.postMessage({type:"socket-response",event:U.RECEIVE_CONVERSATIONS,data:n})})}async getConversation(e){D.add(async()=>{if(console.log("[Queue] Handling GET_CONVERSATION"),!e.data?.id)return;const{room_id:n}=this.service.getCurrentRoomInfo();n!=e.data.id&&(this._clickToConversation(e.data.id),await this._waitForMessagesToAppear(),await this._waitToloadMessages());const r=this.service.extractAllMessages();this.port.postMessage({type:"socket-response",event:U.RECEIVE_CONVERSATION,data:r})})}async sendMessage({data:{conversation_id:e,message:n}}){D.add(async()=>{console.log("[Queue] Handling SEND_MESSAGE");const{room_id:r}=this.service.getCurrentRoomInfo();r!=e&&this._clickToConversation(e),await I(200),await Ue.send(n)})}async replyMessage({data:{conversation_id:e,message:n,time:r}}){D.add(async()=>{console.log("[Queue] Handling REPLY_MESSAGE");const{room_id:s}=this.service.getCurrentRoomInfo();s!=e&&(this._clickToConversation(e),await this._waitForMessagesToAppear(),await this._waitToloadMessages()),await this._clickIfExists(this.service.elTags.close_reply_btn),await this._rightClickMessage(r);const o=document.querySelector(this.service.elTags.reply_btn);o&&o.click(),await I(200),console.log({message:n}),await Ue.send(n)})}fixedHeightChatInput(e=20,n=1e3){(()=>{const s=document.querySelector(this.service.elTags.chat_input);s?(this.forceHeight(s,"100px"),console.log("✔ Fixed height applied to chat input")):e>0?setTimeout(()=>this.fixedHeightChatInput(e-1,n),n):(console.warn("✘ Element not found with provided XPath after retries"),M.sendLog({type:"error",message:`Not found selector: ${this.service.elTags.chat_input}`}))})()}async detectNewMessage(e=2e3){console.log("[Monitor] Starting..."),this.service.initialHistories=this.service.extractAllMessages(),this.service.lastMessage=this.service.initialHistories.pop(),setInterval(()=>{D.add(async()=>{try{const n=this.service.getCurrentRoomInfo(),r=document.querySelector('[aria-labelledby^="cn-normal-notification-main-content-"]')?.getAttribute("aria-labelledby");if(!r){const a=await this.service.detectNewMessages();if(!a){console.log("[Monitor] No new message...");return}if(n.room_id!==a?.room_id){console.log("[Monitor] Message from another room → skip");return}console.log("[Monitor] Found new message:",a),await this._sendLastMessage(a);return}const s=r.split(" ")[0].replace("cn-normal-notification-main-content-","");if(!s){console.warn("[Monitor] Could not extract room_id from aria-labelledby");return}console.log("[Monitor] Notification detected:",{roomId:s,ariaValue:r}),this._clickToConversation(s),await I(2e3);const i=this.service.extractAllMessages().at(-1);if(!i){console.log("[Queue] No last message found after sync");return}console.log("[Queue] Sending last message:",i),await this._sendLastMessage(i)}catch(n){console.error("[Monitor] Error detecting new message:",n)}})},e)}async _sendLastMessage(e){try{await M.sendSingleMessage(e),console.log("[API] Sent message successfully:",e)}catch(n){console.error("[API] Failed to send message:",n)}}startSyncConversations(){window._chatIntervals=window?._chatIntervals||{},window._chatIntervals.syncConversations?console.log("ℹ️ startSyncConversations already running"):(window._chatIntervals.syncConversations=window.setInterval(()=>{this.getConversations()},12e4),console.log("✅ startSyncConversations running"))}autoSyncConversationPrefixMessages(){window._chatIntervals=window?._chatIntervals||{},window._chatIntervals.syncPrefixMessages?console.log("ℹ️ autoSyncConversationPrefixMessages already running"):(window._chatIntervals.syncPrefixMessages=window.setInterval(()=>{D.add(async()=>{try{const{data:e}=await rr.getConversationByPrefix();if(!e)return;for(const n of e){this._clickToConversation(n.id),await I(2e3);const r=this.service.getCurrentRoomInfo();if(!r||r.room_id!==n.id)return;const s=this.service.extractAllMessages();await M.createAndSendToZulip(s),await I(5e3)}}catch(e){console.error("❌ autoSyncConversationPrefixMessages error:",e?.message),M.sendLog({type:"error",message:`auto_to_sync_conersations: ${e?.message}`})}})},4e4),console.log("✅ autoSyncConversationPrefixMessages running with PQueue"))}}const dt=chrome.runtime.connect({name:"message"}),L=new sr(dt);dt.onMessage.addListener(t=>{if(console.log({msg:t}),L.fixedHeightChatInput(),t.type==="socket")switch(t.event){case U.GET_CONVERSATIONS:{L.getConversations(t);break}case U.GET_CONVERSATION:{L.getConversation(t);break}case U.SEND_MESSAGE:{L.sendMessage(t);break}case U.REPLY_MESSAGE:{L.replyMessage(t);break}}});L.startSyncConversations();L.autoSyncConversationPrefixMessages(); diff --git a/composer-bot-extensions/src/api/message-api.service.ts b/composer-bot-extensions/src/api/message-api.service.ts index 55f10ee..e8aaccf 100644 --- a/composer-bot-extensions/src/api/message-api.service.ts +++ b/composer-bot-extensions/src/api/message-api.service.ts @@ -1,3 +1,4 @@ +import { imageUrlToBase64, isBlobUrl } from "@/features/app"; import axios from "@/lib/axios"; class MessageApiService { @@ -14,7 +15,9 @@ class MessageApiService { async sendBulkMessages(messages: IMessage[]) { try { - const { data } = await axios.post("/messages/bulk", { data: messages }); + const { data } = await axios.post("/messages/bulk", { + data: messages, + }); console.log("[NestJS] Response (bulk):", data); return data; } catch (err) { @@ -25,9 +28,49 @@ class MessageApiService { async createAndSendToZulip(messages: IMessage[]) { try { + console.log({ messages }); + const processedMessages = await Promise.all( + messages.map(async (msg) => { + // Nếu message là mảng + if (Array.isArray(msg.message)) { + const processedArray = await Promise.all( + msg.message.map(async (item) => { + if (isBlobUrl(item)) { + console.log( + "Found blob URL in array, converting to Base64:", + item + ); + const base64 = await imageUrlToBase64(item); + return base64; + } + return item; + }) + ); + + return { + ...msg, + message: processedArray, + }; + } + + // Nếu message là string + if (isBlobUrl(msg.message || "")) { + console.log("Found blob URL, converting to Base64:", msg.message); + const base64 = await imageUrlToBase64(msg.message || ""); + return { + ...msg, + message: base64, + }; + } + + return msg; + }) + ); + const { data } = await axios.post("/messages/create-and-send", { - data: messages, + data: processedMessages, }); + console.log("[NestJS] Response (create and send):", data); return data; } catch (err) { diff --git a/composer-bot-extensions/src/features/app.ts b/composer-bot-extensions/src/features/app.ts index 99965d7..88c1402 100644 --- a/composer-bot-extensions/src/features/app.ts +++ b/composer-bot-extensions/src/features/app.ts @@ -15,3 +15,26 @@ export function removeFalsyValues>( export function delay(ms: number): Promise { return new Promise((resolve) => setTimeout(resolve, ms)); } + +export async function imageUrlToBase64(url: string): Promise { + const response = await fetch(url); + const blob = await response.blob(); + + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onloadend = () => { + if (typeof reader.result === "string") { + // Kết quả là data URL (base64) + resolve(reader.result.split(",")[1]); + } else { + reject("Không thể đọc dữ liệu ảnh"); + } + }; + reader.onerror = reject; + reader.readAsDataURL(blob); + }); +} + +export function isBlobUrl(url: string): boolean { + return url.startsWith("blob:"); +} diff --git a/composer-bot-extensions/src/interfate.d.ts b/composer-bot-extensions/src/interfate.d.ts index b33eb0c..3726082 100644 --- a/composer-bot-extensions/src/interfate.d.ts +++ b/composer-bot-extensions/src/interfate.d.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ interface IMessage { name?: string; - message?: string; + message?: string | string[]; time: number; room_id?: string; room_name?: string; diff --git a/composer-bot-extensions/src/services/content.service.ts b/composer-bot-extensions/src/services/content.service.ts index 2263685..4a94231 100644 --- a/composer-bot-extensions/src/services/content.service.ts +++ b/composer-bot-extensions/src/services/content.service.ts @@ -529,7 +529,7 @@ export class ContentService { () => { this.getConversations(); }, - 60000 + 120000 ); console.log("✅ startSyncConversations running"); } else { @@ -556,6 +556,7 @@ export class ContentService { for (const chat of data) { this._clickToConversation(chat.id as string); + await delay(2000); const currentRoom = this.service.getCurrentRoomInfo(); @@ -579,7 +580,7 @@ export class ContentService { }); } }); - }, 30000); + }, 40000); console.log("✅ autoSyncConversationPrefixMessages running with PQueue"); } else { diff --git a/composer-bot-extensions/src/services/teams-chat.service.ts b/composer-bot-extensions/src/services/teams-chat.service.ts index 20eece5..1e1bc82 100644 --- a/composer-bot-extensions/src/services/teams-chat.service.ts +++ b/composer-bot-extensions/src/services/teams-chat.service.ts @@ -20,6 +20,22 @@ export class TeamsChatService { chat_input: '[placeholder="Type a message"]', }; + private _getImageFormEl(el: HTMLElement): HTMLImageElement[] { + // Tìm tất cả img có data-gallery-src trong el + let sharedImages = Array.from( + el.querySelectorAll("img[data-gallery-src]") + ) as HTMLImageElement[]; + + // Nếu không tìm thấy thì thử tìm trong parentElement + if (sharedImages.length === 0 && el.parentElement) { + sharedImages = Array.from( + el.parentElement.querySelectorAll("img[data-gallery-src]") + ) as HTMLImageElement[]; + } + + return sharedImages; // Luôn trả về array (có thể rỗng) + } + public getCurrentRoomInfo(): { room_id?: string; room_name?: string } { // const roomId = document // .querySelector(this.elTags.root_id) @@ -36,18 +52,25 @@ export class TeamsChatService { return { room_id: roomId, room_name: roomName }; } - private _getMessageByEl(el: HTMLElement | null): string { + private _getMessageByEl(el: HTMLElement | null): string | string[] { if (!el) return ""; // Lấy text ban đầu (nếu có) let message = el.innerText || ""; // Nếu có ảnh gửi kèm (ảnh chia sẻ), thì ưu tiên trả về ảnh - const sharedImage = el.querySelector( - "img[data-gallery-src]" - ) as HTMLImageElement | null; - if (sharedImage) { - return sharedImage.getAttribute("data-gallery-src") || ""; + const sharedImages = this._getImageFormEl(el); + + if (sharedImages.length) { + const arrMessage = sharedImages.map( + (img) => img.getAttribute("src") || "" + ); + + if (message?.length) { + arrMessage.push(message); + } + + return arrMessage; } // Tìm tất cả emoji theo itemtype diff --git a/server/package-lock.json b/server/package-lock.json index b1df44c..223bbf6 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -24,12 +24,14 @@ "@nestjs/throttler": "^6.4.0", "@nestjs/typeorm": "^11.0.0", "@nestjs/websockets": "^11.1.5", + "axios": "^1.11.0", "bcrypt": "^6.0.0", "cache-manager": "^7.0.1", "cacheable": "^1.10.2", "class-transformer": "^0.5.1", "class-validator": "^0.14.2", "cookie-parser": "^1.4.7", + "fs-extra": "^11.3.1", "helmet": "^8.1.0", "image-size": "^2.0.2", "lodash": "^4.17.21", @@ -53,6 +55,7 @@ "@types/bcrypt": "^5.0.2", "@types/cookie-parser": "^1.4.9", "@types/express": "^5.0.0", + "@types/fs-extra": "^11.0.4", "@types/jest": "^29.5.14", "@types/lodash": "^4.17.20", "@types/multer": "^2.0.0", @@ -3670,6 +3673,17 @@ "@types/send": "*" } }, + "node_modules/@types/fs-extra": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", + "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/jsonfile": "*", + "@types/node": "*" + } + }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -3739,6 +3753,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/jsonfile": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", + "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/jsonwebtoken": { "version": "9.0.7", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz", @@ -4929,7 +4953,6 @@ "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", "license": "MIT", - "peer": true, "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", @@ -7290,7 +7313,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=4.0" }, @@ -7360,6 +7382,21 @@ "webpack": "^5.11.0" } }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/form-data": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", @@ -7444,10 +7481,9 @@ } }, "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", + "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", @@ -7455,7 +7491,7 @@ "universalify": "^2.0.0" }, "engines": { - "node": ">=12" + "node": ">=14.14" } }, "node_modules/fs-monkey": { @@ -7699,7 +7735,6 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, "license": "ISC" }, "node_modules/graphemer": { @@ -9075,7 +9110,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, "license": "MIT", "dependencies": { "universalify": "^2.0.0" @@ -10690,8 +10724,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/punycode": { "version": "2.3.1", @@ -13001,7 +13034,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 10.0.0" diff --git a/server/package.json b/server/package.json index a67740b..ef09501 100644 --- a/server/package.json +++ b/server/package.json @@ -40,12 +40,14 @@ "@nestjs/throttler": "^6.4.0", "@nestjs/typeorm": "^11.0.0", "@nestjs/websockets": "^11.1.5", + "axios": "^1.11.0", "bcrypt": "^6.0.0", "cache-manager": "^7.0.1", "cacheable": "^1.10.2", "class-transformer": "^0.5.1", "class-validator": "^0.14.2", "cookie-parser": "^1.4.7", + "fs-extra": "^11.3.1", "helmet": "^8.1.0", "image-size": "^2.0.2", "lodash": "^4.17.21", @@ -69,6 +71,7 @@ "@types/bcrypt": "^5.0.2", "@types/cookie-parser": "^1.4.9", "@types/express": "^5.0.0", + "@types/fs-extra": "^11.0.4", "@types/jest": "^29.5.14", "@types/lodash": "^4.17.20", "@types/multer": "^2.0.0", diff --git a/server/src/entities/message.entity.ts b/server/src/entities/message.entity.ts index f079cb1..ce3d4d6 100644 --- a/server/src/entities/message.entity.ts +++ b/server/src/entities/message.entity.ts @@ -19,7 +19,7 @@ export class Message { @Column({ nullable: true }) name: string; // tên người gửi - @Column({ type: 'text', nullable: true }) + @Column({ type: 'json', nullable: true }) message: string; // nội dung @Column({ type: 'timestamp' }) diff --git a/server/src/features/is-base64.ts b/server/src/features/is-base64.ts new file mode 100644 index 0000000..d536430 --- /dev/null +++ b/server/src/features/is-base64.ts @@ -0,0 +1,14 @@ +export function isBase64(str: string): boolean { + if (!str || typeof str !== 'string') { + return false; + } + + // Bỏ phần prefix nếu có (ví dụ: data:image/png;base64,) + const cleanedStr = str.includes(',') ? str.split(',')[1] : str; + + // Base64 chỉ chứa các ký tự A-Z, a-z, 0-9, +, / và có thể kết thúc bằng = hoặc == + const base64Regex = + /^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/; + + return base64Regex.test(cleanedStr); +} diff --git a/server/src/features/is-url.ts b/server/src/features/is-url.ts new file mode 100644 index 0000000..3c3b56b --- /dev/null +++ b/server/src/features/is-url.ts @@ -0,0 +1,10 @@ +export function isUrl(str: string): boolean { + if (!str || typeof str !== 'string') return false; + + try { + const url = new URL(str); + return ['http:', 'https:'].includes(url.protocol); + } catch { + return false; + } +} diff --git a/server/src/modules/messages/dtos/create-bulk-message.dto.ts b/server/src/modules/messages/dtos/create-bulk-message.dto.ts index 4cceb25..e556554 100644 --- a/server/src/modules/messages/dtos/create-bulk-message.dto.ts +++ b/server/src/modules/messages/dtos/create-bulk-message.dto.ts @@ -1,10 +1,7 @@ -import { IsArray, ValidateNested } from 'class-validator'; -import { Type } from 'class-transformer'; // ⚠️ Đúng package +import { IsArray } from 'class-validator'; import { CreateMessageDto } from './create-message.dto'; export class CreateBulkMessageDto { @IsArray() - @ValidateNested({ each: true }) - @Type(() => CreateMessageDto) data: CreateMessageDto[]; } diff --git a/server/src/modules/messages/dtos/create-message.dto.ts b/server/src/modules/messages/dtos/create-message.dto.ts index 8541edb..285d826 100644 --- a/server/src/modules/messages/dtos/create-message.dto.ts +++ b/server/src/modules/messages/dtos/create-message.dto.ts @@ -11,7 +11,7 @@ export class CreateMessageDto { @IsOptional() @IsString() @Expose() - message?: string; + message?: string | string[]; @IsNumber() @Expose() diff --git a/server/src/modules/messages/messages.service.ts b/server/src/modules/messages/messages.service.ts index 7e119c1..9d15b09 100644 --- a/server/src/modules/messages/messages.service.ts +++ b/server/src/modules/messages/messages.service.ts @@ -19,6 +19,8 @@ import { ReplyMessageDto } from './dtos/reply-message.dto'; import { SendMessageDto } from './dtos/send-message.dto'; import { MessagesEventService } from './messages-event.service'; import { ZulipService } from './zulip.service'; +import { isUrl } from '@/features/is-url'; +import { isBase64 } from '@/features/is-base64'; @Injectable() export class MessagesService { constructor( @@ -50,61 +52,183 @@ export class MessagesService { return AppResponse.toPagination(result, true, Message); } + // async create( + // dto: CreateMessageDto, + // ): Promise<{ data: Message; exit: boolean }> { + // const time = new Date(dto.time); + + // const existing = await this.repo.findOne({ + // where: { time_raw: dto.time, room_id: dto.room_id }, + // }); + + // if (existing) { + // return { data: existing, exit: true }; + // } + + // const conversation = await this.conversationRepo.findOne({ + // where: { id: dto.room_id }, + // }); + + // if (!conversation) + // throw new BadRequestException( + // AppResponse.toResponse(null, { + // message: SystemLang.getText('messages', 'not_found'), + // }), + // ); + + // const entity = this.repo.create({ + // ...dto, + // time, + // time_raw: dto.time, + // }); + + // const result = await this.repo.save(entity); + + // if (result) { + // if ( + // !conversation.name + // .toLocaleLowerCase() + // .includes(process.env.GROUP_PREFIX.toLocaleLowerCase()) || + // conversation.type !== 'group' + // ) + // return; + + // if (!conversation) return; + + // // Handle when message is a resource + // if (isBase64(result.message)) { + // const fileUrl = await this.zulipService.uploadFileToZulip( + // result.message, + // ); + // const content = `[](${fileUrl})`; + + // await this.zulipService.sendMessageToTopic( + // process.env.ZULIP_STREAMS_NAME, + // conversation.name, + // content, + // ); + + // await this.repo.update(result.id, { message: fileUrl }); + // } else { + // const content = `** :rocket: ${result.name} sent - ${formatTimeAU(result.time_raw)}:** + // \`\`\` + // ${formatTextIfValid(result.message)} + // \`\`\``; + + // await this.zulipService.sendMessageToTopic( + // process.env.ZULIP_STREAMS_NAME, + // conversation.name, + // content, + // ); + // } + // } + + // return { data: result, exit: false }; + // } + async create( dto: CreateMessageDto, ): Promise<{ data: Message; exit: boolean }> { const time = new Date(dto.time); + // 1. Kiểm tra message đã tồn tại chưa const existing = await this.repo.findOne({ where: { time_raw: dto.time, room_id: dto.room_id }, }); - if (existing) { return { data: existing, exit: true }; } + // 2. Lấy thông tin conversation const conversation = await this.conversationRepo.findOne({ where: { id: dto.room_id }, }); - - if (!conversation) + if (!conversation) { throw new BadRequestException( AppResponse.toResponse(null, { message: SystemLang.getText('messages', 'not_found'), }), ); + } + // 3. Chuẩn hóa message trước khi lưu + let messages: string[] = Array.isArray(dto.message) + ? dto.message + : [dto.message]; + + const finalMessages: string[] = []; + + for (const msg of messages) { + if (isBase64(msg)) { + // Nếu là base64 → upload lên Zulip trước + const fileUrl = await this.zulipService.uploadFileToZulip(msg); + finalMessages.push(fileUrl); // Lưu link ảnh thay vì base64 + } else { + finalMessages.push(msg); // Lưu nguyên text + } + } + + // 4. Lưu vào DB với message đã xử lý const entity = this.repo.create({ ...dto, + message: JSON.stringify(finalMessages), time, time_raw: dto.time, }); const result = await this.repo.save(entity); + if (!result) return { data: null, exit: false }; - if (result) { - if ( - !conversation.name - .toLocaleLowerCase() - .includes(process.env.GROUP_PREFIX.toLocaleLowerCase()) || - conversation.type !== 'group' - ) - return; - - if (!conversation) return; - - const content = `** :rocket: ${result.name} sent - ${formatTimeAU(result.time_raw)}:** -\`\`\` -${formatTextIfValid(result.message)} -\`\`\``; - - await this.zulipService.sendMessageToTopic( - process.env.ZULIP_STREAMS_NAME, - conversation.name, - content, - ); + // 5. Kiểm tra conversation có hợp lệ để gửi Zulip không + const groupPrefix = process.env.GROUP_PREFIX?.toLocaleLowerCase() || ''; + if ( + !conversation.name.toLocaleLowerCase().includes(groupPrefix) || + conversation.type !== 'group' + ) { + return { data: result, exit: false }; } + // 6. Build message để gửi lên Zulip + const buildZulipMessageContent = ( + msgs: string[], + result: Message, + ): string => { + const imageUris: string[] = []; + const textMessages: string[] = []; + + for (const msg of msgs) { + // Nếu là link `/user_uploads/...` thì render ảnh + if (/\/user_uploads\//.test(msg)) { + imageUris.push(`[image](${msg.replace(/^\/api\/v1/, '')})`); + } else { + textMessages.push(formatTextIfValid(msg)); + } + } + + let finalContent = `** :rocket: ${result.name} sent - ${formatTimeAU(result.time_raw)}:**\n`; + + // Nếu có text → thêm block code + if (textMessages.length > 0) { + finalContent += `\`\`\`\n${textMessages.join('\n')}\n\`\`\`\n`; + } + + // Nếu có ảnh → thêm danh sách ảnh ở cuối + if (imageUris.length > 0) { + finalContent += imageUris.join('\n'); + } + + return finalContent.trim(); + }; + + const finalMessage = buildZulipMessageContent(finalMessages, result); + + // 7. Gửi lên Zulip + await this.zulipService.sendMessageToTopic( + process.env.ZULIP_STREAMS_NAME, + conversation.name, + finalMessage, + ); + return { data: result, exit: false }; } @@ -144,7 +268,12 @@ ${formatTextIfValid(result.message)} for (const dto of dtos) { const time = new Date(dto.time); const key = `${dto.time}-${dto.room_id ?? ''}`; - const entity = this.repo.create({ ...dto, time, time_raw: dto.time }); + const entity = this.repo.create({ + ...dto, + time, + time_raw: dto.time, + message: JSON.stringify(dto.message), + }); const existing = existingMap.get(key); if (existing) { @@ -213,7 +342,7 @@ ${formatTextIfValid(result.message)} // Đảo ngược array trước khi xử lý // const reversedData = [...data].reverse(); - for (const mes of data) { + for (const mes of data.filter((message) => message.message.length)) { const result = await this.create(mes); if (result) { diff --git a/server/src/modules/messages/zulip.service.ts b/server/src/modules/messages/zulip.service.ts index ad42d83..07fcef4 100644 --- a/server/src/modules/messages/zulip.service.ts +++ b/server/src/modules/messages/zulip.service.ts @@ -1,22 +1,106 @@ import { Injectable, Logger } from '@nestjs/common'; import { HttpService } from '@nestjs/axios'; +import { ConfigService } from '@nestjs/config'; import { firstValueFrom } from 'rxjs'; +import axios from 'axios'; +import * as FormData from 'form-data'; +import * as fs from 'fs-extra'; +import * as path from 'path'; @Injectable() export class ZulipService { private readonly logger = new Logger(ZulipService.name); - constructor(private readonly httpService: HttpService) {} + private readonly zulipUrl: string; + private readonly botEmail: string; + private readonly apiKey: string; + constructor( + private readonly httpService: HttpService, + private readonly configService: ConfigService, + ) { + this.zulipUrl = this.configService.get('ZULIP_API_URL'); + this.botEmail = this.configService.get('ZULIP_BOT_EMAIL'); + this.apiKey = this.configService.get('ZULIP_API_KEY'); + } + + /** + * Upload bất kỳ file nào từ external URL lên Zulip + */ + async uploadFileToZulip(base64Data: string): Promise { + const tempDir = path.join(process.cwd(), 'tmp'); + await fs.ensureDir(tempDir); + + // 1. Lấy thông tin MIME type và phần dữ liệu base64 + let mimeType = 'application/octet-stream'; + let base64Content = base64Data; + + const base64Regex = /^data:(.*?);base64,(.*)$/; + const match = base64Data.match(base64Regex); + if (match) { + mimeType = match[1]; + base64Content = match[2]; + } + + // 2. Lấy phần đuôi file từ MIME type + const extension = 'png'; + const filename = `${Date.now()}-${Math.random().toString(36).substring(7)}.${extension}`; + const filePath = path.join(tempDir, filename); + + try { + this.logger.log(`Decoding and saving file from base64...`); + + // 3. Decode Base64 và lưu vào file tạm + const fileBuffer = Buffer.from(base64Content, 'base64'); + await fs.writeFile(filePath, fileBuffer); + + this.logger.log(`File saved temporarily at: ${filePath}`); + + // 4. Upload file lên Zulip + const form = new FormData(); + form.append('filename', fs.createReadStream(filePath)); + + const uploadRes = await axios.post( + `${this.zulipUrl}/user_uploads`, + form, + { + auth: { + username: this.botEmail, + password: this.apiKey, + }, + headers: form.getHeaders(), + }, + ); + + const zulipFileUrl = `${uploadRes.data.uri}`; + this.logger.log(`Uploaded to Zulip: ${zulipFileUrl}`); + + return zulipFileUrl; + } catch (error) { + this.logger.error( + 'Upload to Zulip failed', + error?.response?.data || error.message, + ); + throw error; + } finally { + // 5. Xóa file tạm + if (await fs.pathExists(filePath)) { + await fs.remove(filePath); + this.logger.log(`Deleted temp file: ${filePath}`); + } + } + } + + /** + * Gửi tin nhắn vào một topic trong stream + */ async sendMessageToTopic(stream: string, topic: string, content: string) { - const url = process.env.ZULIP_API_URL; - const botEmail = process.env.ZULIP_BOT_EMAIL; - const apiKey = process.env.ZULIP_API_KEY; + const apiUrl = this.zulipUrl + '/messages'; try { const response = await firstValueFrom( this.httpService.post( - url, + apiUrl, new URLSearchParams({ type: 'stream', to: stream, @@ -24,12 +108,10 @@ export class ZulipService { content: content, }).toString(), { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, auth: { - username: botEmail, - password: apiKey, + username: this.botEmail, + password: this.apiKey, }, }, ), diff --git a/server/test.png b/server/test.png new file mode 100644 index 0000000..e69de29 diff --git a/server/tmp/1757489923980-3pmx.octet-stream.jpg b/server/tmp/1757489923980-3pmx.octet-stream.jpg new file mode 100644 index 0000000000000000000000000000000000000000..31ee7fb14ab24a24e3f32bef10ba353f435ad46a GIT binary patch literal 32756 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

y-Q?QpH2DL#-?CqmVWdA6(G^& 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

y-Q?QpH2DL#-?CqmVWdA6(G^& zJV}TeUY|$$EvhO!BWOnM`NktpSi@*gTYQwFM!qn%2Lo|(L}RKa&MAcdJv8@bxF0KLHJW zB1|(!GFu$jRLoEM2k_Cboo=vTu|3`4MyCNf7)N{+M{#%fa^sw+&Mr$46zD!~PQ6>p zrREJ97|k*SofJ?zf{)}ENO-<<*aF(0KrDzcy{)%T$`~kJ`QVYf$mCm{Qzr)#W1|a% ziB`g3?ag$5ZPN;>2MAj7$(Y9r?=%*G0vY@o1fR&IT#ST{=pZj_yi{;@zZ7!w?A78PBzrCxRh-1+9zeky`m$bFWKU~UHWYSD%aCpPn zw*5T3vHeYU=<=KC^`mr<)CSe8?}zcJABiNWskM5JDM22Z<(i66NUj+P2fz&|BK=~c z)4|*7g~j(WKbt)j(=o}95v^F9js$64^u&EiJI#psV8rnF!3YCtEL5i!=}!`+QT*%G_c(3bv##CX@f8C$=wd=|^rPVVNVB2&z+#-5S z8V04e=}{o>|C+o~+MJJ88nRZVYIlq@njubqGk5|%=KZETmu){nsWkVZ_wpy8xP%?- zbSiUZ8ZL87&k;LxExaq2;kCe>-fTZ9>V-TPJwQ5S(Hh<&ff<&>T;F`31p$Wg9?9D76vqf)sVWNe0kYa}UhBdDMp;fR3d6js85a zK&lypn-b{9{gB$9F>=sxdS3}3o zG;nYwv)freeY$x$WjTf%ptlK2M^J0si_VF+Ce8PJEW7ilV)C_iL3^1@sJiP!(>`v+ zG>vw?WSLZ`dgSdZluJ?Ao^R&#K3B!mXYHc)GKEm}B59yC%Ua#8U82->h zB6X3n{%+WAEe&HR9ttxmHQI9G2GnOa2r1Gh78Q)TqQ|VDP(^4_ro6ZF#l~cJiR+y% z?2T7PmdBVx;m