oh-my-pr 3.1.0 → 3.2.0
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/dist/index.cjs +2 -2
- package/dist/public/assets/index-Chjw2niu.css +1 -0
- package/dist/public/assets/index-DlOY0gky.js +48 -0
- package/dist/public/index.html +4 -4
- package/package.json +2 -2
- package/dist/public/assets/index-Biwieeyk.js +0 -48
- package/dist/public/assets/index-C5njJ0nC.css +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1026,8 +1026,8 @@ ${ln}`:ln}function lc(t,e){return[t,...e].join(" ")}function da(t){return t.stde
|
|
|
1026
1026
|
`);return["Respond with ONLY valid JSON and nothing else.","Schema:",'{"shouldRelease":boolean,"reason":string,"bump":"patch"|"minor"|"major"|null,"title":string|null,"notes":string|null}',"","You are deciding whether a merged set of pull requests should be published as a GitHub release.","Be conservative. Release only when the merged changes are meaningful enough for users or operators to care about.","",`Repository: ${t.repo}`,`Release branch: ${t.baseBranch}`,`Latest release tag: ${t.latestTag??"none"}`,"",`Trigger PR: #${t.triggerPr.number} "${t.triggerPr.title}"`,`Trigger merged at: ${t.triggerPr.mergedAt}`,`Trigger merge SHA: ${t.triggerPr.mergeSha}`,"","Merged PRs included in this candidate release:",e||"(none)","","Decision rules:","- shouldRelease=true only when the merged changes are worth announcing as a GitHub release.","- bump must be null when shouldRelease=false.","- bump must be one of patch, minor, or major when shouldRelease=true.","- Use patch for fixes or small improvements, minor for additive user-facing features, and major for breaking changes.","- title should be short and release-note ready when shouldRelease=true, else null.","- notes should be GitHub-release Markdown focused on user-visible/operator-visible impact when shouldRelease=true, else null.","- notes must have exactly TWO sections in this order:"," 1. '## Why This Matters' \u2014 a user-friendly, value-driven summary at the top that explains how the release makes users' lives better."," 2. '## Detailed Changes' \u2014 a line-by-line changelog of the included changes in plain English, more detailed than a headline but not deeply technical.","- notes should mention the key merged PRs in plain language, not internal process commentary.","- Prefer user outcomes, workflow improvements, and visible behavior over implementation details."].join(`
|
|
1027
1027
|
`)}function F2(t){let e=aM(t.trim());if(!e||typeof e!="object")throw new Error(`Could not parse release evaluation JSON: ${t.slice(0,500)}`);let r=e;if(typeof r.shouldRelease!="boolean")throw new Error("Release evaluation missing boolean 'shouldRelease'");if(typeof r.reason!="string"||r.reason.trim().length===0)throw new Error("Release evaluation missing string 'reason'");if(!r.shouldRelease)return{shouldRelease:!1,reason:r.reason.trim(),bump:null,title:null,notes:null};if(r.bump!=="patch"&&r.bump!=="minor"&&r.bump!=="major")throw new Error("Release evaluation returned invalid 'bump'");if(typeof r.title!="string"||r.title.trim().length===0)throw new Error("Release evaluation missing non-empty 'title'");if(typeof r.notes!="string"||r.notes.trim().length===0)throw new Error("Release evaluation missing non-empty 'notes'");return{shouldRelease:!0,reason:r.reason.trim(),bump:r.bump,title:r.title.trim(),notes:r.notes.trim()}}function aM(t){try{return JSON.parse(t)}catch{}let e=t.indexOf("{"),r=t.lastIndexOf("}");if(e===-1||r===-1||r<=e)return null;try{return JSON.parse(t.slice(e,r+1))}catch{return null}}var fc=class{storage;github;evaluateRelease;scheduleBackgroundJob;inProgress=new Set;repoLocks=new Map;constructor(e,r){this.storage=e,this.github=r.github,this.evaluateRelease=r.evaluateRelease??U2,this.scheduleBackgroundJob=r.scheduleBackgroundJob}getActiveRunCount(){return this.inProgress.size}async waitForIdle(e=12e4){let r=Date.now();for(;this.inProgress.size>0;){if(Date.now()-r>=e)return!1;await dM(50)}return!0}async enqueueMergedPullReleaseEvaluation(e){let r=await this.storage.getReleaseRunByTrigger(e.repo,e.triggerPrNumber,e.triggerMergeSha);if(r)return G2(r.status)||this.scheduleProcessing(r),r;let n=await this.storage.createReleaseRun({repo:e.repo,baseBranch:e.baseBranch,triggerPrNumber:e.triggerPrNumber,triggerPrTitle:e.triggerPrTitle,triggerPrUrl:e.triggerPrUrl,triggerMergeSha:e.triggerMergeSha,triggerMergedAt:e.triggerMergedAt,status:"detected",decisionReason:null,recommendedBump:null,proposedVersion:null,releaseTitle:null,releaseNotes:null,includedPrs:[],targetSha:e.triggerMergeSha,githubReleaseId:null,githubReleaseUrl:null,error:null,completedAt:null});return this.scheduleProcessing(n),n}async enqueueManualRepoRelease(e){let r=at(e);if(!r)throw new Error(`Invalid repository slug: ${e}`);let n=`${r.owner}/${r.repo}`,i=await this.storage.getConfig(),a=await this.github.buildOctokit(i),s=await this.github.getDefaultBranch(a,r),u=[...await this.github.listUnreleasedMergedPulls(a,r,{baseBranch:s})].sort((p,d)=>Date.parse(p.mergedAt)-Date.parse(d.mergedAt)).at(-1);if(!u)return null;let c=await this.storage.getReleaseRunByTrigger(n,u.number,u.mergeSha);if(c){let p=c.status==="skipped"||c.status==="error",f=await this.storage.updateReleaseRun(c.id,{source:"manual",...p?{status:"detected",decisionReason:null,recommendedBump:null,proposedVersion:null,releaseTitle:null,releaseNotes:null,includedPrs:[],targetSha:u.mergeSha,githubReleaseId:null,githubReleaseUrl:null,error:null,completedAt:null}:{}})??c;return G2(f.status)||this.scheduleProcessing(f),f}let l=await this.storage.createReleaseRun({repo:n,baseBranch:s,triggerPrNumber:u.number,triggerPrTitle:u.title,triggerPrUrl:u.url,triggerMergeSha:u.mergeSha,triggerMergedAt:u.mergedAt,source:"manual",status:"detected",decisionReason:null,recommendedBump:null,proposedVersion:null,releaseTitle:null,releaseNotes:null,includedPrs:[],targetSha:u.mergeSha,githubReleaseId:null,githubReleaseUrl:null,error:null,completedAt:null});return this.scheduleProcessing(l),l}async retryReleaseRun(e){if(!await this.storage.getReleaseRun(e))return;let n=await this.storage.updateReleaseRun(e,{status:"detected",error:null,completedAt:null});if(n)return this.scheduleProcessing(n),n}async processReleaseRun(e){let r=await this.storage.getReleaseRun(e);if(r)return this.withRepoLock(r.repo,async()=>{if(this.inProgress.has(e))return this.storage.getReleaseRun(e);this.inProgress.add(e);try{let n=await this.storage.getReleaseRun(e);if(!n)return;if(n.status==="published"||n.status==="skipped")return n;let i=at(n.repo);if(!i)return this.failRun(e,`Invalid repository slug: ${n.repo}`);let a=await this.storage.getConfig(),s=n.source==="manual";if(!s&&!a.autoCreateReleases)return await this.storage.updateReleaseRun(e,{status:"skipped",decisionReason:"Automatic release creation is disabled in settings",completedAt:new Date().toISOString()})??void 0;let o=await this.storage.getRepoSettings(n.repo);if(!s&&o&&!o.autoCreateReleases)return await this.storage.updateReleaseRun(e,{status:"skipped",decisionReason:`Automatic release creation is disabled for ${n.repo}`,completedAt:new Date().toISOString()})??void 0;await this.storage.updateReleaseRun(e,{status:"evaluating",error:null,completedAt:null});let u=await this.github.buildOctokit(a),c=await this.github.findLatestSemverReleaseTag(u,i),l=sM(n),p=await this.loadIncludedPulls(u,i,n,l),d=p.map(oM),f=await this.evaluateRelease({preferredAgent:a.codingAgent,repo:n.repo,baseBranch:n.baseBranch,latestTag:c,triggerPr:l,includedPulls:p}),g=f.shouldRelease||!s?f:cM(f,p);if(!g.shouldRelease)return await this.storage.updateReleaseRun(e,{status:"skipped",decisionReason:g.reason,recommendedBump:null,proposedVersion:null,releaseTitle:null,releaseNotes:null,includedPrs:d,targetSha:n.triggerMergeSha,completedAt:new Date().toISOString()})??void 0;if(!g.bump)throw new Error("Release evaluation approved publishing but did not provide a semver bump");let b=this.github.bumpReleaseTag(c,g.bump),y=uM(g,b),C=g.notes??`Release ${b}`;await this.storage.updateReleaseRun(e,{status:"proposed",decisionReason:g.reason,recommendedBump:g.bump,proposedVersion:b,releaseTitle:y,releaseNotes:C,includedPrs:d,targetSha:n.triggerMergeSha});let L=this.github.findReleaseByTag?await this.github.findReleaseByTag(u,i,b):null;if(L)return await this.storage.updateReleaseRun(e,{status:"published",githubReleaseId:L.id,githubReleaseUrl:L.url,completedAt:new Date().toISOString()})??void 0;await this.storage.updateReleaseRun(e,{status:"publishing"});let P=await this.github.createGitHubRelease(u,i,{tagName:b,targetCommitish:n.triggerMergeSha,name:y,body:C});return await this.storage.updateReleaseRun(e,{status:"published",githubReleaseId:P.id,githubReleaseUrl:P.url,completedAt:new Date().toISOString()})??void 0}catch(n){return this.failRun(e,pM(n))}finally{this.inProgress.delete(e)}})}async loadIncludedPulls(e,r,n,i){if(!this.github.listMergedPullsForReleaseCandidate)return[i];let a=await this.github.listMergedPullsForReleaseCandidate(e,r,{baseBranch:n.baseBranch,untilMergedAt:n.triggerMergedAt,triggerPr:i}),s=new Map;for(let o of a)s.set(o.mergeSha||`${o.repo}#${o.number}`,o);return s.has(i.mergeSha)||s.set(i.mergeSha,i),Array.from(s.values()).sort((o,u)=>o.mergedAt.localeCompare(u.mergedAt))}async failRun(e,r){return this.storage.updateReleaseRun(e,{status:"error",error:r,completedAt:new Date().toISOString()})}async withRepoLock(e,r){let n=this.repoLocks.get(e)??Promise.resolve(),i,a=new Promise(o=>{i=()=>o()}),s=n.then(()=>a);this.repoLocks.set(e,s),await n;try{return await r()}finally{i?.(),this.repoLocks.get(e)===s&&this.repoLocks.delete(e)}}scheduleProcessing(e){let r=e.id;if(this.scheduleBackgroundJob){this.scheduleBackgroundJob("process_release_run",r,Qt("process_release_run",r),{releaseRunId:r,...Mr({label:`Processing release for ${e.repo}`,detail:`PR #${e.triggerPrNumber} - ${e.triggerPrTitle}`,targetUrl:e.triggerPrUrl})}).catch(n=>{console.error(`Failed to schedule release run ${r}:`,n)});return}this.processReleaseRun(r).catch(()=>{})}};function sM(t){return{number:t.triggerPrNumber,title:t.triggerPrTitle,url:t.triggerPrUrl,author:"unknown",repo:t.repo,mergedAt:t.triggerMergedAt,mergeSha:t.triggerMergeSha}}function oM(t){return{number:t.number,title:t.title,url:t.url,author:t.author,mergedAt:t.mergedAt,mergeSha:t.mergeSha}}function uM(t,e){let r=t.title?.trim();return r?r.startsWith(e)?r:`${e} - ${r}`:e}function cM(t,e){return{shouldRelease:!0,reason:`Manual release requested. Evaluator recommendation: ${t.reason}`,bump:"patch",title:"Manual release",notes:lM(e)}}function lM(t){return`## Changes
|
|
1028
1028
|
${t.length>0?t.map(r=>`- #${r.number} ${r.title} (@${r.author})`).join(`
|
|
1029
|
-
`):"- Manual release requested."}`}function pM(t){return(t instanceof Error?t.message:String(t)).trim().slice(0,2e3)}function G2(t){return t==="skipped"||t==="published"}function dM(t){return new Promise(e=>setTimeout(e,t))}var fM=["fix_submitted","escalated"],mM={monitoring:["failed","escalated"],failed:["fixing","escalated"],fixing:["fix_submitted","escalated"],fix_submitted:[],escalated:[]},mc=class{constructor(e,r=()=>new Date){this.storage=e;this.clock=r}async createSession(e){return this.storage.createDeploymentHealingSession({...e,deploymentId:null,deploymentLog:null,fixBranch:null,fixPrNumber:null,fixPrUrl:null,state:"monitoring",error:null,completedAt:null})}async ensureSession(e){let r=await this.storage.getDeploymentHealingSessionByRepoAndMergeSha(e.repo,e.mergeSha);return r||this.createSession(e)}async transitionTo(e,r,n={}){let i=await this.storage.getDeploymentHealingSession(e);if(!i)throw new Error(`Deployment healing session not found: ${e}`);if(i.state===r){let o=await this.storage.updateDeploymentHealingSession(e,n);if(!o)throw new Error(`Deployment healing session not found: ${e}`);return o}if(!mM[i.state].includes(r))throw new Error(`Illegal deployment healing transition: ${i.state} -> ${r}`);let a={...n,state:r};fM.includes(r)&&(a.completedAt=n.completedAt??this.clock().toISOString());let s=await this.storage.updateDeploymentHealingSession(e,a);if(!s)throw new Error(`Deployment healing session not found: ${e}`);return s}};var Le=class extends Error{statusCode;constructor(e,r){super(r),this.name="AppRuntimeError",this.statusCode=e}};function q2(t){return t instanceof Error?t.message:String(t)}function Ve(t,e){if(t===void 0)throw new Le(404,e);return t}function gM(t){switch(t.kind){case"sync_watched_repos":return"Sync watched repositories";case"babysit_pr":return"Babysitting PR";case"process_release_run":return"Processing release";case"answer_pr_question":return"Answering PR question";case"generate_social_changelog":return"Generating social changelog";case"heal_deployment":return"Healing deployment"}}function j2(t,e){let r=t.payload[e];return typeof r=="string"&&r.trim()?r:null}function H2(t){return t.flatMap(e=>{let r=e.mergeCommitSha?.trim();return r?[{number:e.number,title:e.title,url:e.url,author:e.author,repo:e.repo,mergedAt:e.mergedAt,mergeSha:r}]:[]})}function $2(t={}){let e=t.storage??D1(),r=new B2.EventEmitter,n=t.backgroundJobQueue??new oc(e),i,a=async(...x)=>{let _=await n.enqueue(...x);return i.wake(),_},s=t.deploymentHealingManager??new mc(e),o=t.releaseManager??new fc(e,{github:{buildOctokit:Kt,getDefaultBranch:am,findLatestSemverReleaseTag:kT,bumpReleaseTag:ST,listUnreleasedMergedPulls:async(x,_,T)=>{let w=await sm(x,_,{baseRef:T.baseBranch});return H2(w)},listMergedPullsForReleaseCandidate:async(x,_,T)=>{let w=await sm(x,_,{baseRef:T.baseBranch}),M=Date.parse(T.untilMergedAt);return H2(w.filter(j=>!Number.isFinite(M)||Date.parse(j.mergedAt)<=M))},findReleaseByTag:async(x,_,T)=>{let M=(await Zu(x,_)).find(j=>!j.draft&&j.tagName===T);return M?{id:M.id,url:M.htmlUrl,tagName:M.tagName,name:M.name}:null},createGitHubRelease:async(x,_,T)=>{let w=await RT(x,_,{tagName:T.tagName,targetCommitish:T.targetCommitish,name:T.name,body:T.body});return{id:w.id,url:w.htmlUrl,tagName:w.tagName,name:w.name}}},scheduleBackgroundJob:a}),u=t.babysitter??new pc(e,void 0,void 0,o,a,s);i=t.backgroundJobDispatcher??new dc({storage:e,queue:n,handlers:N2({storage:e,babysitter:u,releaseManager:o,deploymentHealingManager:s})});let c=null,l=0,p=t.watcherScheduler??L2(async()=>{await a("sync_watched_repos","runtime:1",Qt("sync_watched_repos","runtime:1"))},x=>{console.error("Repository babysitter watcher failed",x)}),d=p.run,f=t.startBackgroundServices??!0,g=t.startWatcher??f,b=!1,y=()=>{r.emit("change")},C=async()=>({...await e.getRuntimeState(),activeRuns:i.getActiveRunCount()}),L=async x=>{let _=new Set,T=new Set,w=new Set,M=new Set;for(let B of x)if(!mm(B.payload))if(B.kind==="babysit_pr")_.add(B.targetId);else if(B.kind==="answer_pr_question"){let X=j2(B,"prId");X&&_.add(X)}else B.kind==="process_release_run"?T.add(B.targetId):B.kind==="generate_social_changelog"?w.add(B.targetId):B.kind==="heal_deployment"&&M.add(B.targetId);let[j,E,S,A,z]=await Promise.all([_.size>0?e.getPRs():Promise.resolve([]),_.size>0?e.getArchivedPRs():Promise.resolve([]),T.size>0?e.listReleaseRuns():Promise.resolve([]),w.size>0?e.getSocialChangelogs():Promise.resolve([]),M.size>0?e.listDeploymentHealingSessions():Promise.resolve([])]),me=new Map;for(let B of z)me.set(B.id,B),me.set(`${B.repo}:${B.mergeSha}`,B);return{prsById:new Map([...j,...E].map(B=>[B.id,B])),releaseRunsById:new Map(S.map(B=>[B.id,B])),socialChangelogsById:new Map(A.map(B=>[B.id,B])),deploymentHealingSessionsByTarget:me}},P=(x,_)=>{let T=mm(x.payload);if(T)return T;if(x.kind==="sync_watched_repos")return{label:"Sync watched repositories",detail:null,targetUrl:null};if(x.kind==="babysit_pr"){let w=_.prsById.get(x.targetId);if(w)return{label:`Babysitting PR #${w.number}`,detail:`${w.repo} - ${w.title}`,targetUrl:w.url}}if(x.kind==="answer_pr_question"){let w=j2(x,"prId"),M=w?_.prsById.get(w):void 0;if(M)return{label:`Answering question for PR #${M.number}`,detail:`${M.repo} - ${M.title}`,targetUrl:M.url}}if(x.kind==="process_release_run"){let w=_.releaseRunsById.get(x.targetId);if(w)return{label:`Processing release for ${w.repo}`,detail:`PR #${w.triggerPrNumber} - ${w.triggerPrTitle}`,targetUrl:w.triggerPrUrl}}if(x.kind==="generate_social_changelog"){let w=_.socialChangelogsById.get(x.targetId);if(w)return{label:"Generating social changelog",detail:`${w.date} - ${w.triggerCount} merged PRs`,targetUrl:null}}if(x.kind==="heal_deployment"){let w=_.deploymentHealingSessionsByTarget.get(x.targetId);if(w)return{label:`Healing ${w.platform} deployment`,detail:`${w.repo} PR #${w.triggerPrNumber} - ${w.triggerPrTitle}`,targetUrl:w.triggerPrUrl}}return{label:gM(x),detail:x.targetId,targetUrl:null}},N=(x,_)=>{let T=P(x,_);return{id:x.id,kind:x.kind,status:x.status==="leased"?"in_progress":"queued",label:T.label,detail:T.detail,targetId:x.targetId,targetUrl:T.targetUrl,queuedAt:x.createdAt,availableAt:x.availableAt,startedAt:x.heartbeatAt,updatedAt:x.updatedAt,attemptCount:x.attemptCount}},F=async x=>{let[_,T,w]=await Promise.all([i.waitForIdle(x),u.waitForIdle(x),o.waitForIdle(x)]);return _&&T&&w},h=async()=>{let x=await e.getConfig(),_=Math.max(1e4,x.pollIntervalMs||12e4);c&&l===_||(c&&(clearInterval(c),c=null),l=_,c=setInterval(()=>{d()},_))},O=async(x,_)=>{await a("babysit_pr",x.id,Qt("babysit_pr",x.id),{preferredAgent:_,...Mr({label:`Babysitting PR #${x.number}`,detail:`${x.repo} - ${x.title}`,targetUrl:x.url})})},D={async start(){b||(b=!0,f&&await i.start(),g&&(await h(),u.resumeInterruptedRuns(),d()))},stop(){b=!1,i.stop(),c&&(clearInterval(c),c=null)},subscribe(x){return r.on("change",x),()=>{r.off("change",x)}},getRuntimeSnapshot:C,async listActivities(){let[x,_]=await Promise.all([e.listBackgroundJobs({status:"leased"}),e.listBackgroundJobs({status:"queued"})]),T=await L([...x,..._]),w=x.map(j=>N(j,T)),M=_.map(j=>N(j,T));return{inProgress:w,queued:M,generatedAt:new Date().toISOString()}},async setDrainMode(x){let _=await e.updateRuntimeState({drainMode:x.enabled,drainRequestedAt:x.enabled?new Date().toISOString():null,drainReason:x.enabled?x.reason??null:null});if(x.enabled&&x.waitForIdle){let w=await F(x.timeoutMs??12e4),M=await C();return y(),{..._,...M,drained:w}}let T=await C();return y(),{..._,...T}},async listRepos(){let x=await e.getConfig(),_=await e.getPRs();return Array.from(new Set([...x.watchedRepos,..._.map(T=>T.repo)])).sort((T,w)=>T.localeCompare(w))},async listRepoSettings(){let[x,_]=await Promise.all([e.listRepoSettings(),e.getPRs()]),T=new Map(x.map(w=>[w.repo,w]));for(let w of _)T.has(w.repo)||T.set(w.repo,{repo:w.repo,autoCreateReleases:!0,ownPrsOnly:!0});return Array.from(T.values()).sort((w,M)=>w.repo.localeCompare(M.repo))},async addRepo(x){let _=at(x);if(!_)throw new Le(400,"Invalid repository. Use owner/repo or https://github.com/owner/repo");let T=Fr(_),w=await e.getConfig();return w.watchedRepos.includes(T)||await e.updateConfig({watchedRepos:[...w.watchedRepos,T].sort((M,j)=>M.localeCompare(j))}),d(),y(),{repo:T}},async updateRepoSettings(x,_){let T=at(x);if(!T)throw new Le(400,"Invalid repository. Use owner/repo or https://github.com/owner/repo");let w=Fr(T),M=await e.updateRepoSettings(w,_);return y(),M},async syncRepos(){if((await e.getRuntimeState()).drainMode)throw new Le(409,"Drain mode is enabled. Sync-triggered runs are blocked until drain mode is disabled.");return await p.runAndReportErrors(),y(),{ok:!0}},async createManualRelease(x){let _=at(x);if(!_)throw new Le(400,"Invalid repository. Use owner/repo or https://github.com/owner/repo");let T=Fr(_),w=await o.enqueueManualRepoRelease(T);if(!w)throw new Le(409,`No unreleased merged pull requests found for ${T}`);return y(),w},async listPRs(x="active"){return x==="archived"?e.getArchivedPRs():e.getPRs()},async getPR(x){return await e.getPR(x)??null},async addPR(x){let _;try{({url:_}=_1.parse({url:x}))}catch(z){throw z instanceof m.ZodError?new Le(400,z.errors[0]?.message??"Invalid PR URL"):z}let T=Xu(_);if(!T)throw new Le(400,"Invalid GitHub PR URL. Expected: https://github.com/owner/repo/pull/123");let w=`${T.owner}/${T.repo}`,M=await e.getPRByRepoAndNumber(w,T.number);if(M)return M;let j=await e.getConfig(),E=await Kt(j),S=await Qu(E,T),A=await e.addPR({number:T.number,title:S.title,repo:w,branch:S.branch,author:S.author,url:S.url,status:"watching",feedbackItems:[],accepted:0,rejected:0,flagged:0,testsPassed:null,lintPassed:null,lastChecked:null});return await e.addLog(A.id,"info",`Registered PR #${T.number} from ${w}`),await e.addLog(A.id,"info",`Repository ${w} added to auto-babysit watch list`),j.watchedRepos.includes(w)||await e.updateConfig({watchedRepos:[...j.watchedRepos,w].sort((z,me)=>z.localeCompare(me))}),await O(A,j.codingAgent),y(),A},async removePR(x){if(!await e.removePR(x))throw new Le(404,"PR not found");return y(),{ok:!0}},async setPRWatchEnabled(x,_){let T=Ve(await e.getPR(x),"PR not found"),w=await e.updatePR(T.id,{watchEnabled:_}),M=Ve(w,"PR not found");return T.watchEnabled!==_&&(await e.addLog(T.id,"info",_?"Background watch resumed":"Background watch paused"),_&&d()),y(),M},async setWatchEnabled(x,_){return D.setPRWatchEnabled(x,_)},async fetchPRFeedback(x){let _=Ve(await e.getPR(x),"PR not found");await e.updatePR(_.id,{status:"processing",lastChecked:new Date().toISOString()}),await e.addLog(_.id,"info","Syncing GitHub comments/reviews...");try{let T=await u.syncFeedbackForPR(_.id);return y(),T}catch(T){let w=q2(T);throw await e.updatePR(_.id,{status:"error",lastChecked:new Date().toISOString()}),await e.addLog(_.id,"error",`Fetch failed: ${w}`),T}},async triagePR(x){let _=Ve(await e.getPR(x),"PR not found");await e.updatePR(_.id,{status:"processing"}),await e.addLog(_.id,"info","Triaging feedback...");let T=_.feedbackItems.map(S=>{if(S.decision)return S;let A=S.body.toLowerCase();return A.includes("lgtm")||A.includes("looks good")?ni(S,!1,"Acknowledgement, no code change requested"):A.includes("please")||A.includes("should")||A.includes("fix")||A.includes("error")||A.includes("fail")?{...ni(S,!0,"Likely actionable request"),action:S.body}:c2(S,"Unclear actionability, flagged for manual review")}),w=T.filter(S=>S.decision==="accept").length,M=T.filter(S=>S.decision==="reject").length,j=T.filter(S=>S.decision==="flag").length,E=await e.updatePR(_.id,{feedbackItems:T,accepted:w,rejected:M,flagged:j,status:"watching"});return await e.addLog(_.id,"info",`Triage complete: ${w} accept, ${M} reject, ${j} flag`),y(),Ve(E,"PR not found")},async applyPR(x){let _=Ve(await e.getPR(x),"PR not found");if((await e.getRuntimeState()).drainMode)throw new Le(409,"Drain mode is enabled. Manual runs are blocked until drain mode is disabled.");let w=await e.getConfig();await e.updatePR(_.id,{status:"processing"}),await e.addLog(_.id,"info",`Launching autonomous babysitter run using ${w.codingAgent}`),await O(_,w.codingAgent);let M=await e.getPR(_.id);return y(),Ve(M,"PR disappeared after apply run")},async babysitPR(x){let _=Ve(await e.getPR(x),"PR not found");if((await e.getRuntimeState()).drainMode)throw new Le(409,"Drain mode is enabled. Manual runs are blocked until drain mode is disabled.");let w=await e.getConfig();await e.addLog(_.id,"info",`Manual babysitter trigger using ${w.codingAgent}`),await O(_,w.codingAgent);let M=await e.getPR(_.id);return y(),Ve(M,"PR disappeared after babysit run")},async queueBabysit(x){return D.babysitPR(x)},async setFeedbackDecision(x,_,T){let w=Ve(await e.getPR(x),"PR not found"),M=await k2({storage:e,pr:w,feedbackId:_,decision:T});return y(),Ve(M,"PR not found")},async retryFeedback(x,_){let T=await u.retryFeedbackItem(x,_);if(T.kind==="pr_not_found")throw new Le(404,"PR not found");if(T.kind==="feedback_not_found")throw new Le(404,"Feedback item not found");if(T.kind==="feedback_not_retryable")throw new Le(400,"Only failed or warning items can be retried");await e.addLog(x,"info",`Feedback item ${_} queued for retry`);let w=await e.getConfig();return await O(T.updated,w.codingAgent),y(),T.updated},async listPRQuestions(x){return Ve(await e.getPR(x),"PR not found"),e.getQuestions(x)},async askQuestion(x,_){let T=Ve(await e.getPR(x),"PR not found"),w;try{w=S1.parse({question:_})}catch(j){throw j instanceof m.ZodError?new Le(400,j.errors[0]?.message??"Invalid question"):j}let M=await e.addQuestion(x,w.question);try{await a("answer_pr_question",M.id,Qt("answer_pr_question",M.id),{prId:x,...Mr({label:`Answering question for PR #${T.number}`,detail:`${T.repo} - ${T.title}`,targetUrl:T.url})})}catch(j){let E=q2(j);throw await e.updateQuestion(M.id,{status:"error",error:E.trim().slice(0,2e3)}),j}return y(),M},async listLogs(x){return e.getLogs(x)},async getOnboardingStatus(){let x=await e.getConfig();return _T(x,x.watchedRepos)},async installReviewWorkflow(x,_){let T=await e.getConfig();return ET(T,x,_)},async listHealingSessions(){return e.listHealingSessions()},async getHealingSession(x){return Ve(await e.getHealingSession(x),"Healing session not found")},async listDeploymentHealingSessions(x){return e.listDeploymentHealingSessions(x?{repo:x}:void 0)},async getDeploymentHealingSession(x){return Ve(await e.getDeploymentHealingSession(x),"Deployment healing session not found")},async getConfig(){return e.getConfig()},async updateConfig(x){let _=await e.updateConfig(x);return g&&b&&await h(),y(),_},async listSocialChangelogs(){return e.getSocialChangelogs()},async getSocialChangelog(x){return Ve(await e.getSocialChangelog(x),"Changelog not found")},async listReleaseRuns(){return e.listReleaseRuns()},async getReleaseRun(x){return Ve(await e.getReleaseRun(x),"Release run not found")},async retryReleaseRun(x){let _=await o.retryReleaseRun(x);if(!_)throw new Le(404,"Release run not found");return y(),_}};return D}function z2(t){return t instanceof Le}var W2="https://github.com/yungookim/oh-my-pr/releases",hM="https://api.github.com/repos/yungookim/oh-my-pr/releases/latest",bM=3600*1e3;function yM(t,e){let r=ei(t),n=ei(e);return!r||!n?0:r.major!==n.major?r.major-n.major:r.minor!==n.minor?r.minor-n.minor:r.patch-n.patch}function vM(t){return{currentVersion:t,latestVersion:null,latestReleaseUrl:W2,updateAvailable:!1}}async function xM(t,e=fetch){let r=t.trim(),n=vM(r);if(!ei(r))return n;try{let i=await e(hM,{headers:{accept:"application/vnd.github+json","user-agent":`oh-my-pr/${r}`}});if(!i.ok)return n;let a=await i.json(),s=a.tag_name?.trim()??null;return a.draft||a.prerelease||!s||!ei(s)?n:{currentVersion:r,latestVersion:s,latestReleaseUrl:a.html_url?.trim()||W2,updateAvailable:yM(s,r)>0}}catch{return n}}function V2(t=fetch,e={}){let r=e.cacheTtlMs??bM,n=e.now??Date.now,i=new Map,a=new Map;return async s=>{let o=s.trim(),u=i.get(o);if(u&&u.expiresAt>n())return u.status;let c=a.get(o);if(c)return c;let l=xM(o,t).then(p=>(i.set(o,{status:p,expiresAt:n()+r}),a.delete(o),p),p=>{throw a.delete(o),p});return a.set(o,l),l}}var X2="***";function wM(t){return t instanceof Error?t.message:String(t)}function he(t,e){if(e instanceof m.ZodError){t.status(400).json({error:e.errors[0]?.message??"Invalid request"});return}if(e instanceof Oe){t.status(e.statusCode).json({error:e.message});return}if(z2(e)){t.status(e.statusCode).json({error:e.message});return}t.status(500).json({error:wM(e)})}function K2(t){return t?`${X2}${t.slice(-4)}`:""}function _M(t,e){let r=t.map(n=>({token:n,masked:K2(n),used:!1}));return e.map(n=>{let i=n.trim();if(!i)return"";if(i.startsWith(X2)){let a=r.find(s=>!s.used&&s.masked===i);if(a)return a.used=!0,a.token}return i}).filter(Boolean)}function EM(t,e){let r=e.githubTokens??(e.githubToken!==void 0?[e.githubToken]:void 0);if(r===void 0)return e;let{githubToken:n,...i}=e;return{...i,githubTokens:_M(t.githubTokens,r)}}function J2(t){let e=t.githubTokens.map(K2);return{...t,githubTokens:e,githubToken:e[0]??""}}async function Q2(t,e,r={}){let n=r.runtime??$2(r),i=r.appUpdateChecker??V2();return await n.start(),t.on("close",()=>{n.stop()}),e.get("/api/runtime",async(a,s)=>{s.json(await n.getRuntimeSnapshot())}),e.get("/api/activities",async(a,s)=>{s.json(await n.listActivities())}),e.post("/api/runtime/drain",async(a,s)=>{try{let o=m.object({enabled:m.boolean(),reason:m.string().optional(),waitForIdle:m.boolean().optional(),timeoutMs:m.number().int().positive().max(6e5).optional()}).parse(a.body),u=await n.setDrainMode(o);if(o.enabled&&o.waitForIdle&&u.drained===!1)return s.status(202).json(u);s.json(u)}catch(o){he(s,o)}}),e.get("/api/repos",async(a,s)=>{s.json(await n.listRepos())}),e.get("/api/repos/settings",async(a,s)=>{s.json(await n.listRepoSettings())}),e.post("/api/repos",async(a,s)=>{try{let{repo:o}=m.object({repo:m.string().min(1)}).parse(a.body);s.status(201).json(await n.addRepo(o))}catch(o){he(s,o)}}),e.patch("/api/repos/settings",async(a,s)=>{try{let o=m.object({repo:m.string().min(1),autoCreateReleases:m.boolean().optional(),ownPrsOnly:m.boolean().optional()}).refine(l=>l.autoCreateReleases!==void 0||l.ownPrsOnly!==void 0,"At least one repository setting must be provided").parse(a.body),{repo:u,...c}=o;s.json(await n.updateRepoSettings(u,c))}catch(o){he(s,o)}}),e.post("/api/repos/sync",async(a,s)=>{try{s.json(await n.syncRepos())}catch(o){he(s,o)}}),e.post("/api/repos/release",async(a,s)=>{try{let{repo:o}=m.object({repo:m.string().min(1)}).parse(a.body);s.status(201).json(await n.createManualRelease(o))}catch(o){he(s,o)}}),e.get("/api/prs",async(a,s)=>{s.json(await n.listPRs("active"))}),e.get("/api/prs/archived",async(a,s)=>{s.json(await n.listPRs("archived"))}),e.get("/api/prs/:id",async(a,s)=>{let o=await n.getPR(a.params.id);if(!o)return s.status(404).json({error:"PR not found"});s.json(o)}),e.post("/api/prs",async(a,s)=>{try{s.status(201).json(await n.addPR(a.body?.url))}catch(o){he(s,o)}}),e.delete("/api/prs/:id",async(a,s)=>{try{s.json(await n.removePR(a.params.id))}catch(o){he(s,o)}}),e.patch("/api/prs/:id/watch",async(a,s)=>{try{let{enabled:o}=m.object({enabled:m.boolean()}).parse(a.body);s.json(await n.setPRWatchEnabled(a.params.id,o))}catch(o){he(s,o)}}),e.post("/api/prs/:id/fetch",async(a,s)=>{try{s.json(await n.fetchPRFeedback(a.params.id))}catch(o){he(s,o)}}),e.post("/api/prs/:id/triage",async(a,s)=>{try{s.json(await n.triagePR(a.params.id))}catch(o){he(s,o)}}),e.post("/api/prs/:id/apply",async(a,s)=>{try{s.json(await n.applyPR(a.params.id))}catch(o){he(s,o)}}),e.post("/api/prs/:id/babysit",async(a,s)=>{try{s.json(await n.babysitPR(a.params.id))}catch(o){he(s,o)}}),e.patch("/api/prs/:id/feedback/:feedbackId",async(a,s)=>{try{let{decision:o}=m.object({decision:m.enum(["accept","reject","flag"])}).parse(a.body);s.json(await n.setFeedbackDecision(a.params.id,a.params.feedbackId,o))}catch(o){he(s,o)}}),e.post("/api/prs/:id/feedback/:feedbackId/retry",async(a,s)=>{try{s.json(await n.retryFeedback(a.params.id,a.params.feedbackId))}catch(o){he(s,o)}}),e.get("/api/prs/:id/questions",async(a,s)=>{try{s.json(await n.listPRQuestions(a.params.id))}catch(o){he(s,o)}}),e.post("/api/prs/:id/questions",async(a,s)=>{try{s.status(201).json(await n.askQuestion(a.params.id,a.body?.question))}catch(o){he(s,o)}}),e.get("/api/logs",async(a,s)=>{let o=typeof a.query.prId=="string"?a.query.prId:void 0;s.json(await n.listLogs(o))}),e.get("/api/onboarding/status",async(a,s)=>{try{s.json(await n.getOnboardingStatus())}catch(o){he(s,o)}}),e.post("/api/onboarding/install-review",async(a,s)=>{try{let{repo:o,tool:u}=m.object({repo:m.string().min(1),tool:m.enum(["claude","codex"])}).parse(a.body);s.json(await n.installReviewWorkflow(o,u))}catch(o){he(s,o)}}),e.get("/api/healing-sessions",async(a,s)=>{try{s.json(await n.listHealingSessions())}catch(o){he(s,o)}}),e.get("/api/healing-sessions/:id",async(a,s)=>{try{s.json(await n.getHealingSession(a.params.id))}catch(o){he(s,o)}}),e.get("/api/deployment-healing-sessions",async(a,s)=>{try{let o=typeof a.query.repo=="string"?a.query.repo:void 0;s.json(await n.listDeploymentHealingSessions(o))}catch(o){he(s,o)}}),e.get("/api/deployment-healing-sessions/:id",async(a,s)=>{try{s.json(await n.getDeploymentHealingSession(a.params.id))}catch(o){he(s,o)}}),e.get("/api/config",async(a,s)=>{s.json(J2(await n.getConfig()))}),e.get("/api/app-update",async(a,s)=>{try{s.json(await i("3.1.0"))}catch(o){he(s,o)}}),e.get("/api/changelogs",async(a,s)=>{try{s.json(await n.listSocialChangelogs())}catch(o){he(s,o)}}),e.get("/api/changelogs/:id",async(a,s)=>{try{s.json(await n.getSocialChangelog(a.params.id))}catch(o){he(s,o)}}),e.get("/api/releases",async(a,s)=>{try{s.json(await n.listReleaseRuns())}catch(o){he(s,o)}}),e.get("/api/releases/:id",async(a,s)=>{try{s.json(await n.getReleaseRun(a.params.id))}catch(o){he(s,o)}}),e.post("/api/releases/:id/retry",async(a,s)=>{try{s.json(await n.retryReleaseRun(a.params.id))}catch(o){he(s,o)}}),e.patch("/api/config",async(a,s)=>{try{let o=Zo.partial().parse(a.body),u=await n.getConfig();s.json(J2(await n.updateConfig(EM(u,o))))}catch(o){he(s,o)}}),t}var Z2=tt(Dp(),1),Y2=tt(require("fs"),1),wm=tt(require("path"),1);function eS(t){let e=wm.default.resolve(__dirname,"public");if(!Y2.default.existsSync(e))throw new Error(`Could not find the build directory: ${e}, make sure to build the client first`);t.use(Z2.default.static(e)),t.use("/{*path}",(r,n)=>{n.sendFile(wm.default.resolve(e,"index.html"))})}var TM=new Set(["127.0.0.1","::1","::ffff:127.0.0.1","localhost"]);function SM(t){if(!t)return!1;let e=t.replace(/^\[|\]$/g,"");return TM.has(e)?!0:e.startsWith("::ffff:")?e.slice(7).startsWith("127."):!!e.startsWith("127.")}function tS(t,e,r){let n=t.ip??t.socket?.remoteAddress;if(!SM(n)){e.status(403).json({error:"Forbidden",message:"oh-my-pr only accepts connections from the local machine. External access is not permitted."});return}r()}var nS=require("http"),ii=(0,gc.default)(),rS=(0,nS.createServer)(ii);ii.use(gc.default.json({verify:(t,e,r)=>{t.rawBody=r}}));ii.use(gc.default.urlencoded({extended:!1}));ii.use("/api",tS);function iS(t,e="express"){let r=new Date().toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",second:"2-digit",hour12:!0});console.log(`${r} [${e}] ${t}`)}async function kM(t){let{default:e}=await import("open");await e(t)}(async()=>{await Q2(rS,ii),ii.use((e,r,n,i)=>{let a=e,s=a.status||a.statusCode||500,o=a.message||"Internal Server Error";return console.error("Internal Server Error:",e),n.headersSent?i(e):n.status(s).json({message:o})}),eS(ii);let t=parseInt(process.env.PORT||"5001",10);rS.listen({port:t,host:"0.0.0.0"},()=>{let e=`http://localhost:${t}`;console.log(`
|
|
1030
|
-
oh-my-pr v3.
|
|
1029
|
+
`):"- Manual release requested."}`}function pM(t){return(t instanceof Error?t.message:String(t)).trim().slice(0,2e3)}function G2(t){return t==="skipped"||t==="published"}function dM(t){return new Promise(e=>setTimeout(e,t))}var fM=["fix_submitted","escalated"],mM={monitoring:["failed","escalated"],failed:["fixing","escalated"],fixing:["fix_submitted","escalated"],fix_submitted:[],escalated:[]},mc=class{constructor(e,r=()=>new Date){this.storage=e;this.clock=r}async createSession(e){return this.storage.createDeploymentHealingSession({...e,deploymentId:null,deploymentLog:null,fixBranch:null,fixPrNumber:null,fixPrUrl:null,state:"monitoring",error:null,completedAt:null})}async ensureSession(e){let r=await this.storage.getDeploymentHealingSessionByRepoAndMergeSha(e.repo,e.mergeSha);return r||this.createSession(e)}async transitionTo(e,r,n={}){let i=await this.storage.getDeploymentHealingSession(e);if(!i)throw new Error(`Deployment healing session not found: ${e}`);if(i.state===r){let o=await this.storage.updateDeploymentHealingSession(e,n);if(!o)throw new Error(`Deployment healing session not found: ${e}`);return o}if(!mM[i.state].includes(r))throw new Error(`Illegal deployment healing transition: ${i.state} -> ${r}`);let a={...n,state:r};fM.includes(r)&&(a.completedAt=n.completedAt??this.clock().toISOString());let s=await this.storage.updateDeploymentHealingSession(e,a);if(!s)throw new Error(`Deployment healing session not found: ${e}`);return s}};var Le=class extends Error{statusCode;constructor(e,r){super(r),this.name="AppRuntimeError",this.statusCode=e}};function q2(t){return t instanceof Error?t.message:String(t)}function Ve(t,e){if(t===void 0)throw new Le(404,e);return t}function gM(t){switch(t.kind){case"sync_watched_repos":return"Sync watched repositories";case"babysit_pr":return"Babysitting PR";case"process_release_run":return"Processing release";case"answer_pr_question":return"Answering PR question";case"generate_social_changelog":return"Generating social changelog";case"heal_deployment":return"Healing deployment"}}function j2(t,e){let r=t.payload[e];return typeof r=="string"&&r.trim()?r:null}function H2(t){return t.flatMap(e=>{let r=e.mergeCommitSha?.trim();return r?[{number:e.number,title:e.title,url:e.url,author:e.author,repo:e.repo,mergedAt:e.mergedAt,mergeSha:r}]:[]})}function $2(t={}){let e=t.storage??D1(),r=new B2.EventEmitter,n=t.backgroundJobQueue??new oc(e),i,a=async(...x)=>{let _=await n.enqueue(...x);return i.wake(),_},s=t.deploymentHealingManager??new mc(e),o=t.releaseManager??new fc(e,{github:{buildOctokit:Kt,getDefaultBranch:am,findLatestSemverReleaseTag:kT,bumpReleaseTag:ST,listUnreleasedMergedPulls:async(x,_,T)=>{let w=await sm(x,_,{baseRef:T.baseBranch});return H2(w)},listMergedPullsForReleaseCandidate:async(x,_,T)=>{let w=await sm(x,_,{baseRef:T.baseBranch}),M=Date.parse(T.untilMergedAt);return H2(w.filter(j=>!Number.isFinite(M)||Date.parse(j.mergedAt)<=M))},findReleaseByTag:async(x,_,T)=>{let M=(await Zu(x,_)).find(j=>!j.draft&&j.tagName===T);return M?{id:M.id,url:M.htmlUrl,tagName:M.tagName,name:M.name}:null},createGitHubRelease:async(x,_,T)=>{let w=await RT(x,_,{tagName:T.tagName,targetCommitish:T.targetCommitish,name:T.name,body:T.body});return{id:w.id,url:w.htmlUrl,tagName:w.tagName,name:w.name}}},scheduleBackgroundJob:a}),u=t.babysitter??new pc(e,void 0,void 0,o,a,s);i=t.backgroundJobDispatcher??new dc({storage:e,queue:n,handlers:N2({storage:e,babysitter:u,releaseManager:o,deploymentHealingManager:s})});let c=null,l=0,p=t.watcherScheduler??L2(async()=>{await a("sync_watched_repos","runtime:1",Qt("sync_watched_repos","runtime:1"))},x=>{console.error("Repository babysitter watcher failed",x)}),d=p.run,f=t.startBackgroundServices??!0,g=t.startWatcher??f,b=!1,y=()=>{r.emit("change")},C=async()=>({...await e.getRuntimeState(),activeRuns:i.getActiveRunCount()}),L=async x=>{let _=new Set,T=new Set,w=new Set,M=new Set;for(let B of x)if(!mm(B.payload))if(B.kind==="babysit_pr")_.add(B.targetId);else if(B.kind==="answer_pr_question"){let X=j2(B,"prId");X&&_.add(X)}else B.kind==="process_release_run"?T.add(B.targetId):B.kind==="generate_social_changelog"?w.add(B.targetId):B.kind==="heal_deployment"&&M.add(B.targetId);let[j,E,S,A,z]=await Promise.all([_.size>0?e.getPRs():Promise.resolve([]),_.size>0?e.getArchivedPRs():Promise.resolve([]),T.size>0?e.listReleaseRuns():Promise.resolve([]),w.size>0?e.getSocialChangelogs():Promise.resolve([]),M.size>0?e.listDeploymentHealingSessions():Promise.resolve([])]),me=new Map;for(let B of z)me.set(B.id,B),me.set(`${B.repo}:${B.mergeSha}`,B);return{prsById:new Map([...j,...E].map(B=>[B.id,B])),releaseRunsById:new Map(S.map(B=>[B.id,B])),socialChangelogsById:new Map(A.map(B=>[B.id,B])),deploymentHealingSessionsByTarget:me}},P=(x,_)=>{let T=mm(x.payload);if(T)return T;if(x.kind==="sync_watched_repos")return{label:"Sync watched repositories",detail:null,targetUrl:null};if(x.kind==="babysit_pr"){let w=_.prsById.get(x.targetId);if(w)return{label:`Babysitting PR #${w.number}`,detail:`${w.repo} - ${w.title}`,targetUrl:w.url}}if(x.kind==="answer_pr_question"){let w=j2(x,"prId"),M=w?_.prsById.get(w):void 0;if(M)return{label:`Answering question for PR #${M.number}`,detail:`${M.repo} - ${M.title}`,targetUrl:M.url}}if(x.kind==="process_release_run"){let w=_.releaseRunsById.get(x.targetId);if(w)return{label:`Processing release for ${w.repo}`,detail:`PR #${w.triggerPrNumber} - ${w.triggerPrTitle}`,targetUrl:w.triggerPrUrl}}if(x.kind==="generate_social_changelog"){let w=_.socialChangelogsById.get(x.targetId);if(w)return{label:"Generating social changelog",detail:`${w.date} - ${w.triggerCount} merged PRs`,targetUrl:null}}if(x.kind==="heal_deployment"){let w=_.deploymentHealingSessionsByTarget.get(x.targetId);if(w)return{label:`Healing ${w.platform} deployment`,detail:`${w.repo} PR #${w.triggerPrNumber} - ${w.triggerPrTitle}`,targetUrl:w.triggerPrUrl}}return{label:gM(x),detail:x.targetId,targetUrl:null}},N=(x,_)=>{let T=P(x,_);return{id:x.id,kind:x.kind,status:x.status==="leased"?"in_progress":"queued",label:T.label,detail:T.detail,targetId:x.targetId,targetUrl:T.targetUrl,queuedAt:x.createdAt,availableAt:x.availableAt,startedAt:x.heartbeatAt,updatedAt:x.updatedAt,attemptCount:x.attemptCount}},F=async x=>{let[_,T,w]=await Promise.all([i.waitForIdle(x),u.waitForIdle(x),o.waitForIdle(x)]);return _&&T&&w},h=async()=>{let x=await e.getConfig(),_=Math.max(1e4,x.pollIntervalMs||12e4);c&&l===_||(c&&(clearInterval(c),c=null),l=_,c=setInterval(()=>{d()},_))},O=async(x,_)=>{await a("babysit_pr",x.id,Qt("babysit_pr",x.id),{preferredAgent:_,...Mr({label:`Babysitting PR #${x.number}`,detail:`${x.repo} - ${x.title}`,targetUrl:x.url})})},D={async start(){b||(b=!0,f&&await i.start(),g&&(await h(),u.resumeInterruptedRuns(),d()))},stop(){b=!1,i.stop(),c&&(clearInterval(c),c=null)},subscribe(x){return r.on("change",x),()=>{r.off("change",x)}},getRuntimeSnapshot:C,async listActivities(){let[x,_]=await Promise.all([e.listBackgroundJobs({status:"leased"}),e.listBackgroundJobs({status:"queued"})]),T=await L([...x,..._]),w=x.map(j=>N(j,T)),M=_.map(j=>N(j,T));return{inProgress:w,queued:M,generatedAt:new Date().toISOString()}},async setDrainMode(x){let _=await e.updateRuntimeState({drainMode:x.enabled,drainRequestedAt:x.enabled?new Date().toISOString():null,drainReason:x.enabled?x.reason??null:null});if(x.enabled&&x.waitForIdle){let w=await F(x.timeoutMs??12e4),M=await C();return y(),{..._,...M,drained:w}}let T=await C();return y(),{..._,...T}},async listRepos(){let x=await e.getConfig(),_=await e.getPRs();return Array.from(new Set([...x.watchedRepos,..._.map(T=>T.repo)])).sort((T,w)=>T.localeCompare(w))},async listRepoSettings(){let[x,_]=await Promise.all([e.listRepoSettings(),e.getPRs()]),T=new Map(x.map(w=>[w.repo,w]));for(let w of _)T.has(w.repo)||T.set(w.repo,{repo:w.repo,autoCreateReleases:!0,ownPrsOnly:!0});return Array.from(T.values()).sort((w,M)=>w.repo.localeCompare(M.repo))},async addRepo(x){let _=at(x);if(!_)throw new Le(400,"Invalid repository. Use owner/repo or https://github.com/owner/repo");let T=Fr(_),w=await e.getConfig();return w.watchedRepos.includes(T)||await e.updateConfig({watchedRepos:[...w.watchedRepos,T].sort((M,j)=>M.localeCompare(j))}),d(),y(),{repo:T}},async updateRepoSettings(x,_){let T=at(x);if(!T)throw new Le(400,"Invalid repository. Use owner/repo or https://github.com/owner/repo");let w=Fr(T),M=await e.updateRepoSettings(w,_);return y(),M},async syncRepos(){if((await e.getRuntimeState()).drainMode)throw new Le(409,"Drain mode is enabled. Sync-triggered runs are blocked until drain mode is disabled.");return await p.runAndReportErrors(),y(),{ok:!0}},async createManualRelease(x){let _=at(x);if(!_)throw new Le(400,"Invalid repository. Use owner/repo or https://github.com/owner/repo");let T=Fr(_),w=await o.enqueueManualRepoRelease(T);if(!w)throw new Le(409,`No unreleased merged pull requests found for ${T}`);return y(),w},async listPRs(x="active"){return x==="archived"?e.getArchivedPRs():e.getPRs()},async getPR(x){return await e.getPR(x)??null},async addPR(x){let _;try{({url:_}=_1.parse({url:x}))}catch(z){throw z instanceof m.ZodError?new Le(400,z.errors[0]?.message??"Invalid PR URL"):z}let T=Xu(_);if(!T)throw new Le(400,"Invalid GitHub PR URL. Expected: https://github.com/owner/repo/pull/123");let w=`${T.owner}/${T.repo}`,M=await e.getPRByRepoAndNumber(w,T.number);if(M)return M;let j=await e.getConfig(),E=await Kt(j),S=await Qu(E,T),A=await e.addPR({number:T.number,title:S.title,repo:w,branch:S.branch,author:S.author,url:S.url,status:"watching",feedbackItems:[],accepted:0,rejected:0,flagged:0,testsPassed:null,lintPassed:null,lastChecked:null});return await e.addLog(A.id,"info",`Registered PR #${T.number} from ${w}`),await e.addLog(A.id,"info",`Repository ${w} added to auto-babysit watch list`),j.watchedRepos.includes(w)||await e.updateConfig({watchedRepos:[...j.watchedRepos,w].sort((z,me)=>z.localeCompare(me))}),await O(A,j.codingAgent),y(),A},async removePR(x){if(!await e.removePR(x))throw new Le(404,"PR not found");return y(),{ok:!0}},async setPRWatchEnabled(x,_){let T=Ve(await e.getPR(x),"PR not found"),w=await e.updatePR(T.id,{watchEnabled:_}),M=Ve(w,"PR not found");return T.watchEnabled!==_&&(await e.addLog(T.id,"info",_?"Background watch resumed":"Background watch paused"),_&&d()),y(),M},async setWatchEnabled(x,_){return D.setPRWatchEnabled(x,_)},async fetchPRFeedback(x){let _=Ve(await e.getPR(x),"PR not found");await e.updatePR(_.id,{status:"processing",lastChecked:new Date().toISOString()}),await e.addLog(_.id,"info","Syncing GitHub comments/reviews...");try{let T=await u.syncFeedbackForPR(_.id);return y(),T}catch(T){let w=q2(T);throw await e.updatePR(_.id,{status:"error",lastChecked:new Date().toISOString()}),await e.addLog(_.id,"error",`Fetch failed: ${w}`),T}},async triagePR(x){let _=Ve(await e.getPR(x),"PR not found");await e.updatePR(_.id,{status:"processing"}),await e.addLog(_.id,"info","Triaging feedback...");let T=_.feedbackItems.map(S=>{if(S.decision)return S;let A=S.body.toLowerCase();return A.includes("lgtm")||A.includes("looks good")?ni(S,!1,"Acknowledgement, no code change requested"):A.includes("please")||A.includes("should")||A.includes("fix")||A.includes("error")||A.includes("fail")?{...ni(S,!0,"Likely actionable request"),action:S.body}:c2(S,"Unclear actionability, flagged for manual review")}),w=T.filter(S=>S.decision==="accept").length,M=T.filter(S=>S.decision==="reject").length,j=T.filter(S=>S.decision==="flag").length,E=await e.updatePR(_.id,{feedbackItems:T,accepted:w,rejected:M,flagged:j,status:"watching"});return await e.addLog(_.id,"info",`Triage complete: ${w} accept, ${M} reject, ${j} flag`),y(),Ve(E,"PR not found")},async applyPR(x){let _=Ve(await e.getPR(x),"PR not found");if((await e.getRuntimeState()).drainMode)throw new Le(409,"Drain mode is enabled. Manual runs are blocked until drain mode is disabled.");let w=await e.getConfig();await e.updatePR(_.id,{status:"processing"}),await e.addLog(_.id,"info",`Launching autonomous babysitter run using ${w.codingAgent}`),await O(_,w.codingAgent);let M=await e.getPR(_.id);return y(),Ve(M,"PR disappeared after apply run")},async babysitPR(x){let _=Ve(await e.getPR(x),"PR not found");if((await e.getRuntimeState()).drainMode)throw new Le(409,"Drain mode is enabled. Manual runs are blocked until drain mode is disabled.");let w=await e.getConfig();await e.addLog(_.id,"info",`Manual babysitter trigger using ${w.codingAgent}`),await O(_,w.codingAgent);let M=await e.getPR(_.id);return y(),Ve(M,"PR disappeared after babysit run")},async queueBabysit(x){return D.babysitPR(x)},async setFeedbackDecision(x,_,T){let w=Ve(await e.getPR(x),"PR not found"),M=await k2({storage:e,pr:w,feedbackId:_,decision:T});return y(),Ve(M,"PR not found")},async retryFeedback(x,_){let T=await u.retryFeedbackItem(x,_);if(T.kind==="pr_not_found")throw new Le(404,"PR not found");if(T.kind==="feedback_not_found")throw new Le(404,"Feedback item not found");if(T.kind==="feedback_not_retryable")throw new Le(400,"Only failed or warning items can be retried");await e.addLog(x,"info",`Feedback item ${_} queued for retry`);let w=await e.getConfig();return await O(T.updated,w.codingAgent),y(),T.updated},async listPRQuestions(x){return Ve(await e.getPR(x),"PR not found"),e.getQuestions(x)},async askQuestion(x,_){let T=Ve(await e.getPR(x),"PR not found"),w;try{w=S1.parse({question:_})}catch(j){throw j instanceof m.ZodError?new Le(400,j.errors[0]?.message??"Invalid question"):j}let M=await e.addQuestion(x,w.question);try{await a("answer_pr_question",M.id,Qt("answer_pr_question",M.id),{prId:x,...Mr({label:`Answering question for PR #${T.number}`,detail:`${T.repo} - ${T.title}`,targetUrl:T.url})})}catch(j){let E=q2(j);throw await e.updateQuestion(M.id,{status:"error",error:E.trim().slice(0,2e3)}),j}return y(),M},async listLogs(x){return e.getLogs(x)},async getOnboardingStatus(){let x=await e.getConfig();return _T(x,x.watchedRepos)},async installReviewWorkflow(x,_){let T=await e.getConfig();return ET(T,x,_)},async listHealingSessions(){return e.listHealingSessions()},async getHealingSession(x){return Ve(await e.getHealingSession(x),"Healing session not found")},async listDeploymentHealingSessions(x){return e.listDeploymentHealingSessions(x?{repo:x}:void 0)},async getDeploymentHealingSession(x){return Ve(await e.getDeploymentHealingSession(x),"Deployment healing session not found")},async getConfig(){return e.getConfig()},async updateConfig(x){let _=await e.updateConfig(x);return g&&b&&await h(),y(),_},async listSocialChangelogs(){return e.getSocialChangelogs()},async getSocialChangelog(x){return Ve(await e.getSocialChangelog(x),"Changelog not found")},async listReleaseRuns(){return e.listReleaseRuns()},async getReleaseRun(x){return Ve(await e.getReleaseRun(x),"Release run not found")},async retryReleaseRun(x){let _=await o.retryReleaseRun(x);if(!_)throw new Le(404,"Release run not found");return y(),_}};return D}function z2(t){return t instanceof Le}var W2="https://github.com/yungookim/oh-my-pr/releases",hM="https://api.github.com/repos/yungookim/oh-my-pr/releases/latest",bM=3600*1e3;function yM(t,e){let r=ei(t),n=ei(e);return!r||!n?0:r.major!==n.major?r.major-n.major:r.minor!==n.minor?r.minor-n.minor:r.patch-n.patch}function vM(t){return{currentVersion:t,latestVersion:null,latestReleaseUrl:W2,updateAvailable:!1}}async function xM(t,e=fetch){let r=t.trim(),n=vM(r);if(!ei(r))return n;try{let i=await e(hM,{headers:{accept:"application/vnd.github+json","user-agent":`oh-my-pr/${r}`}});if(!i.ok)return n;let a=await i.json(),s=a.tag_name?.trim()??null;return a.draft||a.prerelease||!s||!ei(s)?n:{currentVersion:r,latestVersion:s,latestReleaseUrl:a.html_url?.trim()||W2,updateAvailable:yM(s,r)>0}}catch{return n}}function V2(t=fetch,e={}){let r=e.cacheTtlMs??bM,n=e.now??Date.now,i=new Map,a=new Map;return async s=>{let o=s.trim(),u=i.get(o);if(u&&u.expiresAt>n())return u.status;let c=a.get(o);if(c)return c;let l=xM(o,t).then(p=>(i.set(o,{status:p,expiresAt:n()+r}),a.delete(o),p),p=>{throw a.delete(o),p});return a.set(o,l),l}}var X2="***";function wM(t){return t instanceof Error?t.message:String(t)}function he(t,e){if(e instanceof m.ZodError){t.status(400).json({error:e.errors[0]?.message??"Invalid request"});return}if(e instanceof Oe){t.status(e.statusCode).json({error:e.message});return}if(z2(e)){t.status(e.statusCode).json({error:e.message});return}t.status(500).json({error:wM(e)})}function K2(t){return t?`${X2}${t.slice(-4)}`:""}function _M(t,e){let r=t.map(n=>({token:n,masked:K2(n),used:!1}));return e.map(n=>{let i=n.trim();if(!i)return"";if(i.startsWith(X2)){let a=r.find(s=>!s.used&&s.masked===i);if(a)return a.used=!0,a.token}return i}).filter(Boolean)}function EM(t,e){let r=e.githubTokens??(e.githubToken!==void 0?[e.githubToken]:void 0);if(r===void 0)return e;let{githubToken:n,...i}=e;return{...i,githubTokens:_M(t.githubTokens,r)}}function J2(t){let e=t.githubTokens.map(K2);return{...t,githubTokens:e,githubToken:e[0]??""}}async function Q2(t,e,r={}){let n=r.runtime??$2(r),i=r.appUpdateChecker??V2();return await n.start(),t.on("close",()=>{n.stop()}),e.get("/api/runtime",async(a,s)=>{s.json(await n.getRuntimeSnapshot())}),e.get("/api/activities",async(a,s)=>{s.json(await n.listActivities())}),e.post("/api/runtime/drain",async(a,s)=>{try{let o=m.object({enabled:m.boolean(),reason:m.string().optional(),waitForIdle:m.boolean().optional(),timeoutMs:m.number().int().positive().max(6e5).optional()}).parse(a.body),u=await n.setDrainMode(o);if(o.enabled&&o.waitForIdle&&u.drained===!1)return s.status(202).json(u);s.json(u)}catch(o){he(s,o)}}),e.get("/api/repos",async(a,s)=>{s.json(await n.listRepos())}),e.get("/api/repos/settings",async(a,s)=>{s.json(await n.listRepoSettings())}),e.post("/api/repos",async(a,s)=>{try{let{repo:o}=m.object({repo:m.string().min(1)}).parse(a.body);s.status(201).json(await n.addRepo(o))}catch(o){he(s,o)}}),e.patch("/api/repos/settings",async(a,s)=>{try{let o=m.object({repo:m.string().min(1),autoCreateReleases:m.boolean().optional(),ownPrsOnly:m.boolean().optional()}).refine(l=>l.autoCreateReleases!==void 0||l.ownPrsOnly!==void 0,"At least one repository setting must be provided").parse(a.body),{repo:u,...c}=o;s.json(await n.updateRepoSettings(u,c))}catch(o){he(s,o)}}),e.post("/api/repos/sync",async(a,s)=>{try{s.json(await n.syncRepos())}catch(o){he(s,o)}}),e.post("/api/repos/release",async(a,s)=>{try{let{repo:o}=m.object({repo:m.string().min(1)}).parse(a.body);s.status(201).json(await n.createManualRelease(o))}catch(o){he(s,o)}}),e.get("/api/prs",async(a,s)=>{s.json(await n.listPRs("active"))}),e.get("/api/prs/archived",async(a,s)=>{s.json(await n.listPRs("archived"))}),e.get("/api/prs/:id",async(a,s)=>{let o=await n.getPR(a.params.id);if(!o)return s.status(404).json({error:"PR not found"});s.json(o)}),e.post("/api/prs",async(a,s)=>{try{s.status(201).json(await n.addPR(a.body?.url))}catch(o){he(s,o)}}),e.delete("/api/prs/:id",async(a,s)=>{try{s.json(await n.removePR(a.params.id))}catch(o){he(s,o)}}),e.patch("/api/prs/:id/watch",async(a,s)=>{try{let{enabled:o}=m.object({enabled:m.boolean()}).parse(a.body);s.json(await n.setPRWatchEnabled(a.params.id,o))}catch(o){he(s,o)}}),e.post("/api/prs/:id/fetch",async(a,s)=>{try{s.json(await n.fetchPRFeedback(a.params.id))}catch(o){he(s,o)}}),e.post("/api/prs/:id/triage",async(a,s)=>{try{s.json(await n.triagePR(a.params.id))}catch(o){he(s,o)}}),e.post("/api/prs/:id/apply",async(a,s)=>{try{s.json(await n.applyPR(a.params.id))}catch(o){he(s,o)}}),e.post("/api/prs/:id/babysit",async(a,s)=>{try{s.json(await n.babysitPR(a.params.id))}catch(o){he(s,o)}}),e.patch("/api/prs/:id/feedback/:feedbackId",async(a,s)=>{try{let{decision:o}=m.object({decision:m.enum(["accept","reject","flag"])}).parse(a.body);s.json(await n.setFeedbackDecision(a.params.id,a.params.feedbackId,o))}catch(o){he(s,o)}}),e.post("/api/prs/:id/feedback/:feedbackId/retry",async(a,s)=>{try{s.json(await n.retryFeedback(a.params.id,a.params.feedbackId))}catch(o){he(s,o)}}),e.get("/api/prs/:id/questions",async(a,s)=>{try{s.json(await n.listPRQuestions(a.params.id))}catch(o){he(s,o)}}),e.post("/api/prs/:id/questions",async(a,s)=>{try{s.status(201).json(await n.askQuestion(a.params.id,a.body?.question))}catch(o){he(s,o)}}),e.get("/api/logs",async(a,s)=>{let o=typeof a.query.prId=="string"?a.query.prId:void 0;s.json(await n.listLogs(o))}),e.get("/api/onboarding/status",async(a,s)=>{try{s.json(await n.getOnboardingStatus())}catch(o){he(s,o)}}),e.post("/api/onboarding/install-review",async(a,s)=>{try{let{repo:o,tool:u}=m.object({repo:m.string().min(1),tool:m.enum(["claude","codex"])}).parse(a.body);s.json(await n.installReviewWorkflow(o,u))}catch(o){he(s,o)}}),e.get("/api/healing-sessions",async(a,s)=>{try{s.json(await n.listHealingSessions())}catch(o){he(s,o)}}),e.get("/api/healing-sessions/:id",async(a,s)=>{try{s.json(await n.getHealingSession(a.params.id))}catch(o){he(s,o)}}),e.get("/api/deployment-healing-sessions",async(a,s)=>{try{let o=typeof a.query.repo=="string"?a.query.repo:void 0;s.json(await n.listDeploymentHealingSessions(o))}catch(o){he(s,o)}}),e.get("/api/deployment-healing-sessions/:id",async(a,s)=>{try{s.json(await n.getDeploymentHealingSession(a.params.id))}catch(o){he(s,o)}}),e.get("/api/config",async(a,s)=>{s.json(J2(await n.getConfig()))}),e.get("/api/app-update",async(a,s)=>{try{s.json(await i("3.2.0"))}catch(o){he(s,o)}}),e.get("/api/changelogs",async(a,s)=>{try{s.json(await n.listSocialChangelogs())}catch(o){he(s,o)}}),e.get("/api/changelogs/:id",async(a,s)=>{try{s.json(await n.getSocialChangelog(a.params.id))}catch(o){he(s,o)}}),e.get("/api/releases",async(a,s)=>{try{s.json(await n.listReleaseRuns())}catch(o){he(s,o)}}),e.get("/api/releases/:id",async(a,s)=>{try{s.json(await n.getReleaseRun(a.params.id))}catch(o){he(s,o)}}),e.post("/api/releases/:id/retry",async(a,s)=>{try{s.json(await n.retryReleaseRun(a.params.id))}catch(o){he(s,o)}}),e.patch("/api/config",async(a,s)=>{try{let o=Zo.partial().parse(a.body),u=await n.getConfig();s.json(J2(await n.updateConfig(EM(u,o))))}catch(o){he(s,o)}}),t}var Z2=tt(Dp(),1),Y2=tt(require("fs"),1),wm=tt(require("path"),1);function eS(t){let e=wm.default.resolve(__dirname,"public");if(!Y2.default.existsSync(e))throw new Error(`Could not find the build directory: ${e}, make sure to build the client first`);t.use(Z2.default.static(e)),t.use("/{*path}",(r,n)=>{n.sendFile(wm.default.resolve(e,"index.html"))})}var TM=new Set(["127.0.0.1","::1","::ffff:127.0.0.1","localhost"]);function SM(t){if(!t)return!1;let e=t.replace(/^\[|\]$/g,"");return TM.has(e)?!0:e.startsWith("::ffff:")?e.slice(7).startsWith("127."):!!e.startsWith("127.")}function tS(t,e,r){let n=t.ip??t.socket?.remoteAddress;if(!SM(n)){e.status(403).json({error:"Forbidden",message:"oh-my-pr only accepts connections from the local machine. External access is not permitted."});return}r()}var nS=require("http"),ii=(0,gc.default)(),rS=(0,nS.createServer)(ii);ii.use(gc.default.json({verify:(t,e,r)=>{t.rawBody=r}}));ii.use(gc.default.urlencoded({extended:!1}));ii.use("/api",tS);function iS(t,e="express"){let r=new Date().toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",second:"2-digit",hour12:!0});console.log(`${r} [${e}] ${t}`)}async function kM(t){let{default:e}=await import("open");await e(t)}(async()=>{await Q2(rS,ii),ii.use((e,r,n,i)=>{let a=e,s=a.status||a.statusCode||500,o=a.message||"Internal Server Error";return console.error("Internal Server Error:",e),n.headersSent?i(e):n.status(s).json({message:o})}),eS(ii);let t=parseInt(process.env.PORT||"5001",10);rS.listen({port:t,host:"0.0.0.0"},()=>{let e=`http://localhost:${t}`;console.log(`
|
|
1030
|
+
oh-my-pr v3.2.0
|
|
1031
1031
|
Dashboard: ${e}
|
|
1032
1032
|
`),!process.env.TAURI_DEV&&!process.env.OH_MY_PR_DESKTOP&&kM(e).catch(n=>{iS(`Could not open browser automatically: ${n.message}`)})})})();0&&(module.exports={log});
|
|
1033
1033
|
/*! Bundled license information:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:var(--font-sans);font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--font-mono);font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}*{--tw-border-opacity: 1;border-color:hsl(var(--border) / var(--tw-border-opacity, 1))}body{--tw-bg-opacity: 1;background-color:hsl(var(--background) / var(--tw-bg-opacity, 1));font-family:var(--font-mono);--tw-text-opacity: 1;color:hsl(var(--foreground) / var(--tw-text-opacity, 1));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:13px;line-height:1.5;letter-spacing:-.01em}.feedback-markdown{color:hsl(var(--foreground) / .82);word-break:break-word}.feedback-markdown>*+*{margin-top:.6rem}.feedback-markdown ul,.feedback-markdown ol{padding-left:1.25rem}.feedback-markdown li+li{margin-top:.2rem}.feedback-markdown a{color:inherit;text-decoration:underline;text-underline-offset:.15em}.feedback-markdown blockquote{border-left:1px solid hsl(var(--border));color:hsl(var(--muted-foreground));padding-left:.75rem}.feedback-markdown code{background:hsl(var(--muted));border:1px solid hsl(var(--border));padding:.05rem .3rem;font-size:11px}.feedback-markdown pre{overflow-x:auto;background:hsl(var(--muted));border:1px solid hsl(var(--border));padding:.75rem}.feedback-markdown pre code{background:transparent;border:0;padding:0}.feedback-markdown table{width:100%;border-collapse:collapse;font-size:11px}.feedback-markdown th,.feedback-markdown td{border:1px solid hsl(var(--border));padding:.35rem .45rem;text-align:left;vertical-align:top}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.invisible{visibility:hidden}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.inset-x-0{left:0;right:0}.inset-y-0{top:0;bottom:0}.-bottom-12{bottom:-3rem}.-left-12{left:-3rem}.-right-12{right:-3rem}.-top-12{top:-3rem}.bottom-0{bottom:0}.left-0{left:0}.left-1{left:.25rem}.left-1\/2{left:50%}.left-2{left:.5rem}.left-\[50\%\]{left:50%}.right-0{right:0}.right-1{right:.25rem}.right-2{right:.5rem}.right-3{right:.75rem}.right-4{right:1rem}.top-0{top:0}.top-1\.5{top:.375rem}.top-1\/2{top:50%}.top-2{top:.5rem}.top-3\.5{top:.875rem}.top-4{top:1rem}.top-\[1px\]{top:1px}.top-\[50\%\]{top:50%}.top-\[60\%\]{top:60%}.top-full{top:100%}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.z-\[100\]{z-index:100}.z-\[1\]{z-index:1}.-mx-1{margin-left:-.25rem;margin-right:-.25rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-3\.5{margin-left:.875rem;margin-right:.875rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.my-0\.5{margin-top:.125rem;margin-bottom:.125rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.-ml-4{margin-left:-1rem}.-mt-4{margin-top:-1rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.ml-1{margin-left:.25rem}.ml-\[3\.75rem\]{margin-left:3.75rem}.ml-auto{margin-left:auto}.mr-2{margin-right:.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-24{margin-top:6rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-auto{margin-top:auto}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.aspect-square{aspect-ratio:1 / 1}.aspect-video{aspect-ratio:16 / 9}.size-4{width:1rem;height:1rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[1px\]{height:1px}.h-\[var\(--radix-navigation-menu-viewport-height\)\]{height:var(--radix-navigation-menu-viewport-height)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.h-svh{height:100svh}.max-h-52{max-height:13rem}.max-h-\[--radix-context-menu-content-available-height\]{max-height:var(--radix-context-menu-content-available-height)}.max-h-\[--radix-select-content-available-height\]{max-height:var(--radix-select-content-available-height)}.max-h-\[300px\]{max-height:300px}.max-h-\[42vh\]{max-height:42vh}.max-h-\[var\(--radix-dropdown-menu-content-available-height\)\]{max-height:var(--radix-dropdown-menu-content-available-height)}.max-h-screen{max-height:100vh}.min-h-0{min-height:0px}.min-h-10{min-height:2.5rem}.min-h-8{min-height:2rem}.min-h-9{min-height:2.25rem}.min-h-\[24rem\]{min-height:24rem}.min-h-\[32rem\]{min-height:32rem}.min-h-\[80px\]{min-height:80px}.min-h-screen{min-height:100vh}.min-h-svh{min-height:100svh}.w-0{width:0px}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-28{width:7rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-3\/4{width:75%}.w-4{width:1rem}.w-5{width:1.25rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-8{width:2rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-\[100px\]{width:100px}.w-\[1px\]{width:1px}.w-\[var\(--sidebar-width\)\]{width:var(--sidebar-width)}.w-auto{width:auto}.w-full{width:100%}.w-max{width:-moz-max-content;width:max-content}.w-px{width:1px}.min-w-0{min-width:0px}.min-w-10{min-width:2.5rem}.min-w-11{min-width:2.75rem}.min-w-5{min-width:1.25rem}.min-w-9{min-width:2.25rem}.min-w-\[12rem\]{min-width:12rem}.min-w-\[8rem\]{min-width:8rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-\[var\(--skeleton-width\)\]{max-width:var(--skeleton-width)}.max-w-lg{max-width:32rem}.max-w-max{max-width:-moz-max-content;max-width:max-content}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.grow-0{flex-grow:0}.basis-full{flex-basis:100%}.caption-bottom{caption-side:bottom}.border-collapse{border-collapse:collapse}.origin-\[--radix-context-menu-content-transform-origin\]{transform-origin:var(--radix-context-menu-content-transform-origin)}.origin-\[--radix-dropdown-menu-content-transform-origin\]{transform-origin:var(--radix-dropdown-menu-content-transform-origin)}.origin-\[--radix-hover-card-content-transform-origin\]{transform-origin:var(--radix-hover-card-content-transform-origin)}.origin-\[--radix-menubar-content-transform-origin\]{transform-origin:var(--radix-menubar-content-transform-origin)}.origin-\[--radix-popover-content-transform-origin\]{transform-origin:var(--radix-popover-content-transform-origin)}.origin-\[--radix-select-content-transform-origin\]{transform-origin:var(--radix-select-content-transform-origin)}.origin-\[--radix-tooltip-content-transform-origin\]{transform-origin:var(--radix-tooltip-content-transform-origin)}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-x-px{--tw-translate-x: -1px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-\[-50\%\]{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-px{--tw-translate-x: 1px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[-50\%\]{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-45{--tw-rotate: 45deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-stretch{align-items:stretch}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-8{gap:2rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-y-1{row-gap:.25rem}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.25rem * var(--tw-space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(1rem * var(--tw-space-x-reverse));margin-left:calc(1rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.self-end{align-self:flex-end}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-\[2px\]{border-radius:2px}.rounded-\[inherit\]{border-radius:inherit}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5625rem}.rounded-md{border-radius:.375rem}.rounded-sm{border-radius:.1875rem}.rounded-xl{border-radius:.75rem}.rounded-t-\[10px\]{border-top-left-radius:10px;border-top-right-radius:10px}.rounded-tl-sm{border-top-left-radius:.1875rem}.border{border-width:1px}.border-2{border-width:2px}.border-\[1\.5px\]{border-width:1.5px}.border-y{border-top-width:1px;border-bottom-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-\[--color-border\]{border-color:var(--color-border)}.border-border{--tw-border-opacity: 1;border-color:hsl(var(--border) / var(--tw-border-opacity, 1))}.border-border\/50{border-color:hsl(var(--border) / .5)}.border-border\/60{border-color:hsl(var(--border) / .6)}.border-card-border{--tw-border-opacity: 1;border-color:hsl(var(--card-border) / var(--tw-border-opacity, 1))}.border-destructive{--tw-border-opacity: 1;border-color:hsl(var(--destructive) / var(--tw-border-opacity, 1))}.border-destructive-border{border-color:var(--destructive-border)}.border-destructive\/30{border-color:hsl(var(--destructive) / .3)}.border-destructive\/40{border-color:hsl(var(--destructive) / .4)}.border-destructive\/50{border-color:hsl(var(--destructive) / .5)}.border-foreground{--tw-border-opacity: 1;border-color:hsl(var(--foreground) / var(--tw-border-opacity, 1))}.border-foreground\/20{border-color:hsl(var(--foreground) / .2)}.border-foreground\/30{border-color:hsl(var(--foreground) / .3)}.border-foreground\/40{border-color:hsl(var(--foreground) / .4)}.border-input{--tw-border-opacity: 1;border-color:hsl(var(--input) / var(--tw-border-opacity, 1))}.border-primary{--tw-border-opacity: 1;border-color:hsl(var(--primary) / var(--tw-border-opacity, 1))}.border-primary-border{border-color:var(--primary-border)}.border-secondary-border{border-color:var(--secondary-border)}.border-sidebar-border{--tw-border-opacity: 1;border-color:hsl(var(--sidebar-border) / var(--tw-border-opacity, 1))}.border-success-border{--tw-border-opacity: 1;border-color:hsl(var(--success-border) / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.border-warning-border{--tw-border-opacity: 1;border-color:hsl(var(--warning-border) / var(--tw-border-opacity, 1))}.border-l-transparent{border-left-color:transparent}.border-t-transparent{border-top-color:transparent}.bg-\[--color-bg\]{background-color:var(--color-bg)}.bg-accent{--tw-bg-opacity: 1;background-color:hsl(var(--accent) / var(--tw-bg-opacity, 1))}.bg-background{--tw-bg-opacity: 1;background-color:hsl(var(--background) / var(--tw-bg-opacity, 1))}.bg-background\/50{background-color:hsl(var(--background) / .5)}.bg-background\/60{background-color:hsl(var(--background) / .6)}.bg-black\/80{background-color:#000c}.bg-border{--tw-bg-opacity: 1;background-color:hsl(var(--border) / var(--tw-bg-opacity, 1))}.bg-card{--tw-bg-opacity: 1;background-color:hsl(var(--card) / var(--tw-bg-opacity, 1))}.bg-destructive{--tw-bg-opacity: 1;background-color:hsl(var(--destructive) / var(--tw-bg-opacity, 1))}.bg-destructive\/10{background-color:hsl(var(--destructive) / .1)}.bg-destructive\/5{background-color:hsl(var(--destructive) / .05)}.bg-foreground{--tw-bg-opacity: 1;background-color:hsl(var(--foreground) / var(--tw-bg-opacity, 1))}.bg-foreground\/15{background-color:hsl(var(--foreground) / .15)}.bg-foreground\/30{background-color:hsl(var(--foreground) / .3)}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-muted{--tw-bg-opacity: 1;background-color:hsl(var(--muted) / var(--tw-bg-opacity, 1))}.bg-muted-foreground{--tw-bg-opacity: 1;background-color:hsl(var(--muted-foreground) / var(--tw-bg-opacity, 1))}.bg-muted\/30{background-color:hsl(var(--muted) / .3)}.bg-muted\/35{background-color:hsl(var(--muted) / .35)}.bg-muted\/40{background-color:hsl(var(--muted) / .4)}.bg-muted\/50{background-color:hsl(var(--muted) / .5)}.bg-muted\/70{background-color:hsl(var(--muted) / .7)}.bg-popover{--tw-bg-opacity: 1;background-color:hsl(var(--popover) / var(--tw-bg-opacity, 1))}.bg-primary{--tw-bg-opacity: 1;background-color:hsl(var(--primary) / var(--tw-bg-opacity, 1))}.bg-secondary{--tw-bg-opacity: 1;background-color:hsl(var(--secondary) / var(--tw-bg-opacity, 1))}.bg-sidebar{--tw-bg-opacity: 1;background-color:hsl(var(--sidebar) / var(--tw-bg-opacity, 1))}.bg-sidebar-border{--tw-bg-opacity: 1;background-color:hsl(var(--sidebar-border) / var(--tw-bg-opacity, 1))}.bg-success{--tw-bg-opacity: 1;background-color:hsl(var(--success) / var(--tw-bg-opacity, 1))}.bg-success-muted{--tw-bg-opacity: 1;background-color:hsl(var(--success-muted) / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-warning{--tw-bg-opacity: 1;background-color:hsl(var(--warning) / var(--tw-bg-opacity, 1))}.bg-warning-muted{--tw-bg-opacity: 1;background-color:hsl(var(--warning-muted) / var(--tw-bg-opacity, 1))}.fill-current{fill:currentColor}.p-0{padding:0}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-\[1px\]{padding:1px}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0{padding-top:0;padding-bottom:0}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pl-2\.5{padding-left:.625rem}.pl-3{padding-left:.75rem}.pl-4{padding-left:1rem}.pl-8{padding-left:2rem}.pl-\[3\.75rem\]{padding-left:3.75rem}.pr-1{padding-right:.25rem}.pr-2{padding-right:.5rem}.pr-2\.5{padding-right:.625rem}.pr-8{padding-right:2rem}.pt-0{padding-top:0}.pt-0\.5{padding-top:.125rem}.pt-1{padding-top:.25rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.pt-6{padding-top:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[0\.8rem\]{font-size:.8rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.normal-case{text-transform:none}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-4{line-height:1rem}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.tracking-normal{letter-spacing:0em}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.text-accent-foreground{--tw-text-opacity: 1;color:hsl(var(--accent-foreground) / var(--tw-text-opacity, 1))}.text-background{--tw-text-opacity: 1;color:hsl(var(--background) / var(--tw-text-opacity, 1))}.text-card-foreground{--tw-text-opacity: 1;color:hsl(var(--card-foreground) / var(--tw-text-opacity, 1))}.text-current{color:currentColor}.text-destructive{--tw-text-opacity: 1;color:hsl(var(--destructive) / var(--tw-text-opacity, 1))}.text-destructive-foreground{--tw-text-opacity: 1;color:hsl(var(--destructive-foreground) / var(--tw-text-opacity, 1))}.text-foreground{--tw-text-opacity: 1;color:hsl(var(--foreground) / var(--tw-text-opacity, 1))}.text-foreground\/45{color:hsl(var(--foreground) / .45)}.text-foreground\/50{color:hsl(var(--foreground) / .5)}.text-foreground\/55{color:hsl(var(--foreground) / .55)}.text-foreground\/60{color:hsl(var(--foreground) / .6)}.text-foreground\/70{color:hsl(var(--foreground) / .7)}.text-foreground\/75{color:hsl(var(--foreground) / .75)}.text-foreground\/80{color:hsl(var(--foreground) / .8)}.text-foreground\/90{color:hsl(var(--foreground) / .9)}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-muted-foreground{--tw-text-opacity: 1;color:hsl(var(--muted-foreground) / var(--tw-text-opacity, 1))}.text-muted-foreground\/60{color:hsl(var(--muted-foreground) / .6)}.text-popover-foreground{--tw-text-opacity: 1;color:hsl(var(--popover-foreground) / var(--tw-text-opacity, 1))}.text-primary{--tw-text-opacity: 1;color:hsl(var(--primary) / var(--tw-text-opacity, 1))}.text-primary-foreground{--tw-text-opacity: 1;color:hsl(var(--primary-foreground) / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-secondary-foreground{--tw-text-opacity: 1;color:hsl(var(--secondary-foreground) / var(--tw-text-opacity, 1))}.text-sidebar-foreground{--tw-text-opacity: 1;color:hsl(var(--sidebar-foreground) / var(--tw-text-opacity, 1))}.text-sidebar-foreground\/70{color:hsl(var(--sidebar-foreground) / .7)}.text-success-foreground{--tw-text-opacity: 1;color:hsl(var(--success-foreground) / var(--tw-text-opacity, 1))}.text-success-foreground\/75{color:hsl(var(--success-foreground) / .75)}.text-warning-foreground{--tw-text-opacity: 1;color:hsl(var(--warning-foreground) / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.decoration-border{text-decoration-color:hsl(var(--border) / 1)}.underline-offset-2{text-underline-offset:2px}.accent-foreground{accent-color:hsl(var(--foreground) / 1)}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-90{opacity:.9}.shadow-\[0_0_0_1px_hsl\(var\(--sidebar-border\)\)\]{--tw-shadow: 0 0 0 1px hsl(var(--sidebar-border));--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-none{--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.outline-2{outline-width:2px}.outline-offset-2{outline-offset:2px}.outline-transparent{outline-color:transparent}.ring-0{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-ring{--tw-ring-opacity: 1;--tw-ring-color: hsl(var(--ring) / var(--tw-ring-opacity, 1))}.ring-sidebar-ring{--tw-ring-opacity: 1;--tw-ring-color: hsl(var(--sidebar-ring) / var(--tw-ring-opacity, 1))}.ring-offset-background{--tw-ring-offset-color: hsl(var(--background) / 1)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\[margin\,opacity\]{transition-property:margin,opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-1000{transition-duration:1s}.duration-200{transition-duration:.2s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-linear{transition-timing-function:linear}@keyframes enter{0%{opacity:var(--tw-enter-opacity, 1);transform:translate3d(var(--tw-enter-translate-x, 0),var(--tw-enter-translate-y, 0),0) scale3d(var(--tw-enter-scale, 1),var(--tw-enter-scale, 1),var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity, 1);transform:translate3d(var(--tw-exit-translate-x, 0),var(--tw-exit-translate-y, 0),0) scale3d(var(--tw-exit-scale, 1),var(--tw-exit-scale, 1),var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0))}}.animate-in{animation-name:enter;animation-duration:.15s;--tw-enter-opacity: initial;--tw-enter-scale: initial;--tw-enter-rotate: initial;--tw-enter-translate-x: initial;--tw-enter-translate-y: initial}.fade-in-0{--tw-enter-opacity: 0}.fade-in-80{--tw-enter-opacity: .8}.zoom-in-95{--tw-enter-scale: .95}.duration-1000{animation-duration:1s}.duration-200{animation-duration:.2s}.ease-in-out{animation-timing-function:cubic-bezier(.4,0,.2,1)}.ease-linear{animation-timing-function:linear}.running{animation-play-state:running}.paused{animation-play-state:paused}.\[border-color\:var\(--badge-outline\)\]{border-color:var(--badge-outline)}.\[border-color\:var\(--button-outline\)\]{border-color:var(--button-outline)}:root{--button-outline: rgba(0,0,0, .1);--badge-outline: rgba(0,0,0, .05);--opaque-button-border-intensity: -8;--elevate-1: rgba(0,0,0, .03);--elevate-2: rgba(0,0,0, .08);--background: 0 0% 100%;--foreground: 0 0% 5%;--border: 0 0% 88%;--card: 0 0% 100%;--card-foreground: 0 0% 5%;--card-border: 0 0% 90%;--sidebar: 0 0% 97%;--sidebar-foreground: 0 0% 5%;--sidebar-border: 0 0% 90%;--sidebar-primary: 0 0% 5%;--sidebar-primary-foreground: 0 0% 100%;--sidebar-accent: 0 0% 93%;--sidebar-accent-foreground: 0 0% 5%;--sidebar-ring: 0 0% 5%;--popover: 0 0% 100%;--popover-foreground: 0 0% 5%;--popover-border: 0 0% 88%;--primary: 0 0% 5%;--primary-foreground: 0 0% 100%;--secondary: 0 0% 94%;--secondary-foreground: 0 0% 5%;--muted: 0 0% 95%;--muted-foreground: 0 0% 40%;--accent: 0 0% 95%;--accent-foreground: 0 0% 5%;--destructive: 0 0% 30%;--destructive-foreground: 0 0% 100%;--success: 142 64% 30%;--success-foreground: 142 72% 20%;--success-muted: 142 44% 94%;--success-border: 142 32% 68%;--warning: 38 92% 34%;--warning-foreground: 38 78% 22%;--warning-muted: 38 100% 94%;--warning-border: 38 78% 68%;--input: 0 0% 80%;--ring: 0 0% 5%;--chart-1: 0 0% 15%;--chart-2: 0 0% 30%;--chart-3: 0 0% 45%;--chart-4: 0 0% 60%;--chart-5: 0 0% 75%;--font-sans: "JetBrains Mono", "Geist Mono", "SF Mono", Menlo, monospace;--font-serif: Georgia, serif;--font-mono: "JetBrains Mono", "Geist Mono", "SF Mono", Menlo, monospace;--radius: 0rem;--shadow-2xs: none;--shadow-xs: none;--shadow-sm: none;--shadow: none;--shadow-md: none;--shadow-lg: none;--shadow-xl: none;--shadow-2xl: none;--tracking-normal: 0em;--spacing: .25rem;--sidebar-primary-border: hsl(var(--sidebar-primary));--sidebar-accent-border: hsl(var(--sidebar-accent));--primary-border: hsl(var(--primary));--secondary-border: hsl(var(--secondary));--muted-border: hsl(var(--muted));--accent-border: hsl(var(--accent));--destructive-border: hsl(var(--destructive))}.dark{--button-outline: rgba(255,255,255, .1);--badge-outline: rgba(255,255,255, .05);--opaque-button-border-intensity: 9;--elevate-1: rgba(255,255,255, .04);--elevate-2: rgba(255,255,255, .09);--background: 0 0% 4%;--foreground: 0 0% 90%;--border: 0 0% 15%;--card: 0 0% 6%;--card-foreground: 0 0% 90%;--card-border: 0 0% 12%;--sidebar: 0 0% 6%;--sidebar-foreground: 0 0% 90%;--sidebar-border: 0 0% 14%;--sidebar-primary: 0 0% 90%;--sidebar-primary-foreground: 0 0% 4%;--sidebar-accent: 0 0% 12%;--sidebar-accent-foreground: 0 0% 90%;--sidebar-ring: 0 0% 90%;--popover: 0 0% 8%;--popover-foreground: 0 0% 90%;--popover-border: 0 0% 16%;--primary: 0 0% 90%;--primary-foreground: 0 0% 4%;--secondary: 0 0% 14%;--secondary-foreground: 0 0% 90%;--muted: 0 0% 12%;--muted-foreground: 0 0% 55%;--accent: 0 0% 14%;--accent-foreground: 0 0% 90%;--destructive: 0 0% 70%;--destructive-foreground: 0 0% 4%;--success: 142 70% 58%;--success-foreground: 142 76% 76%;--success-muted: 142 32% 10%;--success-border: 142 40% 34%;--warning: 43 96% 68%;--warning-foreground: 43 96% 82%;--warning-muted: 43 42% 12%;--warning-border: 43 50% 34%;--input: 0 0% 25%;--ring: 0 0% 90%;--sidebar-primary-border: hsl(var(--sidebar-primary));--sidebar-accent-border: hsl(var(--sidebar-accent));--primary-border: hsl(var(--primary));--secondary-border: hsl(var(--secondary));--muted-border: hsl(var(--muted));--accent-border: hsl(var(--accent));--destructive-border: hsl(var(--destructive))}.file\:border-0::file-selector-button{border-width:0px}.file\:bg-transparent::file-selector-button{background-color:transparent}.file\:text-sm::file-selector-button{font-size:.875rem;line-height:1.25rem}.file\:font-medium::file-selector-button{font-weight:500}.file\:text-foreground::file-selector-button{--tw-text-opacity: 1;color:hsl(var(--foreground) / var(--tw-text-opacity, 1))}.placeholder\:text-muted-foreground::-moz-placeholder{--tw-text-opacity: 1;color:hsl(var(--muted-foreground) / var(--tw-text-opacity, 1))}.placeholder\:text-muted-foreground::placeholder{--tw-text-opacity: 1;color:hsl(var(--muted-foreground) / var(--tw-text-opacity, 1))}.placeholder\:text-muted-foreground\/50::-moz-placeholder{color:hsl(var(--muted-foreground) / .5)}.placeholder\:text-muted-foreground\/50::placeholder{color:hsl(var(--muted-foreground) / .5)}.after\:pointer-events-none:after{content:var(--tw-content);pointer-events:none}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:-inset-2:after{content:var(--tw-content);inset:-.5rem}.after\:inset-0:after{content:var(--tw-content);inset:0}.after\:inset-y-0:after{content:var(--tw-content);top:0;bottom:0}.after\:left-1\/2:after{content:var(--tw-content);left:50%}.after\:block:after{content:var(--tw-content);display:block}.after\:w-1:after{content:var(--tw-content);width:.25rem}.after\:w-\[2px\]:after{content:var(--tw-content);width:2px}.after\:-translate-x-1\/2:after{content:var(--tw-content);--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.after\:rounded-full:after{content:var(--tw-content);border-radius:9999px}.after\:border:after{content:var(--tw-content);border-width:1px}.after\:border-black\/10:after{content:var(--tw-content);border-color:#0000001a}.after\:content-\[\'\'\]:after{--tw-content: "";content:var(--tw-content)}.first\:rounded-l-md:first-child{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.first\:border-l:first-child{border-left-width:1px}.last\:rounded-r-md:last-child{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.last\:border-b-0:last-child{border-bottom-width:0px}.focus-within\:relative:focus-within{position:relative}.focus-within\:z-20:focus-within{z-index:20}.focus-within\:ring-1:focus-within{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-within\:ring-ring:focus-within{--tw-ring-opacity: 1;--tw-ring-color: hsl(var(--ring) / var(--tw-ring-opacity, 1))}.focus-within\:ring-offset-1:focus-within{--tw-ring-offset-width: 1px}.focus-within\:ring-offset-background:focus-within{--tw-ring-offset-color: hsl(var(--background) / 1)}.hover\:border-foreground:hover{--tw-border-opacity: 1;border-color:hsl(var(--foreground) / var(--tw-border-opacity, 1))}.hover\:bg-accent:hover{--tw-bg-opacity: 1;background-color:hsl(var(--accent) / var(--tw-bg-opacity, 1))}.hover\:bg-foreground:hover{--tw-bg-opacity: 1;background-color:hsl(var(--foreground) / var(--tw-bg-opacity, 1))}.hover\:bg-muted:hover{--tw-bg-opacity: 1;background-color:hsl(var(--muted) / var(--tw-bg-opacity, 1))}.hover\:bg-muted\/30:hover{background-color:hsl(var(--muted) / .3)}.hover\:bg-muted\/50:hover{background-color:hsl(var(--muted) / .5)}.hover\:bg-primary:hover{--tw-bg-opacity: 1;background-color:hsl(var(--primary) / var(--tw-bg-opacity, 1))}.hover\:bg-secondary:hover{--tw-bg-opacity: 1;background-color:hsl(var(--secondary) / var(--tw-bg-opacity, 1))}.hover\:bg-sidebar-accent:hover{--tw-bg-opacity: 1;background-color:hsl(var(--sidebar-accent) / var(--tw-bg-opacity, 1))}.hover\:bg-success-muted\/80:hover{background-color:hsl(var(--success-muted) / .8)}.hover\:text-accent-foreground:hover{--tw-text-opacity: 1;color:hsl(var(--accent-foreground) / var(--tw-text-opacity, 1))}.hover\:text-background:hover{--tw-text-opacity: 1;color:hsl(var(--background) / var(--tw-text-opacity, 1))}.hover\:text-foreground:hover{--tw-text-opacity: 1;color:hsl(var(--foreground) / var(--tw-text-opacity, 1))}.hover\:text-muted-foreground:hover{--tw-text-opacity: 1;color:hsl(var(--muted-foreground) / var(--tw-text-opacity, 1))}.hover\:text-primary-foreground:hover{--tw-text-opacity: 1;color:hsl(var(--primary-foreground) / var(--tw-text-opacity, 1))}.hover\:text-sidebar-accent-foreground:hover{--tw-text-opacity: 1;color:hsl(var(--sidebar-accent-foreground) / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-\[0_0_0_1px_hsl\(var\(--sidebar-accent\)\)\]:hover{--tw-shadow: 0 0 0 1px hsl(var(--sidebar-accent));--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:after\:bg-sidebar-border:hover:after{content:var(--tw-content);--tw-bg-opacity: 1;background-color:hsl(var(--sidebar-border) / var(--tw-bg-opacity, 1))}.focus\:border-foreground:focus{--tw-border-opacity: 1;border-color:hsl(var(--foreground) / var(--tw-border-opacity, 1))}.focus\:bg-accent:focus{--tw-bg-opacity: 1;background-color:hsl(var(--accent) / var(--tw-bg-opacity, 1))}.focus\:bg-muted:focus{--tw-bg-opacity: 1;background-color:hsl(var(--muted) / var(--tw-bg-opacity, 1))}.focus\:bg-primary:focus{--tw-bg-opacity: 1;background-color:hsl(var(--primary) / var(--tw-bg-opacity, 1))}.focus\:text-accent-foreground:focus{--tw-text-opacity: 1;color:hsl(var(--accent-foreground) / var(--tw-text-opacity, 1))}.focus\:text-primary-foreground:focus{--tw-text-opacity: 1;color:hsl(var(--primary-foreground) / var(--tw-text-opacity, 1))}.focus\:opacity-100:focus{opacity:1}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-ring:focus{--tw-ring-opacity: 1;--tw-ring-color: hsl(var(--ring) / var(--tw-ring-opacity, 1))}.focus\:ring-offset-2:focus{--tw-ring-offset-width: 2px}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-1:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-inset:focus-visible{--tw-ring-inset: inset}.focus-visible\:ring-ring:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: hsl(var(--ring) / var(--tw-ring-opacity, 1))}.focus-visible\:ring-offset-1:focus-visible{--tw-ring-offset-width: 1px}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.focus-visible\:ring-offset-background:focus-visible{--tw-ring-offset-color: hsl(var(--background) / 1)}.active\:bg-sidebar-accent:active{--tw-bg-opacity: 1;background-color:hsl(var(--sidebar-accent) / var(--tw-bg-opacity, 1))}.active\:text-sidebar-accent-foreground:active{--tw-text-opacity: 1;color:hsl(var(--sidebar-accent-foreground) / var(--tw-text-opacity, 1))}.active\:shadow-none:active{--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-default:disabled{cursor:default}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-100:disabled{opacity:1}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:hover\:bg-transparent:hover:disabled{background-color:transparent}.group\/menu-item:focus-within .group-focus-within\/menu-item\:opacity-100{opacity:1}.group\/menu-item:hover .group-hover\/menu-item\:opacity-100,.group:hover .group-hover\:opacity-100{opacity:1}.group.destructive .group-\[\.destructive\]\:border-muted\/40{border-color:hsl(var(--muted) / .4)}.group.destructive .group-\[\.destructive\]\:text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.group.destructive .group-\[\.destructive\]\:hover\:border-destructive\/30:hover{border-color:hsl(var(--destructive) / .3)}.group.destructive .group-\[\.destructive\]\:hover\:bg-destructive:hover{--tw-bg-opacity: 1;background-color:hsl(var(--destructive) / var(--tw-bg-opacity, 1))}.group.destructive .group-\[\.destructive\]\:hover\:text-destructive-foreground:hover{--tw-text-opacity: 1;color:hsl(var(--destructive-foreground) / var(--tw-text-opacity, 1))}.group.destructive .group-\[\.destructive\]\:hover\:text-red-50:hover{--tw-text-opacity: 1;color:rgb(254 242 242 / var(--tw-text-opacity, 1))}.group.destructive .group-\[\.destructive\]\:focus\:ring-destructive:focus{--tw-ring-opacity: 1;--tw-ring-color: hsl(var(--destructive) / var(--tw-ring-opacity, 1))}.group.destructive .group-\[\.destructive\]\:focus\:ring-red-400:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(248 113 113 / var(--tw-ring-opacity, 1))}.group.destructive .group-\[\.destructive\]\:focus\:ring-offset-red-600:focus{--tw-ring-offset-color: #dc2626}.peer\/menu-button:hover~.peer-hover\/menu-button\:text-sidebar-accent-foreground{--tw-text-opacity: 1;color:hsl(var(--sidebar-accent-foreground) / var(--tw-text-opacity, 1))}.peer:disabled~.peer-disabled\:cursor-not-allowed{cursor:not-allowed}.peer:disabled~.peer-disabled\:opacity-70{opacity:.7}.has-\[\:disabled\]\:opacity-50:has(:disabled){opacity:.5}.aria-disabled\:pointer-events-none[aria-disabled=true]{pointer-events:none}.aria-disabled\:opacity-50[aria-disabled=true]{opacity:.5}.aria-selected\:bg-accent[aria-selected=true]{--tw-bg-opacity: 1;background-color:hsl(var(--accent) / var(--tw-bg-opacity, 1))}.aria-selected\:bg-accent\/50[aria-selected=true]{background-color:hsl(var(--accent) / .5)}.aria-selected\:text-accent-foreground[aria-selected=true]{--tw-text-opacity: 1;color:hsl(var(--accent-foreground) / var(--tw-text-opacity, 1))}.aria-selected\:text-muted-foreground[aria-selected=true]{--tw-text-opacity: 1;color:hsl(var(--muted-foreground) / var(--tw-text-opacity, 1))}.aria-selected\:opacity-100[aria-selected=true]{opacity:1}.data-\[disabled\=true\]\:pointer-events-none[data-disabled=true],.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[panel-group-direction\=vertical\]\:h-px[data-panel-group-direction=vertical]{height:1px}.data-\[panel-group-direction\=vertical\]\:w-full[data-panel-group-direction=vertical]{width:100%}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=checked\]\:translate-x-5[data-state=checked]{--tw-translate-x: 1.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=unchecked\]\:translate-x-0[data-state=unchecked],.data-\[swipe\=cancel\]\:translate-x-0[data-swipe=cancel]{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[swipe\=end\]\:translate-x-\[var\(--radix-toast-swipe-end-x\)\][data-swipe=end]{--tw-translate-x: var(--radix-toast-swipe-end-x);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[swipe\=move\]\:translate-x-\[var\(--radix-toast-swipe-move-x\)\][data-swipe=move]{--tw-translate-x: var(--radix-toast-swipe-move-x);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes accordion-up{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-2px)}}.data-\[state\=closed\]\:animate-accordion-up[data-state=closed]{animation:accordion-up .2s ease-out}@keyframes accordion-down{0%{opacity:0;transform:translateY(-2px)}to{opacity:1;transform:translateY(0)}}.data-\[state\=open\]\:animate-accordion-down[data-state=open]{animation:accordion-down .2s ease-out}.data-\[panel-group-direction\=vertical\]\:flex-col[data-panel-group-direction=vertical]{flex-direction:column}.data-\[active\=true\]\:bg-sidebar-accent[data-active=true]{--tw-bg-opacity: 1;background-color:hsl(var(--sidebar-accent) / var(--tw-bg-opacity, 1))}.data-\[selected\=\'true\'\]\:bg-accent[data-selected=true]{--tw-bg-opacity: 1;background-color:hsl(var(--accent) / var(--tw-bg-opacity, 1))}.data-\[state\=active\]\:bg-background[data-state=active]{--tw-bg-opacity: 1;background-color:hsl(var(--background) / var(--tw-bg-opacity, 1))}.data-\[state\=checked\]\:bg-primary[data-state=checked]{--tw-bg-opacity: 1;background-color:hsl(var(--primary) / var(--tw-bg-opacity, 1))}.data-\[state\=on\]\:bg-accent[data-state=on],.data-\[state\=open\]\:bg-accent[data-state=open]{--tw-bg-opacity: 1;background-color:hsl(var(--accent) / var(--tw-bg-opacity, 1))}.data-\[state\=open\]\:bg-accent\/50[data-state=open]{background-color:hsl(var(--accent) / .5)}.data-\[state\=open\]\:bg-secondary[data-state=open]{--tw-bg-opacity: 1;background-color:hsl(var(--secondary) / var(--tw-bg-opacity, 1))}.data-\[state\=selected\]\:bg-muted[data-state=selected]{--tw-bg-opacity: 1;background-color:hsl(var(--muted) / var(--tw-bg-opacity, 1))}.data-\[state\=unchecked\]\:bg-input[data-state=unchecked]{--tw-bg-opacity: 1;background-color:hsl(var(--input) / var(--tw-bg-opacity, 1))}.data-\[active\=true\]\:font-medium[data-active=true]{font-weight:500}.data-\[active\=true\]\:text-sidebar-accent-foreground[data-active=true]{--tw-text-opacity: 1;color:hsl(var(--sidebar-accent-foreground) / var(--tw-text-opacity, 1))}.data-\[placeholder\]\:text-muted-foreground[data-placeholder]{--tw-text-opacity: 1;color:hsl(var(--muted-foreground) / var(--tw-text-opacity, 1))}.data-\[selected\=true\]\:text-accent-foreground[data-selected=true]{--tw-text-opacity: 1;color:hsl(var(--accent-foreground) / var(--tw-text-opacity, 1))}.data-\[state\=active\]\:text-foreground[data-state=active]{--tw-text-opacity: 1;color:hsl(var(--foreground) / var(--tw-text-opacity, 1))}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{--tw-text-opacity: 1;color:hsl(var(--primary-foreground) / var(--tw-text-opacity, 1))}.data-\[state\=on\]\:text-accent-foreground[data-state=on],.data-\[state\=open\]\:text-accent-foreground[data-state=open]{--tw-text-opacity: 1;color:hsl(var(--accent-foreground) / var(--tw-text-opacity, 1))}.data-\[state\=open\]\:text-muted-foreground[data-state=open]{--tw-text-opacity: 1;color:hsl(var(--muted-foreground) / var(--tw-text-opacity, 1))}.data-\[disabled\=true\]\:opacity-50[data-disabled=true],.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[state\=open\]\:opacity-100[data-state=open]{opacity:1}.data-\[state\=active\]\:shadow-sm[data-state=active]{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.data-\[swipe\=move\]\:transition-none[data-swipe=move]{transition-property:none}.data-\[state\=closed\]\:duration-300[data-state=closed]{transition-duration:.3s}.data-\[state\=open\]\:duration-500[data-state=open]{transition-duration:.5s}.data-\[motion\^\=from-\]\:animate-in[data-motion^=from-],.data-\[state\=open\]\:animate-in[data-state=open],.data-\[state\=visible\]\:animate-in[data-state=visible]{animation-name:enter;animation-duration:.15s;--tw-enter-opacity: initial;--tw-enter-scale: initial;--tw-enter-rotate: initial;--tw-enter-translate-x: initial;--tw-enter-translate-y: initial}.data-\[motion\^\=to-\]\:animate-out[data-motion^=to-],.data-\[state\=closed\]\:animate-out[data-state=closed],.data-\[state\=hidden\]\:animate-out[data-state=hidden],.data-\[swipe\=end\]\:animate-out[data-swipe=end]{animation-name:exit;animation-duration:.15s;--tw-exit-opacity: initial;--tw-exit-scale: initial;--tw-exit-rotate: initial;--tw-exit-translate-x: initial;--tw-exit-translate-y: initial}.data-\[motion\^\=from-\]\:fade-in[data-motion^=from-]{--tw-enter-opacity: 0}.data-\[motion\^\=to-\]\:fade-out[data-motion^=to-],.data-\[state\=closed\]\:fade-out-0[data-state=closed]{--tw-exit-opacity: 0}.data-\[state\=closed\]\:fade-out-80[data-state=closed]{--tw-exit-opacity: .8}.data-\[state\=hidden\]\:fade-out[data-state=hidden]{--tw-exit-opacity: 0}.data-\[state\=open\]\:fade-in-0[data-state=open],.data-\[state\=visible\]\:fade-in[data-state=visible]{--tw-enter-opacity: 0}.data-\[state\=closed\]\:zoom-out-95[data-state=closed]{--tw-exit-scale: .95}.data-\[state\=open\]\:zoom-in-90[data-state=open]{--tw-enter-scale: .9}.data-\[state\=open\]\:zoom-in-95[data-state=open]{--tw-enter-scale: .95}.data-\[motion\=from-end\]\:slide-in-from-right-52[data-motion=from-end]{--tw-enter-translate-x: 13rem}.data-\[motion\=from-start\]\:slide-in-from-left-52[data-motion=from-start]{--tw-enter-translate-x: -13rem}.data-\[motion\=to-end\]\:slide-out-to-right-52[data-motion=to-end]{--tw-exit-translate-x: 13rem}.data-\[motion\=to-start\]\:slide-out-to-left-52[data-motion=to-start]{--tw-exit-translate-x: -13rem}.data-\[side\=bottom\]\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y: -.5rem}.data-\[side\=left\]\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x: .5rem}.data-\[side\=right\]\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x: -.5rem}.data-\[side\=top\]\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y: .5rem}.data-\[state\=closed\]\:slide-out-to-bottom[data-state=closed]{--tw-exit-translate-y: 100%}.data-\[state\=closed\]\:slide-out-to-left[data-state=closed]{--tw-exit-translate-x: -100%}.data-\[state\=closed\]\:slide-out-to-left-1\/2[data-state=closed]{--tw-exit-translate-x: -50%}.data-\[state\=closed\]\:slide-out-to-right[data-state=closed],.data-\[state\=closed\]\:slide-out-to-right-full[data-state=closed]{--tw-exit-translate-x: 100%}.data-\[state\=closed\]\:slide-out-to-top[data-state=closed]{--tw-exit-translate-y: -100%}.data-\[state\=closed\]\:slide-out-to-top-\[48\%\][data-state=closed]{--tw-exit-translate-y: -48%}.data-\[state\=open\]\:slide-in-from-bottom[data-state=open]{--tw-enter-translate-y: 100%}.data-\[state\=open\]\:slide-in-from-left[data-state=open]{--tw-enter-translate-x: -100%}.data-\[state\=open\]\:slide-in-from-left-1\/2[data-state=open]{--tw-enter-translate-x: -50%}.data-\[state\=open\]\:slide-in-from-right[data-state=open]{--tw-enter-translate-x: 100%}.data-\[state\=open\]\:slide-in-from-top[data-state=open]{--tw-enter-translate-y: -100%}.data-\[state\=open\]\:slide-in-from-top-\[48\%\][data-state=open]{--tw-enter-translate-y: -48%}.data-\[state\=open\]\:slide-in-from-top-full[data-state=open]{--tw-enter-translate-y: -100%}.data-\[state\=closed\]\:duration-300[data-state=closed]{animation-duration:.3s}.data-\[state\=open\]\:duration-500[data-state=open]{animation-duration:.5s}.data-\[panel-group-direction\=vertical\]\:after\:left-0[data-panel-group-direction=vertical]:after{content:var(--tw-content);left:0}.data-\[panel-group-direction\=vertical\]\:after\:h-1[data-panel-group-direction=vertical]:after{content:var(--tw-content);height:.25rem}.data-\[panel-group-direction\=vertical\]\:after\:w-full[data-panel-group-direction=vertical]:after{content:var(--tw-content);width:100%}.data-\[panel-group-direction\=vertical\]\:after\:-translate-y-1\/2[data-panel-group-direction=vertical]:after{content:var(--tw-content);--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[panel-group-direction\=vertical\]\:after\:translate-x-0[data-panel-group-direction=vertical]:after{content:var(--tw-content);--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=open\]\:hover\:bg-accent:hover[data-state=open]{--tw-bg-opacity: 1;background-color:hsl(var(--accent) / var(--tw-bg-opacity, 1))}.data-\[state\=open\]\:hover\:bg-sidebar-accent:hover[data-state=open]{--tw-bg-opacity: 1;background-color:hsl(var(--sidebar-accent) / var(--tw-bg-opacity, 1))}.data-\[state\=open\]\:hover\:text-sidebar-accent-foreground:hover[data-state=open]{--tw-text-opacity: 1;color:hsl(var(--sidebar-accent-foreground) / var(--tw-text-opacity, 1))}.data-\[state\=open\]\:focus\:bg-accent:focus[data-state=open]{--tw-bg-opacity: 1;background-color:hsl(var(--accent) / var(--tw-bg-opacity, 1))}.group[data-collapsible=offcanvas] .group-data-\[collapsible\=offcanvas\]\:left-\[calc\(var\(--sidebar-width\)\*-1\)\]{left:calc(var(--sidebar-width) * -1)}.group[data-collapsible=offcanvas] .group-data-\[collapsible\=offcanvas\]\:right-\[calc\(var\(--sidebar-width\)\*-1\)\]{right:calc(var(--sidebar-width) * -1)}.group[data-side=left] .group-data-\[side\=left\]\:-right-4{right:-1rem}.group[data-side=right] .group-data-\[side\=right\]\:left-0{left:0}.group[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:-mt-8{margin-top:-2rem}.group[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:hidden{display:none}.group[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:w-\[calc\(var\(--sidebar-width-icon\)\+var\(--spacing-4\)\)\]{width:calc(var(--sidebar-width-icon) + var(--spacing-4))}.group[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:w-\[calc\(var\(--sidebar-width-icon\)\+var\(--spacing-4\)\+2px\)\]{width:calc(var(--sidebar-width-icon) + var(--spacing-4) + 2px)}.group[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:w-\[var\(--sidebar-width-icon\)\]{width:var(--sidebar-width-icon)}.group[data-collapsible=offcanvas] .group-data-\[collapsible\=offcanvas\]\:w-0{width:0px}.group[data-collapsible=offcanvas] .group-data-\[collapsible\=offcanvas\]\:translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group[data-side=right] .group-data-\[side\=right\]\:rotate-180,.group[data-state=open] .group-data-\[state\=open\]\:rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:overflow-hidden{overflow:hidden}.group[data-variant=floating] .group-data-\[variant\=floating\]\:rounded-lg{border-radius:.5625rem}.group[data-variant=floating] .group-data-\[variant\=floating\]\:border{border-width:1px}.group[data-side=left] .group-data-\[side\=left\]\:border-r{border-right-width:1px}.group[data-side=right] .group-data-\[side\=right\]\:border-l{border-left-width:1px}.group[data-variant=floating] .group-data-\[variant\=floating\]\:border-sidebar-border{--tw-border-opacity: 1;border-color:hsl(var(--sidebar-border) / var(--tw-border-opacity, 1))}.group[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:opacity-0{opacity:0}.group[data-variant=floating] .group-data-\[variant\=floating\]\:shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.group[data-collapsible=offcanvas] .group-data-\[collapsible\=offcanvas\]\:after\:left-full:after{content:var(--tw-content);left:100%}.group[data-collapsible=offcanvas] .hover\:group-data-\[collapsible\=offcanvas\]\:bg-sidebar:hover{--tw-bg-opacity: 1;background-color:hsl(var(--sidebar) / var(--tw-bg-opacity, 1))}.peer\/menu-button[data-size=default]~.peer-data-\[size\=default\]\/menu-button\:top-1\.5{top:.375rem}.peer\/menu-button[data-size=lg]~.peer-data-\[size\=lg\]\/menu-button\:top-2\.5{top:.625rem}.peer\/menu-button[data-size=sm]~.peer-data-\[size\=sm\]\/menu-button\:top-1{top:.25rem}.peer\/menu-button[data-active=true]~.peer-data-\[active\=true\]\/menu-button\:text-sidebar-accent-foreground{--tw-text-opacity: 1;color:hsl(var(--sidebar-accent-foreground) / var(--tw-text-opacity, 1))}.dark\:border-destructive:is(.dark *){--tw-border-opacity: 1;border-color:hsl(var(--destructive) / var(--tw-border-opacity, 1))}.dark\:after\:border-white\/10:is(.dark *):after{content:var(--tw-content);border-color:#ffffff1a}@media(min-width:640px){.sm\:bottom-0{bottom:0}.sm\:right-0{right:0}.sm\:top-auto{top:auto}.sm\:mt-0{margin-top:0}.sm\:flex{display:flex}.sm\:max-w-sm{max-width:24rem}.sm\:flex-row{flex-direction:row}.sm\:flex-col{flex-direction:column}.sm\:justify-end{justify-content:flex-end}.sm\:gap-2\.5{gap:.625rem}.sm\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.sm\:space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(1rem * var(--tw-space-x-reverse));margin-left:calc(1rem * calc(1 - var(--tw-space-x-reverse)))}.sm\:space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(0px * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0px * var(--tw-space-y-reverse))}.sm\:rounded-lg{border-radius:.5625rem}.sm\:text-left{text-align:left}.data-\[state\=open\]\:sm\:slide-in-from-bottom-full[data-state=open]{--tw-enter-translate-y: 100%}}@media(min-width:768px){.md\:absolute{position:absolute}.md\:block{display:block}.md\:flex{display:flex}.md\:w-\[var\(--radix-navigation-menu-viewport-width\)\]{width:var(--radix-navigation-menu-viewport-width)}.md\:w-auto{width:auto}.md\:max-w-\[420px\]{max-width:420px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:justify-between{justify-content:space-between}.md\:text-sm{font-size:.875rem;line-height:1.25rem}.md\:opacity-0{opacity:0}.md\:after\:hidden:after{content:var(--tw-content);display:none}.peer[data-variant=inset]~.md\:peer-data-\[variant\=inset\]\:m-2{margin:.5rem}.peer[data-variant=inset]~.md\:peer-data-\[variant\=inset\]\:ml-0{margin-left:0}.peer[data-variant=inset][data-state=collapsed]~.md\:peer-data-\[variant\=inset\]\:peer-data-\[state\=collapsed\]\:ml-2{margin-left:.5rem}.peer[data-variant=inset]~.md\:peer-data-\[variant\=inset\]\:rounded-xl{border-radius:.75rem}.peer[data-variant=inset]~.md\:peer-data-\[variant\=inset\]\:shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}}@media(min-width:1024px){.lg\:h-screen{height:100vh}.lg\:max-h-none{max-height:none}.lg\:min-h-0{min-height:0px}.lg\:w-80{width:20rem}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:justify-between{justify-content:space-between}.lg\:overflow-hidden{overflow:hidden}.lg\:border-b-0{border-bottom-width:0px}.lg\:border-l{border-left-width:1px}.lg\:border-r{border-right-width:1px}.lg\:border-t-0{border-top-width:0px}}.\[\&\:has\(\[aria-selected\]\)\]\:bg-accent:has([aria-selected]){--tw-bg-opacity: 1;background-color:hsl(var(--accent) / var(--tw-bg-opacity, 1))}.first\:\[\&\:has\(\[aria-selected\]\)\]\:rounded-l-md:has([aria-selected]):first-child{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.last\:\[\&\:has\(\[aria-selected\]\)\]\:rounded-r-md:has([aria-selected]):last-child{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.\[\&\:has\(\[aria-selected\]\.day-outside\)\]\:bg-accent\/50:has([aria-selected].day-outside){background-color:hsl(var(--accent) / .5)}.\[\&\:has\(\[aria-selected\]\.day-range-end\)\]\:rounded-r-md:has([aria-selected].day-range-end){border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:0}.\[\&\>button\]\:hidden>button{display:none}.\[\&\>span\:last-child\]\:truncate>span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.\[\&\>span\]\:line-clamp-1>span{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.\[\&\>svg\+div\]\:translate-y-\[-3px\]>svg+div{--tw-translate-y: -3px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\[\&\>svg\]\:absolute>svg{position:absolute}.\[\&\>svg\]\:left-4>svg{left:1rem}.\[\&\>svg\]\:top-4>svg{top:1rem}.\[\&\>svg\]\:size-4>svg{width:1rem;height:1rem}.\[\&\>svg\]\:h-2\.5>svg{height:.625rem}.\[\&\>svg\]\:h-3>svg{height:.75rem}.\[\&\>svg\]\:h-3\.5>svg{height:.875rem}.\[\&\>svg\]\:h-4>svg{height:1rem}.\[\&\>svg\]\:w-2\.5>svg{width:.625rem}.\[\&\>svg\]\:w-3>svg{width:.75rem}.\[\&\>svg\]\:w-3\.5>svg{width:.875rem}.\[\&\>svg\]\:w-4>svg{width:1rem}.\[\&\>svg\]\:shrink-0>svg{flex-shrink:0}.\[\&\>svg\]\:text-destructive>svg{--tw-text-opacity: 1;color:hsl(var(--destructive) / var(--tw-text-opacity, 1))}.\[\&\>svg\]\:text-foreground>svg{--tw-text-opacity: 1;color:hsl(var(--foreground) / var(--tw-text-opacity, 1))}.\[\&\>svg\]\:text-muted-foreground>svg{--tw-text-opacity: 1;color:hsl(var(--muted-foreground) / var(--tw-text-opacity, 1))}.\[\&\>svg\]\:text-sidebar-accent-foreground>svg{--tw-text-opacity: 1;color:hsl(var(--sidebar-accent-foreground) / var(--tw-text-opacity, 1))}.\[\&\>svg\~\*\]\:pl-7>svg~*{padding-left:1.75rem}.\[\&\>tr\]\:last\:border-b-0:last-child>tr{border-bottom-width:0px}.\[\&\[data-panel-group-direction\=vertical\]\>div\]\:rotate-90[data-panel-group-direction=vertical]>div{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\[\&\[data-state\=open\]\>svg\]\:rotate-180[data-state=open]>svg{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\[\&_\.recharts-cartesian-axis-tick_text\]\:fill-muted-foreground .recharts-cartesian-axis-tick text{fill:hsl(var(--muted-foreground) / 1)}.\[\&_\.recharts-cartesian-grid_line\[stroke\=\'\#ccc\'\]\]\:stroke-border\/50 .recharts-cartesian-grid line[stroke="#ccc"]{stroke:hsl(var(--border) / .5)}.\[\&_\.recharts-curve\.recharts-tooltip-cursor\]\:stroke-border .recharts-curve.recharts-tooltip-cursor{stroke:hsl(var(--border) / 1)}.\[\&_\.recharts-dot\[stroke\=\'\#fff\'\]\]\:stroke-transparent .recharts-dot[stroke="#fff"]{stroke:transparent}.\[\&_\.recharts-layer\]\:outline-none .recharts-layer{outline:2px solid transparent;outline-offset:2px}.\[\&_\.recharts-polar-grid_\[stroke\=\'\#ccc\'\]\]\:stroke-border .recharts-polar-grid [stroke="#ccc"]{stroke:hsl(var(--border) / 1)}.\[\&_\.recharts-radial-bar-background-sector\]\:fill-muted .recharts-radial-bar-background-sector,.\[\&_\.recharts-rectangle\.recharts-tooltip-cursor\]\:fill-muted .recharts-rectangle.recharts-tooltip-cursor{fill:hsl(var(--muted) / 1)}.\[\&_\.recharts-reference-line_\[stroke\=\'\#ccc\'\]\]\:stroke-border .recharts-reference-line [stroke="#ccc"]{stroke:hsl(var(--border) / 1)}.\[\&_\.recharts-sector\[stroke\=\'\#fff\'\]\]\:stroke-transparent .recharts-sector[stroke="#fff"]{stroke:transparent}.\[\&_\.recharts-sector\]\:outline-none .recharts-sector,.\[\&_\.recharts-surface\]\:outline-none .recharts-surface{outline:2px solid transparent;outline-offset:2px}.\[\&_\[cmdk-group-heading\]\]\:px-2 [cmdk-group-heading]{padding-left:.5rem;padding-right:.5rem}.\[\&_\[cmdk-group-heading\]\]\:py-1\.5 [cmdk-group-heading]{padding-top:.375rem;padding-bottom:.375rem}.\[\&_\[cmdk-group-heading\]\]\:text-xs [cmdk-group-heading]{font-size:.75rem;line-height:1rem}.\[\&_\[cmdk-group-heading\]\]\:font-medium [cmdk-group-heading]{font-weight:500}.\[\&_\[cmdk-group-heading\]\]\:text-muted-foreground [cmdk-group-heading]{--tw-text-opacity: 1;color:hsl(var(--muted-foreground) / var(--tw-text-opacity, 1))}.\[\&_\[cmdk-group\]\:not\(\[hidden\]\)_\~\[cmdk-group\]\]\:pt-0 [cmdk-group]:not([hidden])~[cmdk-group]{padding-top:0}.\[\&_\[cmdk-group\]\]\:px-2 [cmdk-group]{padding-left:.5rem;padding-right:.5rem}.\[\&_\[cmdk-input-wrapper\]_svg\]\:h-5 [cmdk-input-wrapper] svg{height:1.25rem}.\[\&_\[cmdk-input-wrapper\]_svg\]\:w-5 [cmdk-input-wrapper] svg{width:1.25rem}.\[\&_\[cmdk-input\]\]\:h-12 [cmdk-input]{height:3rem}.\[\&_\[cmdk-item\]\]\:px-2 [cmdk-item]{padding-left:.5rem;padding-right:.5rem}.\[\&_\[cmdk-item\]\]\:py-3 [cmdk-item]{padding-top:.75rem;padding-bottom:.75rem}.\[\&_\[cmdk-item\]_svg\]\:h-5 [cmdk-item] svg{height:1.25rem}.\[\&_\[cmdk-item\]_svg\]\:w-5 [cmdk-item] svg{width:1.25rem}.\[\&_p\]\:leading-relaxed p{line-height:1.625}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:1rem;height:1rem}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-width:0px}.\[\&_tr\]\:border-b tr{border-bottom-width:1px}[data-side=left][data-collapsible=offcanvas] .\[\[data-side\=left\]\[data-collapsible\=offcanvas\]_\&\]\:-right-2{right:-.5rem}[data-side=left][data-state=collapsed] .\[\[data-side\=left\]\[data-state\=collapsed\]_\&\]\:cursor-e-resize{cursor:e-resize}[data-side=right][data-collapsible=offcanvas] .\[\[data-side\=right\]\[data-collapsible\=offcanvas\]_\&\]\:-left-2{left:-.5rem}[data-side=right][data-state=collapsed] .\[\[data-side\=right\]\[data-state\=collapsed\]_\&\]\:cursor-w-resize{cursor:w-resize}
|