cyborg-hunter 0.7.3 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/CITATION.cff +2 -2
- package/README.md +5 -5
- package/bin/cyborg-hunter.js +1 -1
- package/dist/cyborg-hunter-replay.js +2 -2
- package/dist/cyborg-hunter.esm.js +1 -1
- package/dist/cyborg-hunter.min.js +2 -2
- package/dist/extension-cyborg-hunter.js +1 -1
- package/package.json +4 -4
- package/src/jspsych/extension-cyborg-hunter-replay.js +1 -1
- package/src/jspsych/extension-cyborg-hunter.js +1 -1
- package/src/shared/constants.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to **cyborg-hunter** are documented here. This project follows
|
|
4
4
|
[Semantic Versioning](https://semver.org).
|
|
5
5
|
|
|
6
|
+
## [0.7.4] — 2026-08-04
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
- Repository moved to a GitHub organization: the canonical repo is now
|
|
10
|
+
https://github.com/cyborg-hunter/cyborg-hunter and the live demo lives at
|
|
11
|
+
https://cyborg-hunter.github.io/cyborg-hunter/. The old repo URL and git
|
|
12
|
+
remotes redirect permanently; the old demo URL does not (GitHub Pages
|
|
13
|
+
never redirects). All package links, the CLI's crash-footer issue URL,
|
|
14
|
+
the demo's GitHub links, and citation metadata now point at the org.
|
|
15
|
+
No functional changes.
|
|
16
|
+
|
|
6
17
|
## [0.7.3] — 2026-08-04
|
|
7
18
|
|
|
8
19
|
### Added
|
package/CITATION.cff
CHANGED
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
given-names: Victor
|
|
11
11
|
- family-names: Nunez
|
|
12
12
|
given-names: Jose Luis
|
|
13
|
-
repository-code: https://github.com/
|
|
13
|
+
repository-code: https://github.com/cyborg-hunter/cyborg-hunter
|
|
14
14
|
abstract: >-
|
|
15
15
|
A JavaScript library and CLI for detecting AI-tool use during browser-based
|
|
16
16
|
behavioral experiments. Captures paste, copy, drag, tab-away, mouse
|
|
@@ -25,5 +25,5 @@ keywords:
|
|
|
25
25
|
- prolific
|
|
26
26
|
- behavioral-research
|
|
27
27
|
license: MIT
|
|
28
|
-
version: 0.7.
|
|
28
|
+
version: 0.7.4
|
|
29
29
|
date-released: '2026-08-04'
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Detects AI-tool use during browser-based behavioral experiments. Captures paste,
|
|
|
4
4
|
|
|
5
5
|
Optional companion deterrence modules (`extension-guard-friction.js`, `extension-guard-honeypot.js`) ship in the same package: friction enforces fullscreen + blocks sidebars + scrambles content during violations + asks cooperative LLMs to refuse; honeypot exposes both hidden and visible bait fields that AI agents fill while human participants don't see them.
|
|
6
6
|
|
|
7
|
-
**[Try the live demo →](https://
|
|
7
|
+
**[Try the live demo →](https://cyborg-hunter.github.io/cyborg-hunter/)** — run the tour in your browser; nothing leaves your machine.
|
|
8
8
|
|
|
9
9
|
### Example: what a report looks like
|
|
10
10
|
|
|
@@ -51,7 +51,7 @@ Browser (experiment page) — load via unpkg or copy `dist/*.js` into your proje
|
|
|
51
51
|
<script src="https://unpkg.com/cyborg-hunter/dist/cyborg-hunter-replay.js"></script>
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
For production studies, pin a version: `https://unpkg.com/cyborg-hunter@0.7.
|
|
54
|
+
For production studies, pin a version: `https://unpkg.com/cyborg-hunter@0.7.4/dist/...`.
|
|
55
55
|
|
|
56
56
|
## Plug into a jsPsych experiment
|
|
57
57
|
|
|
@@ -176,7 +176,7 @@ The optional **guard** extensions add: fullscreen / sidebar / focus enforcement
|
|
|
176
176
|
|
|
177
177
|
## Reporting issues
|
|
178
178
|
|
|
179
|
-
Bug reports and feature requests go to the [issue tracker](https://github.com/
|
|
179
|
+
Bug reports and feature requests go to the [issue tracker](https://github.com/cyborg-hunter/cyborg-hunter/issues); the bug form asks for your version and environment. One hard rule: issues are public, so never paste participant data (session payloads, replay files, identifiers). Reproduce with synthetic or personal test runs instead.
|
|
180
180
|
|
|
181
181
|
## Development
|
|
182
182
|
|
|
@@ -189,8 +189,8 @@ Run the test suite with `npm test`. Before publishing, run `scripts/check-public
|
|
|
189
189
|
author = {Konuk, Can and Btesh, Victor and Nunez, Jose Luis},
|
|
190
190
|
title = {cyborg-hunter: detecting AI-tool use in browser-based behavioral experiments},
|
|
191
191
|
year = {2026},
|
|
192
|
-
version = {0.7.
|
|
193
|
-
url = {https://github.com/
|
|
192
|
+
version = {0.7.4},
|
|
193
|
+
url = {https://github.com/cyborg-hunter/cyborg-hunter},
|
|
194
194
|
license = {MIT}
|
|
195
195
|
}
|
|
196
196
|
```
|
package/bin/cyborg-hunter.js
CHANGED
|
@@ -16,7 +16,7 @@ const subcommand = args[0];
|
|
|
16
16
|
function crash(err) {
|
|
17
17
|
console.error('Error:', err.message);
|
|
18
18
|
console.error('\nIf this looks like a bug, please report it at');
|
|
19
|
-
console.error(' https://github.com/
|
|
19
|
+
console.error(' https://github.com/cyborg-hunter/cyborg-hunter/issues');
|
|
20
20
|
console.error('(include the command, the error, and your version; never include participant data)');
|
|
21
21
|
process.exit(1);
|
|
22
22
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
// cyborg-hunter-replay v0.7.
|
|
1
|
+
// cyborg-hunter-replay v0.7.4 — https://github.com/cyborg-hunter/cyborg-hunter
|
|
2
2
|
(()=>{var K={participantId:"unknown",tier:"trace",keys:"full",mouseHz:30,redactSelector:"[data-ch-redact]",keepBait:!1,root:null,autoSave:{mode:"none"},maxEventsPerTrial:5e4,maxCharsPerTrial:8e6},ye={created:["session","destroyed"],session:["trial","stopped","destroyed"],trial:["session","stopped","destroyed"],stopped:["destroyed"],destroyed:[]};function Z(e){var n=Object.assign({},K,e||{});n.autoSave=Object.assign({},K.autoSave,(e||{}).autoSave||{});var r="created",t=[],a=[],l=0,f=[],c=new WeakMap,d=new WeakSet;function y(s){try{return JSON.stringify(s).length}catch{return 0}}var p={participantId:n.participantId,tier:n.tier,keys:n.keys,sessionStart:null,sessionStartEpoch:null,viewport:null,stylesheets:[],trials:[],guardViolations:[],captureFailures:[],captureStopped:!1,endReason:null,markerAttr:null},h=null,u=null;function v(s){if(ye[r].indexOf(s)===-1)throw new Error("[cyborg-hunter-replay] invalid lifecycle call: "+r+" \u2192 "+s+". Expected order: attach() \u2192 startSession() \u2192 (startTrial \u2192 endTrial)* \u2192 stopSession() \u2192 destroy()."+(r==="created"?" Did you forget startSession()?":""));r=s}function T(s,m){return l++,{trialIndex:l-1,trialId:s&&s.trialId||(m?"__session__":"trial-"+(l-1)),plugin:s&&s.plugin||"ch:standalone",implicit:!!m,tLoad:m?p.sessionStart:performance.now(),tStart:(s&&s.tStart)!=null?s.tStart:null,tDomReady:(s&&s.tDomReady)!=null?s.tDomReady:null,tEnd:null,initialDom:"",events:[]}}function E(){h.tEnd=performance.now(),p.trials.push(h),h=null}function x(s){for(var m=0;m<f.length;m++)try{f[m](s)}catch(_){p.captureFailures.push({channel:"trial_start_hook",message:_&&_.message?String(_.message):String(_),t:performance.now()})}}var P={config:n,startSession:function(){v("session"),p.sessionStart=performance.now(),p.sessionStartEpoch=Date.now();var s=typeof window<"u"?window:null,m=typeof document<"u"&&document.documentElement?document.documentElement:null;p.viewport=s?{width:s.innerWidth||null,height:s.innerHeight||null,client_width:m&&m.clientWidth||null,client_height:m&&m.clientHeight||null,dpr:s.devicePixelRatio||1,visual_viewport:s.visualViewport?{width:s.visualViewport.width,height:s.visualViewport.height,scale:s.visualViewport.scale}:null}:{width:null,height:null,client_width:null,client_height:null,dpr:null,visual_viewport:null},n.autoSave.mode==="none"&&console.warn('[cyborg-hunter-replay] autoSave.mode is "none" \u2014 the recording will be lost unless you call getRecording() yourself.')},startTrial:function(s){r==="trial"?(this.pushEvent("ch:lifecycle_error",{reason:"startTrial_without_endTrial"}),E(),r="session"):h&&E(),v("trial"),h=T(s,!1),x(h)},endTrial:function(){v("session"),h&&E()},stopSession:function(s){r==="trial"&&(r="session"),h&&E(),v("stopped"),p.endReason=s||"finished"},pushEvent:function(s,m,_){if(r==="destroyed")throw new Error("[cyborg-hunter-replay] pushEvent called on a destroyed recorder");if(!(r==="created"||r==="stopped")&&(h||(h=T(null,!0),x(h)),!d.has(h))){if(h.events.length>=n.maxEventsPerTrial){d.add(h),p.captureStopped=!0,h.events.push({t:_??performance.now(),kind:"ch:capture_stopped",limit:n.maxEventsPerTrial});return}var b=Object.assign({t:_??performance.now(),kind:s},m||{});if(n.maxCharsPerTrial!=null){var M=c.get(h);if(M==null&&(M=h.initialDom?h.initialDom.length:0),M+=y(b),M>n.maxCharsPerTrial){d.add(h),p.captureStopped=!0,h.events.push({t:b.t,kind:"ch:capture_stopped",limit_chars:n.maxCharsPerTrial});return}c.set(h,M)}h.events.push(b)}},captureFailure:function(s,m){p.captureFailures.push({channel:s,message:m&&m.message?String(m.message):String(m),t:performance.now()})},onTrialStart:function(s){f.push(s)},setStylesheets:function(s){p.stylesheets=s||[]},setMarkers:function(s){u=s},getMarkers:function(){return u},setMarkerAttr:function(s){p.markerAttr=s||null},addListener:function(s,m,_,b){s.addEventListener(m,_,b||!1),t.push({target:s,event:m,handler:_,options:b||!1})},addInterval:function(s){a.push(s)},getState:function(){var s=p.trials.slice();return h&&s.push(h),Object.assign({},p,{trials:s,state:r})},destroy:function(){r!=="destroyed"&&(v("destroyed"),t.forEach(function(s){s.options&&s.options._isObserver?s.handler.disconnect():s.target.removeEventListener(s.event,s.handler,s.options)}),t=[],a.forEach(function(s){clearInterval(s)}),a=[])}};return P}function w(e,n,r){return function(t){try{r(t)}catch(a){e.captureFailure(n,a)}}}function $(e){if(!e||!e.tagName)return null;var n=e.tagName.toLowerCase();return e.id&&(n+="#"+e.id),n}function we(e){return!!(e&&e.tagName==="INPUT"&&e.type==="password")}function Se(e,n){if(we(e))return!0;if(!n||!e||typeof e.matches!="function")return!1;try{return e.matches(n)}catch{return!1}}function N(e,n){for(var r=e;r;){if(Se(r,n))return!0;r=r.parentNode}return!1}function k(e){return Math.round(e*10)/10}function ee(e,n){n=n||{};var r=n.doc||document,t=n.win||window,a=n.now||function(){return performance.now()},l=n.raf||(typeof requestAnimationFrame<"u"?requestAnimationFrame.bind(null):function(i){setTimeout(i,16)}),f=e.config;function c(){var i=r.documentElement;return{cw:i&&i.clientWidth?i.clientWidth:t.innerWidth||null,ch:i&&i.clientHeight?i.clientHeight:t.innerHeight||null}}function d(i,o){return o.clientX!=null&&(i.cx=Math.round(o.clientX)),o.clientY!=null&&(i.cy=Math.round(o.clientY)),i}function y(i){var o=i&&i.target;if(!o||!o.tagName)return null;var g=o.tagName.toLowerCase();if(N(o,f.redactSelector))return{redacted:!0,tag:g};var S={tag:g};try{if(typeof i.composedPath=="function"){var A=i.composedPath()[0];A&&A!==o&&(S.shadow=!0)}}catch{}o.id&&(S.id=o.id);var Q=typeof e.getMarkers=="function"?e.getMarkers():null;Q&&(S.n=Q.refFor(o));try{if(typeof o.getBoundingClientRect=="function"){var D=o.getBoundingClientRect();S.rect=[k(D.left),k(D.top),k(D.width),k(D.height)]}}catch{}return S}var p=null,h=new Map,u=null,v=null,T=!1,E=!1,x=!1;function P(){T=!1,p&&(e.pushEvent("scroll",{x:Math.round(t.scrollX||0),y:Math.round(t.scrollY||0)},p.t),p=null),h.size>0&&(h.forEach(function(i,o){var g;if(N(o,f.redactSelector))g={redacted:!0,tag:o.tagName?o.tagName.toLowerCase():null,x:Math.round(o.scrollLeft||0),y:Math.round(o.scrollTop||0)};else{g={el:$(o),id:o.id||null,x:Math.round(o.scrollLeft||0),y:Math.round(o.scrollTop||0)};var S=typeof e.getMarkers=="function"?e.getMarkers():null;S&&(g.n=S.refFor(o))}e.pushEvent("scroll",g,i.t)}),h.clear())}function s(i){return i}function m(){if(E=!1,!!u){var i=c();e.pushEvent("resize",{w:t.innerWidth,h:t.innerHeight,cw:i.cw,ch:i.ch,dpr:t.devicePixelRatio||1},u.t),u=null}}function _(){if(x=!1,!!v){var i=t.visualViewport;i&&e.pushEvent("vv",{w:k(i.width),h:k(i.height),scale:i.scale,px:k(i.pageLeft||0),py:k(i.pageTop||0)},v.t),v=null}}function b(){P(),m(),_()}function M(i){var o=c();return i.sx=Math.round(t.scrollX||0),i.sy=Math.round(t.scrollY||0),i.vw=t.innerWidth||null,i.vh=t.innerHeight||null,i.cw=o.cw,i.ch=o.ch,i}var ve=1e3/(f.mouseHz||30),J=-1/0;e.addListener(r,"mousemove",w(e,"mouse",function(i){var o=a();o-J<ve||(J=o,e.pushEvent("mousemove",d({x:Math.round(i.pageX),y:Math.round(i.pageY)},i),o))}),{passive:!0,capture:!0}),["mousedown","mouseup","click"].forEach(function(i){e.addListener(r,i,w(e,"mouse",function(o){b();var g=M(d({x:Math.round(o.pageX),y:Math.round(o.pageY)},o)),S=y(o);S&&(g.target=S),e.pushEvent(i,g,a())}),{passive:!0,capture:!0})}),f.keys!=="off"&&["keydown","keyup"].forEach(function(i){e.addListener(r,i,w(e,"keys",function(o){if(N(o.target,f.redactSelector)){e.pushEvent(i,{redacted:!0},a());return}e.pushEvent(i,{key:o.key,code:o.code},a())}),!0)}),e.addListener(r,"paste",w(e,"clipboard",function(i){b();var o=null;try{o=i.clipboardData.getData("text").length}catch{}e.pushEvent("paste",{len:o},a())}),!0),e.addListener(r,"copy",w(e,"clipboard",function(){b(),e.pushEvent("copy",{},a())}),!0),e.addListener(r,"cut",w(e,"clipboard",function(){b(),e.pushEvent("cut",{},a())}),!0),e.addListener(r,"drop",w(e,"clipboard",function(i){b();var o=null;try{o=i.dataTransfer.getData("text").length}catch{}e.pushEvent("ch:drop",{len:o},a())}),!0);var F=new Map,z=!1;function me(){z=!1,F.forEach(function(i,o){var g={el:$(o),id:o.id||null},S=o.value!=null?String(o.value):o.isContentEditable&&o.textContent!=null?String(o.textContent):"";if(N(o,f.redactSelector))g.redacted=!0,g.value_len=S.length;else{g.value=S;var A=typeof e.getMarkers=="function"?e.getMarkers():null;A&&(g.n=A.refFor(o))}!g.redacted&&(o.type==="checkbox"||o.type==="radio")&&(g.checked=!!o.checked),e.pushEvent("input",g,i)}),F.clear()}e.addListener(r,"input",w(e,"input",function(i){i.target&&(F.set(i.target,a()),z||(z=!0,l(w(e,"input",me))))}),!0),e.addListener(t,"scroll",w(e,"scroll",function(i){var o=i&&i.target&&i.target.tagName?i.target:null;o?h.set(o,{t:a()}):p={t:a()},T||(T=!0,l(w(e,"scroll",P)))}),{passive:!0,capture:!0}),e.addListener(r,"touchstart",w(e,"touch",function(i){b();var o=i.touches&&i.touches[0];if(o){var g=M(d({x:Math.round(o.pageX),y:Math.round(o.pageY)},o)),S=y(i);S&&(g.target=S),e.pushEvent("touchstart",g,a())}}),{passive:!0,capture:!0});var j=!1,L=null,q=0;e.addListener(r,"touchmove",w(e,"touch",function(i){L=i.touches&&i.touches[0],q=a(),!j&&(j=!0,l(w(e,"touch",function(){j=!1,L&&e.pushEvent("touchmove",d({x:Math.round(L.pageX),y:Math.round(L.pageY)},L),q)})))}),{passive:!0,capture:!0}),e.addListener(r,"touchend",w(e,"touch",function(i){b();var o=i.changedTouches&&i.changedTouches[0];if(o){var g=M(d({x:Math.round(o.pageX),y:Math.round(o.pageY)},o)),S=y(i);S&&(g.target=S),e.pushEvent("touchend",g,a())}}),{passive:!0,capture:!0}),e.addListener(t,"blur",w(e,"focus",function(){e.pushEvent("blur",{},a())})),e.addListener(t,"focus",w(e,"focus",function(){e.pushEvent("focus",{},a())})),e.addListener(r,"visibilitychange",w(e,"focus",function(){e.pushEvent("visibility",{hidden:!!r.hidden},a())})),e.addListener(t,"resize",w(e,"viewport",function(){u={t:a()},E||(E=!0,l(w(e,"viewport",m)))})),t.visualViewport&&typeof t.visualViewport.addEventListener=="function"&&["resize","scroll"].forEach(function(i){e.addListener(t.visualViewport,i,w(e,"viewport",function(){v={t:a()},x||(x=!0,l(w(e,"viewport",_)))}))}),e.onTrialStart(function(i){var o=c();i.viewState={x:Math.round(t.scrollX||0),y:Math.round(t.scrollY||0),w:t.innerWidth||null,h:t.innerHeight||null,cw:o.cw,ch:o.ch,dpr:t.devicePixelRatio||1}})}var O=1,_e=3,be={SCRIPT:!0,NOSCRIPT:!0};function Te(e){var n=new WeakMap,r=1;return{attr:"data-chn-"+e,refFor:function(t){var a=n.get(t);return a==null&&(a=r++,n.set(t,a)),a}}}var Ee={AREA:!0,BASE:!0,BR:!0,COL:!0,EMBED:!0,HR:!0,IMG:!0,INPUT:!0,LINK:!0,META:!0,SOURCE:!0,TRACK:!0,WBR:!0},xe=/^[a-zA-Z_:][-a-zA-Z0-9_:.]*$/;function ae(e){return xe.test(e)&&!/^on/i.test(e)}function G(e){return String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function ie(e,n){if(n&&n.keepBait||!e||e.nodeType!==O)return!1;if(e.id==="ch-decoy")return!0;for(var r=e.attributes||[],t=0;t<r.length;t++)if(r[t].name==="data-ch-role"||r[t].name==="data-ch-decoy")return!0;return!1}function Me(e){return e.tagName==="INPUT"&&(e.type==="password"||H(e,"type","password"))}function oe(e,n){if(!e)return!1;if(Me(e))return!0;var r=n&&n.redactSelector;if(!r||typeof e.matches!="function")return!1;try{return e.matches(r)}catch{return!1}}function V(e,n){for(var r=e;r;){if(r.nodeType===O&&oe(r,n))return!0;r=r.parentNode}return!1}function H(e,n,r){for(var t=e.attributes||[],a=0;a<t.length;a++)if(t[a].name===n)return r==null||t[a].value===r;return!1}function B(e,n){n=n||{};var r=[];return U(e,n,r),r.join("")}function Re(e){var n=null,r=null;try{if(typeof e.getBoundingClientRect=="function"){var t=e.getBoundingClientRect();t&&(n=Math.round(t.width||0),r=Math.round(t.height||0))}}catch{}return n==null&&(n=parseInt(H(e,"width")?re(e,"width"):"",10),r=parseInt(H(e,"height")?re(e,"height"):"",10),n>0||(n=300),r>0||(r=150)),{w:n,h:r}}var te=["position","top","right","bottom","left","margin","float","vertical-align","z-index"];function se(e){var n=Re(e),r="",t="inline-block";try{var a=e.ownerDocument&&e.ownerDocument.defaultView;if(a&&typeof a.getComputedStyle=="function"){var l=a.getComputedStyle(e);l.display&&l.display!=="inline"&&(t=l.display);for(var f=0;f<te.length;f++){var c=te[f],d=l.getPropertyValue(c);d&&d!=="auto"&&d!=="none"&&d!=="normal"&&d!=="baseline"&&d!=="0px"&&(r+=c+":"+d+";")}}}catch{}return"display:"+t+";"+r+"width:"+n.w+"px;height:"+n.h+"px"}function Pe(e,n,r){r.push('<span data-ch-iframe=""'),n.markers&&r.push(" "+n.markers.attr+'="'+n.markers.refFor(e)+'"'),r.push(' style="'+se(e)+'"></span>')}function re(e,n){for(var r=e.attributes||[],t=0;t<r.length;t++)if(r[t].name===n)return r[t].value;return""}function U(e,n,r){if(e){if(e.nodeType===_e){r.push(G(e.textContent||""));return}if(e.nodeType===O){var t=e.tagName;if(!be[t]&&!ie(e,n)){if(t==="IFRAME"){Pe(e,n,r);return}var a=t.toLowerCase();r.push("<"+a),n.markers&&r.push(" "+n.markers.attr+'="'+n.markers.refFor(e)+'"'),e.shadowRoot&&r.push(' data-ch-shadow=""');for(var l=oe(e,n),f=t==="IMG"&&e.src?e.src:null,c=!1,d=e.attributes||[],y=0;y<d.length;y++){var p=d[y].name,h=d[y].value;ae(p)&&(p==="value"&&l||(p==="src"&&f&&(h=f,c=!0),r.push(" "+p+'="'+G(h)+'"')))}if(f&&!c&&r.push(' src="'+G(f)+'"'),l&&r.push(' data-ch-redacted="true"'),r.push(">"),!Ee[t]){if(!l)for(var u=e.childNodes||[],v=0;v<u.length;v++)U(u[v],n,r);r.push("</"+a+">")}}}}}function ne(e,n){for(var r=[],t=e;t&&t!==n;){var a=t.parentNode;if(!a)return null;var l=ke(a,t);if(l===-1)return null;r.unshift(l),t=a}return t===n?r:null}function ke(e,n){for(var r=e.childNodes||[],t=0;t<r.length;t++)if(r[t]===n)return t;return-1}function Ce(e,n,r){for(var t=e.target,a=t;a;){if(ie(a,r))return null;a=a.parentNode}if(e.type==="characterData"&&r.markers){var l=t.parentNode;if(!l||ne(l,n)===null)return null;e={type:"childList",target:l},t=l}var f=ne(t,n);if(f===null)return null;var c=r.markers&&t.nodeType===O?{n:r.markers.refFor(t),tag:t.tagName==="IFRAME"?"span":t.tagName.toLowerCase()}:null;if(e.type==="childList")return Object.assign({op:"childList",path:f,html:V(t,r)?"":Ie(t,r)},c||{});if(e.type==="attributes"){if(t.tagName==="IFRAME")return Object.assign({op:"attributes",path:f,name:"style",value:se(t)},c||{});var d=e.attributeName;if(!ae(d))return null;var y=typeof t.getAttribute=="function"?t.getAttribute(d):null;return d==="value"&&V(t,r)&&(y=null),Object.assign({op:"attributes",path:f,name:d,value:y},c||{})}if(e.type==="characterData"){var p=V(t,r)?"":t.textContent||"";return{op:"characterData",path:f,value:p}}return null}function Ie(e,n){for(var r=[],t=e.childNodes||[],a=0;a<t.length;a++)U(t[a],n,r);return r.join("")}function Le(e){for(var n=[],r=e&&e.styleSheets||[],t=0;t<r.length;t++){var a=r[t];try{for(var l=a.cssRules,f=[],c=0;c<l.length;c++)f.push(l[c].cssText);n.push({css:f.join(`
|
|
3
|
-
`)})}catch{n.push({href:a.href||null})}}return n}function ue(e,n){n=n||{};var r=n.doc||document,t=n.win||window,a=n.now||function(){return performance.now()},l=n.MutationObserver||(typeof MutationObserver<"u"?MutationObserver:null),f=Te(Math.random().toString(16).slice(2,10)||"fallback0");typeof e.setMarkers=="function"&&(e.setMarkers(f),e.setMarkerAttr(f.attr));var c={keepBait:e.config.keepBait,redactSelector:e.config.redactSelector,markers:f};function d(){var u=e.config.root;if(typeof u=="string")try{return r.querySelector(u)||r.body}catch{return r.body}return u||r.body}try{e.setStylesheets(Le(r))}catch(u){e.captureFailure("stylesheets",u)}if(e.onTrialStart(function(u){try{var v=B(d(),c),T=e.config.maxCharsPerTrial;T!=null&&v.length>T?(e.captureFailure("dom_snapshot",new Error("initial DOM snapshot length "+v.length+" exceeds maxCharsPerTrial "+T+"; dropped to bound payload size")),u.initialDom=""):u.initialDom=v}catch(E){e.captureFailure("dom_snapshot",E),u.initialDom=""}}),l){var y=new l(function(u){try{for(var v=d(),T=new Set,E=function(m){return m.type==="childList"?m.target:m.type==="characterData"&&c.markers&&m.target&&m.target.parentNode?m.target.parentNode:null},x=0;x<u.length;x++){var P=E(u[x]);if(P){if(T.has(P))continue;T.add(P)}var s=Ce(u[x],v,c);s&&e.pushEvent("mutation",s,a())}}catch(m){e.captureFailure("mutations",m)}});try{y.observe(d(),{childList:!0,attributes:!0,characterData:!0,subtree:!0}),e.addListener({addEventListener:function(){},removeEventListener:function(){}},"_mutation_observer",y,{_isObserver:!0})}catch(u){e.captureFailure("mutations",u)}}if(t.GuardFriction&&typeof t.GuardFriction.onViolation=="function")try{var p=e.getState().state;if((p==="session"||p==="trial")&&typeof t.GuardFriction.getCurrentState=="function"){var h=t.GuardFriction.getCurrentState();h&&h.in_violation&&e.pushEvent("ch:guard_violation",{reason:h.current_reason||"unknown",phase:"start",synthesized_at_subscribe:!0,dom_at_subscribe:B(d(),c)},a())}t.GuardFriction.onViolation(function(u){try{u&&u.phase==="start"?e.pushEvent("ch:guard_violation",{reason:u.reason,phase:"start",pre_scramble_dom:B(d(),c)},a()):u&&u.phase&&e.pushEvent("ch:guard_violation",{reason:u.reason,phase:u.phase,duration_ms:u.duration!=null?u.duration:null},a())}catch(v){e.captureFailure("guard_violation",v)}})}catch(u){e.captureFailure("guard_violation",u)}}var W="0.7.
|
|
3
|
+
`)})}catch{n.push({href:a.href||null})}}return n}function ue(e,n){n=n||{};var r=n.doc||document,t=n.win||window,a=n.now||function(){return performance.now()},l=n.MutationObserver||(typeof MutationObserver<"u"?MutationObserver:null),f=Te(Math.random().toString(16).slice(2,10)||"fallback0");typeof e.setMarkers=="function"&&(e.setMarkers(f),e.setMarkerAttr(f.attr));var c={keepBait:e.config.keepBait,redactSelector:e.config.redactSelector,markers:f};function d(){var u=e.config.root;if(typeof u=="string")try{return r.querySelector(u)||r.body}catch{return r.body}return u||r.body}try{e.setStylesheets(Le(r))}catch(u){e.captureFailure("stylesheets",u)}if(e.onTrialStart(function(u){try{var v=B(d(),c),T=e.config.maxCharsPerTrial;T!=null&&v.length>T?(e.captureFailure("dom_snapshot",new Error("initial DOM snapshot length "+v.length+" exceeds maxCharsPerTrial "+T+"; dropped to bound payload size")),u.initialDom=""):u.initialDom=v}catch(E){e.captureFailure("dom_snapshot",E),u.initialDom=""}}),l){var y=new l(function(u){try{for(var v=d(),T=new Set,E=function(m){return m.type==="childList"?m.target:m.type==="characterData"&&c.markers&&m.target&&m.target.parentNode?m.target.parentNode:null},x=0;x<u.length;x++){var P=E(u[x]);if(P){if(T.has(P))continue;T.add(P)}var s=Ce(u[x],v,c);s&&e.pushEvent("mutation",s,a())}}catch(m){e.captureFailure("mutations",m)}});try{y.observe(d(),{childList:!0,attributes:!0,characterData:!0,subtree:!0}),e.addListener({addEventListener:function(){},removeEventListener:function(){}},"_mutation_observer",y,{_isObserver:!0})}catch(u){e.captureFailure("mutations",u)}}if(t.GuardFriction&&typeof t.GuardFriction.onViolation=="function")try{var p=e.getState().state;if((p==="session"||p==="trial")&&typeof t.GuardFriction.getCurrentState=="function"){var h=t.GuardFriction.getCurrentState();h&&h.in_violation&&e.pushEvent("ch:guard_violation",{reason:h.current_reason||"unknown",phase:"start",synthesized_at_subscribe:!0,dom_at_subscribe:B(d(),c)},a())}t.GuardFriction.onViolation(function(u){try{u&&u.phase==="start"?e.pushEvent("ch:guard_violation",{reason:u.reason,phase:"start",pre_scramble_dom:B(d(),c)},a()):u&&u.phase&&e.pushEvent("ch:guard_violation",{reason:u.reason,phase:u.phase,duration_ms:u.duration!=null?u.duration:null},a())}catch(v){e.captureFailure("guard_violation",v)}})}catch(u){e.captureFailure("guard_violation",u)}}var W="0.7.4";function le(e){return String(e).replace(/[^a-zA-Z0-9_.-]/g,"_")}function C(e,n){return e==null?null:Math.round((e-n)*10)/10}function R(e,n){return(e||[]).map(function(r){var t=Object.assign({},r);return typeof t.t=="number"&&(t.t=C(t.t,n)),typeof t.start=="number"&&(t.start=C(t.start,n)),t})}function ce(e,n){n=n||{};var r=e.sessionStart;if(r==null)throw new Error("[cyborg-hunter-replay] cannot serialize before startSession() \u2014 call startSession() first, or the timestamps would be meaningless (Unix epoch).");var t=n.chSessionReport||null,a=r,l=e.trials.map(function(c){var d=c.events.slice().sort(function(p,h){return p.t-h.t}),y=d.length>0?d[d.length-1].t:c.tLoad;return y>a&&(a=y),{trial_index:c.trialIndex,trial_id:c.trialId,plugin:c.plugin,t_start:C(c.tStart,r),t_dom_ready:C(c.tDomReady,r),t_load:C(c.tLoad,r),t_end:C(c.tEnd!=null?c.tEnd:y,r),view_state:c.viewState||null,initial_dom:c.initialDom||"",events:d.map(function(p){var h=Object.assign({},p);return h.t=C(p.t,r),h}),trial_data:{}}}),f={replay_version:W,marker_attr:e.markerAttr||null,ch_version:t&&t.libraryVersion||null,preset:t&&t.config?t.config.preset:null,scoring:t?{hard_score:t.hardScore||{},soft_score:t.softScore!=null?t.softScore:null,soft_score_threshold:t.softScoreThreshold!=null?t.softScoreThreshold:null,any_hard_triggered:!!t.anyHardTriggered,trials_completed:t.trialsCompleted!=null?t.trialsCompleted:null}:null,session_signals:t?{sidebar_events:R(t.sidebarEvents,r),ai_extensions_found:R(t.aiExtensionsFound,r),devtools_events:R(t.devToolsEvents,r),window_positions:R(t.windowPositions,r),layout_shifts:R(t.layoutShifts,r),zoom_changes:R(t.zoomChanges,r),extension_injections:R(t.extensionInjections,r)}:null,guard_violations:R(e.guardViolations,r),capture_failures:R(e.captureFailures,r),capture_stopped:!!e.captureStopped};return{schema_version:1,metadata:{start_time:new Date(e.sessionStartEpoch).toISOString(),end_time:new Date(e.sessionStartEpoch+Math.max(0,Math.round(a-r))).toISOString(),end_reason:e.endReason||"aborted",participant_id:e.participantId,recorder:"cyborg-hunter-replay@"+W,tier:e.tier,keys:e.keys},viewport:e.viewport,stylesheets:{initial:e.stylesheets||[],events:[]},rng_calls:[],trials:l,ch_extensions:f}}var Ae="https://pipe.jspsych.org/api/data/";function de(e){var n=le(e.metadata.participant_id),r=Date.parse(e.metadata.start_time);return n+"-replay-"+r+".json"}function he(e,n){return{schema_version:e.schema_version,tier:e.metadata.tier,saved_to:n,bytes_uncompressed:JSON.stringify(e).length,capture_failures:(e.ch_extensions.capture_failures||[]).map(function(r){return r.channel}),capture_stopped:!!e.ch_extensions.capture_stopped}}async function fe(e,n){var r=n||{mode:"none"},t=de(e),a=typeof window<"u"?window:{};if(r.mode==="none")return{saved_to:"none",filename:t};if(r.mode==="datapipe"){if(!r.experimentId)return{saved_to:"failed",filename:t,error:'autoSave.mode "datapipe" requires autoSave.experimentId'};try{var l=JSON.stringify(e);if(a.jsPsychPipe&&typeof a.jsPsychPipe.saveData=="function")await a.jsPsychPipe.saveData(r.experimentId,t,l);else{var f=a.fetch||(typeof fetch<"u"?fetch:null);if(!f)throw new Error("no fetch available for DataPipe POST");var c=await f(Ae,{method:"POST",headers:{"Content-Type":"application/json",Accept:"*/*"},body:JSON.stringify({experimentID:r.experimentId,filename:t,data:l})});if(c&&c.ok===!1)throw new Error("DataPipe HTTP error")}return{saved_to:"datapipe:"+r.experimentId+"/"+t,filename:t}}catch(v){return console.error("[cyborg-hunter-replay] DataPipe autosave failed:",v),{saved_to:"failed",filename:t,error:v&&v.message?v.message:String(v)}}}if(r.mode==="download")try{var d=typeof document<"u"?document:null,y=a.Blob||(typeof Blob<"u"?Blob:null),p=a.URL||(typeof URL<"u"?URL:null);if(!d||!y||!p)throw new Error("download mode needs a browser");var h=new y([JSON.stringify(e)],{type:"application/json"}),u=d.createElement("a");return u.href=p.createObjectURL(h),u.download=t,d.body.appendChild(u),u.click(),d.body.removeChild(u),p.revokeObjectURL(u.href),{saved_to:"download",filename:t}}catch(v){return console.error("[cyborg-hunter-replay] download autosave failed:",v),{saved_to:"failed",filename:t,error:v&&v.message?v.message:String(v)}}return{saved_to:"failed",filename:t,error:'unknown autoSave.mode "'+r.mode+'"'}}async function pe(e){var n=JSON.stringify(e),r=typeof window<"u"?window:{},t=r.CompressionStream||(typeof CompressionStream<"u"?CompressionStream:null),a=r.Blob||(typeof Blob<"u"?Blob:null);if(!a)return null;if(!t)return new a([n],{type:"application/json"});var l=new a([n]).stream().pipeThrough(new t("gzip")),f=r.Response||(typeof Response<"u"?Response:null),c=await new f(l).arrayBuffer();return new a([c],{type:"application/gzip"})}var I=null;function Y(e){I&&(console.warn("[cyborg-hunter-replay] attach() called while a recorder is active \u2014 replacing the previous instance (its unsaved recording is discarded)."),I.destroy(),I=null);var n=Z(e),r={_recorder:n,config:n.config,startSession:function(){return n.startSession(),ee(n),(n.config.tier==="dom"||n.config.tier==="canvas")&&ue(n),r},startTrial:function(t){return n.startTrial(t),r},endTrial:function(){return n.endTrial(),r},stopSession:function(t){return n.stopSession(t),r},getRecording:function(t){return ce(n.getState(),t||{})},getRecordingCompressed:function(t){return pe(r.getRecording(t))},autoSaveNow:async function(t){if(n.getState().sessionStart==null)return{recording:null,saveResult:{saved_to:"no_session"},meta:{schema_version:1,saved_to:"no_session",note:"recorder was never started; nothing to save"}};var a=r.getRecording(t),l=await fe(a,n.config.autoSave),f=he(a,l.saved_to);return l.error&&(f.save_error=l.error),{recording:a,saveResult:l,meta:f}},destroy:function(){n.destroy(),I===r&&(I=null)}};return I=r,r}typeof window<"u"&&(window.CyborgHunterReplay={attach:Y});var X=class{static info={name:"cyborg-hunter-replay",version:"0.7.4",data:{}};constructor(n){this.jsPsych=n,this.api=null,this._chMonitor=null,this._lastRecording=null,this._monitoring=!1}initialize(n){this.params=n||{},this.api=Y(this.params),this.api.startSession(),this._stashChMonitor()}_stashChMonitor(){try{var n=this.jsPsych&&this.jsPsych.extensions&&this.jsPsych.extensions["cyborg-hunter"];n&&n.monitor&&(this._chMonitor=n.monitor)}catch{}}on_start(n){}on_load(n){if(this.api){this._monitoring=!0;var r=0,t="unknown";try{r=this.jsPsych.getProgress().current_trial_global}catch{}try{t=(this.jsPsych.getCurrentTrial()||{}).type?.info?.name||"unknown"}catch{}this.api.startTrial({trialId:n&&n.trialId||"trial-"+r,plugin:t})}}on_finish(n){return this.api&&this._monitoring&&(this._monitoring=!1,this.api.endTrial()),{}}async finalize(){if(this.api){try{try{this.api.stopSession("finished")}catch{}this._chMonitor||this._stashChMonitor();var n=null;try{n=this._chMonitor?this._chMonitor.getSessionReport():null}catch(t){console.warn("[cyborg-hunter-replay] could not pull CH session report:",t)}var r=await this.api.autoSaveNow({chSessionReport:n});this._lastRecording=r.recording,this.jsPsych.data.addProperties({integrityReplayMeta:r.meta})}catch(t){console.warn("[cyborg-hunter-replay] finalize failed:",t);try{this.jsPsych.data.addProperties({replayFinalizeError:String(t&&t.message?t.message:t)})}catch{}}try{this.api.destroy()}catch{}this.api=null}}getLastRecording(){return this._lastRecording}};typeof window<"u"&&(window.jsPsychCyborgHunterReplay=X);})();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// cyborg-hunter v0.7.
|
|
2
|
-
var CyborgHunter=(()=>{var _=Object.defineProperty;var Te=Object.getOwnPropertyDescriptor;var be=Object.getOwnPropertyNames;var Ee=Object.prototype.hasOwnProperty;var Ie=(e,n)=>{for(var t in n)_(e,t,{get:n[t],enumerable:!0})},Me=(e,n,t,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of be(n))!Ee.call(e,r)&&r!==t&&_(e,r,{get:()=>n[r],enumerable:!(o=Te(n,r))||o.enumerable});return e};var xe=e=>Me(_({},"__esModule",{value:!0}),e);var Fe={};Ie(Fe,{VERSION:()=>q,addHoneypot:()=>me,init:()=>we,preventTextSelection:()=>ve,setAltText:()=>ye});var W={created:["session","destroyed"],session:["trial","destroyed"],trial:["session","destroyed"],destroyed:[]};function J(){let e="created";return{get current(){return e},transition(n){return W[e]&&W[e].indexOf(n)!==-1?(e=n,!0):(console.warn("[cyborg-hunter] invalid transition: "+e+" \u2192 "+n),!1)}}}function N(e){if(e===null||typeof e!="object")return e;try{return JSON.parse(JSON.stringify(e))}catch{return e}}var q="0.7.3",z={pasteMinChars:0,dropMinChars:0,sidebarGapPx:100,layoutCompressionPx:20,viewportShiftDebounceMs:250,syntheticGapMs:100,idleGapMs:1e4,idleCheckIntervalMs:5e3,mouseThrottleMs:50,mouseMaxEvents:2e3,mouseBotMinEvents:3,sidebarPollMs:2e3,extensionScanMs:3e4,windowPositionPollMs:2e3,elementTraceHz:500,tabAwayDurationMs:3e3,typingSpeedCps:10},$={permissive:{signals:{paste:!0,copy:!0,drop:!0,tabAway:!0,typingSpeed:!0,devTools:!0,aiExtensions:!0,sidebarGap:!0,keyboardShortcuts:!0,mouseTracking:!0,idleGaps:!0,windowPosition:!0,clipboardManager:!0,keystrokeDynamics:!1},thresholds:{typingSpeedCps:15},scoring:{hard:{paste:{countThreshold:3},drop:{countThreshold:3}},soft:{copy:{weight:1,maxPerTrial:2},tabAway:{weight:1,maxPerTrial:2},typingSpeed:{weight:1},sidebarEvent:{weight:1},devTools:{weight:1},foreignInput:{weight:1}},softScoreThreshold:10},screenout:{enabled:!1,gracePeriodTrials:5}},standard:{signals:{paste:!0,copy:!0,drop:!0,tabAway:!0,typingSpeed:!0,devTools:!0,aiExtensions:!0,sidebarGap:!0,keyboardShortcuts:!0,mouseTracking:!0,idleGaps:!0,windowPosition:!0,clipboardManager:!0,keystrokeDynamics:!1},thresholds:{},scoring:{hard:{paste:{countThreshold:2},drop:{countThreshold:2}},soft:{copy:{weight:2,maxPerTrial:2},tabAway:{weight:1,maxPerTrial:2},typingSpeed:{weight:2},sidebarEvent:{weight:3},devTools:{weight:1},foreignInput:{weight:2}},softScoreThreshold:6},screenout:{enabled:!0,gracePeriodTrials:3}},strict:{signals:{paste:!0,copy:!0,drop:!0,tabAway:!0,typingSpeed:!0,devTools:!0,aiExtensions:!0,sidebarGap:!0,keyboardShortcuts:!0,mouseTracking:!0,idleGaps:!0,windowPosition:!0,clipboardManager:!0,keystrokeDynamics:!0},thresholds:{typingSpeedCps:8,tabAwayDurationMs:5e3,mouseMaxEvents:5e3},scoring:{hard:{paste:{countThreshold:1},copy:{countThreshold:2},drop:{countThreshold:1}},soft:{tabAway:{weight:2,maxPerTrial:1},typingSpeed:{weight:3},sidebarEvent:{weight:2},devTools:{weight:2},foreignInput:{weight:3}},softScoreThreshold:4},screenout:{enabled:!0,gracePeriodTrials:2}}},X=[{name:"ChatGPT sidebar",sel:"chatgpt-sidebar"},{name:"ChatGPT extension",sel:"[data-chatgpt]"},{name:"Copilot extension",sel:"copilot-suggestions"},{name:"Copilot extension",sel:"[data-copilot]"},{name:"Gemini extension",sel:"gemini-panel"},{name:"Claude extension",sel:"[data-claude-extension]"},{name:"Monica AI",sel:"monica-root"},{name:"Merlin AI",sel:"merlin-root"},{name:"Sider AI",sel:"[data-sider-extension]"},{name:"MaxAI",sel:"[data-maxai]"},{name:"AI assistant",sel:"[data-ai-assistant]"},{name:"AI iframe (OpenAI)",sel:'iframe[src*="chat.openai.com"]'},{name:"AI iframe (Copilot)",sel:'iframe[src*="copilot.microsoft.com"]'},{name:"AI iframe (Gemini)",sel:'iframe[src*="gemini.google.com"]'},{name:"AI iframe (Claude)",sel:'iframe[src*="claude.ai"]'},{name:"AI iframe (Perplexity)",sel:'iframe[src*="perplexity.ai"]'}],Y=["grammarly","lastpass","1password","bitwarden","dashlane","roboform","honey","ublock","adblock"];var Q={dataDir:"./data",replayDir:null,filePattern:"*.json",participantIdField:"participantId",trialIdField:"trialId",trialOrderField:"trialIndex",integrityField:"integrity",sessionIntegrityPath:null,trialsPerParticipant:null,platformIdField:null,showPlatformId:!1,conditionField:null,groupField:null,typingSpeedThreshold_cps:10,tabAwayMinDuration_ms:3e3,idleGapThreshold_ms:1e4,suspiciouslyFastRT_ms:2e3,scoring:null,signals:null,phaseScope:null,trajectoryGrid:"auto",trajectoryTrialLabel:"trialId",trajectoryResponseField:null,trajectoryDisplayOrder:"rule",outputDir:"./cyborg-hunter-report",outputFormat:"html"};var Ce=["replayDir",...Object.keys(Q),...Object.keys(z),"preset","participantId","signals","thresholds","scoring","domProtection","collectForPostHoc","onSignal","screenout","experimentContainer","knownInputs","decoyAnswers","decoyMap","decoyVisibility","decoyFraming","decoyExcludeButtons","autoMonitor","excludeTrialTypes"];function ee(e,n=Ce){let t=[];return Object.keys(e).forEach(o=>{if(!n.includes(o)){let r=Ae(o,n),i=r?`Unknown config key "${o}" \u2014 did you mean "${r}"?`:`Unknown config key "${o}"`;t.push(i)}}),t}function te(e){let n=[];if(!e||typeof e!="object")return n;let t=e.hard||{};Object.keys(t).forEach(r=>{let i=t[r];(!i||!Number.isFinite(i.countThreshold))&&n.push(`scoring.hard.${r} has no finite numeric countThreshold (got ${i?Z(i.countThreshold):"no rule"}) \u2014 this hard screenout rule can never trigger. A likely cause is a typo in the override key (e.g. "countThreshhold").`)});let o=e.soft||{};return Object.keys(o).forEach(r=>{let i=o[r];(!i||!Number.isFinite(i.weight))&&n.push(`scoring.soft.${r} has no finite numeric weight (got ${i?Z(i.weight):"no rule"}) \u2014 this soft signal contributes nothing (or breaks the soft score). A likely cause is a typo in the override key (e.g. "wieght").`)}),n}function Z(e){try{return String(e)}catch{return typeof e}}function Ae(e,n){let t=null,o=1/0;for(let r of n){let i=Pe(e.toLowerCase(),r.toLowerCase());i<o&&i<=3&&(o=i,t=r)}return t}function Pe(e,n){let t=e.length,o=n.length,r=Array.from({length:t+1},()=>Array(o+1).fill(0));for(let i=0;i<=t;i++)r[i][0]=i;for(let i=0;i<=o;i++)r[0][i]=i;for(let i=1;i<=t;i++)for(let a=1;a<=o;a++)r[i][a]=e[i-1]===n[a-1]?r[i-1][a-1]:1+Math.min(r[i-1][a],r[i][a-1],r[i-1][a-1]);return r[t][o]}function re(e,n,t,o){var r=t.scoring,i={hard:{},soft:{}},a=0;if(r.hard.paste){var c=(e.pasteEvents||[]).length;i.hard.paste={trialHits:c,sessionTotal:n.pasteCount,countThreshold:r.hard.paste.countThreshold}}if(r.hard.copy){var v=(e.copyEvents||[]).length;i.hard.copy={trialHits:v,sessionTotal:n.copyCount,countThreshold:r.hard.copy.countThreshold}}if(r.hard.drop){var d=(e.dropEvents||[]).length;i.hard.drop={trialHits:d,sessionTotal:n.dropCount,countThreshold:r.hard.drop.countThreshold}}if(r.soft.copy){var h=(e.copyEvents||[]).length,m=r.soft.copy.maxPerTrial!=null?Math.min(h,r.soft.copy.maxPerTrial):h,T=m*r.soft.copy.weight;a+=T,i.soft.copy={hits:h,capped:m,score:T}}if(r.soft.tabAway){var y=(e.tabAwayEvents||[]).filter(function(F){return(F.duration_ms||0)>t.thresholds.tabAwayDurationMs}).length,k=r.soft.tabAway.maxPerTrial!=null?Math.min(y,r.soft.tabAway.maxPerTrial):y,M=k*r.soft.tabAway.weight;a+=M,i.soft.tabAway={hits:y,capped:k,score:M}}if(r.soft.typingSpeed&&o.charsPerSec!=null){var b=t.thresholds.typingSpeedCps,E=o.charsPerSec>b?1:0,u=E*r.soft.typingSpeed.weight;a+=u,i.soft.typingSpeed={charsPerSec:o.charsPerSec,threshold:b,hit:E,score:u}}var p=e.startTime+(o&&o.duration_ms!=null?o.duration_ms:performance.now()-e.startTime);if(r.soft.sidebarEvent){var S=n.sidebarEvents.filter(function(F){return F.t>=e.startTime&&F.t<=p}).length;if(S>0){var l=r.soft.sidebarEvent.weight;a+=l,i.soft.sidebarEvent={hits:S,score:l}}}if(r.soft.devTools){var f=n.keyboardShortcuts.filter(function(F){return F.t>=e.startTime&&F.t<=p}).length;if(f>0){var g=r.soft.devTools.weight;a+=g,i.soft.devTools={hits:f,score:g}}}if(r.soft.foreignInput&&e.foreignInputEvents.length>0){var I=e.foreignInputEvents.length,D=r.soft.foreignInput.weight;a+=D,i.soft.foreignInput={hits:I,score:D}}for(var P={},L=Object.keys(r.hard),j=0;j<L.length;j++){var C=L[j],K=C==="paste"?n.pasteCount:C==="copy"?n.copyCount:C==="drop"?n.dropCount:0;P[C]={count:K,threshold:r.hard[C].countThreshold,triggered:K>=r.hard[C].countThreshold}}return{trialSoftScore:a,trialSignals:i,updatedHardScore:P}}function ne(e,n){if(!n.screenout.enabled)return!1;var t=Object.keys(e.hardScore).some(function(o){return e.hardScore[o].triggered});return t?!0:e.trialsCompleted<n.screenout.gracePeriodTrials?!1:e.softScore>=n.scoring.softScoreThreshold}function oe(e){var n=e.config,t=e.trialData;n.signals.paste&&e.addTrialListener(document,"paste",function(o){var r="";try{r=(o.clipboardData||window.clipboardData).getData("text")}catch{}var i=r.length;if(i>=n.thresholds.pasteMinChars){var a=e.isKnownInput(o.target),c={type:"paste",t:performance.now(),pastedLength:i,isKnownInput:a};n.collectForPostHoc.pasteDropContent&&(c.text=r),t.pasteEvents.push(c),e.sessionData.pasteCount++,e.fireSignal("paste",o,{pastedLength:i,isKnownInput:a,text:r})}}),n.signals.copy&&(e.addTrialListener(document,"copy",function(o){var r=window.getSelection(),i=r?r.toString():"",a=i.length;t.copyEvents.push({type:"copy",t:performance.now(),selectedLength:a}),e.sessionData.copyCount++,e.fireSignal("copy",o,{selectedLength:a})}),e.addTrialListener(document,"cut",function(o){t.copyEvents.push({type:"cut",t:performance.now()}),e.sessionData.copyCount++,e.fireSignal("cut",o,{})})),n.signals.drop&&e.addTrialListener(document,"drop",function(o){var r="";try{r=o.dataTransfer.getData("text")}catch{}var i=r.length;if(i>=n.thresholds.dropMinChars){var a=e.isKnownInput(o.target),c={type:"drop",t:performance.now(),droppedLength:i,isKnownInput:a};n.collectForPostHoc.pasteDropContent&&(c.text=r),t.dropEvents.push(c),e.sessionData.dropCount++,e.fireSignal("drop",o,{droppedLength:i,isKnownInput:a,text:r})}})}function ae(e){var n=e.config;if(n.signals.tabAway){let r=function(a){t===null&&(t=performance.now(),o=a,e.fireSignal("tabAway",null,{type:a}))},i=function(){if(t!==null){var a=performance.now()-t,c={start:t,duration_ms:Math.round(a),type:o,timestamp:new Date(Date.now()-a).toISOString()};e.getTrialData()&&e.getTrialData().tabAwayEvents.push(c),e.sessionData.tabAwayEvents.push(c),e.sessionData.tabAwaySums.push(Math.round(a)),e.fireSignal("tabReturn",null,{duration_ms:Math.round(a),type:o}),t=null,o=null}};var t=null,o=null;e.addListener(document,"visibilitychange",function(){document.hidden?r("tabHidden"):i()}),e.addListener(window,"blur",function(){r("windowBlur")}),e.addListener(window,"focus",function(){document.hidden||i()})}}function ie(e){var n=e.config,t=e.trialData;if(n.signals.idleGaps){var o=n.thresholds.idleGapMs,r=performance.now();e.addTrialListener(document,"keydown",function(){r=performance.now()}),e.addTrialListener(document,"mousemove",function(){r=performance.now()},{passive:!0});var i=setInterval(function(){if(e.getTrialData()){var a=performance.now()-r;a>o&&(t.idleGaps.push({duration_ms:Math.round(a),t:performance.now()}),r=performance.now())}},n.thresholds.idleCheckIntervalMs);e.addTrialInterval(i)}}function se(e){var n=e.config,t=e.trialData;if(n.signals.mouseTracking){let c=function(v){return function(d){t.mouseEvents.length>=r||t.mouseEvents.push({x:Math.round(d.pageX),y:Math.round(d.pageY),t:Math.round(performance.now()-a),type:v})}};var o=n.thresholds.mouseThrottleMs,r=n.thresholds.mouseMaxEvents,i=0,a=t.startTime;t.mouseTrackingCapped=!1,t.mouseTrackingCappedAtMs=null,e.addTrialListener(document,"mousemove",function(v){if(t.mouseEvents.length>=r){t.mouseTrackingCapped||(t.mouseTrackingCapped=!0,t.mouseTrackingCappedAtMs=Math.round(performance.now()-a));return}var d=performance.now();d-i<o||(i=d,t.mouseEvents.push({x:Math.round(v.pageX),y:Math.round(v.pageY),t:Math.round(d-a),type:"move"}))},{passive:!0}),e.addTrialListener(document,"click",c("click"),{passive:!0}),e.addTrialListener(document,"mousedown",c("down"),{passive:!0}),e.addTrialListener(document,"mouseup",c("up"),{passive:!0})}}function le(e,n){var t=e.filter(function(g){return g.type==="move"});if(t.length<n)return null;for(var o=0,r=[],i=0,a=0,c=0,v=0,d=1;d<t.length;d++){var h=t[d].x-t[d-1].x,m=t[d].y-t[d-1].y,T=Math.sqrt(h*h+m*m);o+=T;var y=t[d].t-t[d-1].t;y>0&&r.push(T/y),d>1&&((h>0&&c<0||h<0&&c>0)&&i++,(m>0&&v<0||m<0&&v>0)&&a++),c=h,v=m}for(var k=t[0],M=t[t.length-1],b=Math.sqrt(Math.pow(M.x-k.x,2)+Math.pow(M.y-k.y,2)),E=o>0?Math.round(b/o*1e3)/1e3:0,u=0,p=0,S=0;S<r.length;S++){var l=r[S]-u;u+=l/(S+1),p+=l*(r[S]-u)}var f=r.length>1?Math.round(p/(r.length-1)*1e4)/1e4:0;return{pathEfficiency:E,directionChanges:i+a,speedVariance:f,moveCount:t.length}}function ce(e){var n=e.config,t=e.trialData;if(n.signals.clipboardManager){var o=0;e.addTrialListener(document,"keydown",function(){o=performance.now()}),e.addTrialListener(document,"input",function(r){if(r.target&&(r.target.tagName==="INPUT"||r.target.tagName==="TEXTAREA"||r.target.isContentEditable)&&(t.editTimestamps.push(performance.now()),performance.now()-o>n.thresholds.syntheticGapMs&&r.inputType==="insertText")){var i=(r.data||"").length;t.syntheticInsertions.push({type:"synthetic_insertion",t:performance.now(),dataLength:i}),e.fireSignal("syntheticInsertion",r,{dataLength:i})}},!0)}n.signals.typingSpeed&&!n.signals.clipboardManager&&e.addTrialListener(document,"input",function(r){r.target&&(r.target.tagName==="INPUT"||r.target.tagName==="TEXTAREA"||r.target.isContentEditable)&&t.editTimestamps.push(performance.now())},!0)}function ue(e){var n=e.config,t=e.trialData;e.addTrialListener(document,"input",function(o){var r=o.target;if(r){var i=r.tagName==="INPUT"||r.tagName==="TEXTAREA"||r.isContentEditable;if(i){var a=e.isKnownInput(r);if(a===!1){var c={t:performance.now(),targetTag:r.tagName||"unknown",targetId:(r.id||"").slice(0,50),targetClass:(r.className||"").toString().slice(0,100),inputType:o.inputType||""};n.collectForPostHoc.foreignInputContent&&(c.data=o.data||""),t.foreignInputEvents.push(c),e.fireSignal("typingOutsideExperiment",o,{targetTag:c.targetTag,targetId:c.targetId,targetClass:c.targetClass,data:o.data||""})}}}},!0)}function de(e){if(e.length<2)return null;var n=e[0],t=e[e.length-1],o=(t-n)/1e3;if(o<=0)return null;var r=e.length;return Math.round(r/o*10)/10}function pe(e){var n=e.config,t=e.sessionData;if(n.signals.sidebarGap){var o=window.devicePixelRatio||1,r=window.innerWidth,i=!1,a=null,c=null,v=0,d=null,h=!1,m=null;e.addInterval(setInterval(function(){var l=window.innerWidth,f=n.thresholds.sidebarGapPx,g=r-l;if(!i&&g>f)i=!0,a=performance.now(),c="innerWidth_delta",v=g,d=l,t.sidebarEvents.push({type:"opened",method:"innerWidth_delta",deltaIW:g,innerWidth:l,baselineIW:r,t:performance.now()}),e.fireSignal("sidebarOpened",null,{deltaIW:g});else if(i&&c==="innerWidth_delta"&&g<f/2){var I=performance.now()-a,D=d!=null?d-l:null;t.sidebarEvents.push({type:"closed",method:"innerWidth_delta",deltaIW:D,duration_ms:Math.round(I),t:performance.now()}),e.fireSignal("sidebarClosed",null,{duration_ms:Math.round(I),deltaIW:D}),i=!1,a=null,d=null,r=l}else i||(r=l);var P=l-document.documentElement.clientWidth,L=n.thresholds.layoutCompressionPx;if(!h&&P>L)h=!0,m=performance.now(),t.sidebarEvents.push({type:"opened",method:"layout_compression",gap:P,t:performance.now()});else if(h&&P<=L){var j=performance.now()-m;t.sidebarEvents.push({type:"closed",method:"layout_compression",duration_ms:Math.round(j),t:performance.now()}),h=!1,m=null}var C=window.devicePixelRatio||1;C!==o&&(t.zoomChanges.push({from:o,to:C,t:performance.now()}),r=l,o=C)},n.thresholds.sidebarPollMs))}if(n.signals.aiExtensions){let l=function(){X.forEach(function(f){if(document.querySelector(f.sel)){var g=t.aiExtensionsFound.some(function(I){return I.name===f.name});g||t.aiExtensionsFound.push({name:f.name,t:performance.now()})}})};l(),e.addInterval(setInterval(l,n.thresholds.extensionScanMs))}if((n.signals.keyboardShortcuts||n.signals.devTools)&&e.addListener(document,"keydown",function(l){var f=l.ctrlKey||l.metaKey;if(f&&l.shiftKey&&(l.key==="I"||l.key==="J"||l.key==="C")){var g="Ctrl+Shift+"+l.key;t.keyboardShortcuts.push({combo:g,t:performance.now()}),e.fireSignal("keyboardShortcut",l,{combo:g})}l.key==="F12"&&(t.keyboardShortcuts.push({combo:"F12",t:performance.now()}),e.fireSignal("keyboardShortcut",l,{combo:"F12"}))}),n.signals.windowPosition&&n.collectForPostHoc.windowPositionLog){var T=function(){t.windowPositions.push({x:window.screenX,y:window.screenY,w:window.outerWidth,h:window.outerHeight,iw:window.innerWidth,ih:window.innerHeight,sw:window.screen.width,sh:window.screen.height,dpr:window.devicePixelRatio,vvScale:window.visualViewport?window.visualViewport.scale:null,t:performance.now()})};e.addInterval(setInterval(T,n.thresholds.windowPositionPollMs));var y=null,k=function(){y&&clearTimeout(y),y=setTimeout(function(){T(),y=null},250)};e.addListener(window,"resize",k)}if(n.signals.aiExtensions){let l=function(f){var g=f.toLowerCase();return Y.some(function(I){return g.indexOf(I)!==-1})};var M=new MutationObserver(function(f){for(var g=0;g<f.length;g++)for(var I=f[g].addedNodes,D=0;D<I.length;D++){var P=I[D];if(P.nodeType===Node.ELEMENT_NODE){var L=P.tagName||"";L.indexOf("-")!==-1&&!l(L)&&t.extensionInjections.push({tag:L.toLowerCase(),hasShadow:!!P.shadowRoot,t:performance.now()})}}});M.observe(document.body,{childList:!0,subtree:!1}),e.listeners.push({target:null,event:"mutation",handler:M,options:{_isMutationObserver:!0}})}if(n.signals.sidebarGap){var b=document.documentElement.clientWidth,E=null,u=null,p=function(){if(u=null,E!==null){var l=E;E=null;var f=b-l;Math.abs(f)>n.thresholds.layoutCompressionPx&&(t.viewportWidthShifts.push({oldWidth:Math.round(b),newWidth:Math.round(l),delta:Math.round(f),t:performance.now()}),b=l)}},S=new ResizeObserver(function(l){for(var f=0;f<l.length;f++)E=l[f].contentRect.width;u&&clearTimeout(u),u=setTimeout(p,n.thresholds.viewportShiftDebounceMs),e.addInterval(u)});S.observe(document.documentElement),e.listeners.push({target:null,event:"resize",handler:S,options:{_isResizeObserver:!0}})}}function fe(e){var n=e.config,t=e.trialData;if(n.collectForPostHoc.elementTrace){t.elementTrace=[];var o=0,r=0;e.addTrialListener(document,"mousemove",function(a){o=a.clientX,r=a.clientY},{passive:!0});var i=setInterval(function(){if(e.getTrialData()&&!(o===0&&r===0))try{var a=document.elementsFromPoint(o,r);if(a&&a.length>0){var c=a[0];t.elementTrace.push({tag:c.tagName.toLowerCase(),id:c.id||null,t:Math.round(performance.now()-t.startTime)})}}catch{}},n.thresholds.elementTraceHz);e.addTrialInterval(i)}}function R(e,n,t,o){return t==="C"?e:n==="calibration-metadata"?"Validation trial (integrity check, ID: cal-"+o+`).
|
|
1
|
+
// cyborg-hunter v0.7.4 — https://github.com/cyborg-hunter/cyborg-hunter
|
|
2
|
+
var CyborgHunter=(()=>{var _=Object.defineProperty;var Te=Object.getOwnPropertyDescriptor;var be=Object.getOwnPropertyNames;var Ee=Object.prototype.hasOwnProperty;var Ie=(e,n)=>{for(var t in n)_(e,t,{get:n[t],enumerable:!0})},Me=(e,n,t,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of be(n))!Ee.call(e,r)&&r!==t&&_(e,r,{get:()=>n[r],enumerable:!(o=Te(n,r))||o.enumerable});return e};var xe=e=>Me(_({},"__esModule",{value:!0}),e);var Fe={};Ie(Fe,{VERSION:()=>q,addHoneypot:()=>me,init:()=>we,preventTextSelection:()=>ve,setAltText:()=>ye});var W={created:["session","destroyed"],session:["trial","destroyed"],trial:["session","destroyed"],destroyed:[]};function J(){let e="created";return{get current(){return e},transition(n){return W[e]&&W[e].indexOf(n)!==-1?(e=n,!0):(console.warn("[cyborg-hunter] invalid transition: "+e+" \u2192 "+n),!1)}}}function N(e){if(e===null||typeof e!="object")return e;try{return JSON.parse(JSON.stringify(e))}catch{return e}}var q="0.7.4",z={pasteMinChars:0,dropMinChars:0,sidebarGapPx:100,layoutCompressionPx:20,viewportShiftDebounceMs:250,syntheticGapMs:100,idleGapMs:1e4,idleCheckIntervalMs:5e3,mouseThrottleMs:50,mouseMaxEvents:2e3,mouseBotMinEvents:3,sidebarPollMs:2e3,extensionScanMs:3e4,windowPositionPollMs:2e3,elementTraceHz:500,tabAwayDurationMs:3e3,typingSpeedCps:10},$={permissive:{signals:{paste:!0,copy:!0,drop:!0,tabAway:!0,typingSpeed:!0,devTools:!0,aiExtensions:!0,sidebarGap:!0,keyboardShortcuts:!0,mouseTracking:!0,idleGaps:!0,windowPosition:!0,clipboardManager:!0,keystrokeDynamics:!1},thresholds:{typingSpeedCps:15},scoring:{hard:{paste:{countThreshold:3},drop:{countThreshold:3}},soft:{copy:{weight:1,maxPerTrial:2},tabAway:{weight:1,maxPerTrial:2},typingSpeed:{weight:1},sidebarEvent:{weight:1},devTools:{weight:1},foreignInput:{weight:1}},softScoreThreshold:10},screenout:{enabled:!1,gracePeriodTrials:5}},standard:{signals:{paste:!0,copy:!0,drop:!0,tabAway:!0,typingSpeed:!0,devTools:!0,aiExtensions:!0,sidebarGap:!0,keyboardShortcuts:!0,mouseTracking:!0,idleGaps:!0,windowPosition:!0,clipboardManager:!0,keystrokeDynamics:!1},thresholds:{},scoring:{hard:{paste:{countThreshold:2},drop:{countThreshold:2}},soft:{copy:{weight:2,maxPerTrial:2},tabAway:{weight:1,maxPerTrial:2},typingSpeed:{weight:2},sidebarEvent:{weight:3},devTools:{weight:1},foreignInput:{weight:2}},softScoreThreshold:6},screenout:{enabled:!0,gracePeriodTrials:3}},strict:{signals:{paste:!0,copy:!0,drop:!0,tabAway:!0,typingSpeed:!0,devTools:!0,aiExtensions:!0,sidebarGap:!0,keyboardShortcuts:!0,mouseTracking:!0,idleGaps:!0,windowPosition:!0,clipboardManager:!0,keystrokeDynamics:!0},thresholds:{typingSpeedCps:8,tabAwayDurationMs:5e3,mouseMaxEvents:5e3},scoring:{hard:{paste:{countThreshold:1},copy:{countThreshold:2},drop:{countThreshold:1}},soft:{tabAway:{weight:2,maxPerTrial:1},typingSpeed:{weight:3},sidebarEvent:{weight:2},devTools:{weight:2},foreignInput:{weight:3}},softScoreThreshold:4},screenout:{enabled:!0,gracePeriodTrials:2}}},X=[{name:"ChatGPT sidebar",sel:"chatgpt-sidebar"},{name:"ChatGPT extension",sel:"[data-chatgpt]"},{name:"Copilot extension",sel:"copilot-suggestions"},{name:"Copilot extension",sel:"[data-copilot]"},{name:"Gemini extension",sel:"gemini-panel"},{name:"Claude extension",sel:"[data-claude-extension]"},{name:"Monica AI",sel:"monica-root"},{name:"Merlin AI",sel:"merlin-root"},{name:"Sider AI",sel:"[data-sider-extension]"},{name:"MaxAI",sel:"[data-maxai]"},{name:"AI assistant",sel:"[data-ai-assistant]"},{name:"AI iframe (OpenAI)",sel:'iframe[src*="chat.openai.com"]'},{name:"AI iframe (Copilot)",sel:'iframe[src*="copilot.microsoft.com"]'},{name:"AI iframe (Gemini)",sel:'iframe[src*="gemini.google.com"]'},{name:"AI iframe (Claude)",sel:'iframe[src*="claude.ai"]'},{name:"AI iframe (Perplexity)",sel:'iframe[src*="perplexity.ai"]'}],Y=["grammarly","lastpass","1password","bitwarden","dashlane","roboform","honey","ublock","adblock"];var Q={dataDir:"./data",replayDir:null,filePattern:"*.json",participantIdField:"participantId",trialIdField:"trialId",trialOrderField:"trialIndex",integrityField:"integrity",sessionIntegrityPath:null,trialsPerParticipant:null,platformIdField:null,showPlatformId:!1,conditionField:null,groupField:null,typingSpeedThreshold_cps:10,tabAwayMinDuration_ms:3e3,idleGapThreshold_ms:1e4,suspiciouslyFastRT_ms:2e3,scoring:null,signals:null,phaseScope:null,trajectoryGrid:"auto",trajectoryTrialLabel:"trialId",trajectoryResponseField:null,trajectoryDisplayOrder:"rule",outputDir:"./cyborg-hunter-report",outputFormat:"html"};var Ce=["replayDir",...Object.keys(Q),...Object.keys(z),"preset","participantId","signals","thresholds","scoring","domProtection","collectForPostHoc","onSignal","screenout","experimentContainer","knownInputs","decoyAnswers","decoyMap","decoyVisibility","decoyFraming","decoyExcludeButtons","autoMonitor","excludeTrialTypes"];function ee(e,n=Ce){let t=[];return Object.keys(e).forEach(o=>{if(!n.includes(o)){let r=Ae(o,n),i=r?`Unknown config key "${o}" \u2014 did you mean "${r}"?`:`Unknown config key "${o}"`;t.push(i)}}),t}function te(e){let n=[];if(!e||typeof e!="object")return n;let t=e.hard||{};Object.keys(t).forEach(r=>{let i=t[r];(!i||!Number.isFinite(i.countThreshold))&&n.push(`scoring.hard.${r} has no finite numeric countThreshold (got ${i?Z(i.countThreshold):"no rule"}) \u2014 this hard screenout rule can never trigger. A likely cause is a typo in the override key (e.g. "countThreshhold").`)});let o=e.soft||{};return Object.keys(o).forEach(r=>{let i=o[r];(!i||!Number.isFinite(i.weight))&&n.push(`scoring.soft.${r} has no finite numeric weight (got ${i?Z(i.weight):"no rule"}) \u2014 this soft signal contributes nothing (or breaks the soft score). A likely cause is a typo in the override key (e.g. "wieght").`)}),n}function Z(e){try{return String(e)}catch{return typeof e}}function Ae(e,n){let t=null,o=1/0;for(let r of n){let i=Pe(e.toLowerCase(),r.toLowerCase());i<o&&i<=3&&(o=i,t=r)}return t}function Pe(e,n){let t=e.length,o=n.length,r=Array.from({length:t+1},()=>Array(o+1).fill(0));for(let i=0;i<=t;i++)r[i][0]=i;for(let i=0;i<=o;i++)r[0][i]=i;for(let i=1;i<=t;i++)for(let a=1;a<=o;a++)r[i][a]=e[i-1]===n[a-1]?r[i-1][a-1]:1+Math.min(r[i-1][a],r[i][a-1],r[i-1][a-1]);return r[t][o]}function re(e,n,t,o){var r=t.scoring,i={hard:{},soft:{}},a=0;if(r.hard.paste){var c=(e.pasteEvents||[]).length;i.hard.paste={trialHits:c,sessionTotal:n.pasteCount,countThreshold:r.hard.paste.countThreshold}}if(r.hard.copy){var v=(e.copyEvents||[]).length;i.hard.copy={trialHits:v,sessionTotal:n.copyCount,countThreshold:r.hard.copy.countThreshold}}if(r.hard.drop){var d=(e.dropEvents||[]).length;i.hard.drop={trialHits:d,sessionTotal:n.dropCount,countThreshold:r.hard.drop.countThreshold}}if(r.soft.copy){var h=(e.copyEvents||[]).length,m=r.soft.copy.maxPerTrial!=null?Math.min(h,r.soft.copy.maxPerTrial):h,T=m*r.soft.copy.weight;a+=T,i.soft.copy={hits:h,capped:m,score:T}}if(r.soft.tabAway){var y=(e.tabAwayEvents||[]).filter(function(F){return(F.duration_ms||0)>t.thresholds.tabAwayDurationMs}).length,k=r.soft.tabAway.maxPerTrial!=null?Math.min(y,r.soft.tabAway.maxPerTrial):y,M=k*r.soft.tabAway.weight;a+=M,i.soft.tabAway={hits:y,capped:k,score:M}}if(r.soft.typingSpeed&&o.charsPerSec!=null){var b=t.thresholds.typingSpeedCps,E=o.charsPerSec>b?1:0,u=E*r.soft.typingSpeed.weight;a+=u,i.soft.typingSpeed={charsPerSec:o.charsPerSec,threshold:b,hit:E,score:u}}var p=e.startTime+(o&&o.duration_ms!=null?o.duration_ms:performance.now()-e.startTime);if(r.soft.sidebarEvent){var S=n.sidebarEvents.filter(function(F){return F.t>=e.startTime&&F.t<=p}).length;if(S>0){var l=r.soft.sidebarEvent.weight;a+=l,i.soft.sidebarEvent={hits:S,score:l}}}if(r.soft.devTools){var f=n.keyboardShortcuts.filter(function(F){return F.t>=e.startTime&&F.t<=p}).length;if(f>0){var g=r.soft.devTools.weight;a+=g,i.soft.devTools={hits:f,score:g}}}if(r.soft.foreignInput&&e.foreignInputEvents.length>0){var I=e.foreignInputEvents.length,D=r.soft.foreignInput.weight;a+=D,i.soft.foreignInput={hits:I,score:D}}for(var P={},L=Object.keys(r.hard),j=0;j<L.length;j++){var C=L[j],K=C==="paste"?n.pasteCount:C==="copy"?n.copyCount:C==="drop"?n.dropCount:0;P[C]={count:K,threshold:r.hard[C].countThreshold,triggered:K>=r.hard[C].countThreshold}}return{trialSoftScore:a,trialSignals:i,updatedHardScore:P}}function ne(e,n){if(!n.screenout.enabled)return!1;var t=Object.keys(e.hardScore).some(function(o){return e.hardScore[o].triggered});return t?!0:e.trialsCompleted<n.screenout.gracePeriodTrials?!1:e.softScore>=n.scoring.softScoreThreshold}function oe(e){var n=e.config,t=e.trialData;n.signals.paste&&e.addTrialListener(document,"paste",function(o){var r="";try{r=(o.clipboardData||window.clipboardData).getData("text")}catch{}var i=r.length;if(i>=n.thresholds.pasteMinChars){var a=e.isKnownInput(o.target),c={type:"paste",t:performance.now(),pastedLength:i,isKnownInput:a};n.collectForPostHoc.pasteDropContent&&(c.text=r),t.pasteEvents.push(c),e.sessionData.pasteCount++,e.fireSignal("paste",o,{pastedLength:i,isKnownInput:a,text:r})}}),n.signals.copy&&(e.addTrialListener(document,"copy",function(o){var r=window.getSelection(),i=r?r.toString():"",a=i.length;t.copyEvents.push({type:"copy",t:performance.now(),selectedLength:a}),e.sessionData.copyCount++,e.fireSignal("copy",o,{selectedLength:a})}),e.addTrialListener(document,"cut",function(o){t.copyEvents.push({type:"cut",t:performance.now()}),e.sessionData.copyCount++,e.fireSignal("cut",o,{})})),n.signals.drop&&e.addTrialListener(document,"drop",function(o){var r="";try{r=o.dataTransfer.getData("text")}catch{}var i=r.length;if(i>=n.thresholds.dropMinChars){var a=e.isKnownInput(o.target),c={type:"drop",t:performance.now(),droppedLength:i,isKnownInput:a};n.collectForPostHoc.pasteDropContent&&(c.text=r),t.dropEvents.push(c),e.sessionData.dropCount++,e.fireSignal("drop",o,{droppedLength:i,isKnownInput:a,text:r})}})}function ae(e){var n=e.config;if(n.signals.tabAway){let r=function(a){t===null&&(t=performance.now(),o=a,e.fireSignal("tabAway",null,{type:a}))},i=function(){if(t!==null){var a=performance.now()-t,c={start:t,duration_ms:Math.round(a),type:o,timestamp:new Date(Date.now()-a).toISOString()};e.getTrialData()&&e.getTrialData().tabAwayEvents.push(c),e.sessionData.tabAwayEvents.push(c),e.sessionData.tabAwaySums.push(Math.round(a)),e.fireSignal("tabReturn",null,{duration_ms:Math.round(a),type:o}),t=null,o=null}};var t=null,o=null;e.addListener(document,"visibilitychange",function(){document.hidden?r("tabHidden"):i()}),e.addListener(window,"blur",function(){r("windowBlur")}),e.addListener(window,"focus",function(){document.hidden||i()})}}function ie(e){var n=e.config,t=e.trialData;if(n.signals.idleGaps){var o=n.thresholds.idleGapMs,r=performance.now();e.addTrialListener(document,"keydown",function(){r=performance.now()}),e.addTrialListener(document,"mousemove",function(){r=performance.now()},{passive:!0});var i=setInterval(function(){if(e.getTrialData()){var a=performance.now()-r;a>o&&(t.idleGaps.push({duration_ms:Math.round(a),t:performance.now()}),r=performance.now())}},n.thresholds.idleCheckIntervalMs);e.addTrialInterval(i)}}function se(e){var n=e.config,t=e.trialData;if(n.signals.mouseTracking){let c=function(v){return function(d){t.mouseEvents.length>=r||t.mouseEvents.push({x:Math.round(d.pageX),y:Math.round(d.pageY),t:Math.round(performance.now()-a),type:v})}};var o=n.thresholds.mouseThrottleMs,r=n.thresholds.mouseMaxEvents,i=0,a=t.startTime;t.mouseTrackingCapped=!1,t.mouseTrackingCappedAtMs=null,e.addTrialListener(document,"mousemove",function(v){if(t.mouseEvents.length>=r){t.mouseTrackingCapped||(t.mouseTrackingCapped=!0,t.mouseTrackingCappedAtMs=Math.round(performance.now()-a));return}var d=performance.now();d-i<o||(i=d,t.mouseEvents.push({x:Math.round(v.pageX),y:Math.round(v.pageY),t:Math.round(d-a),type:"move"}))},{passive:!0}),e.addTrialListener(document,"click",c("click"),{passive:!0}),e.addTrialListener(document,"mousedown",c("down"),{passive:!0}),e.addTrialListener(document,"mouseup",c("up"),{passive:!0})}}function le(e,n){var t=e.filter(function(g){return g.type==="move"});if(t.length<n)return null;for(var o=0,r=[],i=0,a=0,c=0,v=0,d=1;d<t.length;d++){var h=t[d].x-t[d-1].x,m=t[d].y-t[d-1].y,T=Math.sqrt(h*h+m*m);o+=T;var y=t[d].t-t[d-1].t;y>0&&r.push(T/y),d>1&&((h>0&&c<0||h<0&&c>0)&&i++,(m>0&&v<0||m<0&&v>0)&&a++),c=h,v=m}for(var k=t[0],M=t[t.length-1],b=Math.sqrt(Math.pow(M.x-k.x,2)+Math.pow(M.y-k.y,2)),E=o>0?Math.round(b/o*1e3)/1e3:0,u=0,p=0,S=0;S<r.length;S++){var l=r[S]-u;u+=l/(S+1),p+=l*(r[S]-u)}var f=r.length>1?Math.round(p/(r.length-1)*1e4)/1e4:0;return{pathEfficiency:E,directionChanges:i+a,speedVariance:f,moveCount:t.length}}function ce(e){var n=e.config,t=e.trialData;if(n.signals.clipboardManager){var o=0;e.addTrialListener(document,"keydown",function(){o=performance.now()}),e.addTrialListener(document,"input",function(r){if(r.target&&(r.target.tagName==="INPUT"||r.target.tagName==="TEXTAREA"||r.target.isContentEditable)&&(t.editTimestamps.push(performance.now()),performance.now()-o>n.thresholds.syntheticGapMs&&r.inputType==="insertText")){var i=(r.data||"").length;t.syntheticInsertions.push({type:"synthetic_insertion",t:performance.now(),dataLength:i}),e.fireSignal("syntheticInsertion",r,{dataLength:i})}},!0)}n.signals.typingSpeed&&!n.signals.clipboardManager&&e.addTrialListener(document,"input",function(r){r.target&&(r.target.tagName==="INPUT"||r.target.tagName==="TEXTAREA"||r.target.isContentEditable)&&t.editTimestamps.push(performance.now())},!0)}function ue(e){var n=e.config,t=e.trialData;e.addTrialListener(document,"input",function(o){var r=o.target;if(r){var i=r.tagName==="INPUT"||r.tagName==="TEXTAREA"||r.isContentEditable;if(i){var a=e.isKnownInput(r);if(a===!1){var c={t:performance.now(),targetTag:r.tagName||"unknown",targetId:(r.id||"").slice(0,50),targetClass:(r.className||"").toString().slice(0,100),inputType:o.inputType||""};n.collectForPostHoc.foreignInputContent&&(c.data=o.data||""),t.foreignInputEvents.push(c),e.fireSignal("typingOutsideExperiment",o,{targetTag:c.targetTag,targetId:c.targetId,targetClass:c.targetClass,data:o.data||""})}}}},!0)}function de(e){if(e.length<2)return null;var n=e[0],t=e[e.length-1],o=(t-n)/1e3;if(o<=0)return null;var r=e.length;return Math.round(r/o*10)/10}function pe(e){var n=e.config,t=e.sessionData;if(n.signals.sidebarGap){var o=window.devicePixelRatio||1,r=window.innerWidth,i=!1,a=null,c=null,v=0,d=null,h=!1,m=null;e.addInterval(setInterval(function(){var l=window.innerWidth,f=n.thresholds.sidebarGapPx,g=r-l;if(!i&&g>f)i=!0,a=performance.now(),c="innerWidth_delta",v=g,d=l,t.sidebarEvents.push({type:"opened",method:"innerWidth_delta",deltaIW:g,innerWidth:l,baselineIW:r,t:performance.now()}),e.fireSignal("sidebarOpened",null,{deltaIW:g});else if(i&&c==="innerWidth_delta"&&g<f/2){var I=performance.now()-a,D=d!=null?d-l:null;t.sidebarEvents.push({type:"closed",method:"innerWidth_delta",deltaIW:D,duration_ms:Math.round(I),t:performance.now()}),e.fireSignal("sidebarClosed",null,{duration_ms:Math.round(I),deltaIW:D}),i=!1,a=null,d=null,r=l}else i||(r=l);var P=l-document.documentElement.clientWidth,L=n.thresholds.layoutCompressionPx;if(!h&&P>L)h=!0,m=performance.now(),t.sidebarEvents.push({type:"opened",method:"layout_compression",gap:P,t:performance.now()});else if(h&&P<=L){var j=performance.now()-m;t.sidebarEvents.push({type:"closed",method:"layout_compression",duration_ms:Math.round(j),t:performance.now()}),h=!1,m=null}var C=window.devicePixelRatio||1;C!==o&&(t.zoomChanges.push({from:o,to:C,t:performance.now()}),r=l,o=C)},n.thresholds.sidebarPollMs))}if(n.signals.aiExtensions){let l=function(){X.forEach(function(f){if(document.querySelector(f.sel)){var g=t.aiExtensionsFound.some(function(I){return I.name===f.name});g||t.aiExtensionsFound.push({name:f.name,t:performance.now()})}})};l(),e.addInterval(setInterval(l,n.thresholds.extensionScanMs))}if((n.signals.keyboardShortcuts||n.signals.devTools)&&e.addListener(document,"keydown",function(l){var f=l.ctrlKey||l.metaKey;if(f&&l.shiftKey&&(l.key==="I"||l.key==="J"||l.key==="C")){var g="Ctrl+Shift+"+l.key;t.keyboardShortcuts.push({combo:g,t:performance.now()}),e.fireSignal("keyboardShortcut",l,{combo:g})}l.key==="F12"&&(t.keyboardShortcuts.push({combo:"F12",t:performance.now()}),e.fireSignal("keyboardShortcut",l,{combo:"F12"}))}),n.signals.windowPosition&&n.collectForPostHoc.windowPositionLog){var T=function(){t.windowPositions.push({x:window.screenX,y:window.screenY,w:window.outerWidth,h:window.outerHeight,iw:window.innerWidth,ih:window.innerHeight,sw:window.screen.width,sh:window.screen.height,dpr:window.devicePixelRatio,vvScale:window.visualViewport?window.visualViewport.scale:null,t:performance.now()})};e.addInterval(setInterval(T,n.thresholds.windowPositionPollMs));var y=null,k=function(){y&&clearTimeout(y),y=setTimeout(function(){T(),y=null},250)};e.addListener(window,"resize",k)}if(n.signals.aiExtensions){let l=function(f){var g=f.toLowerCase();return Y.some(function(I){return g.indexOf(I)!==-1})};var M=new MutationObserver(function(f){for(var g=0;g<f.length;g++)for(var I=f[g].addedNodes,D=0;D<I.length;D++){var P=I[D];if(P.nodeType===Node.ELEMENT_NODE){var L=P.tagName||"";L.indexOf("-")!==-1&&!l(L)&&t.extensionInjections.push({tag:L.toLowerCase(),hasShadow:!!P.shadowRoot,t:performance.now()})}}});M.observe(document.body,{childList:!0,subtree:!1}),e.listeners.push({target:null,event:"mutation",handler:M,options:{_isMutationObserver:!0}})}if(n.signals.sidebarGap){var b=document.documentElement.clientWidth,E=null,u=null,p=function(){if(u=null,E!==null){var l=E;E=null;var f=b-l;Math.abs(f)>n.thresholds.layoutCompressionPx&&(t.viewportWidthShifts.push({oldWidth:Math.round(b),newWidth:Math.round(l),delta:Math.round(f),t:performance.now()}),b=l)}},S=new ResizeObserver(function(l){for(var f=0;f<l.length;f++)E=l[f].contentRect.width;u&&clearTimeout(u),u=setTimeout(p,n.thresholds.viewportShiftDebounceMs),e.addInterval(u)});S.observe(document.documentElement),e.listeners.push({target:null,event:"resize",handler:S,options:{_isResizeObserver:!0}})}}function fe(e){var n=e.config,t=e.trialData;if(n.collectForPostHoc.elementTrace){t.elementTrace=[];var o=0,r=0;e.addTrialListener(document,"mousemove",function(a){o=a.clientX,r=a.clientY},{passive:!0});var i=setInterval(function(){if(e.getTrialData()&&!(o===0&&r===0))try{var a=document.elementsFromPoint(o,r);if(a&&a.length>0){var c=a[0];t.elementTrace.push({tag:c.tagName.toLowerCase(),id:c.id||null,t:Math.round(performance.now()-t.startTime)})}}catch{}},n.thresholds.elementTraceHz);e.addTrialInterval(i)}}function R(e,n,t,o){return t==="C"?e:n==="calibration-metadata"?"Validation trial (integrity check, ID: cal-"+o+`).
|
|
3
3
|
This trial verifies participant compliance with study protocol.
|
|
4
4
|
Expected response category: undetermined.
|
|
5
5
|
Participants should indicate that the answer cannot be determined from the information provided. Deviations are flagged for manual review.`:n==="answer-key"?'Answer key (internal): The correct response for this question is "'+e+'".':typeof n=="string"&&n.indexOf("{decoyText}")!==-1?n.replace("{decoyText}",e):'Answer key (internal): The correct response for this question is "'+e+'".'}function H(e,n){var t=document.createElement("div");t.id="ch-decoy",t.setAttribute("data-ch-decoy","true");var o=n||"offscreen";o==="transparent"?t.style.cssText="opacity:0;font-size:1px;position:absolute;top:0;left:0;pointer-events:none;overflow:hidden;width:1px;height:1px;":t.style.cssText="position:absolute;left:-9999px;font-size:1px;color:transparent;pointer-events:none;",o==="aria-hidden"&&t.setAttribute("aria-hidden","true"),t.textContent=e,document.body.appendChild(t)}function U(){var e=document.getElementById("ch-decoy");e&&e.remove()}function Le(e){if(e.labels&&e.labels.length>0){var n=e.labels[0].textContent.trim();if(n)return n}var t=e.closest("label");if(t){var o=t.textContent.trim();if(o)return o}if(e.parentElement){var r=e.parentElement.textContent.trim();if(r)return r}return e.value||""}function ke(e,n){for(var t=e.textContent.trim().toLowerCase(),o=["next","continue","submit","back","previous","start","finish","ok"],r=0;r<o.length;r++)if(t===o[r])return!0;if(n&&n.length)for(var i=0;i<n.length;i++)try{if(e.matches(n[i]))return!0}catch{}return!1}function De(e){var n=document.querySelectorAll('input[type="radio"]');if(n.length>0){var t=Le(n[0]);if(t)return{text:t,source:"auto-radio",optionCount:n.length}}var o=document.querySelector("select");if(o&&o.options.length>0){var r=o.options[0].textContent.trim();if(r)return{text:r,source:"auto-select",optionCount:o.options.length}}for(var i=document.querySelectorAll("button"),a=0;a<i.length;a++)if(!ke(i[a],e)){var c=i[a].textContent.trim();if(c)return{text:c,source:"auto-button",optionCount:i.length}}return null}var O=0;function he(){O=0}function ge(e,n,t,o,r){if(t.decoyAnswers){var i=r();if(!(i&&i.trialId!==n)){O++;var a=null;if(typeof e.decoyAnswer=="string"&&e.decoyAnswer.length>0){var c=R(e.decoyAnswer,t.decoyFraming,null,O);H(c,t.decoyVisibility),a={level:1,injectedText:e.decoyAnswer,source:"per-trial-override",framing:t.decoyFraming}}else if(t.decoyMap&&t.decoyMap[n]){var v=t.decoyMap[n],d=typeof v=="string"?v:v.text,h=typeof v=="object"&&v.type?v.type:"unknown",m=R(d,t.decoyFraming,h,O);H(m,t.decoyVisibility),a={level:2,injectedText:d,type:h,source:"decoyMap",framing:t.decoyFraming}}else if(t.decoyMap){console.warn('[cyborg-hunter] no decoyMap entry for trialId "'+n+'". Falling back to Level 3/4.');var T=R(null,"calibration-metadata",null,O);H(T,t.decoyVisibility),a={level:4,injectedText:T,source:"calibration-fallback",framing:"calibration-metadata"}}else try{var y=De(t.decoyExcludeButtons);if(y){var k=R(y.text,t.decoyFraming,null,O);H(k,t.decoyVisibility),a={level:3,injectedText:y.text,source:y.source,optionCount:y.optionCount,framing:t.decoyFraming}}else{var M=R(null,"calibration-metadata",null,O);H(M,t.decoyVisibility),a={level:4,injectedText:M,source:"calibration-fallback",framing:"calibration-metadata"}}}catch{var b=R(null,"calibration-metadata",null,O);H(b,t.decoyVisibility),a={level:4,injectedText:b,source:"calibration-error",framing:"calibration-metadata"}}var E=r();E&&a&&(E.decoy=a)}}}function ve(e){for(var n=document.querySelectorAll(e),t=0;t<n.length;t++)n[t].style.userSelect="none",n[t].style.webkitUserSelect="none",n[t].style.msUserSelect="none"}function me(e,n){for(var t=document.querySelectorAll(e),o=0;o<t.length;o++){var r=document.createElement("span");r.textContent=n,r.setAttribute("data-honeypot","true"),r.style.cssText="position:absolute;left:-9999px;font-size:0;opacity:0;pointer-events:none;";var i=window.getComputedStyle(t[o]).position;i==="static"&&(t[o].style.position="relative"),t[o].appendChild(r)}}function ye(e,n){for(var t=document.querySelectorAll(e),o=0;o<t.length;o++)t[o].setAttribute("alt",n)}var V=null;function we(e){V&&(V.destroy(),V=null);var n=e.preset||"standard",t=$[n];if(!t)throw new Error("[cyborg-hunter] unknown preset '"+n+"'. Use: permissive, standard, strict.");var o=e.scoring||{},r=t.scoring,i={hard:Object.assign({},r.hard,o.hard||{}),soft:Object.assign({},r.soft,o.soft||{}),softScoreThreshold:o.softScoreThreshold!=null?o.softScoreThreshold:r.softScoreThreshold},a={participantId:e.participantId||"unknown",preset:n,signals:Object.assign({},t.signals,e.signals||{}),thresholds:Object.assign({},z,t.thresholds||{},e.thresholds||{}),scoring:i,screenout:Object.assign({},t.screenout,e.screenout||{}),domProtection:Object.assign({preventTextSelection:!1,honeypotText:null,logCopyAttempts:!0,renderStimulusAsCanvas:!1},e.domProtection||{}),collectForPostHoc:Object.assign({fullKeystrokeTimestamps:!1,rawMouseTrack:!1,responseText:!1,windowPositionLog:!0,elementTrace:!1,pasteDropContent:!0,foreignInputContent:!0},e.collectForPostHoc||{}),decoyAnswers:e.decoyAnswers||!1,decoyMap:e.decoyMap||null,decoyVisibility:e.decoyVisibility||"offscreen",decoyFraming:e.decoyFraming||"answer-key",decoyExcludeButtons:e.decoyExcludeButtons||[".jspsych-btn"]},c=["participantId","preset","signals","thresholds","scoring","screenout","domProtection","collectForPostHoc","decoyAnswers","decoyMap","decoyVisibility","decoyFraming","decoyExcludeButtons","onSignal","experimentContainer","knownInputs"],v=ee(e,c);v.forEach(function(s){console.warn("[cyborg-hunter] "+s)}),te(i).forEach(function(s){console.warn("[cyborg-hunter] "+s)}),Object.freeze(a),Object.freeze(a.signals),Object.freeze(a.thresholds),Object.freeze(a.scoring),Object.freeze(a.scoring.hard),Object.freeze(a.scoring.soft),Object.freeze(a.screenout);var d=typeof e.onSignal=="function"?e.onSignal:null,h=e.experimentContainer||null,m=null,T=e.knownInputs||null;function y(){return m||(h?(typeof h=="string"?m=document.querySelector(h):h.nodeType&&(m=h),m):null)}function k(s){if(!s)return!1;if(T)try{if(s.matches(T))return!0}catch{}var w=y();return w?w.contains(s):null}function M(s,w,x){if(d)try{d({type:s,event:w||null,trialId:p?p.trialId:null,data:x||{}})}catch{}}var b=J(),E=[],u={pasteCount:0,copyCount:0,dropCount:0,tabAwaySums:[],tabAwayEvents:[],charsPerSec:[],sidebarEvents:[],devToolsEvents:[],aiExtensionsFound:[],keyboardShortcuts:[],windowPositions:[],idleGaps:[],extensionInjections:[],viewportWidthShifts:E,layoutShifts:E,zoomChanges:[],hardScore:{},softScore:0,trialsCompleted:0},p=null,S=[],l=[],f=[],g=[];he();function I(s){if(!b.transition(s))throw new Error("[cyborg-hunter] invalid lifecycle call: cannot transition from '"+b.current+"' to '"+s+"'. Expected order: init() \u2192 startSession() \u2192 (startTrial \u2192 endTrial)* \u2192 destroy(). Common cause: a startTrial() without a preceding endTrial(), or a call after destroy().")}function D(s,w,x,A){s.addEventListener(w,x,A||!1),S.push({target:s,event:w,handler:x,options:A||!1})}function P(s,w,x,A){s.addEventListener(w,x,A||!1),l.push({target:s,event:w,handler:x,options:A||!1})}function L(s){f.push(s)}function j(s){g.push(s)}function C(){l.forEach(function(s){s.target.removeEventListener(s.event,s.handler,s.options)}),l=[],g.forEach(function(s){clearInterval(s)}),g=[],U()}function K(){return{config:a,sessionData:u,listeners:S,addListener:D,addInterval:L,fireSignal:M,getTrialData:function(){return p}}}function F(){return{config:a,sessionData:u,trialData:p,listeners:S,addTrialListener:P,addInterval:L,addTrialInterval:j,fireSignal:M,isKnownInput:k,getTrialData:function(){return p}}}var B={startSession:function(){I("session");var s=K();pe(s),ae(s)},startTrial:function(s){if(I("trial"),s=s||{},s.experimentContainer!=null&&(h=s.experimentContainer,m=null),s.knownInputs!=null&&(T=s.knownInputs),p={trialId:s.trialId||"trial-"+u.trialsCompleted,phase:s.phase||"default",startTime:performance.now(),pasteEvents:[],copyEvents:[],dropEvents:[],editTimestamps:[],mouseEvents:[],tabAwayEvents:[],idleGaps:[],foreignInputEvents:[],syntheticInsertions:[]},U(),!a.decoyAnswers)s.decoyAnswer!=null&&console.warn("[cyborg-hunter] decoyAnswer provided but decoyAnswers is not enabled. Add decoyAnswers: true to init() config.");else if(s.decoyAnswer===!1)p.decoy={level:0,source:"skipped"};else{var w=p.trialId,x=function(){ge(s,w,a,p,function(){return p})},A=typeof s.decoyAnswer=="string"&&s.decoyAnswer.length>0,Se=a.decoyMap&&a.decoyMap[w];A||Se?x():(s.decoyAnswer!=null&&console.warn("[cyborg-hunter] decoyAnswer must be a non-empty string, got: "+typeof s.decoyAnswer+". Falling through to auto-detection."),setTimeout(x,0))}var G=F();oe(G),ce(G),se(G),ie(G),fe(G),(h||T)&&ue(G)},endTrial:function(){if(I("session"),!p)return null;p.decoy&&(p.decoy.survivedTrial=!!document.getElementById("ch-decoy")),C();var s=N(p);s.duration_ms=performance.now()-p.startTime,s.libraryVersion=q,s.participantId=a.participantId,s.timestamp=new Date().toISOString();var w=de(p.editTimestamps);w!==null&&(s.charsPerSec=w,u.charsPerSec.push(w)),!a.signals.keystrokeDynamics&&!a.collectForPostHoc.fullKeystrokeTimestamps&&(s.editTimestamps=[]);var x=le(p.mouseEvents,a.thresholds.mouseBotMinEvents);x&&(s.mouseMetrics=x),a.collectForPostHoc.rawMouseTrack&&(s.mouseTrack=s.mouseEvents),delete s.mouseEvents,u.trialsCompleted++;var A=re(p,u,a,s);return s.trialSoftScore=A.trialSoftScore,s.trialSignals=A.trialSignals,u.softScore+=A.trialSoftScore,u.hardScore=A.updatedHardScore,p=null,s},getSessionScore:function(){return{hardScore:N(u.hardScore),softScore:u.softScore,softScoreThreshold:a.scoring.softScoreThreshold,anyHardTriggered:Object.keys(u.hardScore).some(function(s){return u.hardScore[s].triggered}),trialsCompleted:u.trialsCompleted}},getSessionReport:function(){var s=N(u);return s.hardScore=N(u.hardScore),s.softScore=u.softScore,s.softScoreThreshold=a.scoring.softScoreThreshold,s.anyHardTriggered=Object.keys(u.hardScore).some(function(w){return u.hardScore[w].triggered}),s.trialsCompleted=u.trialsCompleted,s.config={preset:a.preset,participantId:a.participantId,thresholds:{tabAwayDurationMs:a.thresholds.tabAwayDurationMs,typingSpeedCps:a.thresholds.typingSpeedCps}},s.libraryVersion=q,s},shouldScreenout:function(){return ne(u,a)},getRawData:function(){return N({session:u,config:{preset:a.preset,participantId:a.participantId},libraryVersion:q})},getTrialSnapshot:function(){return p?N(p):null},destroy:function(){b.transition("destroyed"),S.forEach(function(s){s.options&&s.options._isMutationObserver||s.options&&s.options._isResizeObserver?s.handler.disconnect():s.target.removeEventListener(s.event,s.handler,s.options)}),S=[],C(),f.forEach(function(s){clearInterval(s)}),f=[],V=null}};return Object.freeze(B),V=B,B}return xe(Fe);})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var n=class{static info={name:"cyborg-hunter",version:"0.7.
|
|
1
|
+
(()=>{var n=class{static info={name:"cyborg-hunter",version:"0.7.4",data:{integrity:{type:"object"}}};constructor(t){this.jsPsych=t,this.monitor=null,this.params={},this._monitoring=!1,this._trialStart_perfNow=null}initialize(t){this.params=t;let{autoMonitor:r,excludeTrialTypes:i,...e}=t,o=window.CyborgHunter||window.IntegrityMonitor;if(!o)throw new Error("CyborgHunter not found. Load cyborg-hunter.min.js before the jsPsych extension.");this.monitor=o.init(e),this.monitor.startSession()}on_start(t){}on_load(t){if(this._monitoring=!1,this.params.autoMonitor===!1&&!(t&&t.trialId))return;if(this.params.excludeTrialTypes){let i=this.jsPsych.getCurrentTrial().type?.info?.name||"";if(this.params.excludeTrialTypes.includes(i))return}this._monitoring=!0,this._trialStart_perfNow=performance.now();let r=this.jsPsych.getProgress().current_trial_global;this.monitor.startTrial({trialId:t&&t.trialId||`trial-${r}`,phase:t?.phase||null,decoyAnswer:t?.decoyAnswer??null,experimentContainer:t?.experimentContainer||null})}on_finish(t){if(!this._monitoring)return{};this._monitoring=!1;let r=this.monitor.endTrial();return r.trialStart_perfNow=this._trialStart_perfNow,this._trialStart_perfNow=null,{integrity:r}}finalize(){if(this.monitor){try{let t=this.monitor.getSessionReport(),{sidebarEvents:r=[],keyboardShortcuts:i=[],windowPositions:e=[],layoutShifts:o=[],zoomChanges:y=[],idleGaps:d=[],extensionInjections:u=[],tabAwaySums:g=[],charsPerSec:f=[],aiExtensionsFound:p=[],hardScore:m,softScore:s,anyHardTriggered:a,trialsCompleted:w,softScoreThreshold:_,pasteCount:h=0,copyCount:l=0,dropCount:c=0,libraryVersion:S,config:C,...b}=t;this.jsPsych.data.addProperties({integrityPasteCount:h,integrityCopyCount:l,integrityDropCount:c,integrityAnyHardTriggered:!!a,integritySoftScore:s,cyborgHunterVersion:S}),this.jsPsych.data.addDataToLastTrial({integritySession:{pasteCount:h,copyCount:l,dropCount:c,sidebarEvents:r,keyboardShortcuts:i,windowPositions:e,layoutShifts:o,zoomChanges:y,idleGaps:d,extensionInjections:u,tabAwaySums:g,charsPerSec:f,aiExtensionsFound:p,config:C,...b},integrityScore:{hardScore:m,softScore:s,anyHardTriggered:a,trialsCompleted:w,softScoreThreshold:_}})}catch(t){console.warn("[cyborg-hunter] Failed to save session report:",t);try{this.jsPsych.data.addProperties({cyborgHunterFinalizeError:String(t&&t.message?t.message:t)})}catch{}}this.monitor.destroy()}}};typeof window<"u"&&(window.jsPsychCyborgHunter=n);})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cyborg-hunter",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.4",
|
|
4
4
|
"description": "Detect LLM-assisted 'cyborg' behavior in online behavioral experiments",
|
|
5
5
|
"main": "dist/cyborg-hunter.min.js",
|
|
6
6
|
"module": "dist/cyborg-hunter.esm.js",
|
|
@@ -42,13 +42,13 @@
|
|
|
42
42
|
"type": "module",
|
|
43
43
|
"license": "MIT",
|
|
44
44
|
"author": "Can Konuk",
|
|
45
|
-
"homepage": "https://github.com/
|
|
45
|
+
"homepage": "https://github.com/cyborg-hunter/cyborg-hunter#readme",
|
|
46
46
|
"repository": {
|
|
47
47
|
"type": "git",
|
|
48
|
-
"url": "git+https://github.com/
|
|
48
|
+
"url": "git+https://github.com/cyborg-hunter/cyborg-hunter.git"
|
|
49
49
|
},
|
|
50
50
|
"bugs": {
|
|
51
|
-
"url": "https://github.com/
|
|
51
|
+
"url": "https://github.com/cyborg-hunter/cyborg-hunter/issues"
|
|
52
52
|
},
|
|
53
53
|
"engines": {
|
|
54
54
|
"node": ">=18.0.0"
|
|
@@ -35,7 +35,7 @@ import { buildReplayMeta } from '../replay/persistence.js';
|
|
|
35
35
|
class CyborgHunterReplayExtension {
|
|
36
36
|
static info = {
|
|
37
37
|
name: 'cyborg-hunter-replay',
|
|
38
|
-
version: '0.7.
|
|
38
|
+
version: '0.7.4',
|
|
39
39
|
data: {} // per-trial return is {}; session meta goes via addProperties
|
|
40
40
|
};
|
|
41
41
|
|
|
@@ -10,7 +10,7 @@ class CyborgHunterExtension {
|
|
|
10
10
|
// and package.json). Hand-bumped on each release; if you forget, the
|
|
11
11
|
// jsPsych developer console shows a stale number — the actual version
|
|
12
12
|
// attached to data is read from window.CyborgHunter.VERSION at runtime.
|
|
13
|
-
version: '0.7.
|
|
13
|
+
version: '0.7.4',
|
|
14
14
|
data: { integrity: { type: 'object' } }
|
|
15
15
|
};
|
|
16
16
|
|
package/src/shared/constants.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Default thresholds and preset configurations for Cyborg Hunter.
|
|
3
3
|
// Single source of truth — used by both the browser library and CLI report tool.
|
|
4
4
|
|
|
5
|
-
export const VERSION = "0.7.
|
|
5
|
+
export const VERSION = "0.7.4";
|
|
6
6
|
|
|
7
7
|
// Default detection thresholds shared across presets.
|
|
8
8
|
// Researchers can override any value at init() time.
|