@hienlh/ppm 0.8.61 → 0.8.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/web/assets/browser-tab-BnHjUFD1.js +1 -0
- package/dist/web/assets/chat-tab-CyWueJTv.js +7 -0
- package/dist/web/assets/{code-editor-C6umJOvn.js → code-editor-DLXTYEm2.js} +1 -1
- package/dist/web/assets/{database-viewer-TYwvlW4u.js → database-viewer-eqHDuoj7.js} +1 -1
- package/dist/web/assets/{diff-viewer-DApETeeX.js → diff-viewer-DFwFZ_k5.js} +1 -1
- package/dist/web/assets/{git-graph-mtdNxBZs.js → git-graph-Fu6M3rOo.js} +1 -1
- package/dist/web/assets/index-Bf4IsWu9.js +37 -0
- package/dist/web/assets/keybindings-store-BTg2T4RA.js +1 -0
- package/dist/web/assets/{markdown-renderer-oHkpw_nC.js → markdown-renderer-B7o8ysmw.js} +1 -1
- package/dist/web/assets/{postgres-viewer-XnXGFIcT.js → postgres-viewer-BMJBkwN7.js} +1 -1
- package/dist/web/assets/{settings-tab-t--MmXOo.js → settings-tab-D4FbV-Xi.js} +1 -1
- package/dist/web/assets/{sqlite-viewer-Zm20Z3Ys.js → sqlite-viewer-BIdCcD9_.js} +1 -1
- package/dist/web/assets/{terminal-tab-CxJ3m9tD.js → terminal-tab-1CtxESHt.js} +2 -2
- package/dist/web/index.html +1 -1
- package/dist/web/sw.js +1 -1
- package/package.json +1 -1
- package/src/web/components/chat/message-input.tsx +68 -2
- package/src/web/components/layout/command-palette.tsx +2 -0
- package/src/web/hooks/use-global-keybindings.ts +7 -0
- package/src/web/hooks/use-voice-input.ts +111 -0
- package/src/web/stores/keybindings-store.ts +1 -0
- package/dist/web/assets/browser-tab-CsZFFI1C.js +0 -1
- package/dist/web/assets/chat-tab-WYQKXiDW.js +0 -7
- package/dist/web/assets/index-CYhfwlmi.js +0 -37
- package/dist/web/assets/keybindings-store-DA8at4_B.js +0 -1
package/dist/web/sw.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
try{self[`workbox:core:7.3.0`]&&_()}catch{}var e=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n},t=class extends Error{constructor(t,n){let r=e(t,n);super(r),this.name=t,this.details=n}},n={googleAnalytics:`googleAnalytics`,precache:`precache-v2`,prefix:`workbox`,runtime:`runtime`,suffix:typeof registration<`u`?registration.scope:``},r=e=>[n.prefix,e,n.suffix].filter(e=>e&&e.length>0).join(`-`),i=e=>{for(let t of Object.keys(n))e(t)},a={updateDetails:e=>{i(t=>{typeof e[t]==`string`&&(n[t]=e[t])})},getGoogleAnalyticsName:e=>e||r(n.googleAnalytics),getPrecacheName:e=>e||r(n.precache),getPrefix:()=>n.prefix,getRuntimeName:e=>e||r(n.runtime),getSuffix:()=>n.suffix};function o(e,t){let n=t();return e.waitUntil(n),n}try{self[`workbox:precaching:7.3.0`]&&_()}catch{}var s=`__WB_REVISION__`;function c(e){if(!e)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(typeof e==`string`){let t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}let{revision:n,url:r}=e;if(!r)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(!n){let e=new URL(r,location.href);return{cacheKey:e.href,url:e.href}}let i=new URL(r,location.href),a=new URL(r,location.href);return i.searchParams.set(s,n),{cacheKey:i.href,url:a.href}}var l=class{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:n})=>{if(e.type===`install`&&t&&t.originalRequest&&t.originalRequest instanceof Request){let e=t.originalRequest.url;n?this.notUpdatedURLs.push(e):this.updatedURLs.push(e)}return n}}},u=class{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:e,params:t})=>{let n=t?.cacheKey||this._precacheController.getCacheKeyForURL(e.url);return n?new Request(n,{headers:e.headers}):e},this._precacheController=e}},d;function f(){if(d===void 0){let e=new Response(``);if(`body`in e)try{new Response(e.body),d=!0}catch{d=!1}d=!1}return d}async function p(e,n){let r=null;if(e.url&&(r=new URL(e.url).origin),r!==self.location.origin)throw new t(`cross-origin-copy-response`,{origin:r});let i=e.clone(),a={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=n?n(a):a,s=f()?i.body:await i.blob();return new Response(s,o)}var m=e=>new URL(String(e),location.href).href.replace(RegExp(`^${location.origin}`),``);function h(e,t){let n=new URL(e);for(let e of t)n.searchParams.delete(e);return n.href}async function g(e,t,n,r){let i=h(t.url,n);if(t.url===i)return e.match(t,r);let a=Object.assign(Object.assign({},r),{ignoreSearch:!0}),o=await e.keys(t,a);for(let t of o)if(i===h(t.url,n))return e.match(t,r)}var v=class{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}},y=new Set;async function b(){for(let e of y)await e()}function x(e){return new Promise(t=>setTimeout(t,e))}try{self[`workbox:strategies:7.3.0`]&&_()}catch{}function S(e){return typeof e==`string`?new Request(e):e}var C=class{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new v,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(let e of this._plugins)this._pluginStateMap.set(e,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){let{event:n}=this,r=S(e);if(r.mode===`navigate`&&n instanceof FetchEvent&&n.preloadResponse){let e=await n.preloadResponse;if(e)return e}let i=this.hasCallback(`fetchDidFail`)?r.clone():null;try{for(let e of this.iterateCallbacks(`requestWillFetch`))r=await e({request:r.clone(),event:n})}catch(e){if(e instanceof Error)throw new t(`plugin-error-request-will-fetch`,{thrownErrorMessage:e.message})}let a=r.clone();try{let e;e=await fetch(r,r.mode===`navigate`?void 0:this._strategy.fetchOptions);for(let t of this.iterateCallbacks(`fetchDidSucceed`))e=await t({event:n,request:a,response:e});return e}catch(e){throw i&&await this.runCallbacks(`fetchDidFail`,{error:e,event:n,originalRequest:i.clone(),request:a.clone()}),e}}async fetchAndCachePut(e){let t=await this.fetch(e),n=t.clone();return this.waitUntil(this.cachePut(e,n)),t}async cacheMatch(e){let t=S(e),n,{cacheName:r,matchOptions:i}=this._strategy,a=await this.getCacheKey(t,`read`),o=Object.assign(Object.assign({},i),{cacheName:r});n=await caches.match(a,o);for(let e of this.iterateCallbacks(`cachedResponseWillBeUsed`))n=await e({cacheName:r,matchOptions:i,cachedResponse:n,request:a,event:this.event})||void 0;return n}async cachePut(e,n){let r=S(e);await x(0);let i=await this.getCacheKey(r,`write`);if(!n)throw new t(`cache-put-with-no-response`,{url:m(i.url)});let a=await this._ensureResponseSafeToCache(n);if(!a)return!1;let{cacheName:o,matchOptions:s}=this._strategy,c=await self.caches.open(o),l=this.hasCallback(`cacheDidUpdate`),u=l?await g(c,i.clone(),[`__WB_REVISION__`],s):null;try{await c.put(i,l?a.clone():a)}catch(e){if(e instanceof Error)throw e.name===`QuotaExceededError`&&await b(),e}for(let e of this.iterateCallbacks(`cacheDidUpdate`))await e({cacheName:o,oldResponse:u,newResponse:a.clone(),request:i,event:this.event});return!0}async getCacheKey(e,t){let n=`${e.url} | ${t}`;if(!this._cacheKeys[n]){let r=e;for(let e of this.iterateCallbacks(`cacheKeyWillBeUsed`))r=S(await e({mode:t,request:r,event:this.event,params:this.params}));this._cacheKeys[n]=r}return this._cacheKeys[n]}hasCallback(e){for(let t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(let n of this.iterateCallbacks(e))await n(t)}*iterateCallbacks(e){for(let t of this._strategy.plugins)if(typeof t[e]==`function`){let n=this._pluginStateMap.get(t);yield r=>{let i=Object.assign(Object.assign({},r),{state:n});return t[e](i)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){let e=this._extendLifetimePromises.splice(0),t=(await Promise.allSettled(e)).find(e=>e.status===`rejected`);if(t)throw t.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,n=!1;for(let e of this.iterateCallbacks(`cacheWillUpdate`))if(t=await e({request:this.request,response:t,event:this.event})||void 0,n=!0,!t)break;return n||t&&t.status!==200&&(t=void 0),t}},w=class{constructor(e={}){this.cacheName=a.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){let[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});let t=e.event,n=typeof e.request==`string`?new Request(e.request):e.request,r=`params`in e?e.params:void 0,i=new C(this,{event:t,request:n,params:r}),a=this._getResponse(i,n,t);return[a,this._awaitComplete(a,i,n,t)]}async _getResponse(e,n,r){await e.runCallbacks(`handlerWillStart`,{event:r,request:n});let i;try{if(i=await this._handle(n,e),!i||i.type===`error`)throw new t(`no-response`,{url:n.url})}catch(t){if(t instanceof Error){for(let a of e.iterateCallbacks(`handlerDidError`))if(i=await a({error:t,event:r,request:n}),i)break}if(!i)throw t}for(let t of e.iterateCallbacks(`handlerWillRespond`))i=await t({event:r,request:n,response:i});return i}async _awaitComplete(e,t,n,r){let i,a;try{i=await e}catch{}try{await t.runCallbacks(`handlerDidRespond`,{event:r,request:n,response:i}),await t.doneWaiting()}catch(e){e instanceof Error&&(a=e)}if(await t.runCallbacks(`handlerDidComplete`,{event:r,request:n,response:i,error:a}),t.destroy(),a)throw a}},T=class e extends w{constructor(t={}){t.cacheName=a.getPrecacheName(t.cacheName),super(t),this._fallbackToNetwork=t.fallbackToNetwork!==!1,this.plugins.push(e.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){return await t.cacheMatch(e)||(t.event&&t.event.type===`install`?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,n){let r,i=n.params||{};if(this._fallbackToNetwork){let t=i.integrity,a=e.integrity,o=!a||a===t;r=await n.fetch(new Request(e,{integrity:e.mode===`no-cors`?void 0:a||t})),t&&o&&e.mode!==`no-cors`&&(this._useDefaultCacheabilityPluginIfNeeded(),await n.cachePut(e,r.clone()))}else throw new t(`missing-precache-entry`,{cacheName:this.cacheName,url:e.url});return r}async _handleInstall(e,n){this._useDefaultCacheabilityPluginIfNeeded();let r=await n.fetch(e);if(!await n.cachePut(e,r.clone()))throw new t(`bad-precaching-response`,{url:e.url,status:r.status});return r}_useDefaultCacheabilityPluginIfNeeded(){let t=null,n=0;for(let[r,i]of this.plugins.entries())i!==e.copyRedirectedCacheableResponsesPlugin&&(i===e.defaultPrecacheCacheabilityPlugin&&(t=r),i.cacheWillUpdate&&n++);n===0?this.plugins.push(e.defaultPrecacheCacheabilityPlugin):n>1&&t!==null&&this.plugins.splice(t,1)}};T.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:e}){return!e||e.status>=400?null:e}},T.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:e}){return e.redirected?await p(e):e}};var E=class{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:n=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new T({cacheName:a.getPrecacheName(e),plugins:[...t,new u({precacheController:this})],fallbackToNetwork:n}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||=(self.addEventListener(`install`,this.install),self.addEventListener(`activate`,this.activate),!0)}addToCacheList(e){let n=[];for(let r of e){typeof r==`string`?n.push(r):r&&r.revision===void 0&&n.push(r.url);let{cacheKey:e,url:i}=c(r),a=typeof r!=`string`&&r.revision?`reload`:`default`;if(this._urlsToCacheKeys.has(i)&&this._urlsToCacheKeys.get(i)!==e)throw new t(`add-to-cache-list-conflicting-entries`,{firstEntry:this._urlsToCacheKeys.get(i),secondEntry:e});if(typeof r!=`string`&&r.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==r.integrity)throw new t(`add-to-cache-list-conflicting-integrities`,{url:i});this._cacheKeysToIntegrities.set(e,r.integrity)}if(this._urlsToCacheKeys.set(i,e),this._urlsToCacheModes.set(i,a),n.length>0){let e=`Workbox is precaching URLs without revision info: ${n.join(`, `)}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(e)}}}install(e){return o(e,async()=>{let t=new l;this.strategy.plugins.push(t);for(let[t,n]of this._urlsToCacheKeys){let r=this._cacheKeysToIntegrities.get(n),i=this._urlsToCacheModes.get(t),a=new Request(t,{integrity:r,cache:i,credentials:`same-origin`});await Promise.all(this.strategy.handleAll({params:{cacheKey:n},request:a,event:e}))}let{updatedURLs:n,notUpdatedURLs:r}=t;return{updatedURLs:n,notUpdatedURLs:r}})}activate(e){return o(e,async()=>{let e=await self.caches.open(this.strategy.cacheName),t=await e.keys(),n=new Set(this._urlsToCacheKeys.values()),r=[];for(let i of t)n.has(i.url)||(await e.delete(i),r.push(i.url));return{deletedURLs:r}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){let t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){let t=e instanceof Request?e.url:e,n=this.getCacheKeyForURL(t);if(n)return(await self.caches.open(this.strategy.cacheName)).match(n)}createHandlerBoundToURL(e){let n=this.getCacheKeyForURL(e);if(!n)throw new t(`non-precached-url`,{url:e});return t=>(t.request=new Request(e),t.params=Object.assign({cacheKey:n},t.params),this.strategy.handle(t))}},D,O=()=>(D||=new E,D);try{self[`workbox:routing:7.3.0`]&&_()}catch{}var k=e=>e&&typeof e==`object`?e:{handle:e},A=class{constructor(e,t,n=`GET`){this.handler=k(t),this.match=e,this.method=n}setCatchHandler(e){this.catchHandler=k(e)}},j=class extends A{constructor(e,t,n){super(({url:t})=>{let n=e.exec(t.href);if(n&&!(t.origin!==location.origin&&n.index!==0))return n.slice(1)},t,n)}},M=class{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener(`fetch`,(e=>{let{request:t}=e,n=this.handleRequest({request:t,event:e});n&&e.respondWith(n)}))}addCacheListener(){self.addEventListener(`message`,(e=>{if(e.data&&e.data.type===`CACHE_URLS`){let{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(t=>{typeof t==`string`&&(t=[t]);let n=new Request(...t);return this.handleRequest({request:n,event:e})}));e.waitUntil(n),e.ports&&e.ports[0]&&n.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){let n=new URL(e.url,location.href);if(!n.protocol.startsWith(`http`))return;let r=n.origin===location.origin,{params:i,route:a}=this.findMatchingRoute({event:t,request:e,sameOrigin:r,url:n}),o=a&&a.handler,s=e.method;if(!o&&this._defaultHandlerMap.has(s)&&(o=this._defaultHandlerMap.get(s)),!o)return;let c;try{c=o.handle({url:n,request:e,event:t,params:i})}catch(e){c=Promise.reject(e)}let l=a&&a.catchHandler;return c instanceof Promise&&(this._catchHandler||l)&&(c=c.catch(async r=>{if(l)try{return await l.handle({url:n,request:e,event:t,params:i})}catch(e){e instanceof Error&&(r=e)}if(this._catchHandler)return this._catchHandler.handle({url:n,request:e,event:t});throw r})),c}findMatchingRoute({url:e,sameOrigin:t,request:n,event:r}){let i=this._routes.get(n.method)||[];for(let a of i){let i,o=a.match({url:e,sameOrigin:t,request:n,event:r});if(o)return i=o,(Array.isArray(i)&&i.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o==`boolean`)&&(i=void 0),{route:a,params:i}}return{}}setDefaultHandler(e,t=`GET`){this._defaultHandlerMap.set(t,k(e))}setCatchHandler(e){this._catchHandler=k(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t(`unregister-route-but-not-found-with-method`,{method:e.method});let n=this._routes.get(e.method).indexOf(e);if(n>-1)this._routes.get(e.method).splice(n,1);else throw new t(`unregister-route-route-not-registered`)}},N,P=()=>(N||(N=new M,N.addFetchListener(),N.addCacheListener()),N);function F(e,n,r){let i;if(typeof e==`string`){let t=new URL(e,location.href);i=new A(({url:e})=>e.href===t.href,n,r)}else if(e instanceof RegExp)i=new j(e,n,r);else if(typeof e==`function`)i=new A(e,n,r);else if(e instanceof A)i=e;else throw new t(`unsupported-route-type`,{moduleName:`workbox-routing`,funcName:`registerRoute`,paramName:`capture`});return P().registerRoute(i),i}function I(e,t=[]){for(let n of[...e.searchParams.keys()])t.some(e=>e.test(n))&&e.searchParams.delete(n);return e}function*L(e,{ignoreURLParametersMatching:t=[/^utm_/,/^fbclid$/],directoryIndex:n=`index.html`,cleanURLs:r=!0,urlManipulation:i}={}){let a=new URL(e,location.href);a.hash=``,yield a.href;let o=I(a,t);if(yield o.href,n&&o.pathname.endsWith(`/`)){let e=new URL(o.href);e.pathname+=n,yield e.href}if(r){let e=new URL(o.href);e.pathname+=`.html`,yield e.href}if(i){let e=i({url:a});for(let t of e)yield t.href}}var R=class extends A{constructor(e,t){super(({request:n})=>{let r=e.getURLsToCacheKeys();for(let i of L(n.url,t)){let t=r.get(i);if(t)return{cacheKey:t,integrity:e.getIntegrityForCacheKey(t)}}},e.strategy)}};function z(e){F(new R(O(),e))}function B(e){O().precache(e)}function V(e,t){B(e),z(t)}V([{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"2b981b018b202252559a4f14445b82bd","url":"index.html"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"eb9818b9094675c0c5d303168f273345","url":"monacoeditorwork/ts.worker.bundle.js"},{"revision":"9af0be92dcefdc1f1290441cb5ff5d9b","url":"monacoeditorwork/json.worker.bundle.js"},{"revision":"a261b429c39dbb75ae97972d7d005e6d","url":"monacoeditorwork/html.worker.bundle.js"},{"revision":"79953d804e1bbacecfd79b85fd679016","url":"monacoeditorwork/editor.worker.bundle.js"},{"revision":"fdcba0d09aac31df7a0bc652f6e739bd","url":"monacoeditorwork/css.worker.bundle.js"},{"revision":null,"url":"assets/xychartDiagram-JWTSCODW-BRvXOVlG.js"},{"revision":null,"url":"assets/vennDiagram-LZ73GAT5-DfYFnniI.js"},{"revision":null,"url":"assets/utils-Bslrbb-G.js"},{"revision":null,"url":"assets/use-monaco-theme-BQzvItNE.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-BL9OJq3X.js"},{"revision":null,"url":"assets/timeline-definition-YZTLITO2-DrjxCpEM.js"},{"revision":null,"url":"assets/terminal-tab-CxJ3m9tD.js"},{"revision":null,"url":"assets/terminal-tab-BrP-ENHg.css"},{"revision":null,"url":"assets/tag-CENGyt_L.js"},{"revision":null,"url":"assets/table-C9jDaRl2.js"},{"revision":null,"url":"assets/tab-store-DSz5PQI0.js"},{"revision":null,"url":"assets/switch-goUjvGec.js"},{"revision":null,"url":"assets/stateDiagram-v2-FVOUBMTO-D7qSAjnK.js"},{"revision":null,"url":"assets/stateDiagram-RAJIS63D-C16aO8tn.js"},{"revision":null,"url":"assets/src-CLWraeNW.js"},{"revision":null,"url":"assets/sqlite-viewer-Zm20Z3Ys.js"},{"revision":null,"url":"assets/settings-tab-t--MmXOo.js"},{"revision":null,"url":"assets/settings-store-D3dJqGhB.js"},{"revision":null,"url":"assets/sequenceDiagram-2WXFIKYE-BtRvoUTC.js"},{"revision":null,"url":"assets/sankeyDiagram-WA2Y5GQK-DEGGYsk7.js"},{"revision":null,"url":"assets/rough.esm-c4PR5shF.js"},{"revision":null,"url":"assets/requirementDiagram-Z7DCOOCP-1WWjMQB_.js"},{"revision":null,"url":"assets/react-nm2Ru1Pt.js"},{"revision":null,"url":"assets/react-BPIfZRKM.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-CHptMqVT.js"},{"revision":null,"url":"assets/quadrantDiagram-337W2JSQ-BaRFqlsA.js"},{"revision":null,"url":"assets/preload-helper-CsoeaaUJ.js"},{"revision":null,"url":"assets/postgres-viewer-XnXGFIcT.js"},{"revision":null,"url":"assets/pieDiagram-SKSYHLDU-seSK40d1.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-B0h6hM1j.js"},{"revision":null,"url":"assets/path-CuyvWNAH.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-BbzPU9BK.js"},{"revision":null,"url":"assets/ordinal-CIoJK3nc.js"},{"revision":null,"url":"assets/mindmap-definition-YRQLILUH-DIv-LMXG.js"},{"revision":null,"url":"assets/mermaid-parser.core-BY8JfkE_.js"},{"revision":null,"url":"assets/math-a44lmFDa.js"},{"revision":null,"url":"assets/markdown-renderer-oHkpw_nC.js"},{"revision":null,"url":"assets/linear-BdqW7iQu.js"},{"revision":null,"url":"assets/line--xyfYP3x.js"},{"revision":null,"url":"assets/keybindings-store-DA8at4_B.js"},{"revision":null,"url":"assets/katex-C3cZrCvP.js"},{"revision":null,"url":"assets/kanban-definition-K7BYSVSG-BMUhjxqj.js"},{"revision":null,"url":"assets/jsx-runtime-BRW_vwa9.js"},{"revision":null,"url":"assets/journeyDiagram-4ABVD52K-DFQXUZsc.js"},{"revision":null,"url":"assets/ishikawaDiagram-PHBUUO56-cW7SMLa_.js"},{"revision":null,"url":"assets/isEmpty-DXomfd7J.js"},{"revision":null,"url":"assets/isArrayLikeObject-DvHDmeBe.js"},{"revision":null,"url":"assets/input-DGlv6gt_.js"},{"revision":null,"url":"assets/init-vVpfz1D6.js"},{"revision":null,"url":"assets/infoDiagram-LFFYTUFH-DFh9c-S2.js"},{"revision":null,"url":"assets/info-3K5VOQVL-CbpovIYU.js"},{"revision":null,"url":"assets/index-n0Ww6i6b.css"},{"revision":null,"url":"assets/index-CYhfwlmi.js"},{"revision":null,"url":"assets/graphlib-BbbiUImY.js"},{"revision":null,"url":"assets/gitGraphDiagram-K3NZZRJ6-L7sj3Bs-.js"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-D5qEPjgs.js"},{"revision":null,"url":"assets/git-graph-mtdNxBZs.js"},{"revision":null,"url":"assets/ganttDiagram-A5KZAMGK-BVlftqyZ.js"},{"revision":null,"url":"assets/flowDiagram-PKNHOUZH-B9h_Ba-v.js"},{"revision":null,"url":"assets/erDiagram-INFDFZHY-DK4QEZYh.js"},{"revision":null,"url":"assets/dist-Ckxnw5rl.js"},{"revision":null,"url":"assets/dist-CMmNEgEP.js"},{"revision":null,"url":"assets/diff-viewer-DApETeeX.js"},{"revision":null,"url":"assets/diagram-P4PSJMXO--nUaNiyB.js"},{"revision":null,"url":"assets/diagram-IFDJBPK2-NvhckwcA.js"},{"revision":null,"url":"assets/diagram-E7M64L7V-CkDC2uAj.js"},{"revision":null,"url":"assets/defaultLocale-D_VMtRaY.js"},{"revision":null,"url":"assets/database-viewer-TYwvlW4u.js"},{"revision":null,"url":"assets/dagre-KLK3FWXG-Br4t5TRV.js"},{"revision":null,"url":"assets/dagre-CWo8w9wK.js"},{"revision":null,"url":"assets/cytoscape.esm-B-QQuWwK.js"},{"revision":null,"url":"assets/cose-bilkent-S5V4N54A-C1QJ6GPW.js"},{"revision":null,"url":"assets/columns-2-Bcg3QJBg.js"},{"revision":null,"url":"assets/code-editor-C6umJOvn.js"},{"revision":null,"url":"assets/clone-DNDy9Sms.js"},{"revision":null,"url":"assets/classDiagram-v2-RAHNMMFH-Bo5WN2ok.js"},{"revision":null,"url":"assets/classDiagram-VBA2DB6C-CqaIqYPn.js"},{"revision":null,"url":"assets/chunk-YBOYWFTD-COdZIaX4.js"},{"revision":null,"url":"assets/chunk-XZSTWKYB-5W2emiq4.js"},{"revision":null,"url":"assets/chunk-XPW4576I-CsGTseUr.js"},{"revision":null,"url":"assets/chunk-XIRO2GV7-DUmQrLsF.js"},{"revision":null,"url":"assets/chunk-WL4C6EOR-BHFnnXOt.js"},{"revision":null,"url":"assets/chunk-R5LLSJPH-LdG7RqsM.js"},{"revision":null,"url":"assets/chunk-QZHKN3VN-gaBt0Rbd.js"},{"revision":null,"url":"assets/chunk-PU5JKC2W-D3thuSok.js"},{"revision":null,"url":"assets/chunk-PQ6SQG4A-EdgQyTqa.js"},{"revision":null,"url":"assets/chunk-OZEHJAEY-LfXT4p8B.js"},{"revision":null,"url":"assets/chunk-O4XLMI2P-BdXwVXjJ.js"},{"revision":null,"url":"assets/chunk-NQ4KR5QH-BRj25yO7.js"},{"revision":null,"url":"assets/chunk-MX3YWQON-BnPzQK-O.js"},{"revision":null,"url":"assets/chunk-L3YUKLVL-DNFj84V6.js"},{"revision":null,"url":"assets/chunk-KYZI473N-CBRPKraG.js"},{"revision":null,"url":"assets/chunk-KX2RTZJC-BRj-ZEvL.js"},{"revision":null,"url":"assets/chunk-JSJVCQXG-Pb-JMOgO.js"},{"revision":null,"url":"assets/chunk-HHEYEP7N-BnRVfNc5.js"},{"revision":null,"url":"assets/chunk-GLR3WWYH-Bx2UL5jF.js"},{"revision":null,"url":"assets/chunk-GEFDOKGD-B82RP9ow.js"},{"revision":null,"url":"assets/chunk-FMBD7UC4-JCLgVcaC.js"},{"revision":null,"url":"assets/chunk-EGIJ26TM-Cgt-qg75.js"},{"revision":null,"url":"assets/chunk-CFjPhJqf.js"},{"revision":null,"url":"assets/chunk-C72U2L5F-CcEW1AMZ.js"},{"revision":null,"url":"assets/chunk-7R4GIKGN-DvbvLUIN.js"},{"revision":null,"url":"assets/chunk-7E7YKBS2-CuYKSUgJ.js"},{"revision":null,"url":"assets/chunk-55IACEB6-Dp0pTM5r.js"},{"revision":null,"url":"assets/chunk-4BX2VUAB-0YMkpW2S.js"},{"revision":null,"url":"assets/chat-tab-WYQKXiDW.js"},{"revision":null,"url":"assets/channel-CKNZAqoN.js"},{"revision":null,"url":"assets/c4Diagram-IC4MRINW-DzjR91sM.js"},{"revision":null,"url":"assets/browser-tab-CsZFFI1C.js"},{"revision":null,"url":"assets/blockDiagram-WCTKOSBZ-CU2t4NHJ.js"},{"revision":null,"url":"assets/arrow-left-C_j9Ki73.js"},{"revision":null,"url":"assets/array-CLwNaqU1.js"},{"revision":null,"url":"assets/architectureDiagram-2XIMDMQ5-BVEUkQYB.js"},{"revision":null,"url":"assets/architecture-PBZL5I3N-281eTKQ3.js"},{"revision":null,"url":"assets/arc-D0bJaFyD.js"},{"revision":null,"url":"assets/api-settings-CuUkz5gb.js"},{"revision":null,"url":"assets/api-client-icCZ-07C.js"},{"revision":null,"url":"assets/_baseUniq-DCb0mkTp.js"},{"revision":null,"url":"assets/_basePickBy-COwDPZl_.js"},{"revision":"79c8870653c8f419f2e3323085e1f4be","url":"manifest.webmanifest"}]),self.addEventListener(`push`,e=>{e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{if(t.some(e=>e.visibilityState===`visible`))return;let n=e.data?.json()??{title:`PPM`,body:`Chat completed`};return self.registration.showNotification(n.title,{body:n.body,icon:`/icon-192.png`,badge:`/icon-192.png`,tag:`ppm-chat-done`,silent:!1,data:{url:self.location.origin}})}))}),self.addEventListener(`notificationclick`,e=>{e.notification.close(),e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{for(let e of t)if(e.url.includes(self.location.origin)&&`focus`in e)return e.focus();return self.clients.openWindow(e.notification.data?.url||`/`)}))});
|
|
1
|
+
try{self[`workbox:core:7.3.0`]&&_()}catch{}var e=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n},t=class extends Error{constructor(t,n){let r=e(t,n);super(r),this.name=t,this.details=n}},n={googleAnalytics:`googleAnalytics`,precache:`precache-v2`,prefix:`workbox`,runtime:`runtime`,suffix:typeof registration<`u`?registration.scope:``},r=e=>[n.prefix,e,n.suffix].filter(e=>e&&e.length>0).join(`-`),i=e=>{for(let t of Object.keys(n))e(t)},a={updateDetails:e=>{i(t=>{typeof e[t]==`string`&&(n[t]=e[t])})},getGoogleAnalyticsName:e=>e||r(n.googleAnalytics),getPrecacheName:e=>e||r(n.precache),getPrefix:()=>n.prefix,getRuntimeName:e=>e||r(n.runtime),getSuffix:()=>n.suffix};function o(e,t){let n=t();return e.waitUntil(n),n}try{self[`workbox:precaching:7.3.0`]&&_()}catch{}var s=`__WB_REVISION__`;function c(e){if(!e)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(typeof e==`string`){let t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}let{revision:n,url:r}=e;if(!r)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(!n){let e=new URL(r,location.href);return{cacheKey:e.href,url:e.href}}let i=new URL(r,location.href),a=new URL(r,location.href);return i.searchParams.set(s,n),{cacheKey:i.href,url:a.href}}var l=class{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:n})=>{if(e.type===`install`&&t&&t.originalRequest&&t.originalRequest instanceof Request){let e=t.originalRequest.url;n?this.notUpdatedURLs.push(e):this.updatedURLs.push(e)}return n}}},u=class{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:e,params:t})=>{let n=t?.cacheKey||this._precacheController.getCacheKeyForURL(e.url);return n?new Request(n,{headers:e.headers}):e},this._precacheController=e}},d;function f(){if(d===void 0){let e=new Response(``);if(`body`in e)try{new Response(e.body),d=!0}catch{d=!1}d=!1}return d}async function p(e,n){let r=null;if(e.url&&(r=new URL(e.url).origin),r!==self.location.origin)throw new t(`cross-origin-copy-response`,{origin:r});let i=e.clone(),a={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=n?n(a):a,s=f()?i.body:await i.blob();return new Response(s,o)}var m=e=>new URL(String(e),location.href).href.replace(RegExp(`^${location.origin}`),``);function h(e,t){let n=new URL(e);for(let e of t)n.searchParams.delete(e);return n.href}async function g(e,t,n,r){let i=h(t.url,n);if(t.url===i)return e.match(t,r);let a=Object.assign(Object.assign({},r),{ignoreSearch:!0}),o=await e.keys(t,a);for(let t of o)if(i===h(t.url,n))return e.match(t,r)}var v=class{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}},y=new Set;async function b(){for(let e of y)await e()}function x(e){return new Promise(t=>setTimeout(t,e))}try{self[`workbox:strategies:7.3.0`]&&_()}catch{}function S(e){return typeof e==`string`?new Request(e):e}var C=class{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new v,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(let e of this._plugins)this._pluginStateMap.set(e,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){let{event:n}=this,r=S(e);if(r.mode===`navigate`&&n instanceof FetchEvent&&n.preloadResponse){let e=await n.preloadResponse;if(e)return e}let i=this.hasCallback(`fetchDidFail`)?r.clone():null;try{for(let e of this.iterateCallbacks(`requestWillFetch`))r=await e({request:r.clone(),event:n})}catch(e){if(e instanceof Error)throw new t(`plugin-error-request-will-fetch`,{thrownErrorMessage:e.message})}let a=r.clone();try{let e;e=await fetch(r,r.mode===`navigate`?void 0:this._strategy.fetchOptions);for(let t of this.iterateCallbacks(`fetchDidSucceed`))e=await t({event:n,request:a,response:e});return e}catch(e){throw i&&await this.runCallbacks(`fetchDidFail`,{error:e,event:n,originalRequest:i.clone(),request:a.clone()}),e}}async fetchAndCachePut(e){let t=await this.fetch(e),n=t.clone();return this.waitUntil(this.cachePut(e,n)),t}async cacheMatch(e){let t=S(e),n,{cacheName:r,matchOptions:i}=this._strategy,a=await this.getCacheKey(t,`read`),o=Object.assign(Object.assign({},i),{cacheName:r});n=await caches.match(a,o);for(let e of this.iterateCallbacks(`cachedResponseWillBeUsed`))n=await e({cacheName:r,matchOptions:i,cachedResponse:n,request:a,event:this.event})||void 0;return n}async cachePut(e,n){let r=S(e);await x(0);let i=await this.getCacheKey(r,`write`);if(!n)throw new t(`cache-put-with-no-response`,{url:m(i.url)});let a=await this._ensureResponseSafeToCache(n);if(!a)return!1;let{cacheName:o,matchOptions:s}=this._strategy,c=await self.caches.open(o),l=this.hasCallback(`cacheDidUpdate`),u=l?await g(c,i.clone(),[`__WB_REVISION__`],s):null;try{await c.put(i,l?a.clone():a)}catch(e){if(e instanceof Error)throw e.name===`QuotaExceededError`&&await b(),e}for(let e of this.iterateCallbacks(`cacheDidUpdate`))await e({cacheName:o,oldResponse:u,newResponse:a.clone(),request:i,event:this.event});return!0}async getCacheKey(e,t){let n=`${e.url} | ${t}`;if(!this._cacheKeys[n]){let r=e;for(let e of this.iterateCallbacks(`cacheKeyWillBeUsed`))r=S(await e({mode:t,request:r,event:this.event,params:this.params}));this._cacheKeys[n]=r}return this._cacheKeys[n]}hasCallback(e){for(let t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(let n of this.iterateCallbacks(e))await n(t)}*iterateCallbacks(e){for(let t of this._strategy.plugins)if(typeof t[e]==`function`){let n=this._pluginStateMap.get(t);yield r=>{let i=Object.assign(Object.assign({},r),{state:n});return t[e](i)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){let e=this._extendLifetimePromises.splice(0),t=(await Promise.allSettled(e)).find(e=>e.status===`rejected`);if(t)throw t.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,n=!1;for(let e of this.iterateCallbacks(`cacheWillUpdate`))if(t=await e({request:this.request,response:t,event:this.event})||void 0,n=!0,!t)break;return n||t&&t.status!==200&&(t=void 0),t}},w=class{constructor(e={}){this.cacheName=a.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){let[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});let t=e.event,n=typeof e.request==`string`?new Request(e.request):e.request,r=`params`in e?e.params:void 0,i=new C(this,{event:t,request:n,params:r}),a=this._getResponse(i,n,t);return[a,this._awaitComplete(a,i,n,t)]}async _getResponse(e,n,r){await e.runCallbacks(`handlerWillStart`,{event:r,request:n});let i;try{if(i=await this._handle(n,e),!i||i.type===`error`)throw new t(`no-response`,{url:n.url})}catch(t){if(t instanceof Error){for(let a of e.iterateCallbacks(`handlerDidError`))if(i=await a({error:t,event:r,request:n}),i)break}if(!i)throw t}for(let t of e.iterateCallbacks(`handlerWillRespond`))i=await t({event:r,request:n,response:i});return i}async _awaitComplete(e,t,n,r){let i,a;try{i=await e}catch{}try{await t.runCallbacks(`handlerDidRespond`,{event:r,request:n,response:i}),await t.doneWaiting()}catch(e){e instanceof Error&&(a=e)}if(await t.runCallbacks(`handlerDidComplete`,{event:r,request:n,response:i,error:a}),t.destroy(),a)throw a}},T=class e extends w{constructor(t={}){t.cacheName=a.getPrecacheName(t.cacheName),super(t),this._fallbackToNetwork=t.fallbackToNetwork!==!1,this.plugins.push(e.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){return await t.cacheMatch(e)||(t.event&&t.event.type===`install`?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,n){let r,i=n.params||{};if(this._fallbackToNetwork){let t=i.integrity,a=e.integrity,o=!a||a===t;r=await n.fetch(new Request(e,{integrity:e.mode===`no-cors`?void 0:a||t})),t&&o&&e.mode!==`no-cors`&&(this._useDefaultCacheabilityPluginIfNeeded(),await n.cachePut(e,r.clone()))}else throw new t(`missing-precache-entry`,{cacheName:this.cacheName,url:e.url});return r}async _handleInstall(e,n){this._useDefaultCacheabilityPluginIfNeeded();let r=await n.fetch(e);if(!await n.cachePut(e,r.clone()))throw new t(`bad-precaching-response`,{url:e.url,status:r.status});return r}_useDefaultCacheabilityPluginIfNeeded(){let t=null,n=0;for(let[r,i]of this.plugins.entries())i!==e.copyRedirectedCacheableResponsesPlugin&&(i===e.defaultPrecacheCacheabilityPlugin&&(t=r),i.cacheWillUpdate&&n++);n===0?this.plugins.push(e.defaultPrecacheCacheabilityPlugin):n>1&&t!==null&&this.plugins.splice(t,1)}};T.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:e}){return!e||e.status>=400?null:e}},T.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:e}){return e.redirected?await p(e):e}};var E=class{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:n=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new T({cacheName:a.getPrecacheName(e),plugins:[...t,new u({precacheController:this})],fallbackToNetwork:n}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||=(self.addEventListener(`install`,this.install),self.addEventListener(`activate`,this.activate),!0)}addToCacheList(e){let n=[];for(let r of e){typeof r==`string`?n.push(r):r&&r.revision===void 0&&n.push(r.url);let{cacheKey:e,url:i}=c(r),a=typeof r!=`string`&&r.revision?`reload`:`default`;if(this._urlsToCacheKeys.has(i)&&this._urlsToCacheKeys.get(i)!==e)throw new t(`add-to-cache-list-conflicting-entries`,{firstEntry:this._urlsToCacheKeys.get(i),secondEntry:e});if(typeof r!=`string`&&r.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==r.integrity)throw new t(`add-to-cache-list-conflicting-integrities`,{url:i});this._cacheKeysToIntegrities.set(e,r.integrity)}if(this._urlsToCacheKeys.set(i,e),this._urlsToCacheModes.set(i,a),n.length>0){let e=`Workbox is precaching URLs without revision info: ${n.join(`, `)}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(e)}}}install(e){return o(e,async()=>{let t=new l;this.strategy.plugins.push(t);for(let[t,n]of this._urlsToCacheKeys){let r=this._cacheKeysToIntegrities.get(n),i=this._urlsToCacheModes.get(t),a=new Request(t,{integrity:r,cache:i,credentials:`same-origin`});await Promise.all(this.strategy.handleAll({params:{cacheKey:n},request:a,event:e}))}let{updatedURLs:n,notUpdatedURLs:r}=t;return{updatedURLs:n,notUpdatedURLs:r}})}activate(e){return o(e,async()=>{let e=await self.caches.open(this.strategy.cacheName),t=await e.keys(),n=new Set(this._urlsToCacheKeys.values()),r=[];for(let i of t)n.has(i.url)||(await e.delete(i),r.push(i.url));return{deletedURLs:r}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){let t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){let t=e instanceof Request?e.url:e,n=this.getCacheKeyForURL(t);if(n)return(await self.caches.open(this.strategy.cacheName)).match(n)}createHandlerBoundToURL(e){let n=this.getCacheKeyForURL(e);if(!n)throw new t(`non-precached-url`,{url:e});return t=>(t.request=new Request(e),t.params=Object.assign({cacheKey:n},t.params),this.strategy.handle(t))}},D,O=()=>(D||=new E,D);try{self[`workbox:routing:7.3.0`]&&_()}catch{}var k=e=>e&&typeof e==`object`?e:{handle:e},A=class{constructor(e,t,n=`GET`){this.handler=k(t),this.match=e,this.method=n}setCatchHandler(e){this.catchHandler=k(e)}},j=class extends A{constructor(e,t,n){super(({url:t})=>{let n=e.exec(t.href);if(n&&!(t.origin!==location.origin&&n.index!==0))return n.slice(1)},t,n)}},M=class{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener(`fetch`,(e=>{let{request:t}=e,n=this.handleRequest({request:t,event:e});n&&e.respondWith(n)}))}addCacheListener(){self.addEventListener(`message`,(e=>{if(e.data&&e.data.type===`CACHE_URLS`){let{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(t=>{typeof t==`string`&&(t=[t]);let n=new Request(...t);return this.handleRequest({request:n,event:e})}));e.waitUntil(n),e.ports&&e.ports[0]&&n.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){let n=new URL(e.url,location.href);if(!n.protocol.startsWith(`http`))return;let r=n.origin===location.origin,{params:i,route:a}=this.findMatchingRoute({event:t,request:e,sameOrigin:r,url:n}),o=a&&a.handler,s=e.method;if(!o&&this._defaultHandlerMap.has(s)&&(o=this._defaultHandlerMap.get(s)),!o)return;let c;try{c=o.handle({url:n,request:e,event:t,params:i})}catch(e){c=Promise.reject(e)}let l=a&&a.catchHandler;return c instanceof Promise&&(this._catchHandler||l)&&(c=c.catch(async r=>{if(l)try{return await l.handle({url:n,request:e,event:t,params:i})}catch(e){e instanceof Error&&(r=e)}if(this._catchHandler)return this._catchHandler.handle({url:n,request:e,event:t});throw r})),c}findMatchingRoute({url:e,sameOrigin:t,request:n,event:r}){let i=this._routes.get(n.method)||[];for(let a of i){let i,o=a.match({url:e,sameOrigin:t,request:n,event:r});if(o)return i=o,(Array.isArray(i)&&i.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o==`boolean`)&&(i=void 0),{route:a,params:i}}return{}}setDefaultHandler(e,t=`GET`){this._defaultHandlerMap.set(t,k(e))}setCatchHandler(e){this._catchHandler=k(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t(`unregister-route-but-not-found-with-method`,{method:e.method});let n=this._routes.get(e.method).indexOf(e);if(n>-1)this._routes.get(e.method).splice(n,1);else throw new t(`unregister-route-route-not-registered`)}},N,P=()=>(N||(N=new M,N.addFetchListener(),N.addCacheListener()),N);function F(e,n,r){let i;if(typeof e==`string`){let t=new URL(e,location.href);i=new A(({url:e})=>e.href===t.href,n,r)}else if(e instanceof RegExp)i=new j(e,n,r);else if(typeof e==`function`)i=new A(e,n,r);else if(e instanceof A)i=e;else throw new t(`unsupported-route-type`,{moduleName:`workbox-routing`,funcName:`registerRoute`,paramName:`capture`});return P().registerRoute(i),i}function I(e,t=[]){for(let n of[...e.searchParams.keys()])t.some(e=>e.test(n))&&e.searchParams.delete(n);return e}function*L(e,{ignoreURLParametersMatching:t=[/^utm_/,/^fbclid$/],directoryIndex:n=`index.html`,cleanURLs:r=!0,urlManipulation:i}={}){let a=new URL(e,location.href);a.hash=``,yield a.href;let o=I(a,t);if(yield o.href,n&&o.pathname.endsWith(`/`)){let e=new URL(o.href);e.pathname+=n,yield e.href}if(r){let e=new URL(o.href);e.pathname+=`.html`,yield e.href}if(i){let e=i({url:a});for(let t of e)yield t.href}}var R=class extends A{constructor(e,t){super(({request:n})=>{let r=e.getURLsToCacheKeys();for(let i of L(n.url,t)){let t=r.get(i);if(t)return{cacheKey:t,integrity:e.getIntegrityForCacheKey(t)}}},e.strategy)}};function z(e){F(new R(O(),e))}function B(e){O().precache(e)}function V(e,t){B(e),z(t)}V([{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"dff50ef78c487e657c628d6e40760eda","url":"index.html"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"eb9818b9094675c0c5d303168f273345","url":"monacoeditorwork/ts.worker.bundle.js"},{"revision":"9af0be92dcefdc1f1290441cb5ff5d9b","url":"monacoeditorwork/json.worker.bundle.js"},{"revision":"a261b429c39dbb75ae97972d7d005e6d","url":"monacoeditorwork/html.worker.bundle.js"},{"revision":"79953d804e1bbacecfd79b85fd679016","url":"monacoeditorwork/editor.worker.bundle.js"},{"revision":"fdcba0d09aac31df7a0bc652f6e739bd","url":"monacoeditorwork/css.worker.bundle.js"},{"revision":null,"url":"assets/xychartDiagram-JWTSCODW-BRvXOVlG.js"},{"revision":null,"url":"assets/vennDiagram-LZ73GAT5-DfYFnniI.js"},{"revision":null,"url":"assets/utils-Bslrbb-G.js"},{"revision":null,"url":"assets/use-monaco-theme-BQzvItNE.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-BL9OJq3X.js"},{"revision":null,"url":"assets/timeline-definition-YZTLITO2-DrjxCpEM.js"},{"revision":null,"url":"assets/terminal-tab-BrP-ENHg.css"},{"revision":null,"url":"assets/terminal-tab-1CtxESHt.js"},{"revision":null,"url":"assets/tag-CENGyt_L.js"},{"revision":null,"url":"assets/table-C9jDaRl2.js"},{"revision":null,"url":"assets/tab-store-DSz5PQI0.js"},{"revision":null,"url":"assets/switch-goUjvGec.js"},{"revision":null,"url":"assets/stateDiagram-v2-FVOUBMTO-D7qSAjnK.js"},{"revision":null,"url":"assets/stateDiagram-RAJIS63D-C16aO8tn.js"},{"revision":null,"url":"assets/src-CLWraeNW.js"},{"revision":null,"url":"assets/sqlite-viewer-BIdCcD9_.js"},{"revision":null,"url":"assets/settings-tab-D4FbV-Xi.js"},{"revision":null,"url":"assets/settings-store-D3dJqGhB.js"},{"revision":null,"url":"assets/sequenceDiagram-2WXFIKYE-BtRvoUTC.js"},{"revision":null,"url":"assets/sankeyDiagram-WA2Y5GQK-DEGGYsk7.js"},{"revision":null,"url":"assets/rough.esm-c4PR5shF.js"},{"revision":null,"url":"assets/requirementDiagram-Z7DCOOCP-1WWjMQB_.js"},{"revision":null,"url":"assets/react-nm2Ru1Pt.js"},{"revision":null,"url":"assets/react-BPIfZRKM.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-CHptMqVT.js"},{"revision":null,"url":"assets/quadrantDiagram-337W2JSQ-BaRFqlsA.js"},{"revision":null,"url":"assets/preload-helper-CsoeaaUJ.js"},{"revision":null,"url":"assets/postgres-viewer-BMJBkwN7.js"},{"revision":null,"url":"assets/pieDiagram-SKSYHLDU-seSK40d1.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-B0h6hM1j.js"},{"revision":null,"url":"assets/path-CuyvWNAH.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-BbzPU9BK.js"},{"revision":null,"url":"assets/ordinal-CIoJK3nc.js"},{"revision":null,"url":"assets/mindmap-definition-YRQLILUH-DIv-LMXG.js"},{"revision":null,"url":"assets/mermaid-parser.core-BY8JfkE_.js"},{"revision":null,"url":"assets/math-a44lmFDa.js"},{"revision":null,"url":"assets/markdown-renderer-B7o8ysmw.js"},{"revision":null,"url":"assets/linear-BdqW7iQu.js"},{"revision":null,"url":"assets/line--xyfYP3x.js"},{"revision":null,"url":"assets/keybindings-store-BTg2T4RA.js"},{"revision":null,"url":"assets/katex-C3cZrCvP.js"},{"revision":null,"url":"assets/kanban-definition-K7BYSVSG-BMUhjxqj.js"},{"revision":null,"url":"assets/jsx-runtime-BRW_vwa9.js"},{"revision":null,"url":"assets/journeyDiagram-4ABVD52K-DFQXUZsc.js"},{"revision":null,"url":"assets/ishikawaDiagram-PHBUUO56-cW7SMLa_.js"},{"revision":null,"url":"assets/isEmpty-DXomfd7J.js"},{"revision":null,"url":"assets/isArrayLikeObject-DvHDmeBe.js"},{"revision":null,"url":"assets/input-DGlv6gt_.js"},{"revision":null,"url":"assets/init-vVpfz1D6.js"},{"revision":null,"url":"assets/infoDiagram-LFFYTUFH-DFh9c-S2.js"},{"revision":null,"url":"assets/info-3K5VOQVL-CbpovIYU.js"},{"revision":null,"url":"assets/index-n0Ww6i6b.css"},{"revision":null,"url":"assets/index-Bf4IsWu9.js"},{"revision":null,"url":"assets/graphlib-BbbiUImY.js"},{"revision":null,"url":"assets/gitGraphDiagram-K3NZZRJ6-L7sj3Bs-.js"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-D5qEPjgs.js"},{"revision":null,"url":"assets/git-graph-Fu6M3rOo.js"},{"revision":null,"url":"assets/ganttDiagram-A5KZAMGK-BVlftqyZ.js"},{"revision":null,"url":"assets/flowDiagram-PKNHOUZH-B9h_Ba-v.js"},{"revision":null,"url":"assets/erDiagram-INFDFZHY-DK4QEZYh.js"},{"revision":null,"url":"assets/dist-Ckxnw5rl.js"},{"revision":null,"url":"assets/dist-CMmNEgEP.js"},{"revision":null,"url":"assets/diff-viewer-DFwFZ_k5.js"},{"revision":null,"url":"assets/diagram-P4PSJMXO--nUaNiyB.js"},{"revision":null,"url":"assets/diagram-IFDJBPK2-NvhckwcA.js"},{"revision":null,"url":"assets/diagram-E7M64L7V-CkDC2uAj.js"},{"revision":null,"url":"assets/defaultLocale-D_VMtRaY.js"},{"revision":null,"url":"assets/database-viewer-eqHDuoj7.js"},{"revision":null,"url":"assets/dagre-KLK3FWXG-Br4t5TRV.js"},{"revision":null,"url":"assets/dagre-CWo8w9wK.js"},{"revision":null,"url":"assets/cytoscape.esm-B-QQuWwK.js"},{"revision":null,"url":"assets/cose-bilkent-S5V4N54A-C1QJ6GPW.js"},{"revision":null,"url":"assets/columns-2-Bcg3QJBg.js"},{"revision":null,"url":"assets/code-editor-DLXTYEm2.js"},{"revision":null,"url":"assets/clone-DNDy9Sms.js"},{"revision":null,"url":"assets/classDiagram-v2-RAHNMMFH-Bo5WN2ok.js"},{"revision":null,"url":"assets/classDiagram-VBA2DB6C-CqaIqYPn.js"},{"revision":null,"url":"assets/chunk-YBOYWFTD-COdZIaX4.js"},{"revision":null,"url":"assets/chunk-XZSTWKYB-5W2emiq4.js"},{"revision":null,"url":"assets/chunk-XPW4576I-CsGTseUr.js"},{"revision":null,"url":"assets/chunk-XIRO2GV7-DUmQrLsF.js"},{"revision":null,"url":"assets/chunk-WL4C6EOR-BHFnnXOt.js"},{"revision":null,"url":"assets/chunk-R5LLSJPH-LdG7RqsM.js"},{"revision":null,"url":"assets/chunk-QZHKN3VN-gaBt0Rbd.js"},{"revision":null,"url":"assets/chunk-PU5JKC2W-D3thuSok.js"},{"revision":null,"url":"assets/chunk-PQ6SQG4A-EdgQyTqa.js"},{"revision":null,"url":"assets/chunk-OZEHJAEY-LfXT4p8B.js"},{"revision":null,"url":"assets/chunk-O4XLMI2P-BdXwVXjJ.js"},{"revision":null,"url":"assets/chunk-NQ4KR5QH-BRj25yO7.js"},{"revision":null,"url":"assets/chunk-MX3YWQON-BnPzQK-O.js"},{"revision":null,"url":"assets/chunk-L3YUKLVL-DNFj84V6.js"},{"revision":null,"url":"assets/chunk-KYZI473N-CBRPKraG.js"},{"revision":null,"url":"assets/chunk-KX2RTZJC-BRj-ZEvL.js"},{"revision":null,"url":"assets/chunk-JSJVCQXG-Pb-JMOgO.js"},{"revision":null,"url":"assets/chunk-HHEYEP7N-BnRVfNc5.js"},{"revision":null,"url":"assets/chunk-GLR3WWYH-Bx2UL5jF.js"},{"revision":null,"url":"assets/chunk-GEFDOKGD-B82RP9ow.js"},{"revision":null,"url":"assets/chunk-FMBD7UC4-JCLgVcaC.js"},{"revision":null,"url":"assets/chunk-EGIJ26TM-Cgt-qg75.js"},{"revision":null,"url":"assets/chunk-CFjPhJqf.js"},{"revision":null,"url":"assets/chunk-C72U2L5F-CcEW1AMZ.js"},{"revision":null,"url":"assets/chunk-7R4GIKGN-DvbvLUIN.js"},{"revision":null,"url":"assets/chunk-7E7YKBS2-CuYKSUgJ.js"},{"revision":null,"url":"assets/chunk-55IACEB6-Dp0pTM5r.js"},{"revision":null,"url":"assets/chunk-4BX2VUAB-0YMkpW2S.js"},{"revision":null,"url":"assets/chat-tab-CyWueJTv.js"},{"revision":null,"url":"assets/channel-CKNZAqoN.js"},{"revision":null,"url":"assets/c4Diagram-IC4MRINW-DzjR91sM.js"},{"revision":null,"url":"assets/browser-tab-BnHjUFD1.js"},{"revision":null,"url":"assets/blockDiagram-WCTKOSBZ-CU2t4NHJ.js"},{"revision":null,"url":"assets/arrow-left-C_j9Ki73.js"},{"revision":null,"url":"assets/array-CLwNaqU1.js"},{"revision":null,"url":"assets/architectureDiagram-2XIMDMQ5-BVEUkQYB.js"},{"revision":null,"url":"assets/architecture-PBZL5I3N-281eTKQ3.js"},{"revision":null,"url":"assets/arc-D0bJaFyD.js"},{"revision":null,"url":"assets/api-settings-CuUkz5gb.js"},{"revision":null,"url":"assets/api-client-icCZ-07C.js"},{"revision":null,"url":"assets/_baseUniq-DCb0mkTp.js"},{"revision":null,"url":"assets/_basePickBy-COwDPZl_.js"},{"revision":"79c8870653c8f419f2e3323085e1f4be","url":"manifest.webmanifest"}]),self.addEventListener(`push`,e=>{e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{if(t.some(e=>e.visibilityState===`visible`))return;let n=e.data?.json()??{title:`PPM`,body:`Chat completed`};return self.registration.showNotification(n.title,{body:n.body,icon:`/icon-192.png`,badge:`/icon-192.png`,tag:`ppm-chat-done`,silent:!1,data:{url:self.location.origin}})}))}),self.addEventListener(`notificationclick`,e=>{e.notification.close(),e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{for(let e of t)if(e.url.includes(self.location.origin)&&`focus`in e)return e.focus();return self.clients.openWindow(e.notification.data?.url||`/`)}))});
|
package/package.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useState, useRef, useCallback, useEffect, memo, type KeyboardEvent, type DragEvent, type ClipboardEvent } from "react";
|
|
2
|
-
import { ArrowUp, Square, Paperclip, Loader2 } from "lucide-react";
|
|
2
|
+
import { ArrowUp, Square, Paperclip, Loader2, Mic, MicOff } from "lucide-react";
|
|
3
|
+
import { useVoiceInput } from "@/hooks/use-voice-input";
|
|
3
4
|
import { api, projectUrl, getAuthToken } from "@/lib/api-client";
|
|
4
5
|
import { randomId } from "@/lib/utils";
|
|
5
6
|
import { isSupportedFile, isImageFile } from "@/lib/file-support";
|
|
@@ -74,6 +75,41 @@ export const MessageInput = memo(function MessageInput({
|
|
|
74
75
|
const slashItemsRef = useRef<SlashItem[]>([]);
|
|
75
76
|
const fileItemsRef = useRef<FileNode[]>([]);
|
|
76
77
|
|
|
78
|
+
// Voice input (Web Speech API)
|
|
79
|
+
const voice = useVoiceInput();
|
|
80
|
+
// Store pre-voice text so voice appends to existing input
|
|
81
|
+
const preVoiceTextRef = useRef("");
|
|
82
|
+
const voiceResultCb = useCallback((text: string) => {
|
|
83
|
+
const prefix = preVoiceTextRef.current;
|
|
84
|
+
const newValue = prefix ? prefix + " " + text : text;
|
|
85
|
+
setValue(newValue);
|
|
86
|
+
// Auto-resize textarea
|
|
87
|
+
requestAnimationFrame(() => {
|
|
88
|
+
const ta = window.matchMedia("(min-width: 768px)").matches
|
|
89
|
+
? textareaRef.current
|
|
90
|
+
: mobileTextareaRef.current;
|
|
91
|
+
if (ta) {
|
|
92
|
+
ta.style.height = "auto";
|
|
93
|
+
ta.style.height = Math.min(ta.scrollHeight, 160) + "px";
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}, []);
|
|
97
|
+
const handleVoiceToggle = useCallback(() => {
|
|
98
|
+
if (voice.isListening) {
|
|
99
|
+
voice.stop();
|
|
100
|
+
} else {
|
|
101
|
+
preVoiceTextRef.current = value.trim();
|
|
102
|
+
voice.start(voiceResultCb);
|
|
103
|
+
}
|
|
104
|
+
}, [voice.isListening, voice.start, voice.stop, value, voiceResultCb]);
|
|
105
|
+
|
|
106
|
+
// Listen for global keyboard shortcut (Cmd+Shift+V) to toggle voice
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
const handler = () => { if (voice.supported) handleVoiceToggle(); };
|
|
109
|
+
window.addEventListener("toggle-voice-input", handler);
|
|
110
|
+
return () => window.removeEventListener("toggle-voice-input", handler);
|
|
111
|
+
}, [voice.supported, handleVoiceToggle]);
|
|
112
|
+
|
|
77
113
|
// Apply initialValue when it changes (e.g. "Ask AI" from command palette)
|
|
78
114
|
useEffect(() => {
|
|
79
115
|
if (initialValue) {
|
|
@@ -465,7 +501,7 @@ export const MessageInput = memo(function MessageInput({
|
|
|
465
501
|
onOpenChange={setModeSelectorOpen}
|
|
466
502
|
/>
|
|
467
503
|
</div>
|
|
468
|
-
{/* Mobile: single row — attach + textarea + send */}
|
|
504
|
+
{/* Mobile: single row — attach + mic + textarea + send */}
|
|
469
505
|
<div className="flex items-end gap-1 md:hidden px-2 py-2">
|
|
470
506
|
<button
|
|
471
507
|
type="button"
|
|
@@ -476,6 +512,21 @@ export const MessageInput = memo(function MessageInput({
|
|
|
476
512
|
>
|
|
477
513
|
<Paperclip className="size-4" />
|
|
478
514
|
</button>
|
|
515
|
+
{voice.supported && (
|
|
516
|
+
<button
|
|
517
|
+
type="button"
|
|
518
|
+
onClick={(e) => { e.stopPropagation(); handleVoiceToggle(); }}
|
|
519
|
+
disabled={disabled}
|
|
520
|
+
className={`flex items-center justify-center size-7 shrink-0 rounded-full transition-colors disabled:opacity-50 ${
|
|
521
|
+
voice.isListening
|
|
522
|
+
? "bg-red-600 text-white animate-pulse"
|
|
523
|
+
: "text-text-subtle hover:text-text-primary"
|
|
524
|
+
}`}
|
|
525
|
+
aria-label={voice.isListening ? "Stop voice input" : "Start voice input"}
|
|
526
|
+
>
|
|
527
|
+
{voice.isListening ? <MicOff className="size-4" /> : <Mic className="size-4" />}
|
|
528
|
+
</button>
|
|
529
|
+
)}
|
|
479
530
|
<textarea
|
|
480
531
|
ref={mobileTextareaRef}
|
|
481
532
|
value={value}
|
|
@@ -535,6 +586,21 @@ export const MessageInput = memo(function MessageInput({
|
|
|
535
586
|
>
|
|
536
587
|
<Paperclip className="size-4" />
|
|
537
588
|
</button>
|
|
589
|
+
{voice.supported && (
|
|
590
|
+
<button
|
|
591
|
+
type="button"
|
|
592
|
+
onClick={(e) => { e.stopPropagation(); handleVoiceToggle(); }}
|
|
593
|
+
disabled={disabled}
|
|
594
|
+
className={`flex items-center justify-center size-8 rounded-full transition-colors disabled:opacity-50 ${
|
|
595
|
+
voice.isListening
|
|
596
|
+
? "bg-red-600 text-white animate-pulse"
|
|
597
|
+
: "text-text-subtle hover:text-text-primary hover:bg-surface-elevated"
|
|
598
|
+
}`}
|
|
599
|
+
aria-label={voice.isListening ? "Stop voice input" : "Start voice input"}
|
|
600
|
+
>
|
|
601
|
+
{voice.isListening ? <MicOff className="size-4" /> : <Mic className="size-4" />}
|
|
602
|
+
</button>
|
|
603
|
+
)}
|
|
538
604
|
{/* Mode indicator chip */}
|
|
539
605
|
<div className="relative">
|
|
540
606
|
<ModeChip
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
FolderOpen,
|
|
12
12
|
Loader2,
|
|
13
13
|
Globe,
|
|
14
|
+
Mic,
|
|
14
15
|
} from "lucide-react";
|
|
15
16
|
import { useTabStore, type TabType } from "@/stores/tab-store";
|
|
16
17
|
import { useProjectStore } from "@/stores/project-store";
|
|
@@ -159,6 +160,7 @@ export function CommandPalette({ open, onClose, initialQuery = "" }: { open: boo
|
|
|
159
160
|
{ id: "git-graph", label: "Git Graph", icon: GitBranch, action: openNewTab("git-graph", "Git Graph"), keywords: "branch history log", group: "action", shortcut: formatShortcut(getBinding("open-git-graph")) },
|
|
160
161
|
{ id: "browser", label: "Open Browser", icon: Globe, action: openNewTab("browser", "Browser"), keywords: "web preview localhost iframe url", group: "action" },
|
|
161
162
|
{ id: "postgres", label: "PostgreSQL", icon: Database, action: openNewTab("postgres", "PostgreSQL"), keywords: "database pg sql query", group: "action" },
|
|
163
|
+
{ id: "voice-input", label: "Voice Input", icon: Mic, action: () => { window.dispatchEvent(new CustomEvent("toggle-voice-input")); onClose(); }, keywords: "speech microphone dictate voice", group: "action", shortcut: formatShortcut(getBinding("voice-input")) },
|
|
162
164
|
{ id: "git-status", label: "Git Status", icon: GitCommitHorizontal, action: () => { setSidebarActiveTab("git"); onClose(); }, keywords: "changes diff staged", group: "action", shortcut: formatShortcut(getBinding("open-git-status")) },
|
|
163
165
|
{
|
|
164
166
|
id: "settings", label: "Settings", icon: Settings,
|
|
@@ -124,6 +124,13 @@ export function useGlobalKeybindings() {
|
|
|
124
124
|
return;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
// Toggle voice input in chat
|
|
128
|
+
if (match(e, "voice-input")) {
|
|
129
|
+
e.preventDefault();
|
|
130
|
+
window.dispatchEvent(new CustomEvent("toggle-voice-input"));
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
127
134
|
// Open search (sidebar)
|
|
128
135
|
if (match(e, "open-search")) {
|
|
129
136
|
e.preventDefault();
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { useState, useRef, useCallback } from "react";
|
|
2
|
+
|
|
3
|
+
// Extend Window for webkit prefix
|
|
4
|
+
interface SpeechRecognitionEvent extends Event {
|
|
5
|
+
results: SpeechRecognitionResultList;
|
|
6
|
+
resultIndex: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type SpeechRecognitionInstance = {
|
|
10
|
+
lang: string;
|
|
11
|
+
continuous: boolean;
|
|
12
|
+
interimResults: boolean;
|
|
13
|
+
start(): void;
|
|
14
|
+
stop(): void;
|
|
15
|
+
abort(): void;
|
|
16
|
+
onresult: ((event: SpeechRecognitionEvent) => void) | null;
|
|
17
|
+
onend: (() => void) | null;
|
|
18
|
+
onerror: ((event: Event & { error: string }) => void) | null;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
type SpeechRecognitionConstructor = new () => SpeechRecognitionInstance;
|
|
22
|
+
|
|
23
|
+
function getSpeechRecognition(): SpeechRecognitionConstructor | null {
|
|
24
|
+
const w = window as unknown as {
|
|
25
|
+
SpeechRecognition?: SpeechRecognitionConstructor;
|
|
26
|
+
webkitSpeechRecognition?: SpeechRecognitionConstructor;
|
|
27
|
+
};
|
|
28
|
+
return w.SpeechRecognition ?? w.webkitSpeechRecognition ?? null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function useVoiceInput(options?: { lang?: string }) {
|
|
32
|
+
const [isListening, setIsListening] = useState(false);
|
|
33
|
+
const [interimText, setInterimText] = useState("");
|
|
34
|
+
const recognitionRef = useRef<SpeechRecognitionInstance | null>(null);
|
|
35
|
+
// Accumulate finalized text across multiple result events
|
|
36
|
+
const finalizedRef = useRef("");
|
|
37
|
+
|
|
38
|
+
const supported = typeof window !== "undefined" && getSpeechRecognition() !== null;
|
|
39
|
+
|
|
40
|
+
const start = useCallback(
|
|
41
|
+
(onResult: (text: string, isFinal: boolean) => void) => {
|
|
42
|
+
const SR = getSpeechRecognition();
|
|
43
|
+
if (!SR) return;
|
|
44
|
+
|
|
45
|
+
// Stop any existing session
|
|
46
|
+
recognitionRef.current?.abort();
|
|
47
|
+
|
|
48
|
+
const recognition = new SR();
|
|
49
|
+
recognition.lang = options?.lang ?? "vi-VN";
|
|
50
|
+
recognition.continuous = true;
|
|
51
|
+
recognition.interimResults = true;
|
|
52
|
+
|
|
53
|
+
finalizedRef.current = "";
|
|
54
|
+
|
|
55
|
+
recognition.onresult = (event: SpeechRecognitionEvent) => {
|
|
56
|
+
let interim = "";
|
|
57
|
+
let newFinalized = "";
|
|
58
|
+
|
|
59
|
+
for (let i = 0; i < event.results.length; i++) {
|
|
60
|
+
const result = event.results[i]!;
|
|
61
|
+
if (result.isFinal) {
|
|
62
|
+
newFinalized += result[0]!.transcript;
|
|
63
|
+
} else {
|
|
64
|
+
interim += result[0]!.transcript;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Update finalized accumulator
|
|
69
|
+
if (newFinalized) {
|
|
70
|
+
finalizedRef.current = newFinalized;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const fullText = (finalizedRef.current + " " + interim).trim();
|
|
74
|
+
setInterimText(interim);
|
|
75
|
+
onResult(fullText, interim.length === 0 && finalizedRef.current.length > 0);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
recognition.onend = () => {
|
|
79
|
+
setIsListening(false);
|
|
80
|
+
setInterimText("");
|
|
81
|
+
// Deliver final text if any
|
|
82
|
+
if (finalizedRef.current) {
|
|
83
|
+
onResult(finalizedRef.current.trim(), true);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
recognition.onerror = (event) => {
|
|
88
|
+
// "no-speech" and "aborted" are expected, not real errors
|
|
89
|
+
if (event.error !== "no-speech" && event.error !== "aborted") {
|
|
90
|
+
console.warn("[voice-input] error:", event.error);
|
|
91
|
+
}
|
|
92
|
+
setIsListening(false);
|
|
93
|
+
setInterimText("");
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
recognitionRef.current = recognition;
|
|
97
|
+
recognition.start();
|
|
98
|
+
setIsListening(true);
|
|
99
|
+
},
|
|
100
|
+
[options?.lang],
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
const stop = useCallback(() => {
|
|
104
|
+
recognitionRef.current?.stop();
|
|
105
|
+
recognitionRef.current = null;
|
|
106
|
+
setIsListening(false);
|
|
107
|
+
setInterimText("");
|
|
108
|
+
}, []);
|
|
109
|
+
|
|
110
|
+
return { isListening, interimText, start, stop, supported };
|
|
111
|
+
}
|
|
@@ -36,6 +36,7 @@ export const KEY_ACTIONS: KeyAction[] = [
|
|
|
36
36
|
{ id: "open-git-graph", label: "Git Graph", category: "tabs", defaultKey: "Mod+G" },
|
|
37
37
|
{ id: "open-git-status", label: "Git Status (sidebar)", category: "tabs", defaultKey: "Mod+Shift+E" },
|
|
38
38
|
{ id: "open-search", label: "Search Files (sidebar)", category: "tabs", defaultKey: "Mod+Shift+F" },
|
|
39
|
+
{ id: "voice-input", label: "Voice Input", category: "general", defaultKey: "Mod+Shift+V", note: "Toggle speech-to-text in chat" },
|
|
39
40
|
// Projects — Mod+1..9
|
|
40
41
|
...Array.from({ length: 9 }, (_, i) => ({
|
|
41
42
|
id: `switch-project-${i + 1}`,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{o as e}from"./chunk-CFjPhJqf.js";import{t}from"./react-nm2Ru1Pt.js";import{t as n}from"./jsx-runtime-BRW_vwa9.js";import{t as r}from"./arrow-left-C_j9Ki73.js";import{o as i,t as a}from"./tab-store-DSz5PQI0.js";import{$ as o,A as s,L as c}from"./index-CYhfwlmi.js";var l=e(t(),1),u=n();function d(e){let t=e.trim();if(!t)return null;if(/^\d+$/.test(t))return`http://localhost:${t}`;/^localhost(:\d+)?/.test(t)&&(t=`http://${t}`),/^[\w.-]+:\d+/.test(t)&&!t.includes(`://`)&&(t=`http://${t}`),t.includes(`://`)||(t=t.includes(`localhost`)?`http://${t}`:`https://${t}`);try{return new URL(t),t}catch{return null}}function f(e){try{let t=new URL(e);return t.hostname===`localhost`||t.hostname===`127.0.0.1`||t.hostname===`0.0.0.0`||t.hostname===`::1`}catch{return!1}}function p(e){if(!f(e))return e;try{let t=new URL(e);return`/api/preview/${t.port||`80`}${t.pathname+t.search+t.hash}`}catch{return e}}function m({metadata:e,tabId:t}){let n=e?.url||`http://localhost:3000`,[m,h]=(0,l.useState)(n),[g,_]=(0,l.useState)(n),[v,y]=(0,l.useState)(p(n)),[b,x]=(0,l.useState)(!1),[S,C]=(0,l.useState)(!1),[w,T]=(0,l.useState)(!0),[E,D]=(0,l.useState)(null),O=(0,l.useRef)(null),k=a(e=>e.updateTab),A=(0,l.useRef)([n]),j=(0,l.useRef)(0),M=(0,l.useCallback)((e,n=!0)=>{let r=d(e);if(!r){D(`Invalid URL`);return}if(D(null),_(r),h(r),y(p(r)),T(!0),n){let e=A.current,t=j.current;A.current=e.slice(0,t+1),A.current.push(r),j.current=A.current.length-1}if(x(j.current>0),C(j.current<A.current.length-1),t)try{let e=new URL(r);k(t,{title:f(r)?`localhost:${e.port||`80`}`:e.hostname})}catch{}},[t,k]),N=(0,l.useCallback)(()=>{j.current>0&&(j.current--,M(A.current[j.current],!1))},[M]),P=(0,l.useCallback)(()=>{j.current<A.current.length-1&&(j.current++,M(A.current[j.current],!1))},[M]),F=(0,l.useCallback)(()=>{if(T(!0),D(null),O.current){let e=O.current.src;O.current.src=``,requestAnimationFrame(()=>{O.current&&(O.current.src=e)})}},[]),I=(0,l.useCallback)(()=>{window.open(g,`_blank`)},[g]);return(0,l.useEffect)(()=>{let t=e?.url;t&&t!==g&&M(t)},[e?.url]),(0,u.jsxs)(`div`,{className:`flex flex-col h-full w-full bg-background`,children:[(0,u.jsxs)(`div`,{className:`flex items-center gap-1 px-2 py-1.5 border-b border-border bg-surface shrink-0`,children:[(0,u.jsx)(`button`,{onClick:N,disabled:!b,className:`p-1.5 rounded hover:bg-surface-elevated disabled:opacity-30 transition-colors`,title:`Back`,children:(0,u.jsx)(r,{className:`size-4`})}),(0,u.jsx)(`button`,{onClick:P,disabled:!S,className:`p-1.5 rounded hover:bg-surface-elevated disabled:opacity-30 transition-colors`,title:`Forward`,children:(0,u.jsx)(o,{className:`size-4`})}),(0,u.jsx)(`button`,{onClick:F,className:`p-1.5 rounded hover:bg-surface-elevated transition-colors`,title:`Reload`,children:(0,u.jsx)(s,{className:`size-4 ${w?`animate-spin`:``}`})}),(0,u.jsxs)(`div`,{className:`flex-1 flex items-center gap-2 mx-1 px-2.5 py-1.5 rounded-md bg-background border border-border focus-within:border-accent/50 transition-colors`,children:[(0,u.jsx)(c,{className:`size-3.5 text-text-subtle shrink-0`}),(0,u.jsx)(`input`,{type:`text`,value:m,onChange:e=>h(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),M(m))},placeholder:`Enter URL or port (e.g. 3000, localhost:8080)`,className:`flex-1 bg-transparent text-xs text-text-primary outline-none placeholder:text-text-subtle min-w-0`})]}),(0,u.jsx)(`button`,{onClick:I,className:`p-1.5 rounded hover:bg-surface-elevated transition-colors`,title:`Open in browser`,children:(0,u.jsx)(i,{className:`size-4`})})]}),(0,u.jsxs)(`div`,{className:`flex-1 relative min-h-0`,children:[E?(0,u.jsx)(`div`,{className:`flex items-center justify-center h-full text-text-secondary text-sm`,children:(0,u.jsx)(`p`,{children:E})}):(0,u.jsx)(`iframe`,{ref:O,src:v,className:`w-full h-full border-0`,sandbox:`allow-scripts allow-forms allow-same-origin allow-popups allow-modals`,onLoad:()=>T(!1),onError:()=>{T(!1),D(`Failed to load ${g}`)}}),w&&!E&&(0,u.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center bg-background/50`,children:(0,u.jsxs)(`div`,{className:`flex items-center gap-2 text-sm text-text-secondary`,children:[(0,u.jsx)(s,{className:`size-4 animate-spin`}),(0,u.jsx)(`span`,{children:`Loading...`})]})})]})]})}export{m as BrowserTab};
|