writetrack 0.11.0 → 0.12.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/README.md +100 -30
- package/dist/browser/index.js +1 -1
- package/dist/browser/viz.js +12 -12
- package/dist/browser/writetrack.wasm +0 -0
- package/dist/ckeditor/index.d.ts +2 -20
- package/dist/esm/index.d.ts +69 -4
- package/dist/esm/index.js +1 -1
- package/dist/esm/testing.d.ts +1 -1
- package/dist/esm/testing.js +1 -1
- package/dist/esm/verify.d.ts +1 -1
- package/dist/esm/viz.d.ts +38 -12
- package/dist/esm/viz.js +12 -12
- package/dist/esm/writetrack.wasm +0 -0
- package/dist/index.cjs +1 -1
- package/dist/lexical/index.d.ts +2 -20
- package/dist/lexical/index.js +1 -1
- package/dist/prosemirror/index.d.ts +2 -20
- package/dist/prosemirror/index.js +1 -1
- package/dist/quill/index.d.ts +2 -20
- package/dist/quill/index.js +1 -1
- package/dist/react/index.d.ts +2 -19
- package/dist/react/index.js +1 -1
- package/dist/slate/index.d.ts +2 -20
- package/dist/tiptap/index.d.ts +11 -21
- package/dist/viz.cjs +12 -12
- package/dist/vue/index.d.ts +2 -19
- package/dist/vue/index.js +1 -1
- package/dist/writetrack.wasm +0 -0
- package/package.json +2 -2
package/dist/browser/viz.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var et=`:host {
|
|
2
2
|
--wt-color-primary: #fbbf24;
|
|
3
3
|
--wt-color-secondary: #22d3ee;
|
|
4
4
|
--wt-color-bg: #111113;
|
|
@@ -53,7 +53,7 @@ var nt=`:host {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/* Force light text on dark tooltips regardless of chart theme */
|
|
56
|
-
[aria-label="tip"] { color: #fafafa; }`,M={fill:"#1a1a1d",stroke:"#27272a",textPadding:6,fontSize:11,fontFamily:"'JetBrains Mono', ui-monospace, monospace"};function I(n){console.warn(`[WriteTrack] ${n}`)}function vt(n){return n instanceof Error?n.message:String(n)}var k=class extends HTMLElement{constructor(){super();this._data=null;this._resizeObserver=null;this._resizeRaf=null;this.t=null;this.i=0;this.e=!1;this.a=!1;this.shadow=this.attachShadow({mode:"open"});let e=document.createElement("style");e.textContent=this.getStylesheet(),this.shadow.appendChild(e),this.container=document.createElement("div"),this.container.className="wt-chart",this.shadow.appendChild(this.container)}static get observedAttributes(){return["data","theme","label","compact"]}get compact(){return this.hasAttribute("compact")}getChartWidth(e){let r=getComputedStyle(this).getPropertyValue("--wt-chart-width").trim();return r?parseInt(r,10)||e:this.container.clientWidth||this.clientWidth||e}getChartHeight(e){let r=getComputedStyle(this).getPropertyValue("--wt-chart-height").trim();if(r)return parseInt(r,10)||e;let a=this.style.height;return a&&parseInt(a,10)||e}getStylesheet(){return nt}connectedCallback(){typeof ResizeObserver<"u"&&(this._resizeObserver=new ResizeObserver(e=>{var a,i;let r=((i=(a=e[0])==null?void 0:a.contentRect)==null?void 0:i.width)??0;r===0||r===this.i||(this.i=r,this.e&&this._data&&(this._resizeRaf&&cancelAnimationFrame(this._resizeRaf),this._resizeRaf=requestAnimationFrame(()=>{this._resizeRaf=null,this.onResize()})))}),this._resizeObserver.observe(this.container)),this.c(),typeof MutationObserver<"u"&&(this.t=new MutationObserver(()=>{this.c()}),this.t.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme"]}),document.body&&this.t.observe(document.body,{attributes:!0,attributeFilter:["data-theme"]}))}disconnectedCallback(){this.destroy()}attributeChangedCallback(e,r,a){if(e==="data"&&a)try{let i=JSON.parse(a);this.setData(i)}catch(i){I(`BaseChart: invalid JSON in data attribute: ${vt(i)}`)}(e==="theme"||e==="compact")&&this._data&&this.e&&this.safeRender()}setData(e){this._data=e,this.safeRender()}getData(){return this._data}get hasRendered(){return this.e}replaceChart(...e){for(let r of e)if(r instanceof SVGElement){r.setAttribute("role","img");let a=this.getAttribute("label")??this.tagName.toLowerCase().replace("wt-","").replace(/-/g," ")+" chart";r.setAttribute("aria-label",a)}this.container.replaceChildren(...e),this.e=!0,this.dispatchEvent(new CustomEvent("wt-render",{bubbles:!1}))}showEmptyState(e="No data"){let r=document.createElement("div");r.className="wt-empty",r.textContent=e,r.style.cssText="display:flex;align-items:center;justify-content:center;height:100%;font-family:var(--wt-scorecard-font-data,var(--wt-font-data,ui-monospace,monospace));font-size:0.625rem;color:var(--wt-scorecard-text-tertiary,var(--wt-color-text-muted,#a1a1aa));",this.container.replaceChildren(r),this.e=!1}destroy(){this._resizeRaf&&(cancelAnimationFrame(this._resizeRaf),this._resizeRaf=null),this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),this.t&&(this.t.disconnect(),this.t=null),this.container.replaceChildren(),this._data=null,this.e=!1}onResize(){this.safeRender()}safeRender(){try{this.render()}catch(e){I(`${this.constructor.name} render failed: ${vt(e)}`)}}static register(){customElements.get(this.tagName)||customElements.define(this.tagName,this)}c(){if(this.hasAttribute("theme")&&!this.a)return;let e=this.parentElement;for(;e;){let r=e.getAttribute("data-theme");if(r){this.shadow.host.setAttribute("theme",r),this.a=!0;return}e=e.parentElement}this.a&&(this.shadow.host.removeAttribute("theme"),this.a=!1)}};k.tagName="wt-base-chart";import*as H from"@observablehq/plot";var xe=5;function Ut(n){var i;let t=(((i=n.session)==null?void 0:i.events)??[]).filter(s=>s.type==="keydown"&&s.flightTime!=null&&s.flightTime>0);if(t.length<2)return[[],[]];let e=n.session.sessionStartTime,r=[],a=[];for(let s=0;s<t.length;s++){let o=Math.max(0,s-xe+1),c=0,l=0;for(let p=o;p<=s;p++)c+=t[p].flightTime,l++;let d=c/l,u=Math.round(6e4/d);r.push(Math.round((t[s].timestamp-e)/1e3*100)/100),a.push(u)}return[r,a]}var Q=class Q extends k{connectedCallback(){super.connectedCallback();let t=getComputedStyle(this);!this.style.display&&t.display==="inline"&&(this.style.display="inline-block"),!this.style.width&&(t.width==="auto"||t.width==="0px")&&(this.style.width="200px"),!this.style.height&&(t.height==="auto"||t.height==="0px")&&(this.style.height="40px")}render(){if(!this._data)return;let[t,e]=Ut(this._data);if(t.length===0){this.showEmptyState("No data");return}let r=t.map((c,l)=>({time:c,speed:e[l]})),a=this.getBoundingClientRect(),i=Math.max(a.width||200,50),s=Math.max(a.height||40,20),o=H.plot({width:i,height:s,axis:null,x:{axis:null},y:{axis:null},marks:[H.areaY(r,{x:"time",y:"speed",fill:"var(--wt-color-primary, #fbbf24)",fillOpacity:.1}),H.lineY(r,{x:"time",y:"speed",stroke:"var(--wt-color-primary, #fbbf24)",strokeWidth:1.5})],style:{background:"transparent",overflow:"visible"},margin:0,marginTop:2,marginBottom:2,marginLeft:0,marginRight:0});this.replaceChart(o)}static create(t,e){Q.register();let r=document.createElement(Q.tagName);return t.appendChild(r),r.setData(e),r}};Q.tagName="wt-sparkline";var xt=Q;import*as $ from"@observablehq/plot";var kt="monotone-x";var A={marginTop:4,marginRight:0,marginBottom:4,marginLeft:0};function N(n){let t=document.createElement("div");t.style.cssText="display:flex;flex-wrap:wrap;gap:10px;padding:6px 0 2px;font-family:var(--wt-font-data,ui-monospace,monospace);font-size:10px;color:var(--wt-color-text-muted,#a1a1aa);";for(let{label:e,color:r,shape:a}of n){let i=document.createElement("span");i.style.cssText="display:inline-flex;align-items:center;gap:4px;";let s=document.createElement("span"),o=a==="square"?"2px":"50%";s.style.cssText=`width:8px;height:8px;border-radius:${o};background:${r};flex-shrink:0;`,i.appendChild(s),i.appendChild(document.createTextNode(e)),t.appendChild(i)}return t}var E={background:"transparent",color:"var(--wt-color-text, #fafafa)",fontFamily:"var(--wt-font-data)",fontSize:"11px"},J={strokeDasharray:"4,4",strokeWidth:1};function Kt(n){var a,i,s;let t=(i=(a=n.temporalPatterns)==null?void 0:a.metrics)==null?void 0:i.speedTimeline;if(!((s=t==null?void 0:t.timestamps)!=null&&s.length))return[];let e=Math.min(t.timestamps.length,t.values.length),r=[];for(let o=0;o<e;o++)r.push({time:t.timestamps[o]/1e3,speed:t.values[o]});return r.sort((o,c)=>o.time-c.time),r}var z=class extends k{render(){if(!this._data)return;let t=Kt(this._data);if(t.length===0){this.showEmptyState("No speed data");return}let e=this.getChartWidth(640),r=this.getChartHeight(200),a=this.compact,i=[$.areaY(t,{x:"time",y:"speed",fill:"var(--wt-color-primary, #fbbf24)",fillOpacity:.15,curve:kt}),$.lineY(t,{x:"time",y:"speed",stroke:"var(--wt-color-primary, #fbbf24)",strokeWidth:a?1.5:2,curve:kt})];a||i.push($.ruleY([0],{stroke:"var(--wt-color-border, #27272a)"}),$.tip(t,$.pointerX({x:"time",y:"speed",title:o=>`${o.time.toFixed(1)}s \u2014 ${Math.round(o.speed)} CPM`,...M})));let s=$.plot({width:e,height:r,...a?A:{marginLeft:50,marginBottom:35},x:a?{axis:null}:{label:"Time (s)"},y:a?{axis:null}:{label:"Speed (CPM)",grid:!0},marks:i,style:E});this.replaceChart(s)}};z.tagName="wt-speed-timeline";import*as L from"@observablehq/plot";var ke=10;function Xt(n){var s,o,c,l,d;let t=(o=(s=n.timingAuthenticity)==null?void 0:s.metrics)==null?void 0:o.timingOverTime;if(!((c=t==null?void 0:t.timestamps)!=null&&c.length))return[];let e=((l=t.series)==null?void 0:l.meanDwell)??[],r=((d=t.series)==null?void 0:d.meanFlight)??[];if(!e.length||!r.length)return[];let a=[],i=Math.min(t.timestamps.length,e.length,r.length);for(let u=0;u<i;u++)e[u]!=null&&r[u]!=null&&a.push({dwell:e[u],flight:r[u]});return a}var G=class extends k{render(){if(!this._data)return;let t=Xt(this._data);if(t.length<ke){this.showEmptyState("Insufficient timing data");return}let e=this.getChartWidth(400),r=Math.min(e,this.getChartHeight(300)),a=this.compact,i=[L.dot(t,{x:"dwell",y:"flight",fill:"var(--wt-color-primary, #fbbf24)",fillOpacity:a?.4:.5,r:a?2:3,stroke:"none"})];a||i.push(L.ruleX([t.reduce((o,c)=>o+c.dwell,0)/t.length],{stroke:"var(--wt-color-secondary, #22d3ee)",...J}),L.ruleY([t.reduce((o,c)=>o+c.flight,0)/t.length],{stroke:"var(--wt-color-secondary, #22d3ee)",...J}));let s=L.plot({width:e,height:r,...a?A:{marginLeft:50,marginBottom:35},x:a?{axis:null}:{label:"Dwell (ms)",grid:!0},y:a?{axis:null}:{label:"Flight (ms)",grid:!0},marks:i,style:E});this.replaceChart(s)}};G.tagName="wt-rhythm-heatmap";import*as V from"@observablehq/plot";function Qt(n){var e,r,a;let t=(r=(e=n.temporalPatterns)==null?void 0:e.metrics)==null?void 0:r.pauseDistribution;return(a=t==null?void 0:t.histogram)!=null&&a.length?t.histogram.map(i=>({start:i.binStart,end:i.binEnd,count:i.count})):[]}var at=class extends k{render(){if(!this._data)return;let t=Qt(this._data);if(t.length===0){this.showEmptyState("No pause data");return}let e=this.getChartWidth(640),r=this.clientHeight||200,a=V.plot({width:e,height:r,marginLeft:50,marginBottom:35,x:{label:"Pause Duration (ms)"},y:{label:"Count",grid:!0},marks:[V.rectY(t,{x1:"start",x2:"end",y:"count",fill:"var(--wt-color-primary, #fbbf24)",fillOpacity:.8,inset:.5}),V.ruleY([0])],style:E});this.replaceChart(a)}};at.tagName="wt-pause-distribution";import*as T from"@observablehq/plot";var j=/^.$/u;function P(n){return n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}var ot={insert:"var(--wt-beeswarm-insert, #22c55e)",delete:"var(--wt-beeswarm-delete, #ef4444)",paste:"var(--wt-beeswarm-paste, #22d3ee)",cut:"var(--wt-beeswarm-cut, #f97316)"},Ce=["insert","delete","paste","cut"];function Jt(n){var i,s;let t=(i=n.session)==null?void 0:i.events;if(!(t!=null&&t.length))return[];let e=t.filter(o=>o.type==="keydown");if(e.length===0)return[];let r=e[0].timestamp,a=[];for(let o of e){let c=(o.timestamp-r)/1e3;o.key==="Backspace"||o.key==="Delete"?a.push({time:c,type:"delete",chars:1,key:"\u232B"}):j.test(o.key)&&a.push({time:c,type:"insert",chars:1,key:o.key})}for(let o of((s=n.session)==null?void 0:s.clipboardEvents)??[])if(o.type==="paste"||o.type==="cut"){let c=Math.max(0,(o.timestamp-r)/1e3);a.push({time:c,type:o.type,chars:o.length,key:o.type==="paste"?"\u{1F4CB}":"\u2702"})}return a.sort((o,c)=>o.time-c.time),a}function Te(n,t){if(n.length===0)return[];let e=n[n.length-1].time;if(e===0)return n;let r=Math.max(10,Math.floor(t/4)),a=e/r,i=new Map;for(let s of n){let o=Math.floor(s.time/a),c=`${o}-${s.type}`,l=i.get(c);l?l.chars=s.type==="paste"||s.type==="cut"?Math.max(l.chars,s.chars):l.chars+s.chars:i.set(c,{time:(o+.5)*a,type:s.type,chars:s.chars,key:s.key})}return[...i.values()].sort((s,o)=>s.time-o.time)}var Y=class extends k{static get observedAttributes(){return[...super.observedAttributes,"glyphs"]}get glyphs(){return this.hasAttribute("glyphs")}attributeChangedCallback(t,e,r){super.attributeChangedCallback(t,e,r),t==="glyphs"&&this._data&&this.hasRendered&&this.setData(this._data)}render(){if(!this._data)return;let t=Jt(this._data);if(t.length===0){this.showEmptyState("No edit data");return}let e=this.getChartWidth(640),r=this.getChartHeight(160);if(this.compact){let l=this.renderCompact(t,e,r);this.replaceChart(l);return}let s=this.glyphs?this.buildGlyphMarks(t):this.buildDotMarks(t),o=T.plot({width:e,height:400,marginLeft:40,marginBottom:10,marginTop:35,x:{label:"Time (s)",axis:"top"},y:{axis:null},marks:s,style:E}),c=document.createElement("div");c.appendChild(o),c.appendChild(N(Ce.map(l=>({label:l.charAt(0).toUpperCase()+l.slice(1),color:ot[l]})))),this.replaceChart(c),this.cropViewBox(o,e)}renderCompact(t,e,r){let a=Te(t,e);return T.plot({width:e,height:r,...A,marginLeft:6,marginRight:6,x:{axis:null},y:{axis:null},marks:[T.dot(a,T.dodgeY({anchor:"top",x:"time",r:i=>Math.min(1.5+Math.sqrt(i.chars)*.5,6),fill:i=>ot[i.type],fillOpacity:.6,stroke:"none",clip:!1}))],style:{background:"transparent"}})}buildDotMarks(t){return[T.dot(t,T.dodgeY({anchor:"top",x:"time",r:e=>Math.min(1.5+Math.sqrt(e.chars)*.7,14),fill:e=>ot[e.type],fillOpacity:.7,stroke:"none",clip:!1})),T.tip(t,T.pointer(T.dodgeY({anchor:"top",x:"time",title:e=>`${e.time.toFixed(1)}s \u2014 ${e.key} (${e.type}${e.chars>1?`, ${e.chars} chars`:""})`,...M})))]}buildGlyphMarks(t){let e={insert:r=>r.key,delete:()=>"\xD7",paste:()=>"\u25AE",cut:()=>"\u25AF"};return[T.text(t,T.dodgeY({anchor:"top",x:"time",text:r=>e[r.type](r),fontSize:r=>r.type==="paste"||r.type==="cut"?Math.min(14+Math.sqrt(r.chars)*.8,36):9,r:r=>r.type==="paste"||r.type==="cut"?Math.min(8+Math.sqrt(r.chars)*.5,20):5,fill:r=>ot[r.type],opacity:.8,fontFamily:"ui-monospace, monospace",fontWeight:600,clip:!1})),T.tip(t,T.pointer(T.dodgeY({anchor:"top",x:"time",title:r=>`${r.time.toFixed(1)}s \u2014 ${r.key} (${r.type}${r.chars>1?`, ${r.chars} chars`:""})`,...M})))]}cropViewBox(t,e){let a=['g[aria-label="dot"]','g[aria-label="text"]'].map(i=>t.querySelector(i)).filter(Boolean);if(a.length!==0)try{let i=-1/0;for(let o of a){let c=o.getBBox();i=Math.max(i,c.y+c.height)}let s=Math.max(160,Math.min(parseInt(t.getAttribute("height")||"400",10),i+10));t.setAttribute("height",String(s)),t.setAttribute("viewBox",`0 0 ${e} ${s}`)}catch{}}};Y.tagName="wt-edit-beeswarm";import*as D from"@observablehq/plot";var Se=null;function Zt(){return Se}function st(n,t,e,r){let a=n.length;if(a<=t||t<3)return n;let i=Zt();if(!i)return n;let s=new Float64Array(a),o=new Float64Array(a);for(let d=0;d<a;d++)s[d]=e(n[d]),o[d]=r(n[d]);let c=i.lttb_downsample(s,o,t);if(c.length===0)return n;let l=new Array(c.length);for(let d=0;d<c.length;d++)l[d]=n[c[d]];return l}var it=2e3;function Ee(n,t){let e=[],r=[];for(let a of n??[])a.type==="paste"?e.push({time:Math.max(0,(a.timestamp-t)/1e3),position:a.position}):a.type==="cut"&&r.push({time:Math.max(0,(a.timestamp-t)/1e3),position:a.position});return{pastes:e,cuts:r}}function te(n){var o,c;let t=(o=n.session)==null?void 0:o.events;if(!(t!=null&&t.length))return{keystrokes:[],pastes:[],cuts:[]};let e=t.filter(l=>l.type==="keydown"&&l.cursorPosition!=null);if(e.length===0)return{keystrokes:[],pastes:[],cuts:[]};let r=e[0].timestamp,a=e.map(l=>({time:(l.timestamp-r)/1e3,position:l.cursorPosition})),{pastes:i,cuts:s}=Ee((c=n.session)==null?void 0:c.clipboardEvents,r);return{keystrokes:a,pastes:i,cuts:s}}function Pe(n,t,e){let r=[D.line(n,{x:"time",y:"position",stroke:"var(--wt-color-primary, #fbbf24)",strokeWidth:1.5,strokeOpacity:.8})];return t.length>0&&r.push(D.dot(t,{x:"time",y:"position",fill:"var(--wt-color-secondary, #22d3ee)",r:6,stroke:"var(--wt-color-bg, #111113)",strokeWidth:1})),e.length>0&&r.push(D.dot(e,{x:"time",y:"position",fill:"var(--wt-color-cut, #f97316)",r:6,stroke:"var(--wt-color-bg, #111113)",strokeWidth:1})),r.push(D.tip(n,D.pointerX({x:"time",y:"position",title:a=>`${a.time.toFixed(1)}s \u2014 position ${a.position}`,...M}))),r}var q=class extends k{render(){if(!this._data)return;let t=te(this._data);if(t.keystrokes.length===0){this.showEmptyState("No cursor position data");return}let e=st(t.keystrokes,it,c=>c.time,c=>c.position),{pastes:r,cuts:a}=t,i=this.getChartWidth(640),s=this.getChartHeight(200),o=this.compact;try{let c;o?c=[D.line(e,{x:"time",y:"position",stroke:"var(--wt-color-primary, #fbbf24)",strokeWidth:1.5,strokeOpacity:.6})]:c=Pe(e,r,a);let l=D.plot({width:i,height:s,...o?A:{marginLeft:50,marginBottom:35},x:o?{axis:null}:{label:"Time (s)"},y:o?{axis:null,reverse:!0}:{label:"Position",reverse:!0,grid:!0},marks:c,style:E});this.replaceChart(l)}catch(c){I(`EditWaterfall render failed: ${c}`)}}};q.tagName="wt-edit-waterfall";import*as R from"@observablehq/plot";var ct={insert:"var(--wt-bubble-insert, #22c55e)",delete:"var(--wt-bubble-delete, #ef4444)",paste:"var(--wt-bubble-paste, var(--wt-color-secondary, #22d3ee))",cut:"var(--wt-bubble-cut, #f97316)"},ee=["insert","delete","paste","cut"];function re(n){var l,d;let t=(l=n.session)==null?void 0:l.events;if(!(t!=null&&t.length))return[];let e=t.filter(u=>u.type==="keydown");if(e.length===0)return[];let r=e[0].timestamp,a=[],i=null,s=0,o=0;function c(){i&&s>0&&a.push({time:o,chars:s,type:i}),i=null,s=0}for(let u of e){let p=(u.timestamp-r)/1e3,m=null;u.key==="Backspace"||u.key==="Delete"?m="delete":j.test(u.key)&&(m="insert"),m!==null&&(m!==i&&(c(),i=m,o=p),s++)}c();for(let u of((d=n.session)==null?void 0:d.clipboardEvents)??[])if(u.type==="paste"||u.type==="cut"){let p=Math.max(0,(u.timestamp-r)/1e3),m=u.length;a.push({time:p,chars:m,type:u.type})}return a.sort((u,p)=>u.time-p.time),a}var U=class extends k{render(){if(!this._data)return;let t=re(this._data);if(t.length===0){this.showEmptyState("No edit data");return}let e=this.getChartWidth(640),r=this.getChartHeight(200);if(this.compact){let o=this.renderCompact(t,e,r);this.replaceChart(o);return}let i=R.plot({width:e,height:r,marginLeft:70,marginBottom:35,marginTop:10,x:{label:"Time (s)"},y:{label:null,domain:ee},r:{range:[3,12]},marks:[R.dot(t,{x:"time",y:"type",r:"chars",fill:o=>ct[o.type],fillOpacity:.7,stroke:"none"}),R.tip(t,R.pointer({x:"time",y:"type",title:o=>`${o.time.toFixed(1)}s \u2014 ${o.type}, ${o.chars} chars`,...M}))],style:E}),s=document.createElement("div");s.appendChild(i),s.appendChild(N(ee.map(o=>({label:o.charAt(0).toUpperCase()+o.slice(1),color:ct[o]})))),this.replaceChart(s)}renderCompact(t,e,r){if(!t.some(m=>m.type==="paste"||m.type==="cut"))return R.plot({width:e,height:r,...A,marginLeft:4,marginRight:4,x:{axis:null},y:{axis:null,domain:["insert","delete"]},marks:[R.dot(t,{x:"time",y:"type",r:Math.min(3,Math.max(2,e/t.length/4)),fill:m=>ct[m.type],fillOpacity:.6,stroke:"none"})],style:{background:"transparent"}});let i=t.map(m=>m.time),s=Math.min(...i),c=Math.max(...i)-s||1,l=20,d=c/l,u=new Map;for(let m of t){let f=Math.min(l-1,Math.floor((m.time-s)/d)),h=`${f}-${m.type}`,b=u.get(h);b?b.chars+=m.chars:u.set(h,{time:s+(f+.5)*d,chars:m.chars,type:m.type})}let p=[...u.values()];return R.plot({width:e,height:r,...A,marginLeft:4,marginRight:4,x:{axis:null},y:{axis:null,domain:["cut","paste","insert","delete"]},marks:[R.dot(p,{x:"time",y:"type",r:Math.min(4,Math.max(2,e/p.length/3)),fill:m=>ct[m.type],fillOpacity:.6,stroke:"none"})],style:{background:"transparent"}})}};U.tagName="wt-corrections-bubble";import*as B from"@observablehq/plot";var ne={Typed:"typed",Pasted:"pasted",Autocompleted:"autocompleted"},Ae={typed:"var(--wt-color-primary, #2B7A5D)",pasted:"var(--wt-color-secondary, #B8412D)",autocompleted:"var(--wt-color-tertiary, #7C6DAF)"};function dt(n){var i,s;let t=(s=(i=n.contentOrigin)==null?void 0:i.metrics)==null?void 0:s.charactersByOrigin,e=Math.round(((t==null?void 0:t.typed)??1)*100),r=Math.round(((t==null?void 0:t.pasted)??0)*100),a=Math.round(((t==null?void 0:t.autocompleted)??0)*100);return[{category:"origin",segment:"Typed",value:e},{category:"origin",segment:"Pasted",value:r},{category:"origin",segment:"Autocompleted",value:a}].filter(o=>o.value>0)}function mt(n,t,e=Ae,r){if(n.length===0){let s=document.createElementNS("http://www.w3.org/2000/svg","svg");s.setAttribute("width",String(t)),s.setAttribute("height","24"),s.setAttribute("viewBox",`0 0 ${t} 24`);let o=document.createElementNS("http://www.w3.org/2000/svg","rect");return o.setAttribute("width",String(t)),o.setAttribute("height","24"),o.setAttribute("rx","4"),o.setAttribute("fill","var(--wt-color-border, #3f3f46)"),o.setAttribute("opacity","0.3"),s.appendChild(o),s}let i=[B.barX(n,B.stackX({x:"value",fill:s=>e[ne[s.segment]??"typed"],inset:.5})),B.text(n,B.stackX({x:"value",text:s=>s.value<10?"":s.value<25?`${s.value}%`:`${s.segment} ${s.value}%`,fill:s=>{let o=ne[s.segment]??"typed";return(r==null?void 0:r[o])??"white"},fontSize:11,fontWeight:500}))];return B.plot({width:t,height:32,marginTop:0,marginRight:0,marginBottom:0,marginLeft:0,x:{axis:null,domain:[0,100]},y:{axis:null},marks:i,style:{background:"transparent",fontFamily:"var(--wt-scorecard-font-data, var(--wt-font-data, ui-monospace))"}})}var lt=class extends k{render(){if(!this._data)return;let t=dt(this._data);if(t.length===0){this.showEmptyState("No content origin data");return}let e=this.clientWidth||400,r=mt(t,e);r&&this.replaceChart(r)}};lt.tagName="wt-origin-bar";var Z=`:host {
|
|
56
|
+
[aria-label="tip"] { color: #fafafa; }`,$={fill:"#1a1a1d",stroke:"#27272a",textPadding:6,fontSize:11,fontFamily:"'JetBrains Mono', ui-monospace, monospace"};function _(r){console.warn(`[WriteTrack] ${r}`)}function bt(r){return r instanceof Error?r.message:String(r)}var T=class extends HTMLElement{constructor(){super();this._data=null;this.i=[];this._resizeObserver=null;this._resizeRaf=null;this.e=null;this.l=0;this.s=!1;this.o=!1;this.a=!1;this.shadow=this.attachShadow({mode:"open"});let e=document.createElement("style");e.textContent=this.getStylesheet(),this.shadow.appendChild(e),this.container=document.createElement("div"),this.container.className="wt-chart",this.container.style.transition="opacity 80ms ease",this.shadow.appendChild(this.container)}static get observedAttributes(){return["data","theme","label","compact"]}get compact(){return this.hasAttribute("compact")}getChartWidth(e){let n=getComputedStyle(this).getPropertyValue("--wt-chart-width").trim();return n?parseInt(n,10)||e:this.container.clientWidth||this.clientWidth||e}getChartHeight(e){let n=getComputedStyle(this).getPropertyValue("--wt-chart-height").trim();if(n)return parseInt(n,10)||e;let a=this.style.height;return a&&parseInt(a,10)||e}getStylesheet(){return et}connectedCallback(){typeof ResizeObserver<"u"&&(this._resizeObserver=new ResizeObserver(e=>{var a,o;let n=((o=(a=e[0])==null?void 0:a.contentRect)==null?void 0:o.width)??0;n===0||n===this.l||(this.l=n,this.s&&this._data&&(this._resizeRaf&&cancelAnimationFrame(this._resizeRaf),this._resizeRaf=requestAnimationFrame(()=>{this._resizeRaf=null,this.onResize()})))}),this._resizeObserver.observe(this.container)),this.d(),typeof MutationObserver<"u"&&(this.e=new MutationObserver(()=>{this.d()}),this.e.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme"]}),document.body&&this.e.observe(document.body,{attributes:!0,attributeFilter:["data-theme"]}))}disconnectedCallback(){this.destroy()}attributeChangedCallback(e,n,a){if(e==="data"&&a)try{let o=JSON.parse(a);this.setData(o)}catch(o){_(`BaseChart: invalid JSON in data attribute: ${bt(o)}`)}(e==="theme"||e==="compact")&&this._data&&this.s&&this.safeRender()}setActiveWindows(e){this.i=e}setData(e){this._data=e,this.safeRender()}getData(){return this._data}get hasRendered(){return this.s}replaceChart(...e){for(let a of e)if(a instanceof SVGElement){a.setAttribute("role","img");let o=this.getAttribute("label")??this.tagName.toLowerCase().replace("wt-","").replace(/-/g," ")+" chart";a.setAttribute("aria-label",o)}let n=this.a;this.a=!1,n||(this.container.style.opacity="0"),this.container.replaceChildren(...e),n||requestAnimationFrame(()=>{this.container.style.opacity="1"}),this.s=!0,this.dispatchEvent(new CustomEvent("wt-render",{bubbles:!1}))}showEmptyState(e="No data"){let n=document.createElement("div");n.className="wt-empty",n.textContent=e,n.style.cssText="display:flex;align-items:center;justify-content:center;height:100%;font-family:var(--wt-scorecard-font-data,var(--wt-font-data,ui-monospace,monospace));font-size:0.625rem;color:var(--wt-scorecard-text-tertiary,var(--wt-color-text-muted,#a1a1aa));",this.container.style.opacity="0",this.container.replaceChildren(n),requestAnimationFrame(()=>{this.container.style.opacity="1"}),this.s=!1}destroy(){this._resizeRaf&&(cancelAnimationFrame(this._resizeRaf),this._resizeRaf=null),this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),this.e&&(this.e.disconnect(),this.e=null),this.container.replaceChildren(),this._data=null,this.s=!1}onResize(){this.a=!0,this.safeRender()}safeRender(){try{this.render()}catch(e){_(`${this.constructor.name} render failed: ${bt(e)}`)}}static register(){customElements.get(this.tagName)||customElements.define(this.tagName,this)}d(){if(this.hasAttribute("theme")&&!this.o)return;let e=this.parentElement;for(;e;){let n=e.getAttribute("data-theme");if(n){this.shadow.host.setAttribute("theme",n),this.o=!0;return}e=e.parentElement}this.o&&(this.shadow.host.removeAttribute("theme"),this.o=!1)}};T.tagName="wt-base-chart";var vt=null,rt=null;async function Vt(){return rt||(rt=import("@observablehq/plot").then(r=>(vt=r,r)).catch(()=>(vt=null,null)),rt)}function k(){return vt}var C="Chart unavailable";var be=5;function jt(r){var o;let t=(((o=r.session)==null?void 0:o.events)??[]).filter(s=>s.type==="keydown"&&s.flightTime!=null&&s.flightTime>0);if(t.length<2)return[[],[]];let e=r.session.sessionStartTime,n=[],a=[];for(let s=0;s<t.length;s++){let i=Math.max(0,s-be+1),c=0,l=0;for(let u=i;u<=s;u++)c+=t[u].flightTime,l++;let d=c/l,m=Math.round(6e4/d);n.push(Math.round((t[s].timestamp-e)/1e3*100)/100),a.push(m)}return[n,a]}var j=class j extends T{connectedCallback(){super.connectedCallback();let t=getComputedStyle(this);!this.style.display&&t.display==="inline"&&(this.style.display="inline-block"),!this.style.width&&(t.width==="auto"||t.width==="0px")&&(this.style.width="200px"),!this.style.height&&(t.height==="auto"||t.height==="0px")&&(this.style.height="40px")}render(){if(!this._data)return;let t=k();if(!t){this.showEmptyState(C);return}let[e,n]=jt(this._data);if(e.length===0){this.showEmptyState("No data");return}let a=e.map((l,d)=>({time:l,speed:n[d]})),o=this.getBoundingClientRect(),s=Math.max(o.width||200,50),i=Math.max(o.height||40,20),c=t.plot({width:s,height:i,axis:null,x:{axis:null},y:{axis:null},marks:[t.areaY(a,{x:"time",y:"speed",fill:"var(--wt-color-primary, #fbbf24)",fillOpacity:.1}),t.lineY(a,{x:"time",y:"speed",stroke:"var(--wt-color-primary, #fbbf24)",strokeWidth:1.5})],style:{background:"transparent",overflow:"visible"},margin:0,marginTop:2,marginBottom:2,marginLeft:0,marginRight:0});this.replaceChart(c)}static create(t,e){j.register();let n=document.createElement(j.tagName);return t.appendChild(n),n.setData(e),n}};j.tagName="wt-sparkline";var xt=j;function E(r,t){if(t.length===0)return 0;let e=0;for(let n of t){if(r<=n.startMs)return e/1e3;if(r<=n.endMs)return(e+r-n.startMs)/1e3;e+=n.endMs-n.startMs}return e/1e3}var Tt="monotone-x";var M={marginTop:4,marginRight:0,marginBottom:4,marginLeft:0};function R(r){let t=document.createElement("div");t.style.cssText="display:flex;flex-wrap:wrap;gap:10px;padding:6px 0 2px;font-family:var(--wt-font-data,ui-monospace,monospace);font-size:10px;color:var(--wt-color-text-muted,#a1a1aa);";for(let{label:e,color:n,shape:a}of r){let o=document.createElement("span");o.style.cssText="display:inline-flex;align-items:center;gap:4px;";let s=document.createElement("span"),i=a==="square"?"2px":"50%";s.style.cssText=`width:8px;height:8px;border-radius:${i};background:${n};flex-shrink:0;`,o.appendChild(s),o.appendChild(document.createTextNode(e)),t.appendChild(o)}return t}var A={background:"transparent",color:"var(--wt-color-text, #fafafa)",fontFamily:"var(--wt-font-data)",fontSize:"11px"},Y={strokeDasharray:"4,4",strokeWidth:1};function Yt(r,t){var i,c,l,d;let e=(c=(i=r.temporalPatterns)==null?void 0:i.metrics)==null?void 0:c.speedTimeline;if(!((l=e==null?void 0:e.timestamps)!=null&&l.length))return[];let n=t??((d=r.activeTime)==null?void 0:d.activeWindows)??[],a=n.length>0,o=Math.min(e.timestamps.length,e.values.length),s=[];for(let m=0;m<o;m++)s.push({time:a?E(e.timestamps[m],n):e.timestamps[m]/1e3,speed:e.values[m]});return s.sort((m,u)=>m.time-u.time),s}var L=class extends T{render(){if(!this._data)return;let t=k();if(!t){this.showEmptyState(C);return}let e=Yt(this._data);if(e.length===0){this.showEmptyState("No speed data");return}let n=this.getChartWidth(640),a=this.getChartHeight(200),o=this.compact,s=[t.areaY(e,{x:"time",y:"speed",fill:"var(--wt-color-primary, #fbbf24)",fillOpacity:.15,curve:Tt}),t.lineY(e,{x:"time",y:"speed",stroke:"var(--wt-color-primary, #fbbf24)",strokeWidth:o?1.5:2,curve:Tt})];o||s.push(t.ruleY([0],{stroke:"var(--wt-color-border, #27272a)"}),t.tip(e,t.pointerX({x:"time",y:"speed",title:c=>`${c.time.toFixed(1)}s \u2014 ${Math.round(c.speed)} CPM`,...$})));let i=t.plot({width:n,height:a,...o?M:{marginLeft:50,marginBottom:35},x:o?{axis:null}:{label:"Active Time (s)"},y:o?{axis:null}:{label:"Speed (CPM)",grid:!0},marks:s,style:A});this.replaceChart(i)}};L.tagName="wt-speed-timeline";var ve=10;function Kt(r){var s,i,c,l,d;let t=(i=(s=r.timingAuthenticity)==null?void 0:s.metrics)==null?void 0:i.timingOverTime;if(!((c=t==null?void 0:t.timestamps)!=null&&c.length))return[];let e=((l=t.series)==null?void 0:l.meanDwell)??[],n=((d=t.series)==null?void 0:d.meanFlight)??[];if(!e.length||!n.length)return[];let a=[],o=Math.min(t.timestamps.length,e.length,n.length);for(let m=0;m<o;m++)e[m]!=null&&n[m]!=null&&a.push({dwell:e[m],flight:n[m]});return a}var F=class extends T{render(){if(!this._data)return;let t=k();if(!t){this.showEmptyState(C);return}let e=Kt(this._data);if(e.length<ve){this.showEmptyState("Insufficient timing data");return}let n=this.getChartWidth(400),a=Math.min(n,this.getChartHeight(300)),o=this.compact,s=[t.dot(e,{x:"dwell",y:"flight",fill:"var(--wt-color-primary, #fbbf24)",fillOpacity:o?.4:.5,r:o?2:3,stroke:"none"})];o||s.push(t.ruleX([e.reduce((c,l)=>c+l.dwell,0)/e.length],{stroke:"var(--wt-color-secondary, #22d3ee)",...Y}),t.ruleY([e.reduce((c,l)=>c+l.flight,0)/e.length],{stroke:"var(--wt-color-secondary, #22d3ee)",...Y}));let i=t.plot({width:n,height:a,...o?M:{marginLeft:50,marginBottom:35},x:o?{axis:null}:{label:"Dwell (ms)",grid:!0},y:o?{axis:null}:{label:"Flight (ms)",grid:!0},marks:s,style:A});this.replaceChart(i)}};F.tagName="wt-rhythm-heatmap";function Ut(r){var e,n,a;let t=(n=(e=r.temporalPatterns)==null?void 0:e.metrics)==null?void 0:n.pauseDistribution;return(a=t==null?void 0:t.histogram)!=null&&a.length?t.histogram.map(o=>({start:o.binStart,end:o.binEnd,count:o.count})):[]}var nt=class extends T{render(){if(!this._data)return;let t=k();if(!t){this.showEmptyState(C);return}let e=Ut(this._data);if(e.length===0){this.showEmptyState("No pause data");return}let n=this.getChartWidth(640),a=this.clientHeight||200,o=t.plot({width:n,height:a,marginLeft:50,marginBottom:35,x:{label:"Pause Duration (ms)"},y:{label:"Count",grid:!0},marks:[t.rectY(e,{x1:"start",x2:"end",y:"count",fill:"var(--wt-color-primary, #fbbf24)",fillOpacity:.8,inset:.5}),t.ruleY([0])],style:A});this.replaceChart(o)}};nt.tagName="wt-pause-distribution";var H=/^.$/u;function P(r){return r.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}var at={insert:"var(--wt-beeswarm-insert, #22c55e)",delete:"var(--wt-beeswarm-delete, #ef4444)",paste:"var(--wt-beeswarm-paste, #22d3ee)",cut:"var(--wt-beeswarm-cut, #f97316)"},xe=["insert","delete","paste","cut"];function Xt(r,t=[]){var i,c;let e=(i=r.session)==null?void 0:i.events;if(!(e!=null&&e.length))return[];let n=e.filter(l=>l.type==="keydown");if(n.length===0)return[];let a=n[0].timestamp,o=t.length>0,s=[];for(let l of n){let d=l.timestamp-a,m=o?E(d,t):d/1e3;l.key==="Backspace"||l.key==="Delete"?s.push({time:m,type:"delete",chars:1,key:"\u232B"}):H.test(l.key)&&s.push({time:m,type:"insert",chars:1,key:l.key})}for(let l of((c=r.session)==null?void 0:c.clipboardEvents)??[])if(l.type==="paste"||l.type==="cut"){let d=l.timestamp-a,m=o?E(d,t):Math.max(0,d/1e3);s.push({time:m,type:l.type,chars:l.length,key:l.type==="paste"?"\u{1F4CB}":"\u2702"})}return s.sort((l,d)=>l.time-d.time),s}function Te(r,t){if(r.length===0)return[];let e=r[r.length-1].time;if(e===0)return r;let n=Math.max(10,Math.floor(t/4)),a=e/n,o=new Map;for(let s of r){let i=Math.floor(s.time/a),c=`${i}-${s.type}`,l=o.get(c);l?l.chars=s.type==="paste"||s.type==="cut"?Math.max(l.chars,s.chars):l.chars+s.chars:o.set(c,{time:(i+.5)*a,type:s.type,chars:s.chars,key:s.key})}return[...o.values()].sort((s,i)=>s.time-i.time)}var G=class extends T{static get observedAttributes(){return[...super.observedAttributes,"glyphs"]}get glyphs(){return this.hasAttribute("glyphs")}attributeChangedCallback(t,e,n){super.attributeChangedCallback(t,e,n),t==="glyphs"&&this._data&&this.hasRendered&&this.setData(this._data)}render(){if(!this._data)return;let t=k();if(!t){this.showEmptyState(C);return}let e=Xt(this._data,this.i);if(e.length===0){this.showEmptyState("No edit data");return}let n=this.getChartWidth(640),a=this.getChartHeight(160);if(this.compact){let d=this.renderCompact(e,n,a);this.replaceChart(d);return}let i=this.glyphs?this.buildGlyphMarks(e):this.buildDotMarks(e),c=t.plot({width:n,height:400,marginLeft:40,marginBottom:10,marginTop:35,x:{label:"Active Time (s)",axis:"top"},y:{axis:null},marks:i,style:A}),l=document.createElement("div");l.appendChild(c),l.appendChild(R(xe.map(d=>({label:d.charAt(0).toUpperCase()+d.slice(1),color:at[d]})))),this.replaceChart(l),this.cropViewBox(c,n)}renderCompact(t,e,n){let a=k(),o=Te(t,e);return a.plot({width:e,height:n,...M,marginLeft:6,marginRight:6,x:{axis:null},y:{axis:null},marks:[a.dot(o,a.dodgeY({anchor:"top",x:"time",r:s=>Math.min(1.5+Math.sqrt(s.chars)*.5,6),fill:s=>at[s.type],fillOpacity:.6,stroke:"none",clip:!1}))],style:{background:"transparent"}})}buildDotMarks(t){let e=k();return[e.dot(t,e.dodgeY({anchor:"top",x:"time",r:n=>Math.min(1.5+Math.sqrt(n.chars)*.7,14),fill:n=>at[n.type],fillOpacity:.7,stroke:"none",clip:!1})),e.tip(t,e.pointer(e.dodgeY({anchor:"top",x:"time",title:n=>`${n.time.toFixed(1)}s \u2014 ${n.key} (${n.type}${n.chars>1?`, ${n.chars} chars`:""})`,...$})))]}buildGlyphMarks(t){let e=k(),n={insert:a=>a.key,delete:()=>"\xD7",paste:()=>"\u25AE",cut:()=>"\u25AF"};return[e.text(t,e.dodgeY({anchor:"top",x:"time",text:a=>n[a.type](a),fontSize:a=>a.type==="paste"||a.type==="cut"?Math.min(14+Math.sqrt(a.chars)*.8,36):9,r:a=>a.type==="paste"||a.type==="cut"?Math.min(8+Math.sqrt(a.chars)*.5,20):5,fill:a=>at[a.type],opacity:.8,fontFamily:"ui-monospace, monospace",fontWeight:600,clip:!1})),e.tip(t,e.pointer(e.dodgeY({anchor:"top",x:"time",title:a=>`${a.time.toFixed(1)}s \u2014 ${a.key} (${a.type}${a.chars>1?`, ${a.chars} chars`:""})`,...$})))]}cropViewBox(t,e){let a=['g[aria-label="dot"]','g[aria-label="text"]'].map(o=>t.querySelector(o)).filter(Boolean);if(a.length!==0)try{let o=-1/0;for(let i of a){let c=i.getBBox();o=Math.max(o,c.y+c.height)}let s=Math.max(160,Math.min(parseInt(t.getAttribute("height")||"400",10),o+10));t.setAttribute("height",String(s)),t.setAttribute("viewBox",`0 0 ${e} ${s}`)}catch{}}};G.tagName="wt-edit-beeswarm";var ke=null;function Qt(){return ke}function st(r,t,e,n){let a=r.length;if(a<=t||t<3)return r;let o=Qt();if(!o)return r;let s=new Float64Array(a),i=new Float64Array(a);for(let d=0;d<a;d++)s[d]=e(r[d]),i[d]=n(r[d]);let c=o.lttb_downsample(s,i,t);if(c.length===0)return r;let l=new Array(c.length);for(let d=0;d<c.length;d++)l[d]=r[c[d]];return l}var it=2e3;function Se(r,t,e){let n=[],a=[],o=e.length>0;for(let s of r??[]){let i=s.timestamp-t,c=o?E(i,e):Math.max(0,i/1e3);s.type==="paste"?n.push({time:c,position:s.position}):s.type==="cut"&&a.push({time:c,position:s.position})}return{pastes:n,cuts:a}}function Jt(r,t=[]){var l,d;let e=(l=r.session)==null?void 0:l.events;if(!(e!=null&&e.length))return{keystrokes:[],pastes:[],cuts:[]};let n=e.filter(m=>m.type==="keydown"&&m.cursorPosition!=null);if(n.length===0)return{keystrokes:[],pastes:[],cuts:[]};let a=n[0].timestamp,o=t.length>0,s=n.map(m=>({time:o?E(m.timestamp-a,t):(m.timestamp-a)/1e3,position:m.cursorPosition})),{pastes:i,cuts:c}=Se((d=r.session)==null?void 0:d.clipboardEvents,a,t);return{keystrokes:s,pastes:i,cuts:c}}function Ce(r,t,e){let n=k(),a=[n.line(r,{x:"time",y:"position",stroke:"var(--wt-color-primary, #fbbf24)",strokeWidth:1.5,strokeOpacity:.8})];return t.length>0&&a.push(n.dot(t,{x:"time",y:"position",fill:"var(--wt-color-secondary, #22d3ee)",r:6,stroke:"var(--wt-color-bg, #111113)",strokeWidth:1})),e.length>0&&a.push(n.dot(e,{x:"time",y:"position",fill:"var(--wt-color-cut, #f97316)",r:6,stroke:"var(--wt-color-bg, #111113)",strokeWidth:1})),a.push(n.tip(r,n.pointerX({x:"time",y:"position",title:o=>`${o.time.toFixed(1)}s \u2014 position ${o.position}`,...$}))),a}var z=class extends T{render(){if(!this._data)return;let t=k();if(!t){this.showEmptyState(C);return}let e=Jt(this._data,this.i);if(e.keystrokes.length===0){this.showEmptyState("No cursor position data");return}let n=st(e.keystrokes,it,l=>l.time,l=>l.position),{pastes:a,cuts:o}=e,s=this.getChartWidth(640),i=this.getChartHeight(200),c=this.compact;try{let l;c?l=[t.line(n,{x:"time",y:"position",stroke:"var(--wt-color-primary, #fbbf24)",strokeWidth:1.5,strokeOpacity:.6})]:l=Ce(n,a,o);let d=t.plot({width:s,height:i,...c?M:{marginLeft:50,marginBottom:35},x:c?{axis:null}:{label:"Active Time (s)"},y:c?{axis:null,reverse:!0}:{label:"Position",reverse:!0,grid:!0},marks:l,style:A});this.replaceChart(d)}catch(l){_(`EditWaterfall render failed: ${l}`)}}};z.tagName="wt-edit-waterfall";var ot={insert:"var(--wt-bubble-insert, #22c55e)",delete:"var(--wt-bubble-delete, #ef4444)",paste:"var(--wt-bubble-paste, var(--wt-color-secondary, #22d3ee))",cut:"var(--wt-bubble-cut, #f97316)"},Zt=["insert","delete","paste","cut"];function te(r,t=[]){var u,g;let e=(u=r.session)==null?void 0:u.events;if(!(e!=null&&e.length))return[];let n=e.filter(h=>h.type==="keydown");if(n.length===0)return[];let a=n[0].timestamp,o=t.length>0,s=h=>o?E(h-a,t):(h-a)/1e3,i=[],c=null,l=0,d=0;function m(){c&&l>0&&i.push({time:d,chars:l,type:c}),c=null,l=0}for(let h of n){let p=s(h.timestamp),f=null;h.key==="Backspace"||h.key==="Delete"?f="delete":H.test(h.key)&&(f="insert"),f!==null&&(f!==c&&(m(),c=f,d=p),l++)}m();for(let h of((g=r.session)==null?void 0:g.clipboardEvents)??[])if(h.type==="paste"||h.type==="cut"){let p=o?E(h.timestamp-a,t):Math.max(0,(h.timestamp-a)/1e3),f=h.length;i.push({time:p,chars:f,type:h.type})}return i.sort((h,p)=>h.time-p.time),i}var q=class extends T{render(){if(!this._data)return;let t=k();if(!t){this.showEmptyState(C);return}let e=te(this._data,this.i);if(e.length===0){this.showEmptyState("No edit data");return}let n=this.getChartWidth(640),a=this.getChartHeight(200);if(this.compact){let c=this.renderCompact(e,n,a);this.replaceChart(c);return}let s=t.plot({width:n,height:a,marginLeft:70,marginBottom:35,marginTop:10,x:{label:"Active Time (s)"},y:{label:null,domain:Zt},r:{range:[3,12]},marks:[t.dot(e,{x:"time",y:"type",r:"chars",fill:c=>ot[c.type],fillOpacity:.7,stroke:"none"}),t.tip(e,t.pointer({x:"time",y:"type",title:c=>`${c.time.toFixed(1)}s \u2014 ${c.type}, ${c.chars} chars`,...$}))],style:A}),i=document.createElement("div");i.appendChild(s),i.appendChild(R(Zt.map(c=>({label:c.charAt(0).toUpperCase()+c.slice(1),color:ot[c]})))),this.replaceChart(i)}renderCompact(t,e,n){let a=k();if(!t.some(h=>h.type==="paste"||h.type==="cut"))return a.plot({width:e,height:n,...M,marginLeft:4,marginRight:4,x:{axis:null},y:{axis:null,domain:["insert","delete"]},marks:[a.dot(t,{x:"time",y:"type",r:Math.min(3,Math.max(2,e/t.length/4)),fill:h=>ot[h.type],fillOpacity:.6,stroke:"none"})],style:{background:"transparent"}});let s=t.map(h=>h.time),i=Math.min(...s),l=Math.max(...s)-i||1,d=20,m=l/d,u=new Map;for(let h of t){let p=Math.min(d-1,Math.floor((h.time-i)/m)),f=`${p}-${h.type}`,v=u.get(f);v?v.chars+=h.chars:u.set(f,{time:i+(p+.5)*m,chars:h.chars,type:h.type})}let g=[...u.values()];return a.plot({width:e,height:n,...M,marginLeft:4,marginRight:4,x:{axis:null},y:{axis:null,domain:["cut","paste","insert","delete"]},marks:[a.dot(g,{x:"time",y:"type",r:Math.min(4,Math.max(2,e/g.length/3)),fill:h=>ot[h.type],fillOpacity:.6,stroke:"none"})],style:{background:"transparent"}})}};q.tagName="wt-corrections-bubble";var ee={Typed:"typed",Pasted:"pasted",Autocompleted:"autocompleted"},Ee={typed:"var(--wt-color-primary, #2B7A5D)",pasted:"var(--wt-color-secondary, #B8412D)",autocompleted:"var(--wt-color-tertiary, #7C6DAF)"};function lt(r){var o,s;let t=(s=(o=r.contentOrigin)==null?void 0:o.metrics)==null?void 0:s.charactersByOrigin,e=Math.round(((t==null?void 0:t.typed)??1)*100),n=Math.round(((t==null?void 0:t.pasted)??0)*100),a=Math.round(((t==null?void 0:t.autocompleted)??0)*100);return[{category:"origin",segment:"Typed",value:e},{category:"origin",segment:"Pasted",value:n},{category:"origin",segment:"Autocompleted",value:a}].filter(i=>i.value>0)}function dt(r,t,e=Ee,n){let a=k();if(!a)return null;if(r.length===0){let i=document.createElementNS("http://www.w3.org/2000/svg","svg");i.setAttribute("width",String(t)),i.setAttribute("height","24"),i.setAttribute("viewBox",`0 0 ${t} 24`);let c=document.createElementNS("http://www.w3.org/2000/svg","rect");return c.setAttribute("width",String(t)),c.setAttribute("height","24"),c.setAttribute("rx","4"),c.setAttribute("fill","var(--wt-color-border, #3f3f46)"),c.setAttribute("opacity","0.3"),i.appendChild(c),i}let o=i=>e[ee[i.segment]??"typed"],s=[a.barX(r,a.stackX({x:"value",fill:o,inset:.5})),a.text(r,a.stackX({x:"value",text:i=>i.value<10?"":i.value<25?`${i.value}%`:`${i.segment} ${i.value}%`,fill:i=>{let c=ee[i.segment]??"typed";return(n==null?void 0:n[c])??"white"},fontSize:11,fontWeight:500}))];return a.plot({width:t,height:32,marginTop:0,marginRight:0,marginBottom:0,marginLeft:0,x:{axis:null,domain:[0,100]},y:{axis:null},marks:s,style:{background:"transparent",fontFamily:"var(--wt-scorecard-font-data, var(--wt-font-data, ui-monospace))"}})}var ct=class extends T{render(){if(!this._data)return;let t=lt(this._data);if(t.length===0){this.showEmptyState("No content origin data");return}let e=this.clientWidth||400,n=dt(t,e);n?this.replaceChart(n):this.showEmptyState(C)}};ct.tagName="wt-origin-bar";var K=`:host {
|
|
57
57
|
/* \u2500\u2500 Surface colors (light default) \u2500\u2500 */
|
|
58
58
|
--wt-scorecard-bg: #F7F6F2;
|
|
59
59
|
--wt-scorecard-bg-card: #FFFFFF;
|
|
@@ -122,7 +122,7 @@ var nt=`:host {
|
|
|
122
122
|
.wt-term:hover {
|
|
123
123
|
text-decoration-color: var(--wt-scorecard-text-secondary);
|
|
124
124
|
}
|
|
125
|
-
`,
|
|
125
|
+
`,An=(()=>{try{let r=new CSSStyleSheet;return r.replaceSync(K),r}catch{return null}})();var U=new Uint8Array(256),kt=new Uint8Array(256);(function(){let r=1;for(let t=0;t<255;t++)U[t]=r,kt[r]=t,r=r<<1^(r>=128?285:0);U[255]=U[0]})();function ae(r,t){return r===0||t===0?0:U[(kt[r]+kt[t])%255]}function Ae(r){let t=[1];for(let e=0;e<r;e++){let n=new Array(t.length+1).fill(0);for(let a=0;a<t.length;a++)n[a]^=t[a],n[a+1]^=ae(t[a],U[e]);t=n}return t}function Pe(r,t){let e=Ae(t),n=new Uint8Array(r.length+t);n.set(r);for(let a=0;a<r.length;a++){let o=n[a];if(o!==0)for(let s=0;s<e.length;s++)n[a+s]^=ae(e[s],o)}return n.slice(r.length)}var Me=[{ver:1,size:21,dc:16,ec:10,blocks:1,cap:14},{ver:2,size:25,dc:28,ec:16,blocks:1,cap:26},{ver:3,size:29,dc:44,ec:26,blocks:1,cap:42},{ver:4,size:33,dc:64,ec:18,blocks:2,cap:62},{ver:5,size:37,dc:86,ec:24,blocks:2,cap:84},{ver:6,size:41,dc:108,ec:16,blocks:4,cap:106}],$e=[[],[6,18],[6,22],[6,26],[6,30],[6,34]];function De(r){for(let t of Me)if(r<=t.cap)return t;return null}function We(r,t){let e=[];function n(p,f){for(let v=f-1;v>=0;v--)e.push(p>>v&1)}n(4,4),n(r.length,8);for(let p of r)n(p,8);let a=t.dc*8;for(n(0,Math.min(4,a-e.length));e.length%8!==0;)e.push(0);let o=[236,17],s=0;for(;e.length<a;)n(o[s%2],8),s++;let i=[];for(let p=0;p<e.length;p+=8){let f=0;for(let v=0;v<8;v++)f=f<<1|e[p+v];i.push(f)}let c=Math.floor(t.dc/t.blocks),l=t.dc-c*t.blocks,d=[],m=[],u=0;for(let p=0;p<t.blocks;p++){let f=c+(p>=t.blocks-l?1:0),v=new Uint8Array(i.slice(u,u+f));d.push(v),m.push(Pe(v,t.ec)),u+=f}let g=[],h=0;for(let p of d)h=Math.max(h,p.length);for(let p=0;p<h;p++)for(let f of d)p<f.length&&g.push(f[p]);for(let p=0;p<t.ec;p++)for(let f of m)g.push(f[p]);return g}function Re(r){let t=r.size,e=[],n=[];for(let i=0;i<t;i++)e.push(new Int8Array(t)),n.push(new Uint8Array(t));function a(i,c,l){e[c][i]=l?1:-1,n[c][i]=1}function o(i,c){for(let d=-3;d<=3;d++)for(let m=-3;m<=3;m++){let u=i+m,g=c+d;u<0||u>=t||g<0||g>=t||a(u,g,Math.max(Math.abs(m),Math.abs(d))!==2)}let l=[[-4,0],[4,0],[0,-4],[0,4]];for(let d=-4;d<=4;d++)for(let m of l){let u=i+(m[0]!==0?m[0]:d),g=c+(m[1]!==0?m[1]:d);u>=0&&u<t&&g>=0&&g<t&&a(u,g,!1)}}o(3,3),o(t-4,3),o(3,t-4);for(let i=8;i<t-8;i++)a(i,6,i%2===0),a(6,i,i%2===0);let s=$e[r.ver-1];if(s.length>0)for(let i=0;i<s.length;i++)for(let c=0;c<s.length;c++){let l=s[i],d=s[c];if(!n[l][d])for(let m=-2;m<=2;m++)for(let u=-2;u<=2;u++)a(d+u,l+m,Math.max(Math.abs(u),Math.abs(m))!==1)}a(8,4*r.ver+9,!0);for(let i=0;i<8;i++)n[8][i]||(n[8][i]=1),n[8][t-1-i]||(n[8][t-1-i]=1),n[i][8]||(n[i][8]=1),n[t-1-i][8]||(n[t-1-i][8]=1);return n[8][8]=1,{grid:e,reserved:n,n:t}}function _e(r,t){let{grid:e,reserved:n,n:a}=r,o=[];for(let l of t)for(let d=7;d>=0;d--)o.push(l>>d&1);let s=0,i=a-1,c=!0;for(;i>=0;){if(i===6){i--;continue}let l=c?a-1:0,d=c?-1:a,m=c?-1:1;for(let u=l;u!==d;u+=m)for(let g=0;g<2;g++){let h=i-g;h<0||n[u][h]||(e[u][h]=s<o.length&&o[s]?1:-1,s++)}i-=2,c=!c}}var Be=[(r,t)=>(r+t)%2===0,(r,t)=>t%2===0,(r,t)=>r%3===0,(r,t)=>(r+t)%3===0,(r,t)=>(Math.floor(t/2)+Math.floor(r/3))%2===0,(r,t)=>r*t%2+r*t%3===0,(r,t)=>(r*t%2+r*t%3)%2===0,(r,t)=>((r+t)%2+r*t%3)%2===0];function re(r,t,e,n){let a=Be[n],o=r.map(s=>Int8Array.from(s));for(let s=0;s<e;s++)for(let i=0;i<e;i++)!t[s][i]&&a(i,s)&&(o[s][i]=o[s][i]===1?-1:1);return o}var Oe=[21522,20773,24188,23371,17913,16590,20375,19104];function ne(r,t,e){let n=Oe[e],a=[];for(let i=14;i>=0;i--)a.push(n>>i&1);let o=[[0,8],[1,8],[2,8],[3,8],[4,8],[5,8],[7,8],[8,8],[8,7],[8,5],[8,4],[8,3],[8,2],[8,1],[8,0]],s=[[8,t-1],[8,t-2],[8,t-3],[8,t-4],[8,t-5],[8,t-6],[8,t-7],[t-8,8],[t-7,8],[t-6,8],[t-5,8],[t-4,8],[t-3,8],[t-2,8],[t-1,8]];for(let i=0;i<15;i++){let c=a[i]?1:-1;r[o[i][1]][o[i][0]]=c,r[s[i][1]][s[i][0]]=c}}function Ne(r,t){let e=0;for(let l=0;l<t;l++){let d=1;for(let m=1;m<t;m++)r[l][m]>0==r[l][m-1]>0?d++:(d>=5&&(e+=3+(d-5)),d=1);d>=5&&(e+=3+(d-5))}for(let l=0;l<t;l++){let d=1;for(let m=1;m<t;m++)r[m][l]>0==r[m-1][l]>0?d++:(d>=5&&(e+=3+(d-5)),d=1);d>=5&&(e+=3+(d-5))}for(let l=0;l<t-1;l++)for(let d=0;d<t-1;d++){let m=r[l][d]>0;m===r[l][d+1]>0&&m===r[l+1][d]>0&&m===r[l+1][d+1]>0&&(e+=3)}let n=[1,0,1,1,1,0,1,0,0,0,0],a=[0,0,0,0,1,0,1,1,1,0,1];for(let l=0;l<t;l++)for(let d=0;d<=t-11;d++){let m=!0,u=!0;for(let g=0;g<11;g++){let h=r[l][d+g]>0;if(h!==(n[g]===1)&&(m=!1),h!==(a[g]===1)&&(u=!1),!m&&!u)break}m&&(e+=40),u&&(e+=40)}for(let l=0;l<t;l++)for(let d=0;d<=t-11;d++){let m=!0,u=!0;for(let g=0;g<11;g++){let h=r[d+g][l]>0;if(h!==(n[g]===1)&&(m=!1),h!==(a[g]===1)&&(u=!1),!m&&!u)break}m&&(e+=40),u&&(e+=40)}let o=0;for(let l=0;l<t;l++)for(let d=0;d<t;d++)r[l][d]>0&&o++;let s=o*100/(t*t),i=Math.floor(s/5)*5,c=i+5;return e+=10*Math.min(Math.abs(i-50)/5,Math.abs(c-50)/5),e}function St(r){let t=[];for(let c=0;c<r.length;c++){let l=r.charCodeAt(c);l<128?t.push(l):l<2048&&(t.push(192|l>>6),t.push(128|l&63))}let e=De(t.length);if(!e)return null;let n=We(t,e),a=Re(e);_e(a,n);let o=0,s=1/0;for(let c=0;c<8;c++){let l=re(a.grid,a.reserved,a.n,c);ne(l,a.n,c);let d=Ne(l,a.n);d<s&&(s=d,o=c)}let i=re(a.grid,a.reserved,a.n,o);return ne(i,a.n,o),{grid:i,size:a.n}}function Ct(r,t,e){let n=r.size,a=Math.max(2,Math.floor(88/n)),o=n*a,s=a/2,i=s*.82;function c(d,m){let u=Math.sin(d*31+m*17)*1e4;return .75+.25*(u-Math.floor(u))}let l="";for(let d=0;d<n;d++)for(let m=0;m<n;m++){if(r.grid[d][m]<=0)continue;if(m<7&&d<7||m>=n-7&&d<7||m<7&&d>=n-7)l+=`<rect x="${m*a}" y="${d*a}" width="${a}" height="${a}" rx="${a*.15}" fill="${t}"/>`;else{let g=i*c(m,d);l+=`<circle cx="${m*a+s}" cy="${d*a+s}" r="${g.toFixed(1)}" fill="${t}"/>`}}return`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${o} ${o}" width="${o}" height="${o}">${l}</svg>`}function se(r,t,e){let a=72*(r/100),o=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 72" width="${r}" height="${a}">`;return o+=`<path d="M86 2 L86 64" stroke="${e}" stroke-width="5" stroke-linecap="round"/>`,o+=`<path d="M7 12 L98 12" stroke="${e}" stroke-width="5" stroke-linecap="round"/>`,o+=`<path d="M7 18 C7 32, 16 64, 30 64 C44 64, 38 28, 52 28 C66 28, 62 64, 86 64" stroke="${t}" stroke-width="5" stroke-linecap="round" fill="none"/>`,o+=`<circle cx="7" cy="12" r="7" fill="${t}"/>`,o+=`<circle cx="86" cy="64" r="7" fill="${e}"/>`,o+="</svg>",o}var Ie=`.integrity-section {
|
|
126
126
|
margin-top: 2rem;
|
|
127
127
|
padding-top: 1.5rem;
|
|
128
128
|
border-top: 1px solid var(--wt-scorecard-border);
|
|
@@ -187,11 +187,11 @@ var nt=`:host {
|
|
|
187
187
|
color: var(--wt-scorecard-text-tertiary);
|
|
188
188
|
flex: 1;
|
|
189
189
|
}
|
|
190
|
-
`,
|
|
191
|
-
`+Fe}render(){if(!this._data)return;let{integrity:t,outputSignature:e}=this._data,r=document.createElement("div");r.className="integrity-section";let a=document.createElement("div");a.className="integrity-title",a.textContent="Integrity & Verification",r.appendChild(a);let i=document.createElement("div");i.className="integrity-stats",i.textContent=`${t.eventCount} events \xB7 ${t.checkpoints.length} checkpoints`,r.appendChild(i);let s=document.createElement("div");s.className="integrity-hash-block";let o=document.createElement("span");o.className="integrity-hash-label",o.textContent="Digest (SHA-256)";let c=document.createElement("code");c.className="hash",c.textContent=t.finalDigest,s.append(o,c),r.appendChild(s);let l=document.createElement("div");l.className="integrity-hash-block";let d=document.createElement("span");d.className="integrity-hash-label",d.textContent="Output Signature";let u=document.createElement("code");u.className="hash",u.textContent=e,l.append(d,u),r.appendChild(l);let p=document.createElement("div");p.className="integrity-bottom";let m=document.createElement("div");m.className="qr-container";let f=document.createElement("p");f.className="integrity-explainer",f.textContent="This scorecard includes cryptographic integrity verification. The digest covers all input events; the signature covers the analysis output. Compare against original session data or scan for verification.",p.appendChild(m),p.appendChild(f),r.appendChild(p),this.replaceChart(r),requestAnimationFrame(()=>this.renderQr(t.finalDigest))}renderQr(t){let e=this.shadow.querySelector(".qr-container");if(!e)return;let r=Tt(t);if(!r)return;let a=getComputedStyle(this),i=a.getPropertyValue("--wt-scorecard-text").trim()||"#E4E2DA",s=a.getPropertyValue("--wt-scorecard-status-clear").trim()||"#5EAE78";e.innerHTML=St(r,i,s)}};ut.tagName="wt-integrity-footer";function ce(n){if(n<1e3)return"0 seconds";let t=Math.floor(n/1e3),e=Math.floor(t/86400),r=Math.floor(t%86400/3600),a=Math.floor(t%3600/60),i=t%60,s=[];return e>0&&s.push(`${e} ${e===1?"day":"days"}`),r>0&&s.push(`${r} ${r===1?"hour":"hours"}`),a>0&&s.push(`${a} ${a===1?"minute":"minutes"}`),i>0&&e===0&&s.push(`${i} ${i===1?"second":"seconds"}`),s.join(" ")||"0 seconds"}function Et(n){var w,v,g,C,_,x,O,Wt,_t,Bt,Ot,Nt,Lt,It,Ft,Ht,zt,Gt,Vt,jt,Yt,qt;if(!n.sufficientData){let X=n.keydownCount??0,we=((v=(w=n.temporalPatterns)==null?void 0:w.metrics)==null?void 0:v.sessionDurationMs)??0;if(X===0)return null;let ve=ce(we);return`This session captured ${X} keystroke${X===1?"":"s"} over ${ve}.`}let t=((_=(C=(g=n.contentOrigin)==null?void 0:g.metrics)==null?void 0:C.charactersByOrigin)==null?void 0:_.typed)??0,e=((Wt=(O=(x=n.contentOrigin)==null?void 0:x.metrics)==null?void 0:O.charactersByOrigin)==null?void 0:Wt.pasted)??0,r=((Ot=(Bt=(_t=n.revisionBehavior)==null?void 0:_t.metrics)==null?void 0:Bt.insertionDeletion)==null?void 0:Ot.deletionCount)??0,a=((It=(Lt=(Nt=n.contentOrigin)==null?void 0:Nt.metrics)==null?void 0:Lt.pasteEditSummary)==null?void 0:It.meanReworkRatio)??0,i=((Ht=(Ft=n.temporalPatterns)==null?void 0:Ft.metrics)==null?void 0:Ht.sessionDurationMs)??0,s=((Vt=(Gt=(zt=n.temporalPatterns)==null?void 0:zt.metrics)==null?void 0:Gt.pause2000ms)==null?void 0:Vt.count)??0,o=((qt=(Yt=(jt=n.sessionContinuity)==null?void 0:jt.metrics)==null?void 0:Yt.tabAwayEvents)==null?void 0:qt.length)??0,c=ce(i),l=(t*100).toFixed(1),d=(e*100).toFixed(1),u=t>=.8,p=e>.5,m;u?m=`This text was typed directly over ${c}.`:p?m=`${d}% of this text was pasted from an external source.`:m=`This text contains a mix of typed (${l}%) and pasted (${d}%) content.`;let f=a>0?", and edited pasted content afterward":"",h;r>0?h=`The author made ${r} ${r===1?"correction":"corrections"}${f}.`:h=`No corrections were made${f}.`;let b=o>0?` and ${o} tab-away${o===1?"":"s"}`:"",y;return s>0?y=`The session lasted ${c} with ${s} ${s===1?"pause":"pauses"} to think${b}.`:y=`The session lasted ${c} with no significant pauses${b}.`,`${m} ${h} ${y}`}function Pt(n){let t=n.internalPct??0,e=n.externalPct??0,r=n.unknownPct??0,a=n.copyPct??0,i=n.cutPct??0,s=t+e+r;if(s>0&&t>s*.8)return i>a?{type:"internal-cut",label:"cut and re-pasted within the document",breakdown:null}:a>i?{type:"internal-copy",label:"copied and re-pasted within the document",breakdown:null}:{type:"internal",label:"reorganised within the document",breakdown:null};if(s>0&&e>s*.8)return{type:"external",label:"pasted from external sources",breakdown:null};let o=[];return t>0&&(i>a?o.push(`${Math.round(t)}% cut-pasted`):a>i?o.push(`${Math.round(t)}% copy-pasted`):o.push(`${Math.round(t)}% reorganised`)),e>0&&o.push(`${Math.round(e)}% external`),r>0&&o.push(`${Math.round(r)}% unclassified`),o.length>=1?{type:"mixed",label:"pasted",breakdown:o.join(", ")}:{type:"unknown",label:"pasted",breakdown:null}}var de=new Set(["WT-103","WT-104","WT-106","WT-204","WT-301","WT-302","WT-403","WT-500","WT-503","WT-505","WT-506","WT-509","WT-601","WT-602","WT-603","WT-606","WT-700","WT-701","WT-702","WT-703","WT-704"]);function He(n){return de.has(n)}function K(n){return n?de.has(n)?"pass":"flag":"unknown"}var et={contentOrigin:"Content Origin",timingAuthenticity:"Timing & Rhythm",revisionBehavior:"Revision Behavior",sessionContinuity:"Session Continuity",physicalPlausibility:"Physical Plausibility",temporalPatterns:"Temporal Patterns",writingProcess:"Writing Process"};var ze=["contentOrigin","timingAuthenticity","revisionBehavior"],Ge=["sessionContinuity","physicalPlausibility","temporalPatterns","writingProcess"],Ve={"WT-100":()=>"No content was recorded during this session.","WT-101":n=>{let t=n.params.pct??0,e=100-t,r=Pt(n.params);return r.type==="internal-cut"?`Nearly all content (${t}%) was cut and re-pasted within the document \u2014 the writer reorganised their own text. ${e}% of characters were typed directly.`:r.type==="internal-copy"?`Nearly all content (${t}%) was copied and re-pasted within the document \u2014 the writer duplicated and reworked their own text. ${e}% of characters were typed directly.`:r.type==="internal"?`Nearly all content (${t}%) was reorganised within the document. ${e}% of characters were typed directly.`:r.type==="external"?`Nearly all content (${t}%) was pasted from an external source. Only ${e}% of characters were typed directly.`:r.breakdown?`${t}% of content was pasted \u2014 ${r.breakdown}. ${e}% was typed directly.`:`Nearly all content (${t}%) was pasted. Only ${e}% of characters were typed directly.`},"WT-102":n=>`${n.params.pct??0}% of text was inserted via autocomplete, suggesting reliance on predictive input rather than original composition.`,"WT-103":n=>{let t=n.params.pct??0,e=100-t,r=Pt(n.params);return r.type==="internal-cut"?`${t}% of text was cut and re-pasted within the document \u2014 the writer reorganised their own text. The remaining ${e}% was typed directly.`:r.type==="internal-copy"?`${t}% of text was copied and re-pasted within the document \u2014 the writer duplicated and reworked their own text. The remaining ${e}% was typed directly.`:r.type==="internal"?`${t}% of text was reorganised within the document. The remaining ${e}% was typed directly.`:r.type==="external"?`${t}% of text was pasted from external sources. The remaining ${e}% was typed directly.`:r.breakdown?`${t}% of text was pasted \u2014 ${r.breakdown}. The remaining ${e}% was typed directly.`:`${t}% of text was pasted. The remaining ${e}% was typed directly.`},"WT-104":()=>"All text was typed directly \u2014 no paste or autocomplete events were detected.","WT-105":()=>"Unmodified external content detected \u2014 pasted text was not edited after insertion, suggesting pre-composed content.","WT-106":n=>`${n.params.rework??0}% of pasted content was subsequently reworked, indicating the writer integrated external material into their own composition.`,"WT-107":n=>{let t=n.params.pasteRatio??0,e=n.params.retentionPct??0;return`High paste volume (${t}% paste ratio) with ${e}% left unmodified \u2014 content was pasted in bulk without rework.`}},je={"WT-105":()=>"Unmodified external content detected \u2014 pasted text was not edited after insertion, suggesting pre-composed content.","WT-106":n=>`${n.params.rework??0}% of pasted content was subsequently reworked, indicating the writer integrated external material into their own composition.`,"WT-107":n=>{let t=n.params.pasteRatio??0,e=n.params.retentionPct??0;return`High paste volume (${t}% paste ratio) with ${e}% left unmodified \u2014 content was pasted in bulk without rework.`}},Ye={"WT-200":n=>{let t=(n.params.dwellMean??0).toFixed(1),e=(n.params.flightMean??0).toFixed(1);return`Keystroke timing magnitudes (dwell ${t}ms, flight ${e}ms) fall below plausible human ranges, consistent with programmatic input injection.`},"WT-201":n=>`Keystroke timing is mechanically uniform \u2014 the coefficient of variation (${(n.params.cv??0).toFixed(2)}) falls far below the human range of 0.3\u20130.8. This pattern is consistent with automated input.`,"WT-202":n=>`A highly periodic keystroke pattern was detected (score ${(n.params.score??0).toFixed(2)}). Human typing naturally varies; metronomic regularity suggests automation.`,"WT-203":n=>`Flight times between keystrokes are suspiciously uniform (CV ${(n.params.cv??0).toFixed(2)}), lacking the natural variability expected from human finger movement.`,"WT-204":()=>"Keystroke timing variability falls within normal human ranges. The rhythm is consistent with natural typing.","WT-205":n=>{let t=(n.params.dwellCv??0).toFixed(2),e=(n.params.flightCv??0).toFixed(2);return`Metronomic keystroke timing \u2014 dwell CV ${t} and flight CV ${e} are far below human ranges, indicating machine-perfect regularity.`}},qe={"WT-500":(n,t)=>{let e=t.keydownCount;return e<50?`No corrections in a short ${e}-keystroke session. This is normal for brief input.`:`No corrections in a ${e}-keystroke session. Longer sessions typically include some corrections.`},"WT-501":()=>"No keystrokes were recorded, so revision behavior could not be analyzed.","WT-502":n=>`Very low correction rate (${(n.params.pct??0).toFixed(1)}%). While some writers are precise, this level of accuracy across an entire session is unusual.`,"WT-503":n=>`Normal correction rate (${(n.params.pct??0).toFixed(1)}%). The writer made and fixed mistakes at a rate consistent with natural composition.`,"WT-504":n=>`No corrections, navigation, or undo in a ${n.params.count??0}-keystroke session \u2014 the text was entered linearly without any revision.`,"WT-505":()=>"Non-linear editing was detected despite a low correction rate, suggesting some revision activity.","WT-506":n=>`Authentic revision depth detected (product-process ratio ${(n.params.ratio??0).toFixed(2)}). The writing process shows genuine iterative refinement.`,"WT-507":n=>{let t=n.params.count??0,e=n.params.keydowns??0;return`Sequential typing pattern: ${t} mid-document insertions in a ${e}-keystroke session. Content was entered start-to-finish without returning to edit earlier sections.`},"WT-508":n=>`Forward-edge concentration: ${Math.round((n.params.ratio??0)*100)}% of keystrokes occurred at the end of the document with almost no in-document editing, consistent with copy-typing or automation.`,"WT-509":n=>`Multi-word restructuring detected (${Math.round((n.params.ratio??0)*100)}% of chars from multi-word pastes), suggesting authentic revision where the writer rearranged their own text.`},Ue={"WT-300":n=>{let t=Math.round(n.params.timestamp??0),e=(n.params.magnitude??0).toFixed(1);return`Typing rhythm changed abruptly at ${t}s (magnitude ${e}), suggesting a possible switch in input method or author.`},"WT-301":n=>`${n.params.count??0} tab-away events detected \u2014 the writer left and returned to this field multiple times during the session.`,"WT-302":()=>"Behavior was consistent throughout the session with no abrupt changes in typing rhythm or style.","WT-303":()=>"No focus events were detected during the session. Real browsers generate focus events on interaction; absence is consistent with headless automation."},Ke={"WT-400":n=>`${n.params.pct??0}% of events lack browser trust indicators (isTrusted=false), suggesting synthetic event injection.`,"WT-401":n=>{let t=n.params.count??0,e=n.params.pct??0;return`${t} keydown events had no matching keyup (${e}% of keydowns). Automation tools often omit keyup events.`},"WT-402":n=>`${n.params.count??0} keystroke sequences exceed the maximum human typing speed, indicating programmatic input.`,"WT-403":()=>"All keystroke timing is physically plausible \u2014 no evidence of synthetic or injected events.","WT-404":n=>{let t=n.params.chars??0,e=n.params.pct??0;return`${t} characters (${e}%) were inserted via untrusted programmatic events rather than direct user input.`},"WT-405":n=>{let t=n.params.count??0,e=n.params.pct??0;return`${t} events (${e}% of keydowns) have sub-millisecond dwell time. Human key press/release always takes 30\u2013150ms; zero-latency events indicate programmatic injection.`},"WT-406":()=>"All dwell times fall within a single histogram bin, indicating uniform key-hold duration. Human typing always produces variation in how long keys are held."},Xe={"WT-600":n=>`No speed variation over a ${n.params.minutes??0}-minute session. Human typing naturally fluctuates; constant speed suggests automation.`,"WT-601":()=>"Natural warmup and fatigue pattern detected \u2014 the writer started slow, reached peak speed, then gradually slowed.","WT-602":()=>"Significant fatigue detected toward the end of the session, consistent with sustained human cognitive effort.","WT-603":()=>"Temporal patterns fall within normal range \u2014 typing pace varied naturally over the session.","WT-604":n=>`${n.params.ratio??0}% of keystrokes occurred in machine-like bursts, suggesting automated input segments.`,"WT-605":n=>`Uniform typing pace across the session (fluency SD ${(n.params.sd??0).toFixed(1)}). Human writers show more variation as they think, pause, and revise.`,"WT-606":n=>`Frequent revision interruptions detected (R-burst median ${(n.params.median??0).toFixed(1)}s), consistent with active editing behavior.`,"WT-607":n=>`No linguistic pause structure detected (sentence/word pause ratio ${(n.params.ratio??0).toFixed(2)}). Human writers pause longer before sentences than within words.`,"WT-608":n=>`Low cognitive pause rate (${(n.params.rate??0).toFixed(1)}% of keystrokes), suggesting text was transcribed rather than composed.`},Qe={"WT-700":()=>"Insufficient data for writing process analysis \u2014 the session was too short to classify phases.","WT-701":n=>`${n.params.pct??0}% of the session was spent in a planning phase \u2014 pausing and thinking before typing. This is a strong human signal.`,"WT-702":n=>`${n.params.pct??0}% of the session was spent in continuous drafting with minimal planning or revision, consistent with transcription or copy-typing.`,"WT-703":n=>`${n.params.pct??0}% of the session was spent revising earlier text. Frequent returns to edit are a strong human signal.`,"WT-704":n=>{let t=n.params.planning??0,e=n.params.drafting??0,r=n.params.revision??0;return`Balanced writing process \u2014 ${t}% planning, ${e}% drafting, ${r}% revision. This distribution is typical of genuine composition.`}},Je={contentOrigin:Ve,timingAuthenticity:Ye,revisionBehavior:qe,sessionContinuity:Ue,physicalPlausibility:Ke,temporalPatterns:Xe,writingProcess:Qe};function pt(n,t){let e=t[n];if(!(e!=null&&e.indicator))return"Analysis data not available.";let r=Je[n];if(!r)return le(e.indicator);if(n==="contentOrigin"&&e.pasteReworkIndicator){let i=e.pasteReworkIndicator.code,s=je[i];if(s)return s(e.pasteReworkIndicator,t)}let a=r[e.indicator.code];return a?a(e.indicator,t):le(e.indicator)}function le(n){return`Indicator ${n.code} detected.`}var Ze={contentOrigin:"Shows the mix of typed, pasted, and autocompleted content. Most writing sessions include some paste events \u2014 the balance and context matter more than presence alone.",timingAuthenticity:"A human heatmap shows scattered clusters reflecting natural variation in finger movement. Tight single-point concentration indicates programmatic keystroke injection.",revisionBehavior:"Human writers produce clusters of corrections as they re-read and revise. Absence of corrections suggests transcription rather than composition.",sessionContinuity:"Steady growth with small plateaus (thinking pauses) is typical. A sudden vertical jump indicates bulk content insertion.",physicalPlausibility:"Human editing jumps around the document \u2014 revising earlier sections, appending new text. Strictly sequential cursor movement suggests automated input.",temporalPatterns:"Human typing shows varied pause durations \u2014 short pauses within words, longer pauses between sentences. Uniform pause lengths suggest automated pacing.",writingProcess:"Shows the session divided into planning, drafting, and revision phases. Balanced phase distribution is typical of genuine composition; near-100% drafting suggests transcription."};function At(n){return Ze[n]??null}function ht(n,t){return({contentOrigin:tr,timingAuthenticity:er,revisionBehavior:rr,sessionContinuity:nr,physicalPlausibility:ar,temporalPatterns:or,writingProcess:sr}[n]??(()=>[]))(t)}function tr(n){let t=n.contentOrigin.metrics,e=Math.round(t.charactersByOrigin.pasted*100),r=Math.round(t.charactersByOrigin.typed*100),a=t.pasteEvents.length,i=t.pasteEvents.reduce((s,o)=>s+o.characterCount,0);return[{label:"pasted",value:`${e}%`,flagged:e>50},{label:"typed",value:`${r}%`,flagged:!1},{label:"paste events",value:String(a),flagged:!1},{label:"chars pasted",value:ir(i),flagged:!1}]}function er(n){let t=n.timingAuthenticity.metrics,e=t.flightTimeDistribution.cv,r=t.dwellTimeDistribution.mean;return[{label:"timing cv",value:e.toFixed(2),flagged:e<.2},{label:"mean dwell",value:`${Math.round(r)}ms`,flagged:r<20},{label:"periodicity",value:t.periodicityScore.toFixed(2),flagged:t.periodicityScore>.5},{label:"entropy",value:t.entropy.toFixed(1),flagged:t.entropy<1.5}]}function rr(n){let t=n.revisionBehavior.metrics;return[{label:"corrections",value:String(t.correctionCount),flagged:t.correctionCount===0&&n.keydownCount>=50},{label:"navigation",value:String(t.navigationCount),flagged:t.navigationCount===0&&n.keydownCount>=50},{label:"undo / redo",value:String(t.undoRedoCount),flagged:!1},{label:"product-process",value:t.productProcessRatio.toFixed(2),flagged:t.productProcessRatio===0}]}function nr(n){let t=n.sessionContinuity.metrics;return[{label:"change points",value:String(t.changePoints.length),flagged:t.changePoints.length>2},{label:"tab-away events",value:String(t.tabAwayEvents.length),flagged:!1}]}function ar(n){let t=n.physicalPlausibility.metrics;return[{label:"synthetic ratio",value:`${Math.round(t.syntheticEventRatio*100)}%`,flagged:t.syntheticEventRatio>.05},{label:"impossible seq.",value:String(t.impossibleSequences.count),flagged:t.impossibleSequences.count>0},{label:"unmatched keydowns",value:String(t.unmatchedKeydownCount),flagged:t.unmatchedKeydownCount>5},{label:"zero-latency",value:String(t.zeroLatencyEventCount),flagged:t.zeroLatencyEventCount>0},{label:"Bulk Insert",value:String(t.bulkInsertCharCount),flagged:!1}]}function or(n){let t=n.temporalPatterns.metrics;return[{label:"duration",value:me(t.sessionDurationMs),flagged:!1},{label:"warmup ratio",value:t.warmupRatio.toFixed(2),flagged:!1},{label:"fatigue ratio",value:t.fatigueRatio.toFixed(2),flagged:!1},{label:"burst ratio",value:t.burstPattern.burstToTotalRatio.toFixed(2),flagged:t.burstPattern.burstToTotalRatio>.7}]}function sr(n){let t=n.writingProcess.metrics,e=Math.round(t.timeInPhase.planning*100),r=Math.round(t.timeInPhase.drafting*100),a=Math.round(t.timeInPhase.revision*100);return[{label:"planning",value:`${e}%`,flagged:!1},{label:"drafting",value:`${r}%`,flagged:r>85},{label:"revision",value:`${a}%`,flagged:!1},{label:"phase changes",value:String(t.phaseChangeCount),flagged:t.phaseChangeCount===0&&n.keydownCount>=200}]}function ir(n){return n>=1e6?`${(n/1e6).toFixed(1)}m`:n>=1e3?`${(n/1e3).toFixed(1)}k`:String(n)}function me(n){let t=Math.round(n/1e3);if(t<60)return`${t}s`;let e=Math.floor(t/60),r=t%60;return r===0?`${e}m`:`${e}m ${r}s`}var ue={"coefficient of variation":{definition:"Standard deviation divided by the mean \u2014 measures how spread out values are relative to their average. Low CV means uniform timing.",docsPath:"/docs/analysis/timing/"},"dwell time":{definition:"How long a key is held down before being released.",docsPath:"/docs/analysis/timing/"},"flight time":{definition:"The gap between releasing one key and pressing the next.",docsPath:"/docs/analysis/timing/"},"product-process ratio":{definition:"The ratio of final text length to total characters typed. Low values suggest heavy revision; near 1.0 suggests linear transcription.",docsPath:"/docs/analysis/revision/"},periodicity:{definition:"How rhythmically regular the typing pattern is. High periodicity suggests metronomic (automated) input."},entropy:{definition:"A measure of randomness in timing. Low entropy means predictable, uniform intervals."},burst:{definition:"A rapid sequence of keystrokes between pauses. Human typing naturally occurs in bursts."},"synthetic event":{definition:"A keyboard event generated programmatically rather than by a real keypress. Browsers mark these with isTrusted=false."},"change point":{definition:"A moment where typing rhythm shifts abruptly, potentially indicating a switch in input method."}};function gt(n,t){let e=P(n);for(let[r,a]of Object.entries(ue)){let i=new RegExp(`\\b(${cr(r)})\\b`,"gi");e=e.replace(i,s=>{let o=`title="${P(a.definition)}" class="wt-term"`,c=P(s);if(a.docsPath){let l=(t??"https://writetrack.dev")+a.docsPath;return`<a href="${P(l)}" target="_blank" rel="noopener"><abbr ${o}>${c}</abbr></a>`}return`<abbr ${o}>${c}</abbr>`})}return e}function cr(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}import*as S from"@observablehq/plot";function $t(n,t=500){var y,w,v;let e=(y=n.session)==null?void 0:y.events;if(!(e!=null&&e.length))return{points:[],pauses:[]};let r=e.filter(g=>g.type==="keydown");if(r.length===0)return{points:[],pauses:[]};let a=r.filter(g=>g.key!=="FOCUS"&&g.key!=="BLUR");if(a.length===0)return{points:[],pauses:[]};let i=n.session.sessionStartTime,s=[];for(let g of a)g.key==="Backspace"||g.key==="Delete"?s.push({timestamp:g.timestamp,processDelta:1,productDelta:-1,cursorPosition:g.cursorPosition,kind:"key",key:g.key}):j.test(g.key)&&s.push({timestamp:g.timestamp,processDelta:1,productDelta:1,cursorPosition:g.cursorPosition,kind:"key",key:g.key});let o=[];for(let g of((w=n.session)==null?void 0:w.clipboardEvents)??[])g.type==="paste"?o.push({timestamp:g.timestamp,processDelta:g.length,productDelta:g.length,kind:"clipboard"}):g.type==="cut"&&o.push({timestamp:g.timestamp,processDelta:g.length,productDelta:-g.length,kind:"clipboard"});let c=[];for(let g of((v=n.session)==null?void 0:v.selectionEvents)??[])c.push({timestamp:g.timestamp,selectedLength:g.selectedLength,kind:"selection"});let l=[...s,...o,...c];if(l.sort((g,C)=>g.timestamp-C.timestamp),l.length===0)return{points:[],pauses:[]};let d=[],u=[],p=0,m=0,f=0,h=0;for(let g of l){if(g.kind==="selection"){h=g.selectedLength;continue}let C=g.productDelta;g.kind==="key"&&h>0?(g.key==="Backspace"||g.key==="Delete"?C=-h:C=1-h,h=0):g.kind==="key"&&(h=0),"processDelta"in g&&(p+=g.processDelta),m=Math.max(0,m+C),g.kind==="key"&&g.cursorPosition!==void 0&&(f=g.cursorPosition),d.push({time:(g.timestamp-i)/1e3,process:p,product:m,cursor:f}),g.kind==="key"&&u.push({timestamp:g.timestamp,productAfter:m})}let b=[];for(let g=1;g<u.length;g++){let C=u[g-1],x=u[g].timestamp-C.timestamp;if(x>=t){let O=C.timestamp+x/2;b.push({time:(O-i)/1e3,product:C.productAfter,pauseMs:x})}}return{points:d,pauses:b}}var pe="var(--wt-color-secondary, #22d3ee)",he="var(--wt-color-primary, #fbbf24)",ge="var(--wt-color-tertiary, #7C6DAF)",Mt="#f97316";function lr(n,t){let e=n/t,r=Math.pow(10,Math.floor(Math.log10(e))),a=e/r;return(a<=1?1:a<=2?2:a<=5?5:10)*r}var dr=28,mr=24,F=class extends k{constructor(){super(...arguments);this.s=null}setChangePoint(e){this.s=e,this._data&&this.safeRender()}static get observedAttributes(){return[...super.observedAttributes,"process","cursor","pauses","pause-threshold"]}attributeChangedCallback(e,r,a){super.attributeChangedCallback(e,r,a),(e==="process"||e==="cursor"||e==="pauses"||e==="pause-threshold")&&this._data&&this.hasRendered&&this.safeRender()}render(){if(!this._data)return;let e=this.getAttribute("pause-threshold"),r=e!==null?Math.max(0,Number(e)):void 0,{points:a,pauses:i}=$t(this._data,r);if(a.length===0){this.showEmptyState("No keystroke data");return}let s=st(a,it,h=>h.time,h=>h.product),o=this.compact,c=this.hasAttribute("process"),l=this.hasAttribute("cursor"),d=this.hasAttribute("pauses")&&!o,u=!o&&(c||l||d),p=this.getChartHeight(400),m=Math.max(p-mr-(u?dr:0),60),f=this.getChartWidth(640);try{let h=[];if(h.push(S.lineY(s,{x:"time",y:"product",stroke:he,strokeWidth:1.5,curve:"step-after"})),c&&h.push(S.lineY(s,{x:"time",y:"process",stroke:pe,strokeWidth:2,curve:"step-after"})),l&&h.push(S.lineY(s,{x:"time",y:"cursor",stroke:ge,strokeWidth:1,strokeDasharray:"4,3",curve:"step-after"})),d&&i.length>0){let y=Math.max(...s.map(x=>x.product));c&&(y=Math.max(y,...s.map(x=>x.process))),l&&(y=Math.max(y,...s.map(x=>x.cursor)));let w=Math.max(...i.map(x=>x.pauseMs/1e3)),v=x=>y>0&&w>0?x/w*y:x,C=lr(w,4),_=[];for(let x=C;x<=w+C*.01;x+=C)_.push(x);h.push(S.axisY({anchor:"left",label:"Characters"})),h.push(S.axisY(_.map(v),{anchor:"right",color:Mt,label:"Pause (s)",tickFormat:(x,O)=>`${_[O]}s`})),h.push(S.dot(i,S.mapY(x=>x.map(v),{x:"time",y:x=>x.pauseMs/1e3,r:x=>Math.max(3,Math.sqrt(x.pauseMs/150)),fill:Mt,fillOpacity:.6})))}!o&&this.s!=null&&h.push(S.ruleX([this.s],{stroke:"var(--wt-color-secondary, #22d3ee)",...J})),o||h.push(S.tip(s,S.pointerX({x:"time",y:"product",title:y=>{let w=`${y.time.toFixed(1)}s
|
|
192
|
-
Product: ${
|
|
193
|
-
Process: ${
|
|
194
|
-
Cursor: ${
|
|
190
|
+
`,mt=class extends T{getStylesheet(){return K+`
|
|
191
|
+
`+Ie}render(){if(!this._data)return;let{integrity:t,outputSignature:e}=this._data,n=document.createElement("div");n.className="integrity-section";let a=document.createElement("div");a.className="integrity-title",a.textContent="Integrity & Verification",n.appendChild(a);let o=document.createElement("div");o.className="integrity-stats",o.textContent=`${t.eventCount} events \xB7 ${t.checkpoints.length} checkpoints`,n.appendChild(o);let s=document.createElement("div");s.className="integrity-hash-block";let i=document.createElement("span");i.className="integrity-hash-label",i.textContent="Digest (SHA-256)";let c=document.createElement("code");c.className="hash",c.textContent=t.finalDigest,s.append(i,c),n.appendChild(s);let l=document.createElement("div");l.className="integrity-hash-block";let d=document.createElement("span");d.className="integrity-hash-label",d.textContent="Output Signature";let m=document.createElement("code");m.className="hash",m.textContent=e,l.append(d,m),n.appendChild(l);let u=document.createElement("div");u.className="integrity-bottom";let g=document.createElement("div");g.className="qr-container";let h=document.createElement("p");h.className="integrity-explainer",h.textContent="This scorecard includes cryptographic integrity verification. The digest covers all input events; the signature covers the analysis output. Compare against original session data or scan for verification.",u.appendChild(g),u.appendChild(h),n.appendChild(u),this.replaceChart(n),requestAnimationFrame(()=>this.renderQr(t.finalDigest))}renderQr(t){let e=this.shadow.querySelector(".qr-container");if(!e)return;let n=St(t);if(!n)return;let a=getComputedStyle(this),o=a.getPropertyValue("--wt-scorecard-text").trim()||"#E4E2DA",s=a.getPropertyValue("--wt-scorecard-status-clear").trim()||"#5EAE78";e.innerHTML=Ct(n,o,s)}};mt.tagName="wt-integrity-footer";function ie(r){if(r<1e3)return"0 seconds";let t=Math.floor(r/1e3),e=Math.floor(t/86400),n=Math.floor(t%86400/3600),a=Math.floor(t%3600/60),o=t%60,s=[];return e>0&&s.push(`${e} ${e===1?"day":"days"}`),n>0&&s.push(`${n} ${n===1?"hour":"hours"}`),a>0&&s.push(`${a} ${a===1?"minute":"minutes"}`),o>0&&e===0&&s.push(`${o} ${o===1?"second":"seconds"}`),s.join(" ")||"0 seconds"}function ut(r){var w,b,S,D,W,y,x,N,I,tt,Rt,_t,Bt,Ot,Nt,It,Lt,Ft,Ht,Gt,zt,qt;if(!r.sufficientData){let V=r.keydownCount??0,ye=((b=(w=r.temporalPatterns)==null?void 0:w.metrics)==null?void 0:b.sessionDurationMs)??0;if(V===0)return null;let we=ie(ye);return`This session captured ${V} keystroke${V===1?"":"s"} over ${we}.`}let t=((W=(D=(S=r.contentOrigin)==null?void 0:S.metrics)==null?void 0:D.charactersByOrigin)==null?void 0:W.typed)??0,e=((N=(x=(y=r.contentOrigin)==null?void 0:y.metrics)==null?void 0:x.charactersByOrigin)==null?void 0:N.pasted)??0,n=((Rt=(tt=(I=r.revisionBehavior)==null?void 0:I.metrics)==null?void 0:tt.insertionDeletion)==null?void 0:Rt.deletionCount)??0,a=((Ot=(Bt=(_t=r.contentOrigin)==null?void 0:_t.metrics)==null?void 0:Bt.pasteEditSummary)==null?void 0:Ot.meanReworkRatio)??0,o=((It=(Nt=r.temporalPatterns)==null?void 0:Nt.metrics)==null?void 0:It.sessionDurationMs)??0,s=((Ht=(Ft=(Lt=r.temporalPatterns)==null?void 0:Lt.metrics)==null?void 0:Ft.pause2000ms)==null?void 0:Ht.count)??0,i=((qt=(zt=(Gt=r.sessionContinuity)==null?void 0:Gt.metrics)==null?void 0:zt.tabAwayEvents)==null?void 0:qt.length)??0,c=ie(o),l=(t*100).toFixed(1),d=(e*100).toFixed(1),m=t>=.8,u=e>.5,g;m?g=`This text was typed directly over ${c}.`:u?g=`${d}% of this text was pasted from an external source.`:g=`This text contains a mix of typed (${l}%) and pasted (${d}%) content.`;let h=a>0?", and edited pasted content afterward":"",p;n>0?p=`The author made ${n} ${n===1?"correction":"corrections"}${h}.`:p=`No corrections were made${h}.`;let f=i>0?` and ${i} tab-away${i===1?"":"s"}`:"",v;return s>0?v=`The session lasted ${c} with ${s} ${s===1?"pause":"pauses"} to think${f}.`:v=`The session lasted ${c} with no significant pauses${f}.`,`${g} ${p} ${v}`}function Et(r){let t=r.internalPct??0,e=r.externalPct??0,n=r.unknownPct??0,a=r.copyPct??0,o=r.cutPct??0,s=t+e+n;if(s>0&&t>s*.8)return o>a?{type:"internal-cut",label:"cut and re-pasted within the document",breakdown:null}:a>o?{type:"internal-copy",label:"copied and re-pasted within the document",breakdown:null}:{type:"internal",label:"reorganised within the document",breakdown:null};if(s>0&&e>s*.8)return{type:"external",label:"pasted from external sources",breakdown:null};let i=[];return t>0&&(o>a?i.push(`${Math.round(t)}% cut-pasted`):a>o?i.push(`${Math.round(t)}% copy-pasted`):i.push(`${Math.round(t)}% reorganised`)),e>0&&i.push(`${Math.round(e)}% external`),n>0&&i.push(`${Math.round(n)}% unclassified`),i.length>=1?{type:"mixed",label:"pasted",breakdown:i.join(", ")}:{type:"unknown",label:"pasted",breakdown:null}}function Le(r){return{days:Math.trunc(r/864e5),hours:Math.trunc(r/36e5%24),minutes:Math.trunc(r/6e4%60),seconds:Math.trunc(r/1e3%60),milliseconds:Math.trunc(r%1e3)}}var Fe=(r,t)=>t===1?r:`${r}s`,He=1e-7;function At(r,t={}){if(!Number.isFinite(r))throw new TypeError("Expected a finite number");let e={...t},n=r<0?"-":"";r=Math.abs(r),e.colonNotation&&(e.compact=!1,e.separateMilliseconds=!1,e.verbose=!1),e.compact&&(e.unitCount=1,e.secondsDecimalDigits=0,e.millisecondsDecimalDigits=0);let a=[],o=(l,d)=>{let m=Math.floor(l*10**d+He);return(Math.round(m)/10**d).toFixed(d)},s=(l,d,m,u)=>{if(!((a.length===0||!e.colonNotation)&&l===0&&!(e.colonNotation&&m==="m"))){if(u??=String(l),e.colonNotation){let g=u.includes(".")?u.split(".")[0].length:u.length,h=a.length>0?2:1;u="0".repeat(Math.max(0,h-g))+u}else u+=e.verbose?" "+Fe(d,l):m;a.push(u)}},i=Le(r);if(e.hideYearAndDays?s(i.days*24+i.hours,"hour","h"):(e.hideYear?s(i.days,"day","d"):(s(Math.trunc(i.days/365),"year","y"),s(i.days%365,"day","d")),s(i.hours,"hour","h")),s(i.minutes,"minute","m"),!e.hideSeconds)if(e.separateMilliseconds||!e.colonNotation&&r<1e3){s(i.seconds,"second","s");let l=typeof e.millisecondsDecimalDigits=="number"?e.millisecondsDecimalDigits:0,d=l?i.milliseconds.toFixed(l):String(Math.round(i.milliseconds));s(Number.parseFloat(d),"millisecond","ms",d)}else{let l=r/1e3%60,d=typeof e.secondsDecimalDigits=="number"?e.secondsDecimalDigits:1,m=o(l,d),u=e.keepDecimalsOnWholeSeconds?m:m.replace(/\.0+$/,"");s(Number.parseFloat(u),"second","s",u)}if(a.length===0)return n+"0"+(e.verbose?" milliseconds":"ms");let c=e.colonNotation?":":" ";return typeof e.unitCount=="number"&&(a=a.slice(0,Math.max(e.unitCount,1))),n+a.join(c)}var ce=new Set(["WT-103","WT-104","WT-106","WT-204","WT-207","WT-301","WT-302","WT-403","WT-500","WT-503","WT-505","WT-506","WT-507","WT-508","WT-509","WT-601","WT-602","WT-603","WT-605","WT-606","WT-607","WT-700","WT-701","WT-702","WT-703","WT-704"]);function Ge(r){return ce.has(r)}function B(r){return r?ce.has(r)?"pass":"flag":"unknown"}var X={contentOrigin:"Content Origin",timingAuthenticity:"Timing & Rhythm",revisionBehavior:"Revision Behavior",sessionContinuity:"Session Continuity",physicalPlausibility:"Physical Plausibility",temporalPatterns:"Temporal Patterns",writingProcess:"Writing Process"};var ze=["contentOrigin","timingAuthenticity","revisionBehavior"],qe=["sessionContinuity","physicalPlausibility","temporalPatterns","writingProcess"],Ve={"WT-100":()=>"No content was recorded during this session.","WT-101":r=>{let t=r.params.pct??0,e=100-t,n=Et(r.params);return n.type==="internal-cut"?`Nearly all content (${t}%) was cut and re-pasted within the document \u2014 the writer reorganised their own text. ${e}% of characters were typed directly.`:n.type==="internal-copy"?`Nearly all content (${t}%) was copied and re-pasted within the document \u2014 the writer duplicated and reworked their own text. ${e}% of characters were typed directly.`:n.type==="internal"?`Nearly all content (${t}%) was reorganised within the document. ${e}% of characters were typed directly.`:n.type==="external"?`Nearly all content (${t}%) was pasted from an external source. Only ${e}% of characters were typed directly.`:n.breakdown?`${t}% of content was pasted \u2014 ${n.breakdown}. ${e}% was typed directly.`:`Nearly all content (${t}%) was pasted. Only ${e}% of characters were typed directly.`},"WT-102":r=>`${r.params.pct??0}% of text was inserted via autocomplete, suggesting reliance on predictive input rather than original composition.`,"WT-103":r=>{let t=r.params.pct??0,e=100-t,n=Et(r.params);return n.type==="internal-cut"?`${t}% of text was cut and re-pasted within the document \u2014 the writer reorganised their own text. The remaining ${e}% was typed directly.`:n.type==="internal-copy"?`${t}% of text was copied and re-pasted within the document \u2014 the writer duplicated and reworked their own text. The remaining ${e}% was typed directly.`:n.type==="internal"?`${t}% of text was reorganised within the document. The remaining ${e}% was typed directly.`:n.type==="external"?`${t}% of text was pasted from external sources. The remaining ${e}% was typed directly.`:n.breakdown?`${t}% of text was pasted \u2014 ${n.breakdown}. The remaining ${e}% was typed directly.`:`${t}% of text was pasted. The remaining ${e}% was typed directly.`},"WT-104":()=>"All text was typed directly \u2014 no paste or autocomplete events were detected.","WT-105":()=>"Unmodified external content detected \u2014 pasted text was not edited after insertion, suggesting pre-composed content.","WT-106":r=>`${r.params.rework??0}% of pasted content was subsequently reworked, indicating the writer integrated external material into their own composition.`,"WT-107":r=>{let t=r.params.pasteRatio??0,e=r.params.retentionPct??0;return`High paste volume (${t}% paste ratio) with ${e}% left unmodified \u2014 content was pasted in bulk without rework.`}},je={"WT-105":()=>"Unmodified external content detected \u2014 pasted text was not edited after insertion, suggesting pre-composed content.","WT-106":r=>`${r.params.rework??0}% of pasted content was subsequently reworked, indicating the writer integrated external material into their own composition.`,"WT-107":r=>{let t=r.params.pasteRatio??0,e=r.params.retentionPct??0;return`High paste volume (${t}% paste ratio) with ${e}% left unmodified \u2014 content was pasted in bulk without rework.`}},Ye={"WT-200":r=>{let t=(r.params.dwellMean??0).toFixed(1),e=(r.params.flightMean??0).toFixed(1);return`Keystroke timing magnitudes (dwell ${t}ms, flight ${e}ms) fall below plausible human ranges, consistent with programmatic input injection.`},"WT-201":r=>`Keystroke timing is mechanically uniform \u2014 the coefficient of variation (${(r.params.cv??0).toFixed(2)}) falls far below the human range of 0.3\u20130.8. This pattern is consistent with automated input.`,"WT-202":r=>`A highly periodic keystroke pattern was detected (score ${(r.params.score??0).toFixed(2)}). Human typing naturally varies; metronomic regularity suggests automation.`,"WT-203":r=>`Flight times between keystrokes are suspiciously uniform (CV ${(r.params.cv??0).toFixed(2)}), lacking the natural variability expected from human finger movement.`,"WT-204":()=>"Keystroke timing variability falls within normal human ranges. The rhythm is consistent with natural typing.","WT-205":r=>{let t=(r.params.dwellCv??0).toFixed(2),e=(r.params.flightCv??0).toFixed(2);return`Metronomic keystroke timing \u2014 dwell CV ${t} and flight CV ${e} are far below human ranges, indicating machine-perfect regularity.`},"WT-207":r=>`${((r.params.ratio??0)*100).toFixed(0)}% of inter-keystroke intervals fall on exact millisecond boundaries, consistent with setTimeout-based automation. Human typing produces fractional-ms precision.`,"WT-208":r=>`Key-hold and flight times are statistically independent (r=${(r.params.r??0).toFixed(3)}). Human typing shows correlation between how long a key is held and the gap before the next key, reflecting shared cognitive tempo.`,"WT-209":r=>`Key-hold times have a suspiciously symmetric distribution (skewness ${(r.params.skewness??0).toFixed(2)}). Human key-holds are right-skewed due to occasional long presses during hesitation.`,"WT-210":r=>`Timing for repeated key pairs is too variable (CV ${(r.params.cv??0).toFixed(2)}). Skilled typists produce consistent timing for familiar letter combinations through muscle memory.`,"WT-211":r=>`Corrections happen at the same speed as normal typing (ratio ${(r.params.ratio??0).toFixed(2)}). Humans pause noticeably before reaching for Backspace \u2014 the recognition delay is a hallmark of authentic error correction.`,"WT-212":r=>`Flight times between keystrokes have a suspiciously symmetric distribution (skewness ${(r.params.skewness??0).toFixed(2)}). Human inter-key gaps are right-skewed due to thinking pauses and word boundaries.`,"WT-213":r=>`Consecutive keystrokes within typing bursts show no speed continuity (r=${(r.params.r??0).toFixed(3)}). Human motor control creates positive correlation \u2014 fast sequences stay fast, slow stays slow.`,"WT-214":r=>`${r.params.nearCount??0} timing metrics cluster suspiciously close to their detection thresholds, suggesting parameter tuning to evade individual checks while leaving a statistical fingerprint.`,"WT-215":r=>`Keystroke timing compressibility (${(r.params.ratio??0).toFixed(2)}) falls outside the human range. Human typing has structured temporal patterns; automation produces either too-random or too-regular sequences.`,"WT-216":r=>`Low temporal pattern complexity (WPE ${(r.params.wpe??0).toFixed(2)}). Human keystroke sequences have rich ordinal patterns from natural rhythm variation; this session's patterns are too simple.`,"WT-217":r=>`The overall timing profile diverges significantly from human reference patterns (distance ${(r.params.distance??0).toFixed(1)}). Multiple timing metrics are simultaneously anomalous.`},Ke={"WT-500":(r,t)=>{let e=t.keydownCount;return e<50?`No corrections in a short ${e}-keystroke session. This is normal for brief input.`:`No corrections in a ${e}-keystroke session. Longer sessions typically include some corrections.`},"WT-501":()=>"No keystrokes were recorded, so revision behavior could not be analyzed.","WT-502":r=>`Very low correction rate (${(r.params.pct??0).toFixed(1)}%). While some writers are precise, this level of accuracy across an entire session is unusual.`,"WT-503":r=>`Normal correction rate (${(r.params.pct??0).toFixed(1)}%). The writer made and fixed mistakes at a rate consistent with natural composition.`,"WT-504":r=>`No corrections, navigation, or undo in a ${r.params.count??0}-keystroke session \u2014 the text was entered linearly without any revision.`,"WT-505":()=>"Non-linear editing was detected despite a low correction rate, suggesting some revision activity.","WT-506":r=>`Authentic revision depth detected (product-process ratio ${(r.params.ratio??0).toFixed(2)}). The writing process shows genuine iterative refinement.`,"WT-507":r=>{let t=r.params.count??0,e=r.params.keydowns??0;return`Sequential typing pattern: ${t} mid-document insertions in a ${e}-keystroke session. Content was entered start-to-finish without returning to edit earlier sections.`},"WT-508":r=>`Forward-edge concentration: ${Math.round((r.params.ratio??0)*100)}% of keystrokes occurred at the end of the document with almost no in-document editing, consistent with copy-typing or automation.`,"WT-509":r=>`Multi-word restructuring detected (${Math.round((r.params.ratio??0)*100)}% of chars from multi-word pastes), suggesting authentic revision where the writer rearranged their own text.`,"WT-511":()=>"Every correction deletes exactly one character. Human corrections vary \u2014 sometimes a single letter, sometimes whole words. Uniform single-character deletion suggests automation.","WT-512":r=>`Only ${r.params.regions??r.params.corrections??0} text regions were revised more than once. Human writers frequently return to earlier sections to refine their work.`,"WT-513":r=>`An implausible number of text regions (${r.params.regions??0}) were revised multiple times. While human writers revisit earlier sections, this level of re-editing is far beyond normal patterns and suggests automated revision injection.`,"WT-514":r=>`${((r.params.ratio??0)*100).toFixed(0)}% of all corrections revisited previously-edited regions. Real writers occasionally return to earlier fixes, but this ratio suggests systematic automated revision rather than organic editing.`,"WT-515":()=>"No editing behind the text frontier \u2014 all keystrokes occurred at the end of the document. Human writers navigate backward to revise earlier sections.","WT-516":r=>`Correction characters are ${(r.params.mean??r.params.adjacencyMean??0).toFixed(1)} keys apart on the keyboard on average. Real typos hit adjacent keys; random corrections land far apart.`,"WT-611":r=>`${((r.params.ratio??0)*100).toFixed(0)}% of pauses occur after completing words. An extremely high concentration of post-word pauses suggests automated word-by-word insertion rather than natural composition flow.`},Ue={"WT-300":r=>{let t=Math.round(r.params.timestamp??0),e=(r.params.magnitude??0).toFixed(1);return`Typing rhythm changed abruptly at ${t}s (magnitude ${e}), suggesting a possible switch in input method or author.`},"WT-301":r=>`${r.params.count??0} tab-away events detected \u2014 the writer left and returned to this field multiple times during the session.`,"WT-302":()=>"Behavior was consistent throughout the session with no abrupt changes in typing rhythm or style.","WT-303":()=>"No focus events were detected during the session. Real browsers generate focus events on interaction; absence is consistent with headless automation."},Xe={"WT-400":r=>`${r.params.pct??0}% of events lack browser trust indicators (isTrusted=false), suggesting synthetic event injection.`,"WT-401":r=>{let t=r.params.count??0,e=r.params.pct??0;return`${t} keydown events had no matching keyup (${e}% of keydowns). Automation tools often omit keyup events.`},"WT-402":r=>`${r.params.count??0} keystroke sequences exceed the maximum human typing speed, indicating programmatic input.`,"WT-403":()=>"All keystroke timing is physically plausible \u2014 no evidence of synthetic or injected events.","WT-404":r=>{let t=r.params.chars??0,e=r.params.pct??0;return`${t} characters (${e}%) were inserted via untrusted programmatic events rather than direct user input.`},"WT-405":r=>{let t=r.params.count??0,e=r.params.pct??0;return`${t} events (${e}% of keydowns) have sub-millisecond dwell time. Human key press/release always takes 30\u2013150ms; zero-latency events indicate programmatic injection.`},"WT-406":()=>"All dwell times fall within a single histogram bin, indicating uniform key-hold duration. Human typing always produces variation in how long keys are held.","WT-408":r=>`Key rollover rate is only ${((r.params.rate??0)*100).toFixed(0)}% at fast typing speed. Skilled typists press the next key before releasing the current one; automation tools release before pressing.`,"WT-409":r=>{let t=((r.params.rollover??0)*100).toFixed(0),e=((r.params.mouse??0)*100).toFixed(0);return`Low key rollover (${t}%) combined with low mouse activity (${e}%). Real users move the mouse between typing bursts; automation bypasses the mouse entirely.`},"WT-410":r=>`No navigation or modifier keys in a ${r.params.keydowns??0}-keystroke session. Real typing uses arrow keys, Shift, Ctrl, and other modifiers \u2014 their complete absence suggests automation.`,"WT-412":()=>"No modifier key variety detected despite uppercase characters being present. Real typing uses Shift keys for capitalisation.","WT-413":()=>"Modifier keys were pressed but never held down. Real Shift usage involves holding the key while typing the capitalised letter.","WT-415":r=>`Mouse activity detected during ${((r.params.mouseRatio??0)*100).toFixed(0)}% of typing periods, which is unusually high. Constant mouse movement during typing suggests automated cursor repositioning.`,"WT-421":r=>`Synthetic event ratio (${((r.params.ratio??0)*100).toFixed(2)}%) is unusually high. A small number of browser-generated events is normal, but this level suggests deliberate injection.`,"WT-422":r=>`${r.params.count??0} zero-latency key events detected, which is unusually high. While some rapid keypresses produce near-zero timing, this many suggests programmatic injection.`},Qe={"WT-600":r=>`No speed variation over a ${r.params.minutes??0}-minute session. Human typing naturally fluctuates; constant speed suggests automation.`,"WT-601":()=>"Natural warmup and fatigue pattern detected \u2014 the writer started slow, reached peak speed, then gradually slowed.","WT-602":()=>"Significant fatigue detected toward the end of the session, consistent with sustained human cognitive effort.","WT-603":()=>"Temporal patterns fall within normal range \u2014 typing pace varied naturally over the session.","WT-604":r=>`${r.params.ratio??0}% of keystrokes occurred in machine-like bursts, suggesting automated input segments.`,"WT-605":r=>`Uniform typing pace across the session (fluency SD ${(r.params.sd??0).toFixed(1)}). Human writers show more variation as they think, pause, and revise.`,"WT-606":r=>`Frequent revision interruptions detected (R-burst median ${(r.params.median??0).toFixed(1)}s), consistent with active editing behavior.`,"WT-607":r=>`No linguistic pause structure detected (sentence/word pause ratio ${(r.params.ratio??0).toFixed(2)}). Human writers pause longer before sentences than within words.`,"WT-608":r=>`Low cognitive pause rate (${(r.params.rate??0).toFixed(1)}% of keystrokes), suggesting text was transcribed rather than composed.`,"WT-609":()=>"Very few typing bursts detected in a substantial session. Human writing naturally alternates between bursts of typing and pauses for thought.","WT-610":r=>{let t=(r.params.pauseRate??0).toFixed(0),e=(r.params.ratio??0).toFixed(1);return`High pause frequency (${t}/min) with ${e}x more short pauses than long ones. Human typing produces fewer, more varied pauses; this pattern suggests artificial pacing.`},"WT-612":r=>`Typing speed varies dramatically between session segments (SD ${(r.params.sd??0).toFixed(1)}). While some variation is normal, extreme fluctuation suggests alternating between automated and manual input.`},Je={"WT-700":()=>"Insufficient data for writing process analysis \u2014 the session was too short to classify phases.","WT-701":r=>`${r.params.pct??0}% of the session was spent in a planning phase \u2014 pausing and thinking before typing. This is a strong human signal.`,"WT-702":r=>`${r.params.pct??0}% of the session was spent in continuous drafting with minimal planning or revision, consistent with transcription or copy-typing.`,"WT-703":r=>`${r.params.pct??0}% of the session was spent revising earlier text. Frequent returns to edit are a strong human signal.`,"WT-704":r=>{let t=r.params.planning??0,e=r.params.drafting??0,n=r.params.revision??0;return`Balanced writing process \u2014 ${t}% planning, ${e}% drafting, ${n}% revision. This distribution is typical of genuine composition.`}},Ze={contentOrigin:Ve,timingAuthenticity:Ye,revisionBehavior:Ke,sessionContinuity:Ue,physicalPlausibility:Xe,temporalPatterns:Qe,writingProcess:Je};function pt(r,t){let e=t[r];if(!(e!=null&&e.indicator))return"Analysis data not available.";let n=Ze[r];if(!n)return oe(e.indicator);if(r==="contentOrigin"&&e.pasteReworkIndicator){let o=e.pasteReworkIndicator.code,s=je[o];if(s)return s(e.pasteReworkIndicator,t)}let a=n[e.indicator.code];return a?a(e.indicator,t):oe(e.indicator)}function oe(r){return`Indicator ${r.code} detected.`}var tr={contentOrigin:"Shows the mix of typed, pasted, and autocompleted content. Most writing sessions include some paste events \u2014 the balance and context matter more than presence alone.",timingAuthenticity:"A human heatmap shows scattered clusters reflecting natural variation in finger movement. Tight single-point concentration indicates programmatic keystroke injection.",revisionBehavior:"Human writers produce clusters of corrections as they re-read and revise. Absence of corrections suggests transcription rather than composition.",sessionContinuity:"Steady growth with small plateaus (thinking pauses) is typical. A sudden vertical jump indicates bulk content insertion.",physicalPlausibility:"Human editing jumps around the document \u2014 revising earlier sections, appending new text. Strictly sequential cursor movement suggests automated input.",temporalPatterns:"Human typing shows varied pause durations \u2014 short pauses within words, longer pauses between sentences. Uniform pause lengths suggest automated pacing.",writingProcess:"Shows the session divided into planning, drafting, and revision phases. Balanced phase distribution is typical of genuine composition; near-100% drafting suggests transcription."};function Pt(r){return tr[r]??null}function Q(r,t){return({contentOrigin:er,timingAuthenticity:rr,revisionBehavior:nr,sessionContinuity:ar,physicalPlausibility:sr,temporalPatterns:ir,writingProcess:or}[r]??(()=>[]))(t)}function er(r){let t=r.contentOrigin.metrics,e=Math.round(t.charactersByOrigin.pasted*100),n=Math.round(t.charactersByOrigin.typed*100),a=t.pasteEvents.length,o=t.pasteEvents.reduce((s,i)=>s+i.characterCount,0);return[{label:"pasted",value:`${e}%`,flagged:e>50},{label:"typed",value:`${n}%`,flagged:!1},{label:"paste events",value:String(a),flagged:!1},{label:"chars pasted",value:cr(o),flagged:!1}]}function rr(r){let t=r.timingAuthenticity.metrics,e=t.flightTimeDistribution.cv,n=t.dwellTimeDistribution.mean;return[{label:"timing cv",value:e.toFixed(2),flagged:e<.2},{label:"mean dwell",value:`${Math.round(n)}ms`,flagged:n<20},{label:"periodicity",value:t.periodicityScore.toFixed(2),flagged:t.periodicityScore>.5},{label:"entropy",value:t.entropy.toFixed(1),flagged:t.entropy<1.5}]}function nr(r){let t=r.revisionBehavior.metrics;return[{label:"corrections",value:String(t.correctionCount),flagged:t.correctionCount===0&&r.keydownCount>=50},{label:"navigation",value:String(t.navigationCount),flagged:t.navigationCount===0&&r.keydownCount>=50},{label:"undo / redo",value:String(t.undoRedoCount),flagged:!1},{label:"product-process",value:t.productProcessRatio.toFixed(2),flagged:t.productProcessRatio===0}]}function ar(r){let t=r.sessionContinuity.metrics;return[{label:"change points",value:String(t.changePoints.length),flagged:t.changePoints.length>2},{label:"tab-away events",value:String(t.tabAwayEvents.length),flagged:!1}]}function sr(r){let t=r.physicalPlausibility.metrics;return[{label:"synthetic ratio",value:`${Math.round(t.syntheticEventRatio*100)}%`,flagged:t.syntheticEventRatio>.05},{label:"impossible seq.",value:String(t.impossibleSequences.count),flagged:t.impossibleSequences.count>0},{label:"unmatched keydowns",value:String(t.unmatchedKeydownCount),flagged:t.unmatchedKeydownCount>5},{label:"zero-latency",value:String(t.zeroLatencyEventCount),flagged:t.zeroLatencyEventCount>0},{label:"Bulk Insert",value:String(t.bulkInsertCharCount),flagged:!1}]}function ir(r){let t=r.temporalPatterns.metrics;return[{label:"duration",value:le(t.sessionDurationMs),flagged:!1},{label:"warmup ratio",value:t.warmupRatio.toFixed(2),flagged:!1},{label:"fatigue ratio",value:t.fatigueRatio.toFixed(2),flagged:!1},{label:"burst ratio",value:t.burstPattern.burstToTotalRatio.toFixed(2),flagged:t.burstPattern.burstToTotalRatio>.7}]}function or(r){let t=r.writingProcess.metrics,e=Math.round(t.timeInPhase.planning*100),n=Math.round(t.timeInPhase.drafting*100),a=Math.round(t.timeInPhase.revision*100);return[{label:"planning",value:`${e}%`,flagged:!1},{label:"drafting",value:`${n}%`,flagged:n>85},{label:"revision",value:`${a}%`,flagged:!1},{label:"phase changes",value:String(t.phaseChangeCount),flagged:t.phaseChangeCount===0&&r.keydownCount>=200}]}function cr(r){return r>=1e6?`${(r/1e6).toFixed(1)}m`:r>=1e3?`${(r/1e3).toFixed(1)}k`:String(r)}function le(r){return!Number.isFinite(r)||r<1e3?"0s":At(r,{secondsDecimalDigits:0,unitCount:2})}var de={"coefficient of variation":{definition:"Standard deviation divided by the mean \u2014 measures how spread out values are relative to their average. Low CV means uniform timing.",docsPath:"/docs/analysis/timing/"},"dwell time":{definition:"How long a key is held down before being released.",docsPath:"/docs/analysis/timing/"},"flight time":{definition:"The gap between releasing one key and pressing the next.",docsPath:"/docs/analysis/timing/"},"product-process ratio":{definition:"The ratio of final text length to total characters typed. Low values suggest heavy revision; near 1.0 suggests linear transcription.",docsPath:"/docs/analysis/revision/"},periodicity:{definition:"How rhythmically regular the typing pattern is. High periodicity suggests metronomic (automated) input."},entropy:{definition:"A measure of randomness in timing. Low entropy means predictable, uniform intervals."},burst:{definition:"A rapid sequence of keystrokes between pauses. Human typing naturally occurs in bursts."},"synthetic event":{definition:"A keyboard event generated programmatically rather than by a real keypress. Browsers mark these with isTrusted=false."},"change point":{definition:"A moment where typing rhythm shifts abruptly, potentially indicating a switch in input method."},"warmup ratio":{definition:"The ratio of early-session typing speed to peak speed. Low values indicate a natural ramp-up period."},"fatigue ratio":{definition:"The ratio of late-session typing speed to peak speed. Declining speed suggests natural fatigue."},"burst ratio":{definition:"The proportion of keystrokes that occur in rapid bursts versus steady typing."},"R-burst":{definition:"A burst of rapid revisions \u2014 deletes and retypes in quick succession, typical of real-time self-correction."},"P-burst":{definition:"A burst of rapid production \u2014 sustained fast typing without pauses, typical of transcription or paste-like input."},"cognitive pause":{definition:"A pause longer than typical inter-keystroke gaps, suggesting the writer is thinking about what to write next."},"fluency SD":{definition:"Standard deviation of typing fluency across the session. Higher values indicate natural variation in writing flow."}},lr=Object.entries(de).sort((r,t)=>t[0].length-r[0].length);function ht(r,t){let e=P(r),n=[];for(let[a,o]of lr){let s=new RegExp(`\\b(${dr(a)})\\b`,"gi");e=e.replace(s,i=>{let c=`title="${P(o.definition)}" class="wt-term"`,l=P(i),d;if(o.docsPath){let u=(t??"https://writetrack.dev")+o.docsPath;d=`<a href="${P(u)}" target="_blank" rel="noopener"><abbr ${c}>${l}</abbr></a>`}else d=`<abbr ${c}>${l}</abbr>`;let m=n.length;return n.push(d),`\u200B${m}\u200B`})}return e=e.replace(/\u200B(\d+)\u200B/g,(a,o)=>n[Number(o)]),e}function dr(r){return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function $t(r,t=500,e=[]){var S,D,W;let n=(S=r.session)==null?void 0:S.events;if(!(n!=null&&n.length))return{points:[],pauses:[]};let a=n.filter(y=>y.type==="keydown");if(a.length===0)return{points:[],pauses:[]};let o=a.filter(y=>y.key!=="FOCUS"&&y.key!=="BLUR");if(o.length===0)return{points:[],pauses:[]};let s=r.session.sessionStartTime,i=e.length>0,c=y=>i?E(y-s,e):(y-s)/1e3,l=[];for(let y of o)y.key==="Backspace"||y.key==="Delete"?l.push({timestamp:y.timestamp,processDelta:1,productDelta:-1,cursorPosition:y.cursorPosition,kind:"key",key:y.key}):H.test(y.key)&&l.push({timestamp:y.timestamp,processDelta:1,productDelta:1,cursorPosition:y.cursorPosition,kind:"key",key:y.key});let d=[];for(let y of((D=r.session)==null?void 0:D.clipboardEvents)??[])y.type==="paste"?d.push({timestamp:y.timestamp,processDelta:y.length,productDelta:y.length,kind:"clipboard"}):y.type==="cut"&&d.push({timestamp:y.timestamp,processDelta:y.length,productDelta:-y.length,kind:"clipboard"});let m=[];for(let y of((W=r.session)==null?void 0:W.selectionEvents)??[])m.push({timestamp:y.timestamp,selectedLength:y.selectedLength,kind:"selection"});let u=[...l,...d,...m];if(u.sort((y,x)=>y.timestamp-x.timestamp),u.length===0)return{points:[],pauses:[]};let g=[],h=[],p=0,f=0,v=0,w=0;for(let y of u){if(y.kind==="selection"){w=y.selectedLength;continue}let x=y.productDelta;y.kind==="key"&&w>0?(y.key==="Backspace"||y.key==="Delete"?x=-w:x=1-w,w=0):y.kind==="key"&&(w=0),"processDelta"in y&&(p+=y.processDelta),f=Math.max(0,f+x),y.kind==="key"&&y.cursorPosition!==void 0&&(v=y.cursorPosition),g.push({time:c(y.timestamp),process:p,product:f,cursor:v}),y.kind==="key"&&h.push({timestamp:y.timestamp,productAfter:f})}let b=[];for(let y=1;y<h.length;y++){let x=h[y-1],I=h[y].timestamp-x.timestamp;if(I>=t){let tt=x.timestamp+I/2;b.push({time:c(tt),product:x.productAfter,pauseMs:I})}}return{points:g,pauses:b}}var me="var(--wt-color-secondary, #22d3ee)",ue="var(--wt-color-primary, #fbbf24)",pe="var(--wt-color-tertiary, #7C6DAF)",Mt="#f97316";function mr(r,t){let e=r/t,n=Math.pow(10,Math.floor(Math.log10(e))),a=e/n;return(a<=1?1:a<=2?2:a<=5?5:10)*n}var ur=28,pr=24,O=class extends T{constructor(){super(...arguments);this.c=null}setChangePoint(e){this.c=e,this._data&&this.safeRender()}static get observedAttributes(){return[...super.observedAttributes,"process","cursor","pauses","pause-threshold"]}attributeChangedCallback(e,n,a){super.attributeChangedCallback(e,n,a),(e==="process"||e==="cursor"||e==="pauses"||e==="pause-threshold")&&this._data&&this.hasRendered&&this.safeRender()}render(){if(!this._data)return;let e=k();if(!e){this.showEmptyState(C);return}let n=this.getAttribute("pause-threshold"),a=n!==null?Math.max(0,Number(n)):void 0,{points:o,pauses:s}=$t(this._data,a,this.i);if(o.length===0){this.showEmptyState("No keystroke data");return}let i=st(o,it,f=>f.time,f=>f.product),c=this.compact,l=this.hasAttribute("process"),d=this.hasAttribute("cursor"),m=this.hasAttribute("pauses")&&!c,u=!c&&(l||d||m),g=this.getChartHeight(400),h=Math.max(g-pr-(u?ur:0),60),p=this.getChartWidth(640);try{let f=[];if(f.push(e.lineY(i,{x:"time",y:"product",stroke:ue,strokeWidth:1.5,curve:"step-after"})),l&&f.push(e.lineY(i,{x:"time",y:"process",stroke:me,strokeWidth:2,curve:"step-after"})),d&&f.push(e.lineY(i,{x:"time",y:"cursor",stroke:pe,strokeWidth:1,strokeDasharray:"4,3",curve:"step-after"})),m&&s.length>0){let w=Math.max(...i.map(x=>x.product));l&&(w=Math.max(w,...i.map(x=>x.process))),d&&(w=Math.max(w,...i.map(x=>x.cursor)));let b=Math.max(...s.map(x=>x.pauseMs/1e3)),S=x=>w>0&&b>0?x/b*w:x,W=mr(b,4),y=[];for(let x=W;x<=b+W*.01;x+=W)y.push(x);f.push(e.axisY({anchor:"left",label:"Characters"})),f.push(e.axisY(y.map(S),{anchor:"right",color:Mt,label:"Pause (s)",tickFormat:(x,N)=>`${y[N]}s`})),f.push(e.dot(s,e.mapY(x=>x.map(S),{x:"time",y:x=>x.pauseMs/1e3,r:x=>Math.max(3,Math.sqrt(x.pauseMs/150)),fill:Mt,fillOpacity:.6})))}!c&&this.c!=null&&f.push(e.ruleX([this.c],{stroke:"var(--wt-color-secondary, #22d3ee)",...Y})),c||f.push(e.tip(i,e.pointerX({x:"time",y:"product",title:w=>{let b=`${w.time.toFixed(1)}s
|
|
192
|
+
Product: ${w.product}`;return l&&(b+=`
|
|
193
|
+
Process: ${w.process}`),d&&(b+=`
|
|
194
|
+
Cursor: ${w.cursor}`),b},...$})));let v=e.plot({width:p,height:h,...c?M:{marginLeft:50,marginBottom:35,...m?{marginRight:60}:{}},x:c?{axis:null}:{label:"Active Time (s)"},y:c?{axis:null}:{label:"Characters",grid:!0},marks:f,style:A});if(u){let w=[];l&&w.push({label:"Process",color:me}),w.push({label:"Product",color:ue}),d&&w.push({label:"Cursor Position",color:pe}),m&&w.push({label:"Pauses",color:Mt});let b=document.createElement("div");b.appendChild(v),b.appendChild(R(w)),this.replaceChart(b)}else this.replaceChart(v)}catch(f){_(`DocumentGrowth render failed: ${f}`)}}};O.tagName="wt-document-growth";var hr=O,gr=$t;var fr=10;function J(r){var u,g,h,p,f,v,w,b,S,D,W,y;let t=r.finalTextLength??0,e=r.keydownCount??0,o=e>=fr&&t>0?Math.round(e/t*100)/100:null,s=((g=(u=r.contentOrigin)==null?void 0:u.metrics)==null?void 0:g.pasteEvents)??[],i=s.length>0&&t>0?Math.round(Math.max(...s.map(x=>x.characterCount))/t*100):null,c=((f=(p=(h=r.revisionBehavior)==null?void 0:h.metrics)==null?void 0:p.insertionDeletion)==null?void 0:f.deletionCount)??0,l=((w=(v=r.revisionBehavior)==null?void 0:v.metrics)==null?void 0:w.revisionAtFrontierRatio)??0,d=((S=(b=r.revisionBehavior)==null?void 0:b.metrics)==null?void 0:S.revisionAtPriorRatio)??0,m=((y=(W=(D=r.sessionContinuity)==null?void 0:D.metrics)==null?void 0:W.tabAwayEvents)==null?void 0:y.length)??0;return[{label:"Effort Ratio",value:o!==null?`${o.toFixed(2)}\xD7`:"--",status:o===null?"neutral":o<1?"flag":"clear",metric:"effort-ratio"},{label:"Largest Paste",value:i!==null?`${i}%`:"--",status:"neutral",metric:"largest-paste"},{label:"Corrections",value:c>0?`${Math.round(l*100)}% typo / ${Math.round(d*100)}% revision`:"--",status:"neutral",metric:"corrections"},{label:"Tab-Aways",value:String(m),status:"neutral",metric:"tab-aways"}]}var yr=new Set(["effort-ratio","largest-paste","corrections","tab-aways"]),wr=`
|
|
195
195
|
.wt-chart {
|
|
196
196
|
background: transparent;
|
|
197
197
|
padding: 0;
|
|
@@ -229,8 +229,8 @@ Cursor: ${y.cursor}`),w},...M})));let b=S.plot({width:f,height:m,...o?A:{marginL
|
|
|
229
229
|
background: var(--wt-color-border, #27272a);
|
|
230
230
|
color: var(--wt-color-text, #fafafa);
|
|
231
231
|
}
|
|
232
|
-
`;function
|
|
233
|
-
`+
|
|
232
|
+
`;function ft(r){let t=document.createElement("div");t.className="wt-badges";for(let e of r){let n=document.createElement("span");n.className="wt-badge";let a=document.createElement("span");a.className="wt-badge-label",a.textContent=e.label;let o=document.createElement("span");o.className=`wt-badge-value ${e.status}`,o.textContent=e.value,n.append(a,o),t.appendChild(n)}return t}var gt=class extends T{static get observedAttributes(){return["data","theme","label","metric"]}attributeChangedCallback(t,e,n){if(t==="metric"&&this._data){this.setData(this._data);return}super.attributeChangedCallback(t,e,n)}getStylesheet(){return et+`
|
|
233
|
+
`+wr}render(){if(!this._data)return;let t=this.getAttribute("metric");if(!t||!yr.has(t)){this.container.replaceChildren();return}let n=J(this._data).find(i=>i.metric===t);if(!n||n.value==="--"){this.container.replaceChildren();return}let a=document.createElement("div");a.className="wt-badge";let o=document.createElement("span");o.className="wt-badge-label",o.textContent=n.label;let s=document.createElement("span");s.className=`wt-badge-value ${n.status}`,s.textContent=n.value,a.append(o,s),this.replaceChart(a)}};gt.tagName="wt-badge";var br="0.12.0",Dt=["contentOrigin","timingAuthenticity","revisionBehavior","sessionContinuity","physicalPlausibility","temporalPatterns"],he={contentOrigin:[0,1],timingAuthenticity:[0,1],revisionBehavior:[0,3],sessionContinuity:[0,1],physicalPlausibility:[0,1],temporalPatterns:[1,2],writingProcess:[0,1]},vr={contentOrigin:"Origin",timingAuthenticity:"Rhythm",revisionBehavior:"Revisions",sessionContinuity:"Continuity",physicalPlausibility:"Plausibility",temporalPatterns:"Temporal",writingProcess:"Process"},xr={contentOrigin:{name:"Edit Beeswarm",desc:"Every keystroke in the session \u2014 colour shows whether text was typed, pasted, or deleted"},timingAuthenticity:{name:"Rhythm Heatmap",desc:"How long each key was held vs. the gap before it \u2014 clusters mean consistent rhythm, scatter means natural variation"},revisionBehavior:{name:"Corrections Timeline",desc:"Corrections and deletions over the session \u2014 bigger dots mean larger edits"},sessionContinuity:{name:"Document Growth Curve",desc:"How the document grew \u2014 steady climbs mean typing, vertical jumps mean pasted blocks"},physicalPlausibility:{name:"Edit Waterfall",desc:"Where in the document edits happened \u2014 jumping around suggests real editing, straight lines suggest automation"},temporalPatterns:{name:"Speed Timeline",desc:"Typing speed over the session \u2014 most writers start slow, speed up, then tire"},writingProcess:{name:"Writing Process",desc:"Time spent thinking, writing, and revising \u2014 a mix of all three is typical of real composition"}},Tr=`:host { display: block; overflow-x: hidden; overflow-y: visible; }
|
|
234
234
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
235
235
|
.page {
|
|
236
236
|
max-width: 100%;
|
|
@@ -503,5 +503,5 @@ Cursor: ${y.cursor}`),w},...M})));let b=S.plot({width:f,height:m,...o?A:{marginL
|
|
|
503
503
|
.page { padding: 1.25rem 1rem 2rem; }
|
|
504
504
|
.detail-inner { padding: 1rem; }
|
|
505
505
|
}
|
|
506
|
-
`,
|
|
507
|
-
`+xr}attributeChangedCallback(e,r,a){if(e==="theme"&&this._data&&this.hasRendered){requestAnimationFrame(()=>this.rerenderAllCharts());return}if((e==="share"||e==="download")&&this._data&&this.hasRendered){this.setData(this._data);return}super.attributeChangedCallback(e,r,a)}render(){var b;if(!((b=this._data)!=null&&b.analysis))return;let{data:e,analysis:r}=this._data,a=this.o,i=document.createElement("div");i.className="page",i.setAttribute("part","page"),i.appendChild(this.buildHeader(r,e));let s=yt(r);i.appendChild(Dt(s));let o=Et(r)??"No text was entered.",c=document.createElement("p");c.className="narrative",c.textContent=o,i.appendChild(c);let l=document.createElement("div");l.className="origin-bar-container",l.id="origin-bar",i.appendChild(l);let d=this.buildFlags(r);d&&i.appendChild(d);let u=this.buildGrid(r);i.appendChild(u);let p=this.buildDetailPanel();i.appendChild(p),i.appendChild(this.buildIntegrityDetails(r));let m=document.createElement("div");m.className="version-footer",m.textContent=`WriteTrack v${yr}`,i.appendChild(m);let f=this.closest('[class*="scorecard"]')??this.parentElement,h=(f==null?void 0:f.scrollTop)??0;this.replaceChart(i),requestAnimationFrame(()=>{this.renderAllCharts(),this.renderOriginBarIfPresent(),this.selectCell(a),f&&h>0&&(f.scrollTop=h)})}buildHeader(e,r){let a=document.createElement("header");a.className="header";let i=document.createElement("div");i.className="header-logo",a.appendChild(i);let s=document.createElement("div");s.className="header-meta";let o=document.createElement("div");o.className="header-title",o.textContent="WriteTrack Session",s.appendChild(o);let c=r.metadata.sessionId??"";if(c){let w=document.createElement("div");w.className="header-session-id",w.textContent=c,s.appendChild(w)}let l=document.createElement("div");l.className="header-meta-line";let d=r.metadata.timestamp,p=r.metadata.duration,m=d?new Date(d):new Date(e.analyzedAt),f={day:"numeric",month:"long",year:"numeric"};if(p&&p>0){let w=new Date(m.getTime()+p),v=m.toLocaleDateString("en-GB",f),g=w.toLocaleDateString("en-GB",f);l.textContent=v===g?v:`${v} \u2013 ${g}`}else l.textContent=m.toLocaleDateString("en-GB",f);s.appendChild(l),a.appendChild(s);let h=document.createElement("div");h.className="header-qr",this.hasAttribute("share")&&(h.style.cursor="pointer",h.title="Share",h.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("wt-share",{bubbles:!0,composed:!0,detail:{report:this._data}}))})),a.appendChild(h);let b=this.hasAttribute("share"),y=this.hasAttribute("download");if(b||y){let w=document.createElement("span");if(w.className="header-actions",b){let v=document.createElement("button");v.setAttribute("data-action","share"),v.setAttribute("aria-label","Share report"),v.title="Share",v.innerHTML='<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12v1a1 1 0 001 1h6a1 1 0 001-1v-1M8 2v8M5 5l3-3 3 3"/></svg>',v.addEventListener("click",g=>{g.stopPropagation(),this.dispatchEvent(new CustomEvent("wt-share",{bubbles:!0,composed:!0,detail:{report:this._data}}))}),w.appendChild(v)}if(y){let v=document.createElement("button");v.setAttribute("data-action","download"),v.setAttribute("aria-label","Download session data"),v.title="Download session data",v.innerHTML='<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12v1a1 1 0 001 1h6a1 1 0 001-1v-1M8 10V2M5 7l3 3 3-3"/></svg>',v.addEventListener("click",g=>{g.stopPropagation(),this.dispatchEvent(new CustomEvent("wt-download",{bubbles:!0,composed:!0,detail:{report:this._data}}))}),w.appendChild(v)}o.appendChild(w)}return requestAnimationFrame(()=>{let w=getComputedStyle(this),v=w.getPropertyValue("--wt-scorecard-text").trim()||"#E4E2DA",g=w.getPropertyValue("--wt-scorecard-status-clear").trim()||"#5EAE78";i.innerHTML=ie(60,v,g);let C=Tt(e.integrity.finalDigest);C&&(h.innerHTML=St(C,v))}),a}buildFlags(e){if(!e.sufficientData)return null;let r=fe.filter(i=>K(this.getIndicatorCode(e,i))==="flag");if(r.length===0)return null;let a=document.createElement("div");a.className="flags";for(let i of r){let s=document.createElement("div");s.className="flag-item";let o=pt(i,e);s.innerHTML=`<strong class="flag-label">Flagged</strong> ${P(et[i]??i)}\u2009\u2014\u2009${P(o)}`,a.appendChild(s)}return a}buildIntegrityDetails(e){let r=document.createElement("details");r.className="integrity-details";let a=document.createElement("summary"),i=document.createElement("span");i.textContent="Integrity & Verification";let s=document.createElement("span");s.className="integrity-stats",s.textContent=`${e.integrity.eventCount} events \xB7 ${e.integrity.checkpoints.length} checkpoints`,a.append(i,s),r.appendChild(a);let o=document.createElement("div");o.className="integrity-hash-block";let c=document.createElement("span");c.className="integrity-hash-label",c.textContent="Digest (SHA-256)";let l=document.createElement("code");if(l.className="hash",l.textContent=e.integrity.finalDigest,o.append(c,l),r.appendChild(o),e.outputSignature){let d=document.createElement("div");d.className="integrity-hash-block";let u=document.createElement("span");u.className="integrity-hash-label",u.textContent="Output Signature";let p=document.createElement("code");p.className="hash",p.textContent=e.outputSignature,d.append(u,p),r.appendChild(d)}return r}buildGrid(e){let r=document.createElement("div");r.className="grid-container";let a=document.createElement("div");a.className="indicator-grid",a.id="grid";for(let i of fe)a.appendChild(this.buildCell(i,e));return r.appendChild(a),r}buildCell(e,r){let a=this.getIndicatorCode(r,e),i=K(a),s=r.sufficientData&&i==="flag",o=document.createElement("div");o.className="cell"+(s?" flagged":""),o.setAttribute("data-category",e),o.addEventListener("click",()=>this.selectCell(e));let c=document.createElement("div");c.className="cell-header";let l=document.createElement("div");l.className="cell-name-col";let d=document.createElement("span");d.className="cell-name";let u=document.createElement("span");u.className="cell-name-short",u.textContent=wr[e]??e;let p=document.createElement("span");p.className="cell-name-full",p.textContent=et[e]??e,d.append(u,p),l.appendChild(d);let m=document.createElement("span");m.className=`cell-status ${s?"flagged":"clear"}`,m.title=s?"Flagged":"Clear",c.append(l,m),o.appendChild(c);let f=document.createElement("div");f.className="cell-chart",o.appendChild(f);let h=ht(e,r),b=br[e];return o.appendChild(this.buildCellMetrics(h,b)),o}buildCellMetrics(e,r){let a=document.createElement("div");a.className="cell-metrics";for(let i of r){let s=e[i];if(!s)continue;let o=document.createElement("div");o.className="cell-metric",o.innerHTML=`<span class="cell-metric-label">${P(s.label)}</span><span class="cell-metric-value">${P(s.value)}</span>`,a.appendChild(o)}return a}buildDetailPanel(){let e=document.createElement("div");e.className="detail-panel",e.id="detail";let r=document.createElement("div");return r.className="detail-inner",r.id="detail-inner",e.appendChild(r),e}selectCell(e){var c;let r=(c=this._data)==null?void 0:c.analysis;if(!r)return;let a=this.shadow.getElementById("detail-inner"),i=a&&a.children.length===0;if(this.o===e&&!i)return;this.o=e;let s=this.shadow.getElementById("grid");s==null||s.querySelectorAll(".cell").forEach(l=>l.classList.remove("selected"));let o=s==null?void 0:s.querySelector(`[data-category="${e}"]`);o==null||o.classList.add("selected"),this.populateAndRenderDetail(e,r)}populateAndRenderDetail(e,r){let a=this.shadow.getElementById("detail-inner");if(!a)return;a.classList.add("fading");let i=()=>{this.populateDetail(a,e,r),requestAnimationFrame(()=>{let s=a.querySelector(".detail-chart-area");if(s){let o=this.createDetailChart(e);if(o){let c=s.clientWidth;c>0&&o.el.style.setProperty("--wt-chart-width",`${c}px`),s.replaceChildren(o.el),o.init()}else{let c=document.createElement("span");c.className="detail-chart-empty",c.textContent="Insufficient data for chart",s.replaceChildren(c)}}a.classList.remove("fading")})};if(a.children.length===0)i();else{let s=!1,o=()=>{s||(s=!0,i())},c=setTimeout(o,300);a.addEventListener("transitionend",()=>{clearTimeout(c),o()},{once:!0})}}populateDetail(e,r,a){let i=this.getIndicatorCode(a,r),s=K(i),o=a.sufficientData&&s==="flag",c='<div class="detail-head">';c+=`<span class="detail-name">${P(et[r]??r)}</span>`,c+=`<span class="detail-code">${P(i??"")}</span>`,c+=`<span class="detail-status-label ${o?"flagged":"clear"}">${o?"flagged":"clear"}</span>`,c+="</div>";let l=pt(r,a);c+=`<p class="detail-summary">${gt(l)}</p>`,c+='<div class="detail-chart-area"></div>';let d=vr[r];c+=`<div class="detail-chart-caption">${P(d.name)} \u2014 ${P(d.desc)}</div>`;let u=ht(r,a);c+='<div class="detail-metrics">';for(let m of u)c+=`<div class="detail-metric"><span class="detail-metric-value">${P(m.value)}</span><span class="detail-metric-label">${P(m.label)}</span></div>`;c+="</div>";let p=At(r);p&&(c+=`<p class="detail-explainer">${gt(p)}</p>`),e.innerHTML=c}getIndicatorCode(e,r){var i;let a=e[r];return(i=a==null?void 0:a.indicator)==null?void 0:i.code}getComputedColors(){let e=getComputedStyle(this);return{line:e.getPropertyValue("--wt-scorecard-chart-line").trim()||"#1C1B18",accent:e.getPropertyValue("--wt-scorecard-chart-accent").trim()||"#2B7A5D",flagged:e.getPropertyValue("--wt-scorecard-chart-flagged").trim()||"#B8412D",border:e.getPropertyValue("--wt-scorecard-border").trim()||"#E0DED6",tertiary:e.getPropertyValue("--wt-scorecard-text-tertiary").trim()||"#706E64",chartTertiary:e.getPropertyValue("--wt-scorecard-chart-tertiary").trim()||"#7C6DAF",cyan:e.getPropertyValue("--wt-scorecard-chart-cyan").trim()||"#5B8FA8"}}renderOriginBarIfPresent(){var l;let e=(l=this._data)==null?void 0:l.analysis;if(!e)return;let r=this.shadow.getElementById("origin-bar");if(!r)return;let a=this.getComputedColors(),i={typed:a.accent,pasted:a.chartTertiary,autocompleted:a.cyan},s={autocompleted:a.line},o=r.getBoundingClientRect().width||400,c=mt(dt(e),o,i,s);c&&r.replaceChildren(c)}createDetailChart(e,r=!1){var p;if(!((p=this._data)!=null&&p.analysis))return null;let{data:a,analysis:i}=this._data,s=this.getComputedColors(),o=this.getIndicatorCode(i,e),l=K(o)==="flag"?s.flagged:s.accent,d=(m,f)=>{f&&m.style.setProperty("--wt-chart-height",`${f}px`),m.style.setProperty("--wt-color-primary",l),m.style.setProperty("--wt-color-secondary",s.accent),m.style.setProperty("--wt-color-text",s.tertiary),m.style.setProperty("--wt-color-text-muted",s.tertiary),m.style.setProperty("--wt-color-border",s.border),m.style.setProperty("--wt-color-bg","transparent"),m.style.setProperty("--wt-color-surface","transparent"),m.style.setProperty("--wt-font-data","var(--wt-scorecard-font-data)"),m.style.setProperty("--wt-font-ui","var(--wt-scorecard-font-display)"),m.style.setProperty("--wt-beeswarm-insert",s.accent),m.style.setProperty("--wt-beeswarm-delete",s.flagged),m.style.setProperty("--wt-beeswarm-paste",s.chartTertiary),m.style.setProperty("--wt-beeswarm-cut",s.tertiary),m.style.setProperty("--wt-bubble-insert",s.accent),m.style.setProperty("--wt-bubble-delete",s.flagged),m.style.setProperty("--wt-bubble-paste",s.chartTertiary),m.style.setProperty("--wt-bubble-cut",s.tertiary),m.style.setProperty("--wt-color-cut",s.flagged),m.style.display="block"},u=(m,f)=>{m.register();let h=new m;return d(h,r?void 0:200),r&&(h.setAttribute("compact",""),h.style.height="52px"),{el:h,init:()=>f(h)}};switch(e){case"contentOrigin":return u(Y,m=>m.setData(a));case"timingAuthenticity":return u(G,m=>m.setData(i));case"revisionBehavior":return u(U,m=>m.setData(a));case"sessionContinuity":return u(F,m=>{var h,b;m.setAttribute("process",""),m.setAttribute("cursor","");let f=((b=(h=i.sessionContinuity)==null?void 0:h.metrics)==null?void 0:b.changePoints)??[];f.length>0&&m.setChangePoint(f[0].timestamp/1e3),m.setData(a)});case"physicalPlausibility":return u(q,m=>m.setData(a));case"temporalPatterns":return u(z,m=>m.setData(i));default:return null}}renderAllCharts(){this.shadow.querySelectorAll(".cell-chart").forEach(e=>{let r=e.closest(".cell"),a=r==null?void 0:r.getAttribute("data-category");if(!a)return;let i=this.createDetailChart(a,!0);i&&(e.replaceChildren(i.el),i.init())})}rerenderAllCharts(){this.renderAllCharts();let e=this.o;if(e){let r=this.shadow.querySelector("#detail-inner .detail-chart-area");if(r){let a=this.createDetailChart(e);if(a){let i=r.clientWidth;i>0&&a.el.style.setProperty("--wt-chart-width",`${i}px`),r.replaceChildren(a.el),a.init()}}}this.renderOriginBarIfPresent()}};bt.tagName="wt-scorecard";import*as W from"@observablehq/plot";var rt={typing:"var(--wt-segment-typing, var(--wt-color-primary, #fbbf24))",paste:"var(--wt-segment-paste, var(--wt-color-secondary, #22d3ee))",pause:"var(--wt-segment-pause, var(--wt-color-text-muted, #a1a1aa))",tabAway:"var(--wt-segment-tab-away, #ef4444)",autocomplete:"var(--wt-segment-autocomplete, #a78bfa)",navigating:"var(--wt-segment-navigating, #34d399)"},kr={typing:"Typed",paste:"Pasted",pause:"Pause",tabAway:"Tab away",autocomplete:"Autocomplete",navigating:"Navigating"};function Rt(n){let t=n.sessionTimeline;return t!=null&&t.length?t.map(e=>({start:e.startTime/1e3,end:e.endTime/1e3,type:e.type,color:rt[e.type]??"#666"})):[]}function ye(n){var e,r;return(((r=(e=n.contentOrigin)==null?void 0:e.metrics)==null?void 0:r.pasteEvents)??[]).map(a=>({time:a.timestamp/1e3,chars:a.characterCount,source:a.source}))}function be(n){return Rt(n).filter(t=>t.type==="tabAway")}var wt=class extends k{static get observedAttributes(){return[...super.observedAttributes,"mode"]}get mode(){return this.getAttribute("mode")??"full"}render(){if(!this._data)return;if(this.mode==="focus"){this.d();return}let t=Rt(this._data);if(t.length===0){this.showEmptyState("No session data");return}let e=ye(this._data),r=this.compact,a=[W.barX(t,{x1:"start",x2:"end",fill:"color",y:()=>"Activity",inset:.5})];r||a.push(W.tip(t,W.pointer({x:c=>(c.start+c.end)/2,y:()=>"Activity",title:c=>`${c.type} \u2014 ${(c.end-c.start).toFixed(1)}s`,...M}))),!r&&e.length&&a.push(W.dot(e,{x:"time",y:()=>"Activity",r:"chars",fill:rt.paste,fillOpacity:.7,stroke:"var(--wt-color-bg, #111113)",strokeWidth:1}));let i=this.getChartWidth(640),s=this.getChartHeight(120),o=W.plot({width:i,height:s,...r?A:{marginLeft:8,marginBottom:35},x:r?{axis:null}:{label:"Time (s)"},y:{axis:null,padding:.2},marks:a,style:E});if(r)this.replaceChart(o);else{let c=[...new Set(t.map(d=>d.type))],l=document.createElement("div");l.appendChild(o),l.appendChild(N(c.map(d=>({label:kr[d]??d,color:rt[d]??"#666"})))),this.replaceChart(l)}}d(){if(!this._data)return;let t=be(this._data);if(t.length===0){this.showEmptyState("No tab-away events");return}let e=this.getChartWidth(640),r=this.getChartHeight(60),a=W.plot({width:e,height:r,marginLeft:8,marginBottom:35,x:{label:"Time (s)"},y:{axis:null,padding:.2},marks:[W.barX(t,{x1:"start",x2:"end",fill:rt.tabAway,y:()=>"Focus",inset:.5})],style:E});this.replaceChart(a)}};wt.tagName="wt-composition-timeline";export{k as BaseChart,et as CATEGORY_NAMES,wt as CompositionTimeline,U as CorrectionsBubble,F as DocumentGrowth,Y as EditBeeswarm,q as EditWaterfall,ue as GLOSSARY,ut as IntegrityFooter,at as PauseDistribution,ur as ProcessGraph,G as RhythmHeatmap,rt as SEGMENT_COLORS,xt as Sparkline,z as SpeedTimeline,ze as TIER1_CATEGORIES,Ge as TIER2_CATEGORIES,ft as WtBadge,lt as WtOriginBar,bt as WtScorecard,Jt as extractBeeswarmData,re as extractCorrectionBubbles,be as extractFocusSegments,pr as extractGrowthData,dt as extractOriginData,ye as extractPasteMarkers,Qt as extractPauseHistogram,$t as extractProcessData,Xt as extractRhythmPairs,Rt as extractSegments,Ut as extractSeries,Kt as extractSpeedData,yt as extractStatBadges,te as extractWaterfallData,me as formatDuration,At as generateCaption,pt as generateSummary,Et as generateWritingSummary,ht as getMetrics,K as getStatus,He as isPass,mt as renderOriginBar,Dt as renderStatBadges,gt as wrapTerms};
|
|
506
|
+
`,yt=class extends T{constructor(){super(...arguments);this.t="contentOrigin"}static get observedAttributes(){return[...super.observedAttributes,"share","download"]}onResize(){if(this.t){let n=this.shadow.querySelector("#detail-inner .detail-chart-area"),a=n==null?void 0:n.firstElementChild;if(a&&n){let o=n.clientWidth;o>0&&a.style.setProperty("--wt-chart-width",`${o}px`)}}}getStylesheet(){return K+`
|
|
507
|
+
`+Tr}attributeChangedCallback(e,n,a){if(e==="theme"&&this._data&&this.hasRendered){requestAnimationFrame(()=>this.rerenderAllCharts());return}if((e==="share"||e==="download")&&this._data&&this.hasRendered){this.setData(this._data);return}super.attributeChangedCallback(e,n,a)}connectedCallback(){super.connectedCallback(),Vt().then(()=>{this._data&&this.hasRendered&&this.safeRender()})}render(){var p;if(!((p=this._data)!=null&&p.analysis))return;if(this.hasRendered&&this.shadow.querySelector(".page")){this.updateInPlace();return}let{data:e,analysis:n}=this._data,a=document.createElement("div");a.className="page",a.setAttribute("part","page"),a.appendChild(this.buildHeader(n,e));let o=J(n);a.appendChild(ft(o));let s=ut(n)??"No text was entered.",i=document.createElement("p");i.className="narrative",i.textContent=s,a.appendChild(i);let c=document.createElement("div");c.className="origin-bar-container",c.id="origin-bar",a.appendChild(c);let l=this.buildFlags(n);l&&a.appendChild(l);let d=this.buildGrid(n);a.appendChild(d);let m=this.buildDetailPanel();a.appendChild(m),a.appendChild(this.buildIntegrityDetails(n));let u=document.createElement("div");u.className="version-footer",u.textContent=`WriteTrack v${br}`,a.appendChild(u);let g=this.closest('[class*="scorecard"]')??this.parentElement,h=(g==null?void 0:g.scrollTop)??0;this.replaceChart(a),requestAnimationFrame(()=>{this.renderAllCharts(),this.renderOriginBarIfPresent(),this.selectCell(this.t),g&&h>0&&(g.scrollTop=h)})}updateInPlace(){var m;let e=this._data.analysis,n=this.shadow.querySelector(".wt-badges");if(n){let u=J(e);n.replaceChildren(...ft(u).childNodes)}let a=this.shadow.querySelector(".narrative");a&&(a.textContent=ut(e)??"No text was entered.");let o=this.shadow.querySelector(".flags"),s=this.buildFlags(e);if(o&&s)o.replaceWith(s);else if(o&&!s)o.remove();else if(!o&&s){let u=this.shadow.querySelector(".grid-container");(m=u==null?void 0:u.parentElement)==null||m.insertBefore(s,u)}for(let u of Dt){let g=this.shadow.querySelector(`.cell[data-category="${u}"]`);if(!g)continue;let h=this.getIndicatorCode(e,u),p=B(h),f=e.sufficientData&&p==="flag";g.className="cell"+(f?" flagged":""),this.t===u&&g.classList.add("selected");let v=g.querySelector(".cell-status");v&&(v.className=`cell-status ${f?"flagged":"clear"}`,v.title=f?"Flagged":"Clear");let w=g.querySelector(".cell-metrics");if(w){let b=Q(u,e),S=he[u];w.replaceWith(this.buildCellMetrics(b,S))}}let i=this.shadow.querySelector(".integrity-stats");i&&(i.textContent=`${e.integrity.eventCount} events \xB7 ${e.integrity.checkpoints.length} checkpoints`);let c=this.shadow.querySelector(".integrity-hash-block .hash");c&&(c.textContent=e.integrity.finalDigest);let l=this.closest('[class*="scorecard"]')??this.parentElement,d=(l==null?void 0:l.scrollTop)??0;this.updateChartsInPlace(),this.renderOriginBarIfPresent(),l&&d>0&&(l.scrollTop=d)}updateChartsInPlace(){var o;if(!((o=this._data)!=null&&o.analysis))return;let{data:e,analysis:n}=this._data;this.shadow.querySelectorAll(".cell-chart").forEach(s=>{let i=s.closest(".cell"),c=i==null?void 0:i.getAttribute("data-category");if(!c)return;let l=s.firstElementChild;if(l&&typeof l.setData=="function")this.feedChartData(c,l,e,n);else{let d=this.createDetailChart(c,!0);d&&(s.replaceChildren(d.el),d.init())}});let a=this.t;if(a){let s=this.shadow.querySelector("#detail-inner .detail-chart-area");if(s){let i=s.firstElementChild;if(i&&typeof i.setData=="function"&&i.getAttribute("data-category")===a)this.feedChartData(a,i,e,n);else{let c=this.createDetailChart(a);if(c){let l=s.clientWidth;l>0&&c.el.style.setProperty("--wt-chart-width",`${l}px`),c.el.setAttribute("data-category",a),s.replaceChildren(c.el),c.init()}}}}}feedChartData(e,n,a,o){var i,c,l;let s=((i=o.activeTime)==null?void 0:i.activeWindows)??[];switch(e){case"contentOrigin":case"revisionBehavior":case"physicalPlausibility":n.setActiveWindows(s),n.setData(a);break;case"timingAuthenticity":case"temporalPatterns":n.setData(o);break;case"sessionContinuity":{n.setActiveWindows(s);let d=((l=(c=o.sessionContinuity)==null?void 0:c.metrics)==null?void 0:l.changePoints)??[];d.length>0&&n.setChangePoint&&n.setChangePoint(s.length>0?E(d[0].timestamp,s):d[0].timestamp/1e3),n.setData(a);break}default:break}}buildHeader(e,n){let a=document.createElement("header");a.className="header";let o=document.createElement("div");o.className="header-logo",a.appendChild(o);let s=document.createElement("div");s.className="header-meta";let i=document.createElement("div");i.className="header-title",i.textContent="WriteTrack Session",s.appendChild(i);let c=n.metadata.sessionId??"";if(c){let w=document.createElement("div");w.className="header-session-id",w.textContent=c,s.appendChild(w)}let l=document.createElement("div");l.className="header-meta-line";let d=n.metadata.timestamp,u=n.metadata.duration,g=d?new Date(d):new Date(e.analyzedAt),h={day:"numeric",month:"long",year:"numeric"};if(u&&u>0){let w=new Date(g.getTime()+u),b=g.toLocaleDateString("en-GB",h),S=w.toLocaleDateString("en-GB",h);l.textContent=b===S?b:`${b} \u2013 ${S}`}else l.textContent=g.toLocaleDateString("en-GB",h);s.appendChild(l),a.appendChild(s);let p=document.createElement("div");p.className="header-qr",this.hasAttribute("share")&&(p.style.cursor="pointer",p.title="Share",p.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("wt-share",{bubbles:!0,composed:!0,detail:{report:this._data}}))})),a.appendChild(p);let f=this.hasAttribute("share"),v=this.hasAttribute("download");if(f||v){let w=document.createElement("span");if(w.className="header-actions",f){let b=document.createElement("button");b.setAttribute("data-action","share"),b.setAttribute("aria-label","Share report"),b.title="Share",b.innerHTML='<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12v1a1 1 0 001 1h6a1 1 0 001-1v-1M8 2v8M5 5l3-3 3 3"/></svg>',b.addEventListener("click",S=>{S.stopPropagation(),this.dispatchEvent(new CustomEvent("wt-share",{bubbles:!0,composed:!0,detail:{report:this._data}}))}),w.appendChild(b)}if(v){let b=document.createElement("button");b.setAttribute("data-action","download"),b.setAttribute("aria-label","Download session data"),b.title="Download session data",b.innerHTML='<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12v1a1 1 0 001 1h6a1 1 0 001-1v-1M8 10V2M5 7l3 3 3-3"/></svg>',b.addEventListener("click",S=>{S.stopPropagation(),this.dispatchEvent(new CustomEvent("wt-download",{bubbles:!0,composed:!0,detail:{report:this._data}}))}),w.appendChild(b)}i.appendChild(w)}return requestAnimationFrame(()=>{let w=getComputedStyle(this),b=w.getPropertyValue("--wt-scorecard-text").trim()||"#E4E2DA",S=w.getPropertyValue("--wt-scorecard-status-clear").trim()||"#5EAE78";o.innerHTML=se(60,b,S);let D=St(e.integrity.finalDigest);D&&(p.innerHTML=Ct(D,b))}),a}buildFlags(e){if(!e.sufficientData)return null;let n=Dt.filter(o=>B(this.getIndicatorCode(e,o))==="flag");if(n.length===0)return null;let a=document.createElement("div");a.className="flags";for(let o of n){let s=document.createElement("div");s.className="flag-item";let i=pt(o,e);s.innerHTML=`<strong class="flag-label">Flagged</strong> ${P(X[o]??o)}\u2009\u2014\u2009${P(i)}`,a.appendChild(s)}return a}buildIntegrityDetails(e){let n=document.createElement("details");n.className="integrity-details";let a=document.createElement("summary"),o=document.createElement("span");o.textContent="Integrity & Verification";let s=document.createElement("span");s.className="integrity-stats",s.textContent=`${e.integrity.eventCount} events \xB7 ${e.integrity.checkpoints.length} checkpoints`,a.append(o,s),n.appendChild(a);let i=document.createElement("div");i.className="integrity-hash-block";let c=document.createElement("span");c.className="integrity-hash-label",c.textContent="Digest (SHA-256)";let l=document.createElement("code");if(l.className="hash",l.textContent=e.integrity.finalDigest,i.append(c,l),n.appendChild(i),e.outputSignature){let d=document.createElement("div");d.className="integrity-hash-block";let m=document.createElement("span");m.className="integrity-hash-label",m.textContent="Output Signature";let u=document.createElement("code");u.className="hash",u.textContent=e.outputSignature,d.append(m,u),n.appendChild(d)}return n}buildGrid(e){let n=document.createElement("div");n.className="grid-container";let a=document.createElement("div");a.className="indicator-grid",a.id="grid";for(let o of Dt)a.appendChild(this.buildCell(o,e));return n.appendChild(a),n}buildCell(e,n){let a=this.getIndicatorCode(n,e),o=B(a),s=n.sufficientData&&o==="flag",i=document.createElement("div");i.className="cell"+(s?" flagged":""),i.setAttribute("data-category",e),i.addEventListener("click",()=>this.selectCell(e));let c=document.createElement("div");c.className="cell-header";let l=document.createElement("div");l.className="cell-name-col";let d=document.createElement("span");d.className="cell-name";let m=document.createElement("span");m.className="cell-name-short",m.textContent=vr[e]??e;let u=document.createElement("span");u.className="cell-name-full",u.textContent=X[e]??e,d.append(m,u),l.appendChild(d);let g=document.createElement("span");g.className=`cell-status ${s?"flagged":"clear"}`,g.title=s?"Flagged":"Clear",c.append(l,g),i.appendChild(c);let h=document.createElement("div");h.className="cell-chart",i.appendChild(h);let p=Q(e,n),f=he[e];return i.appendChild(this.buildCellMetrics(p,f)),i}buildCellMetrics(e,n){let a=document.createElement("div");a.className="cell-metrics";for(let o of n){let s=e[o];if(!s)continue;let i=document.createElement("div");i.className="cell-metric",i.innerHTML=`<span class="cell-metric-label">${P(s.label)}</span><span class="cell-metric-value">${P(s.value)}</span>`,a.appendChild(i)}return a}buildDetailPanel(){let e=document.createElement("div");e.className="detail-panel",e.id="detail";let n=document.createElement("div");return n.className="detail-inner",n.id="detail-inner",e.appendChild(n),e}selectCell(e){var c;let n=(c=this._data)==null?void 0:c.analysis;if(!n)return;let a=this.shadow.getElementById("detail-inner"),o=a&&a.children.length===0;if(this.t===e&&!o)return;this.t=e;let s=this.shadow.getElementById("grid");s==null||s.querySelectorAll(".cell").forEach(l=>l.classList.remove("selected"));let i=s==null?void 0:s.querySelector(`[data-category="${e}"]`);i==null||i.classList.add("selected"),this.populateAndRenderDetail(e,n)}populateAndRenderDetail(e,n){let a=this.shadow.getElementById("detail-inner");if(!a)return;a.classList.add("fading");let o=()=>{this.populateDetail(a,e,n),requestAnimationFrame(()=>{let s=a.querySelector(".detail-chart-area");if(s){let i=this.createDetailChart(e);if(i){let c=s.clientWidth;c>0&&i.el.style.setProperty("--wt-chart-width",`${c}px`),s.replaceChildren(i.el),i.init()}else{let c=document.createElement("span");c.className="detail-chart-empty",c.textContent="Insufficient data for chart",s.replaceChildren(c)}}a.classList.remove("fading")})};if(a.children.length===0)o();else{let s=!1,i=()=>{s||(s=!0,o())},c=setTimeout(i,300);a.addEventListener("transitionend",()=>{clearTimeout(c),i()},{once:!0})}}populateDetail(e,n,a){let o=this.getIndicatorCode(a,n),s=B(o),i=a.sufficientData&&s==="flag",c='<div class="detail-head">';c+=`<span class="detail-name">${P(X[n]??n)}</span>`,c+=`<span class="detail-code">${P(o??"")}</span>`,c+=`<span class="detail-status-label ${i?"flagged":"clear"}">${i?"flagged":"clear"}</span>`,c+="</div>";let l=pt(n,a);c+=`<p class="detail-summary">${ht(l)}</p>`,c+='<div class="detail-chart-area"></div>';let d=xr[n];c+=`<div class="detail-chart-caption">${P(d.name)} \u2014 ${P(d.desc)}</div>`;let m=Q(n,a);c+='<div class="detail-metrics">';for(let g of m)c+=`<div class="detail-metric"><span class="detail-metric-value">${P(g.value)}</span><span class="detail-metric-label">${P(g.label)}</span></div>`;c+="</div>";let u=Pt(n);u&&(c+=`<p class="detail-explainer">${ht(u)}</p>`),e.innerHTML=c}getIndicatorCode(e,n){var o;let a=e[n];return(o=a==null?void 0:a.indicator)==null?void 0:o.code}getComputedColors(){let e=getComputedStyle(this);return{line:e.getPropertyValue("--wt-scorecard-chart-line").trim()||"#1C1B18",accent:e.getPropertyValue("--wt-scorecard-chart-accent").trim()||"#2B7A5D",flagged:e.getPropertyValue("--wt-scorecard-chart-flagged").trim()||"#B8412D",border:e.getPropertyValue("--wt-scorecard-border").trim()||"#E0DED6",tertiary:e.getPropertyValue("--wt-scorecard-text-tertiary").trim()||"#706E64",chartTertiary:e.getPropertyValue("--wt-scorecard-chart-tertiary").trim()||"#7C6DAF",cyan:e.getPropertyValue("--wt-scorecard-chart-cyan").trim()||"#5B8FA8"}}renderOriginBarIfPresent(){var l;let e=(l=this._data)==null?void 0:l.analysis;if(!e)return;let n=this.shadow.getElementById("origin-bar");if(!n)return;let a=this.getComputedColors(),o={typed:a.accent,pasted:a.chartTertiary,autocompleted:a.cyan},s={autocompleted:a.line},i=n.getBoundingClientRect().width||400,c=dt(lt(e),i,o,s);c&&n.replaceChildren(c)}createDetailChart(e,n=!1){var g,h;if(!((g=this._data)!=null&&g.analysis))return null;let{data:a,analysis:o}=this._data,s=this.getComputedColors(),i=this.getIndicatorCode(o,e),l=B(i)==="flag"?s.flagged:s.accent,d=(p,f)=>{f&&p.style.setProperty("--wt-chart-height",`${f}px`),p.style.setProperty("--wt-color-primary",l),p.style.setProperty("--wt-color-secondary",s.accent),p.style.setProperty("--wt-color-text",s.tertiary),p.style.setProperty("--wt-color-text-muted",s.tertiary),p.style.setProperty("--wt-color-border",s.border),p.style.setProperty("--wt-color-bg","transparent"),p.style.setProperty("--wt-color-surface","transparent"),p.style.setProperty("--wt-font-data","var(--wt-scorecard-font-data)"),p.style.setProperty("--wt-font-ui","var(--wt-scorecard-font-display)"),p.style.setProperty("--wt-beeswarm-insert",s.accent),p.style.setProperty("--wt-beeswarm-delete",s.flagged),p.style.setProperty("--wt-beeswarm-paste",s.chartTertiary),p.style.setProperty("--wt-beeswarm-cut",s.tertiary),p.style.setProperty("--wt-bubble-insert",s.accent),p.style.setProperty("--wt-bubble-delete",s.flagged),p.style.setProperty("--wt-bubble-paste",s.chartTertiary),p.style.setProperty("--wt-bubble-cut",s.tertiary),p.style.setProperty("--wt-color-cut",s.flagged),p.style.display="block"},m=(p,f)=>{p.register();let v=new p;return d(v,n?void 0:200),n&&(v.setAttribute("compact",""),v.style.height="52px"),{el:v,init:()=>f(v)}},u=((h=o.activeTime)==null?void 0:h.activeWindows)??[];switch(e){case"contentOrigin":return m(G,p=>{p.setActiveWindows(u),p.setData(a)});case"timingAuthenticity":return m(F,p=>p.setData(o));case"revisionBehavior":return m(q,p=>{p.setActiveWindows(u),p.setData(a)});case"sessionContinuity":return m(O,p=>{var v,w;p.setAttribute("process",""),p.setAttribute("cursor",""),p.setActiveWindows(u);let f=((w=(v=o.sessionContinuity)==null?void 0:v.metrics)==null?void 0:w.changePoints)??[];f.length>0&&p.setChangePoint(u.length>0?E(f[0].timestamp,u):f[0].timestamp/1e3),p.setData(a)});case"physicalPlausibility":return m(z,p=>{p.setActiveWindows(u),p.setData(a)});case"temporalPatterns":return m(L,p=>p.setData(o));default:return null}}renderAllCharts(){this.shadow.querySelectorAll(".cell-chart").forEach(e=>{let n=e.closest(".cell"),a=n==null?void 0:n.getAttribute("data-category");if(!a)return;let o=this.createDetailChart(a,!0);o&&(e.replaceChildren(o.el),o.init())})}rerenderAllCharts(){this.renderAllCharts();let e=this.t;if(e){let n=this.shadow.querySelector("#detail-inner .detail-chart-area");if(n){let a=this.createDetailChart(e);if(a){let o=n.clientWidth;o>0&&a.el.style.setProperty("--wt-chart-width",`${o}px`),n.replaceChildren(a.el),a.init()}}}this.renderOriginBarIfPresent()}};yt.tagName="wt-scorecard";var Z={typing:"var(--wt-segment-typing, var(--wt-color-primary, #fbbf24))",paste:"var(--wt-segment-paste, var(--wt-color-secondary, #22d3ee))",pause:"var(--wt-segment-pause, var(--wt-color-text-muted, #a1a1aa))",tabAway:"var(--wt-segment-tab-away, #ef4444)",autocomplete:"var(--wt-segment-autocomplete, #a78bfa)",navigating:"var(--wt-segment-navigating, #34d399)"},kr={typing:"Typed",paste:"Pasted",pause:"Pause",tabAway:"Tab away",autocomplete:"Autocomplete",navigating:"Navigating"};function Wt(r,t){var o;let e=r.sessionTimeline;if(!(e!=null&&e.length))return[];let n=t??((o=r.activeTime)==null?void 0:o.activeWindows)??[],a=n.length>0;return e.map(s=>({start:a?E(s.startTime,n):s.startTime/1e3,end:a?E(s.endTime,n):s.endTime/1e3,type:s.type,color:Z[s.type]??"#666"}))}function ge(r,t){var o,s,i;let e=((s=(o=r.contentOrigin)==null?void 0:o.metrics)==null?void 0:s.pasteEvents)??[],n=t??((i=r.activeTime)==null?void 0:i.activeWindows)??[],a=n.length>0;return e.map(c=>({time:a?E(c.timestamp,n):c.timestamp/1e3,chars:c.characterCount,source:c.source}))}function fe(r,t){return Wt(r,t).filter(e=>e.type==="tabAway")}var wt=class extends T{static get observedAttributes(){return[...super.observedAttributes,"mode"]}get mode(){return this.getAttribute("mode")??"full"}render(){if(!this._data)return;let t=k();if(!t){this.showEmptyState(C);return}if(this.mode==="focus"){this.m();return}let e=Wt(this._data);if(e.length===0){this.showEmptyState("No session data");return}let n=ge(this._data),a=this.compact,o=[t.barX(e,{x1:"start",x2:"end",fill:"color",y:()=>"Activity",inset:.5})];a||o.push(t.tip(e,t.pointer({x:l=>(l.start+l.end)/2,y:()=>"Activity",title:l=>`${l.type} \u2014 ${(l.end-l.start).toFixed(1)}s`,...$}))),!a&&n.length&&o.push(t.dot(n,{x:"time",y:()=>"Activity",r:"chars",fill:Z.paste,fillOpacity:.7,stroke:"var(--wt-color-bg, #111113)",strokeWidth:1}));let s=this.getChartWidth(640),i=this.getChartHeight(120),c=t.plot({width:s,height:i,...a?M:{marginLeft:8,marginBottom:35},x:a?{axis:null}:{label:"Active Time (s)"},y:{axis:null,padding:.2},marks:o,style:A});if(a)this.replaceChart(c);else{let l=[...new Set(e.map(m=>m.type))],d=document.createElement("div");d.appendChild(c),d.appendChild(R(l.map(m=>({label:kr[m]??m,color:Z[m]??"#666"})))),this.replaceChart(d)}}m(){if(!this._data)return;let t=k();if(!t){this.showEmptyState(C);return}let e=fe(this._data);if(e.length===0){this.showEmptyState("No tab-away events");return}let n=this.getChartWidth(640),a=this.getChartHeight(60),o=t.plot({width:n,height:a,marginLeft:8,marginBottom:35,x:{label:"Active Time (s)"},y:{axis:null,padding:.2},marks:[t.barX(e,{x1:"start",x2:"end",fill:Z.tabAway,y:()=>"Focus",inset:.5})],style:A});this.replaceChart(o)}};wt.tagName="wt-composition-timeline";export{T as BaseChart,X as CATEGORY_NAMES,wt as CompositionTimeline,q as CorrectionsBubble,O as DocumentGrowth,G as EditBeeswarm,z as EditWaterfall,de as GLOSSARY,mt as IntegrityFooter,nt as PauseDistribution,hr as ProcessGraph,F as RhythmHeatmap,Z as SEGMENT_COLORS,xt as Sparkline,L as SpeedTimeline,ze as TIER1_CATEGORIES,qe as TIER2_CATEGORIES,gt as WtBadge,ct as WtOriginBar,yt as WtScorecard,Xt as extractBeeswarmData,te as extractCorrectionBubbles,fe as extractFocusSegments,gr as extractGrowthData,lt as extractOriginData,ge as extractPasteMarkers,Ut as extractPauseHistogram,$t as extractProcessData,Kt as extractRhythmPairs,Wt as extractSegments,jt as extractSeries,Yt as extractSpeedData,J as extractStatBadges,Jt as extractWaterfallData,le as formatDuration,Pt as generateCaption,pt as generateSummary,ut as generateWritingSummary,Q as getMetrics,B as getStatus,Ge as isPass,dt as renderOriginBar,ft as renderStatBadges,ht as wrapTerms};
|
|
Binary file
|
package/dist/ckeditor/index.d.ts
CHANGED
|
@@ -1,26 +1,8 @@
|
|
|
1
1
|
import { WriteTrack } from 'writetrack';
|
|
2
|
+
import type { BaseBindingOptions } from 'writetrack';
|
|
2
3
|
import { Plugin } from 'ckeditor5';
|
|
3
4
|
|
|
4
|
-
export
|
|
5
|
-
/** WriteTrack license key */
|
|
6
|
-
license?: string;
|
|
7
|
-
/** User identifier for metadata */
|
|
8
|
-
userId?: string;
|
|
9
|
-
/** Content identifier for metadata */
|
|
10
|
-
contentId?: string;
|
|
11
|
-
/** Additional metadata */
|
|
12
|
-
metadata?: Record<string, unknown>;
|
|
13
|
-
/** Auto-start tracking when editor is ready (default: true) */
|
|
14
|
-
autoStart?: boolean;
|
|
15
|
-
/** URL to the WASM binary for analysis. If omitted, uses default loader path. */
|
|
16
|
-
wasmUrl?: string;
|
|
17
|
-
/** Enable IndexedDB session persistence and auto-resume. Requires contentId. */
|
|
18
|
-
persist?: boolean;
|
|
19
|
-
/** Callback fired every second with active session time. */
|
|
20
|
-
onTick?: (data: { activeTime: number; totalTime: number }) => void;
|
|
21
|
-
/** Callback invoked when the tracker is created and ready (persistence loaded if applicable). Avoids polling for tracker availability. */
|
|
22
|
-
onReady?: (tracker: WriteTrack) => void;
|
|
23
|
-
}
|
|
5
|
+
export type WriteTrackPluginOptions = BaseBindingOptions;
|
|
24
6
|
|
|
25
7
|
/**
|
|
26
8
|
* CKEditor 5 plugin for WriteTrack keystroke analysis
|