uluscan 0.1.2

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 ADDED
@@ -0,0 +1,18 @@
1
+ # uluscan
2
+
3
+ Browser Go board image recognition using WebGL2 and WebAssembly. Recognition runs in a Worker.
4
+
5
+ ```ts
6
+ import { recognizeBoard, StoneColor } from "uluscan";
7
+
8
+ recognizeBoard(imageBlob, (result) => {
9
+ if ("d" in result) {
10
+ const board: StoneColor[][] = result.d;
11
+ }
12
+ }, { lineCount: 19 });
13
+ ```
14
+
15
+ - `lineCount`: integer from 4 to 19; default `19`.
16
+ - `disableReprocess`: default `false`.
17
+ - Result: `{ d: StoneColor[][] }`, `{ s: true }`, or `{ e: true }`.
18
+ - Colors: empty `0`, black `1`, white `2`.
package/index.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ export declare enum StoneColor {
2
+ Empty = 0,
3
+ Black = 1,
4
+ White = 2,
5
+ Unknown = 4
6
+ }
7
+ export interface RecognizeBoardOptions {
8
+ lineCount?: number;
9
+ disableReprocess?: boolean;
10
+ sCheck?: boolean;
11
+ }
12
+ export type RecognizeBoardResult = {
13
+ d: StoneColor[][];
14
+ } | {
15
+ s: true;
16
+ } | {
17
+ e: true;
18
+ };
19
+ export type RecognizeBoardCallback = (result: RecognizeBoardResult) => void;
20
+ export declare function recognizeBoard(image: Blob, callback: RecognizeBoardCallback, options?: RecognizeBoardOptions): void;
package/index.js ADDED
@@ -0,0 +1 @@
1
+ var b=(r=>(r[r.Empty=0]="Empty",r[r.Black=1]="Black",r[r.White=2]="White",r[r.Unknown=4]="Unknown",r))(b||{}),f=1,t=null,a=new Map;function R(n,e,o={}){if(!(n instanceof Blob))throw new TypeError("image must be a Blob");if(typeof e!="function")throw new TypeError("callback must be a function");let s=g(o.lineCount??19),r=o.sCheck??!0;globalThis.uluSCheck=r?"enabled":"";let i=f++;a.set(i,e);try{m().postMessage({id:i,image:n,lineCount:s,disableReprocess:!!o.disableReprocess,sCheck:r})}catch{a.delete(i),queueMicrotask(()=>e({e:!0}))}}function m(){return t||(t=new Worker(new URL("./scan-worker.js",import.meta.url),{type:"module"}),t.addEventListener("message",p),t.addEventListener("error",l),t.addEventListener("messageerror",l),t)}function p(n){let e=n.data,o=a.get(e.id);if(o){if(a.delete(e.id),e.s){o({s:!0});return}if(e.encoded&&e.lineCount!==void 0)try{o({d:k(new Uint8Array(e.encoded),e.lineCount)});return}catch{}o({e:!0})}}function l(){t?.terminate(),t=null;let n=[...a.values()];a.clear();for(let e of n)e({e:!0})}function g(n){if(!Number.isInteger(n)||n<4||n>19)throw new RangeError("lineCount must be an integer from 4 to 19");return n}function k(n,e){let o=Array.from({length:e},()=>[]),s=0,r=0;for(let i of n){let u=i>>6,c=i&63;if(c===0||u>2||s>=e||r+c>e)throw new Error("invalid encoded board");for(let d=0;d<c;d++)o[s].push(u);r+=c,r===e&&(s++,r=0)}if(s!==e||r!==0)throw new Error("incomplete encoded board");return o}export{b as StoneColor,R as recognizeBoard};
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "uluscan",
3
+ "version": "0.1.2",
4
+ "description": "Browser Go board image recognition powered by WebGL2 and WebAssembly",
5
+ "type": "module",
6
+ "main": "./index.js",
7
+ "module": "./index.js",
8
+ "types": "./index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./index.d.ts",
12
+ "import": "./index.js",
13
+ "default": "./index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "index.js",
18
+ "index.d.ts",
19
+ "scan-worker.js",
20
+ "README.md"
21
+ ],
22
+ "sideEffects": false,
23
+ "publishConfig": {
24
+ "access": "public"
25
+ }
26
+ }
package/scan-worker.js ADDED
@@ -0,0 +1,21 @@
1
+ var So="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AEGI77kCIA45AwBBgO+5AiAEOQMAQfjuuQIgBzkDAEHw7rkCIAY5AwBBwO+5AiAZuDkDAEG477kCIBe4OQMACyAWCwUAQYAgCwcAQdDvuQILBwBB0O+/AgsHAEHw778CCwcAQaDwvwILBwBB0PC/AgsFAEGAEAsHAEGA8b8CCwcAQYDxvwoLBwBB0PG/Cgu1CAMMfBB/An4jAEHgAGsiESQAQX8hEwJAQYAQIAFrQYAQIABrckH/D0sNACACvSIhQgF9Qv7///////8HViAhQgBTICFC////////////AINCgICAgICAgAh9Qv/////////v/wBWcnENACADvSIiQv///////////wCDIiFQICJCAFMiEiAhQgF9Qv////////8HVHFyICFCgICAgICAgPj/AFFyICFCgICAgICAgPj/AFZyICFCgICAgICAgAh9QoCAgICAgIDw/wBUIBJxcg0AIARBFGtBb0kNACARQdgAaiEVQQAhE0EAIRIDQCARIAAgASACIAMgBCASRAAAAAAAAOA/ECQiBTkDACARIAAgASACIAMgBCASRAAAAAAAAOg/ECQiBjkDCCARIAAgASACIAMgBCASRAAAAAAAAPA/ECQiBzkDECARIAAgASACIAMgBCASRAAAAAAAAPQ/ECQiCDkDGCARIAAgASACIAMgBCASRAAAAAAAAPg/ECQiCTkDICARIAAgASACIAMgBCASRAAAAAAAAPw/ECQiCjkDKCARIAAgASACIAMgBCASRAAAAAAAAABAECQiCzkDMCARIAAgASACIAMgBCASRAAAAAAAAAJAECQiDDkDOCARIAAgASACIAMgBCASRAAAAAAAAARAECQiDTkDQCARIAAgASACIAMgBCASRAAAAAAAAAZAECQiDjkDSCARIAAgASACIAMgBCASRAAAAAAAAAhAECQiDzkDUCARIBUQZyARKwMoIRAgEkEYbCIUIA8gDiANIAwgCyAKIAkgCCAHIAYgBUQAAAAAAADw/yAFRAAAAAAAAPD/ZCIWGyIFIAUgBmMiFxsiBSAFIAdjIhgbIgUgBSAIYyIZGyIFIAUgCWMiGhsiBSAFIApjIhsbIgUgBSALYyIcGyIFIAUgDGMiHRsiBSAFIA1jIh4bIgUgBSAOYyIfGyIFIAUgD2MiIBsiBTkD2PG/CiAURAAAAAAAAAhARAAAAAAAAAZARAAAAAAAAARARAAAAAAAAAJARAAAAAAAAABARAAAAAAAAPw/RAAAAAAAAPg/RAAAAAAAAPQ/RAAAAAAAAPA/RAAAAAAAAOg/RAAAAAAAAOA/RAAAAAAAAPA/IBYbIBcbIBgbIBkbIBobIBsbIBwbIB0bIB4bIB8bICAbOQPQ8b8KIBQgBUTsUbgeheuhv6BE7FG4HoXrwT+jIgZEAAAAAAAA8D8gBkQAAAAAAADwP2MbIgZEAAAAAAAAAAAgBkQAAAAAAAAAAGQbIAUgEKFEexSuR+F6tD+jIgVEAAAAAAAA8D8gBUQAAAAAAADwP2MbIgVEAAAAAAAAAAAgBUQAAAAAAAAAAGQbRM3MzMzMzOQ/okRmZmZmZmbWP6CiOQPg8b8KIBJBAWoiEkEERw0ACwsgEUHgAGokACATC/cYAg5/IXwjAEHQEWsiByQAIAFBAWshDyAAQQFrIRBECtejcD0Kx78gBqEhF0QK16NwPQrHPyAGoSEjIARBAWu4IhVEZmZmZmZm5r+gITAgBiAVoCIGRArXo3A9Csc/oCEhIAZECtejcD0Kx7+gISQgAbghJSAAuCEmQajxvworAwAhJ0Gg8b8KKwMAIShBmPG/CisDACEpQZDxvworAwAhKkGI8b8KKwMAIStBgPG/CisDACEsQcDxvworAwAhLUG48b8KKwMAIS5BsPG/CisDACEvQQAhAQNAIDAgAbiiRAAAAAAAADtAo0RmZmZmZmbWP6AiGCEGICMhGSAYIRUgFyEWAkACfAJAAkACQCAFDgMEAAECCyAkIRkgISEWDAMLIBUhGSAXIRUgIwwBCyAVIRkgISEVICQLIQYgGCEWCwJAICogLCAZoiAGICuioKAgLSAvIBmiIAYgLqKgoCIboyACoyIYRAAAAAAAAAAAYw0AICcgKSAZoiAGICiioKAgG6MgA6MiBkQAAAAAAAAAAGMNACAYICZmDQAgBiAlZg0AIAlBGGwiCyAHQeAIamoiBCAPIAZEAAAAAAAA4D+gnPwDIgggCCAPSxsgAGwgECAYRAAAAAAAAOA/oJz8AyIIIAggEEsbakECdCIILQCA8b8CuEQAAAAAAOBvQKMiBjkDACAEIAgtAIHxvwK4RAAAAAAA4G9AoyIZOQMIIAQgCC0AgvG/ArhEAAAAAADgb0CjIhg5AxAgKiAsIBaiIBUgK6KgoCAtIC8gFqIgFSAuoqCgIh2jIAKjIhtEAAAAAAAAAABjDQAgJyApIBaiIBUgKKKgoCAdoyADoyIVRAAAAAAAAAAAYw0AIBsgJmYNACAVICVmDQAgB0HAA2ogC2oiBCAPIBVEAAAAAAAA4D+gnPwDIgggCCAPSxsgAGwgECAbRAAAAAAAAOA/oJz8AyIIIAggEEsbakECdCIILQCA8b8CuEQAAAAAAOBvQKMiFjkDACAEIAgtAIHxvwK4RAAAAAAA4G9AoyIbOQMIIAQgCC0AgvG/ArhEAAAAAADgb0CjIh05AxACfCAGIAYgGaAgGKBEexSuR+F6tD+gIh6jIjEgFiAWIBugIB2gRHsUrkfherQ/oCIfo6EiMpkhFSAYIB6jIjMgHSAfo6EiNJkhGiAZIB6jIjUgGyAfo6EiH5kiHr1C////////////AINCgICAgICAgPj/AFgEQCAeIBogHqUgGr1C////////////AINCgICAgICAgPj/AFYbIRoLRAAAAAAAALAeIBW9Qv///////////wCDQoCAgICAgID4/wBYBHwgFSAVIBqlIBq9Qv///////////wCDQoCAgICAgID4/wBWGwUgGgsiFUQAAAAAAADwX2QNABpEAAAAAAAA8D8gFUQAAAAAAADwH2NFDQAaRAAAAAAAADBhCyEVIAdB4A9qIAlBA3RqIDQgFaIiGiAaoiAyIBWiIhogGqIgHyAVoiIaIBqioKCfIBWjRDMzMzMzM/s/oiAYRJqZmZmZmbk/oiAGRAAAAAAAANA/oiAZRM3MzMzMzOQ/oqCgRHsUrkfheqQ/oCIaIB1EmpmZmZmZuT+iIBZEAAAAAAAA0D+iIBtEzczMzMzM5D+ioKBEexSuR+F6pD+goxBemUSamZmZmZnJP6KgOQMAIAoEQAJ8ICAgICAcoCAioER7FK5H4Xq0P6AiG6MgMaEiHZkhFSAiIBujIDOhIh6ZIRYgHCAboyA1oSIfmSIbvUL///////////8Ag0KAgICAgICA+P8AWARAIBsgFiAbpSAWvUL///////////8Ag0KAgICAgICA+P8AVhshFgtEAAAAAAAAsB4gFb1C////////////AINCgICAgICAgPj/AFgEfCAVIBUgFqUgFr1C////////////AINCgICAgICAgPj/AFYbBSAWCyIVRAAA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/////+//AFZycQ0AIAVBA0sNACADvSIHQv///////////wCDIgZQIAdCAFMiCSAGQgF9Qv////////8HVHFyIAZCgICAgICAgPj/AFFyIAZCgICAgICAgPj/AFZyIAZCgICAgICAgAh9QoCAgICAgIDw/wBUIAlxcg0AIARBFGtBb0kNAEQAAAAAAADgvyELQQAhCEQAAAAAAADw/yEKA0AgACABIAIgAyAEIAUgCLhEAAAAAAAA0L+iRAAAAAAAANC/oCIMECQiDSAKIAogDWMiCRshCiAMIAsgCRshCyAIQQFqIghBGEcNAAtBACEIQdjxvwogCjkDAEHQ8b8KIAs5AwALIAgLnA0DGnwGfwJ+IwBBoAFrIiIkAEF/ISACQEGAECABa0GAECAAa3JB/w9LDQAgAr0iJUIBfUL+////////B1YgJUIAUyAlQv///////////wCDQoCAgICAgIAIfUL/////////7/8AVnJxDQAgA70iJkL///////////8AgyIlUCAmQgBTIiEgJUIBfUL/////////B1RxciAlQoCAgICAgID4/wBRciAlQoCAgICAgID4/wBWciAlQoCAgICAgIAIfUKAgICAgICA8P8AVCAhcXINACAEQRRrQW9JDQAgAUEBayEhIABBAWshIyAEQQFrIiS4IgVEZmZmZmZm1j+gIRYgBURmZmZmZmbWv6AhFyAFRDMzMzMzM+M/oiEcQajxvworAwAhDUGg8b8KKwMAIQ5BmPG/CisDACEPQZDxvworAwAhEEGI8b8KKwMAIRFBgPG/CisDACESQcDxvworAwAhE0G48b8KKwMAIRRBsPG/CisDACEVIAG4IRggALghGUEAISADQEEAIQFBACEEA0BEZmZmZmZm1r8hBURmZmZmZmbWPyEHIAG4RAAAAAAAAOA/oCIJIQggCSEGAkACfAJAAkACQCAgDgMEAQACC0RmZmZmZmbWvyEGRGZmZmZmZtY/IQggCQwCCyAXIQcgFiEFDAILIBchCCAWIQYgCQshByAJIQULAkAgECASIAeiIAggEaKgoCATIBUgB6IgCCAUoqCgIgqjIAKjIglEAAAAAAAAAABjDQAgDSAPIAeiIAggDqKgoCAKoyADoyIHRAAAAAAAAAAAYw0AIAkgGWYNACAHIBhmDQAgECASIAWiIAYgEaKgoCATIBUg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AAwBCyAFIAD9AAMA/QsDACAAIAEpAwg3AwggACABKQMANwMAIAEgBSkDCDcDCCABIAUpAwA3AwAgAisDACABKwMAZEUNACAFIAH9AAMA/QsDACABIAIpAwg3AwggASACKQMANwMAIAIgBSkDCDcDCCACIAUpAwA3AwALAkAgAysDACACKwMAZEUNACAFIAL9AAMA/QsDACACIAMpAwg3AwggAiADKQMANwMAIAMgBSkDCDcDCCADIAUpAwA3AwAgAisDACABKwMAZEUNACAFIAH9AAMA/QsDACABIAIpAwg3AwggASACKQMANwMAIAIgBSkDCDcDCCACIAUpAwA3AwAgASsDACAAKwMAZEUNACAFIAD9AAMA/QsDACAAIAEpAwg3AwggACABKQMANwMAIAEgBSkDCDcDCCABIAUpAwA3AwALAkAgBCsDACADKwMAZEUNACAFIAP9AAMA/QsDACADIAQpAwg3AwggAyAEKQMANwMAIAQgBSkDCDcDCCAEIAUpAwA3AwAgAysDACACKwMAZEUNACAFIAL9AAMA/QsDACACIAMpAwg3AwggAiADKQMANwMAIAMgBSkDCDcDCCADIAUpAwA3AwAgAisDACABKwMAZEUNACAFIAH9AAMA/QsDACABIAIpAwg3AwggASACKQMANwMAIAIgBSkDCDcDCCACIAUpAwA3AwAgASsDACAAKwMAZEUNACAFIAD9AAMA/QsDACAAIAEpAwg3AwggACABKQMANwMAIAEgBSkDCDcDCCABIAUpAwA3AwALC6oHAgN/AnwjAEEgayEEIAIrAxAiByABKwMQIghkIAEoAgQiBiACKAIESyAHIAhiGyEFAkAgCCAAKwMQIgdkIAYgACgCBEkgByAIYhtFBEAgBUUNASAEIAH9AAMA/QsDCCAEIAEpAxA3AxggASACKQMQNwMQIAEgAikDCDcDCCABIAIpAwA3AwAgAiAEKQMYNwMQIAIgBCkDEDcDCCACIAQpAwg3AwAgASsDECIIIAArAxAiB2QgASgCBCAAKAIESSAHIAhiG0EBRw0BIAQgACkDEDcDGCAEIAD9AAMA/QsDCCAAIAEpAxA3AxAgACABKQMINwMIIAAgASkDADcDACABIAQpAxg3AxAgASAEKQMQNwMIIAEgBCkDCDcDAAwBCyAFBEAgBCAAKQMQNwMYIAQgAP0A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IAAgACkDGDcDACAAIAIpAxg3AyggACACKQMQNwMgIAAgAikDCDcDGCAJIAArAyAiCmMgBiAAKAIcSSAJIApiG0EBRw0AIAIgACkDKDcDGCACIAD9AAMY/QsDCCAAIAMpAxA3AyggACADKQMINwMgIAAgAykDADcDGCADIAIpAxg3AxAgAyACKQMQNwMIIAMgAikDCDcDAAsgAEHIAGoiBCABRg0AQQAhBgNAAkAgBCsDCCIJIAMrAwgiCmMgBCgCBCIHIAMoAgRJIAkgCmIbQQFHDQAgBCgCACEIIAQgAykDADcDACAEKwMQIQogBCAD/QADCP0LAwgCQANAIAkgA0EQaysDACILYyAHIANBFGsoAgBJIAkgC2IbRQ0BIAMgA0EYayIFKQMQNwMQIAMgBf0AAwD9CwMAIAUiAyAARw0ACyAAIQMLIAMgCjkDECADIAk5AwggAyAHNgIEIAMgCDYCACAGQQFqIgZBCEcNACAEQRhqIAFGIQUMAgsgBCIDQRhqIgQgAUcNAAtBASEFCyACQSBqJAAgBQuHDAEGfyMAQRBrIgIkAEEBIQYCQAJAAkACQAJAAkAgASAAa0EEdQ4GBQUAAQIDBAsgAUEQayIBKAIAIAAoAgBODQQgAiAA/QADAP0LAwAgACABKQMINwMIIAAgASkDADcDACABIAIpAwg3AwggASACKQMANwMADAQLIAFBEGsiASgCACEDIAAoAhAiBCAAKAIATgRAIAMgBE4NBCACIAD9AAMQ/QsDACAAIAEpAwg3AxggACABKQMANwMQIAEgAikDCDcDCCABIAIpAwA3AwAgACgCECAAKAIATg0EIAIgAP0AAwD9CwMAIAAgACkDGDcDCCAAIAApAxA3AwAgACACKQMINwMYIAAgAikDADcDEAwECyADIARIBEAgAiAA/QADAP0LAwAgACABKQMINwMIIAAgASkDADcDACABIAIpAwg3AwggASACKQMANwMADAQLIAIgAP0AAwD9CwMAIAAgACkDGDcDCCAAIAApAxA3AwAgACACKQMINwMYIAAgAikDADcDECABKAIAIAAoAhBODQMgAiAA/QADEP0LAwAgACABKQMINwMYIAAgASkDADcDECABIAIpAwg3AwggASACKQMANwMADAMLIAFBEGshASAAKAIgIQMCQCAAKAIQIgQgACgCACIFTgRAIAMgBE4NASACIAD9AAMQ/QsDACAAIAApAyg3AxggACAAKQMgNwMQIAAgAikDCDcDKCAAIAIpAwA3AyAgACgCECAFTg0BIAIgAP0AAwD9CwMAIAAgACkDGDcDCCAAIAApAxA3AwAgACACKQMINwMYIAAgAikDADcDEAwBCyADIARIBEAgAiAA/QADAP0LAwAgACAAKQMoNwMIIAAgACkDIDcDACAAIAIpAwg3AyggACACKQMANwMgDAELIAIgAP0AAwD9CwMAIAAgACkDGDcDCCAAIAApAxA3AwAgACACKQMINwMYIAAgAikDADcDECADIAAoAhBODQAgAiAA/QADEP0LAwAgACAAKQMoNwMYIAAgACkDIDcDECAAIAIpAwg3AyggACACKQMANwMgCyABKAIAIAAoAiBODQIgAiAA/QADIP0LAwAgACABKQMINwMoIAAgASkDADcDICABIAIpAwg3AwggASACKQMANwMAIAAoAiAgACgCEE4NAiACIAD9AAMQ/QsDACAAIAApAyg3AxggACAAKQMgNwMQIAAgAikDCDcDKCAAIAIpAwA3AyAgACgCECAAKAIATg0CIAIgAP0AAwD9CwMAIAAgACkDGDcDCCAAIAApAxA3AwAgACACKQMINwMYIAAgAikDADcDEAwCCyAAIABBEGogAEEgaiAAQTBqIAFBEGsQUwwBCyAAQSBqIQMgACgCICEEAkAgACgCECIFIAAoAgAiB04EQCAEIAVODQEgAiAA/QADEP0LAwAgACADKQMINwMYIAAgAykDADcDECADIAIpAwg3AwggAyACKQMANwMAIAAoAhAgB04NASACIAD9AAMA/QsDACAAIAApAxg3AwggACAAKQMQNwMAIAAgAikDCDcDGCAAIAIpAwA3AxAMAQsgBCAFSARAIAIgAP0AAwD9CwMAIAAgAykDCDcDCCAAIAMpAwA3AwAgAyACKQMINwMIIAMgAikDADcDAAwBCyACIAD9AAMA/QsDACAAIAApAxg3AwggACAAKQMQNwMAIAAgAikDCDcDGCAAIAIpAwA3AxAgBCAAKAIQTg0AIAIgAP0AAxD9CwMAIAAgAykDCDcDGCAAIAMpAwA3AxAgAyACKQMINwMIIAMgAikDADcDAAsgAEEwaiIEIAFGDQBBACEFA0ACQCAEKAIAIgcgAygCAE4NACACIAQoAgw2AgggAiAEKQIENwMAIAQgA/0AAwD9CwMAAkADQCAHIANBEGsiBigCAE4NASADIAb9AAMA/QsDACAGIgMgAEcNAAsgACEDCyADIAc2AgAgAyACKQMANwIEIAMgAigCCDYCDCAFQQFqIgVBCEcNACAEQRBqIAFGIQYMAgsgBCIDQRBqIgQgAUcNAAtBASEGCyACQRBqJAAgBgujBgEDfyMAQRBrIQUgAigCACEGAkAgASgCACIHIAAoAgBOBEAgBiAHTg0BIAUgAf0AAwD9CwMAIAEgAikDCDcDCCABIAIpAwA3AwAgAiAFKQMINwMIIAIgBSkDADcDACABKAIAIAAoAgBODQEgBSAA/QADAP0LAwAgACABKQMINwMIIAAgASkDADcDACABIAUpAwg3AwggASAFKQMANwMADAELIAYgB0gEQCAFIAD9AAMA/QsDACAAIAIpAwg3AwggACACKQMANwMAIAIgBSkDCDcDCCACIAUpAwA3AwAMAQsgBSAA/QADAP0LAwAgACABKQMINwMIIAAgASkDADcDACABIAUpAwg3AwggASAFKQMANwMAIAIoAgAgASgCAE4NACAFIAH9AAMA/QsDACABIAIpAwg3AwggASACKQMANwMAIAIgBSkDCDcDCCACIAUpAwA3AwALAkAgAygCACACKAIATg0AIAUgAv0AAwD9CwMAIAIgAykDCDcDCCACIAMpAwA3AwAgAyAFKQMINwMIIAMgBSkDADcDACACKAIAIAEoAgBODQAgBSAB/QADAP0LAwAgASACKQMINwMIIAEgAikDADcDACACIAUpAwg3AwggAiAFKQMANwMAIAEoAgAgACgCAE4NACAFIAD9AAMA/QsDACAAIAEpAwg3AwggACABKQMANwMAIAEgBSkDCDcDCCABIAUpAwA3AwALAkAgBCgCACADKAIATg0AIAUgA/0AAwD9CwMAIAMgBCkDCDcDCCADIAQpAwA3AwAgBCAFKQMINwMIIAQgBSkDADcDACADKAIAIAIoAgBODQAgBSAC/QADAP0LAwAgAiADKQMINwMIIAIgAykDADcDACADIAUpAwg3AwggAyAFKQMANwMAIAIoAgAgASgCAE4NACAFIAH9AAMA/QsDACABIAIpAwg3AwggASACKQMANwMAIAIgBSkDCDcDCCACIAUpAwA3AwAgASgCACAAKAIATg0AIAUgAP0AAwD9CwMAIAAgASkDCDcDCCAAIAEpAwA3AwAgASAFKQMINwMIIAEgBSkDADcDAAsL9QMDA3wCfwF+IAC9IgZCIIinQf////8HcSIEQYCAwKAETwRAIABEGC1EVPsh+T8gAKYgBkL///////////8Ag0KAgICAgICA+P8AVhsPCwJAAn8gBEH//+/+A00EQEF/IARBgICA8gNPDQEaDAILIACZIQAgBEH//8v/A00EQCAEQf//l/8DTQRAIAAgAKBEAAAAAAAA8L+gIABEAAAAAAAAAECgoyEAQQAMAgsgAEQAAAAAAADwv6AgAEQAAAAAAADwP6CjIQBBAQwBCyAEQf//jYAETQRAIABEAAAAAAAA+L+gIABEAAAAAAAA+D+iRAAAAAAAAPA/oKMhAEECDAELRAAAAAAAAPC/IACjIQBBAwshBSAAIACiIgIgAqIiASABIAEgASABRC9saixEtKK/okSa/d5SLd6tv6CiRG2adK/ysLO/oKJEcRYj/sZxvL+gokTE65iZmZnJv6CiIQMgAiABIAEgASABIAFEEdoi4zqtkD+iROsNdiRLe6k/oKJEUT3QoGYNsT+gokRuIEzFzUW3P6CiRP+DAJIkScI/oKJEDVVVVVVV1T+goiEBIARB///v/gNNBEAgACAAIAMgAaCioQ8LIAVBA3QiBCsDgAggACADIAGgoiAEKwOgCKEgAKGhIgCaIAAgBkIAUxshAAsgAAumAwIFfwF+AkAgAb1C////////////AINCgICAgICAgPj/AFgEQCAAvUL///////////8Ag0KBgICAgICA+P8AVA0BCyAAIAGgDwsgAb0iB0IgiKciAkGAgMD/A2sgB6ciBXJFBEAgABBUDwsgAkEedkECcSIGIAC9IgdCP4inciEDAkACQAJAAkACQCAHQiCIp0H/////B3EiBCAHp3JFBEAgA0ECaw4CAQIFCyACQf////8HcSICIAVyRQRARBgtRFT7Ifk/IACmDwsgAkGAgMD/B0cNAiAEQYCAwP8HRw0DIANBA3QrA8AIDwtEGC1EVPshCUAPC0QYLURU+yEJwA8LIARBgIDA/wdHIAJBgICAIGogBE9xRQRARBgtRFT7Ifk/IACmDwsCfCAGBEBEAAAAAAAAAAAgBEGAgIAgaiACSQ0BGgsgACABo5kQVAsh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DQEaIAVB/w9PBEAgAEQAAAAAAADwP6APCyAGQgBTBEAjAEEQayIERAAAAAAAAAAQOQMIIAQrAwhEAAAAAAAAABCiDwsjAEEQayIERAAAAAAAAABwOQMIIAQrAwhEAAAAAAAAAHCiDwsgAEGgHysDAKJBqB8rAwAiAaAiAiABoSIBQbgfKwMAoiABQbAfKwMAoiAAoKAiASABoiIAIACiIAFB2B8rAwCiQdAfKwMAoKIgACABQcgfKwMAokHAHysDAKCiIAK9IganQQR0QfAPcSIFKwOQICABoKCgIQEgBSkDmCAgBkIthnwhByAERQRAAnwgBkKAgICACINQBEAgB0KAgICAgICAiD99vyIAIAGiIACgRAAAAAAAAAB/ogwBCyAHQoCAgICAgIDwP3y/IgIgAaIiASACoCIDRAAAAAAAAPA/YwR8IwBBEGsiBCAEQoCAgICAgIAINwMIIAQrAwhEAAAAAAAAEACiOQMIRAAAAAAAAAAAIANEAAAAAAAA8D+gIgAgASACIAOhoCADRAAAAAAAAPA/IAChoKCgRAAAAAAAAPC/oCIAIABEAAAAAAAAAABhGwUgAwtEAAAAAAAAEACiCw8LIAe/IgAgAaIgAKALC4AEAgR+An8CQAJAIAG9IgIiBEIBhiIDUA0AIAJC////////////AINCgICAgICAgPj/AFYNACAAvSIFQjSIp0H/D3EiBkH/D0cNAQsgACABoiIAIACjDwsgAyAFQgGGIgJaBEAgAEQAAAAAAAAAAKIgACACIANRGw8LIARCNIinQf8PcSEHAn4gBkUEQEEAIQYgBUIMhiICQgBZBEADQCAGQQFrIQYgAkIBhiICQgBZDQALCyAFQQEgBmuthgwBCyAFQv////////8Hg0KAgICAgICACIQLIQICfiAHRQRAQQAhByAEQgyGIgNCAFkEQANAIAdBAWshByADQgGGIgNCAFkNAAsLIARBASAHa62GDAELIARC/////////weDQoCAgICAgIAIhAshBCAGIAdKBEADQAJAIAIgBH0iA0IAUw0AIAMiAkIAUg0AIABEAAAAAAAAAACiDwsgAkIBhiECIAZBAWsiBiAHSg0ACyAHIQYLAkAgAiAEfSIDQgBTDQAgAyICQgBSDQAgAEQAAAAAAAAAAKIPCyACQv////////8HWARAA0AgBkEBayEG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";function Dt(){try{let A=atob(So),e=Uint8Array.from(A,t=>t.charCodeAt(0)),o=new WebAssembly.Module(e);return new WebAssembly.Instance(o,{}).exports}catch{return null}}var cA=134,MA=32,bo=361,ye=54,yo=`
2
+ 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
3
+ `,GA=No(yo),ko=GA.subarray(0,cA),vo=GA.subarray(cA,cA*2),Go=GA.subarray(cA*2,cA*2+cA*MA),Fo=GA.subarray(cA*2+cA*MA,cA*2+cA*MA+MA),Po=GA.subarray(cA*2+cA*MA+MA,GA.length-3),xo=GA.subarray(GA.length-3);function ut(A,e,o,r,t,n,a,c,C,Q,s,g,i,B,E){if(Ve){let l=Lo(Ve,A,e,o,r,t,n,a,c,C,Q,s,g,i,B,E);if(l)return l}return Ko(A,e,o,r,t,n,a,c,C,Q,s,g,i,B,E)}function uA(){return Ve}function Ko(A,e,o,r,t,n,a,c,C,Q,s,g,i,B,E){let l=A.length,I=new Float32Array(l),u=Array.from({length:22},()=>new Float32Array(l));for(let y=0;y<l;y++){let b=y*4;for(let R=0;R<4;R++)u[R][y]=o[b+R],u[R+4][y]=r[b+R];let G=t[b]-t[b+3],K=t[b+1]-n[b],P=t[b+2]-n[b+1];u[8][y]=G,u[9][y]=K,u[10][y]=P,u[11][y]=Math.hypot(G,K,P),u[12][y]=n[b]-n[b+2],u[13][y]=n[b+3]-n[b+1];for(let R=0;R<4;R++)u[R+14][y]=C[b+R],u[R+18][y]=Q[b+R]}let d=u.map(HA),D=u.map((y,b)=>HA(Array.from(y,G=>Math.abs(G-d[b])))+.02),h=[1,2].map(y=>u.map((b,G)=>{let K=Array.from(b).filter((P,R)=>A[R]===y);return K.length?HA(K):d[G]})),m=[1,2].map(y=>[0,1].map(b=>{let G=Array.from(A.entries()).flatMap(([K,P])=>P===y?[g[K*4+(y-1)*2+b]]:[]);return G.length?HA(G):0})),w=Array.from({length:4},(y,b)=>Float32Array.from({length:l},(G,K)=>B[K*4+b])),p=w.map(HA),f=w.map((y,b)=>HA(Array.from(y,G=>Math.abs(G-p[b])))+.02),S=[1,2].map(y=>w.map((b,G)=>{let K=Array.from(b).filter((P,R)=>A[R]===y);return K.length?HA(K):p[G]})),M=new Float32Array(cA),k=new Float32Array(MA);for(let y=0;y<l;y++){let b=0;for(let F of u)M[b++]=F[y];M[b++]=A[y]===1?1:0,M[b++]=A[y]===2?1:0;for(let F=0;F<u.length;F++)M[b++]=be(u[F][y],d[F],D[F]);for(let F of h)for(let N=0;N<u.length;N++)M[b++]=be(u[N][y],F[N],D[N]);for(let F=0;F<4;F++)M[b++]=s[y*4+F];let G=y*4;for(let F=0;F<4;F++)M[b++]=c[G+F]/2;for(let F=0;F<4;F++)M[b++]=a[G+F];for(let F=0;F<4;F++)M[b++]=g[G+F];M[b++]=Math.hypot(g[G],g[G+1]),M[b++]=Math.hypot(g[G+2],g[G+3]),M[b++]=Math.hypot(g[G]-m[0][0],g[G+1]-m[0][1]),M[b++]=Math.hypot(g[G+2]-m[1][0],g[G+3]-m[1][1]);let K=y*6;for(let F=0;F<2;F++){let N=K+F*3,q=Math.max(i[N],i[N+1],i[N+2],.01);for(let Y=0;Y<3;Y++)M[b++]=i[N+Y]/q}for(let F=0;F<4;F++)M[b++]=w[F][y];for(let F=0;F<4;F++)M[b++]=be(w[F][y],p[F],f[F]);for(let F of S)for(let N=0;N<4;N++)M[b++]=be(w[N][y],F[N],f[N]);M[b++]=E[y*4],M[b++]=E[y*4+1];for(let F=0;F<MA;F++){let N=Fo[F];for(let q=0;q<cA;q++)N+=(M[q]-ko[q])/vo[q]*Go[q*MA+F];k[F]=Math.max(N,0)}let P=0,R=-1/0,x=-1/0,z=-1/0;for(let F=0;F<3;F++){let N=xo[F];for(let q=0;q<MA;q++)N+=k[q]*Po[q*3+F];N>R&&(P=F,R=N),F===0?x=N:z=Math.max(z,N)}A[y]=P,I[y]=P===0?z-x:R-x,e[y*2]=0,e[y*2+1]=0}return I}var Ve=Ro();function Ro(){try{let A=Dt();return!A||(A.at(),A.b()!==1||A.c()!==cA||A.d()!==ye||A.e()!==GA.length||A.k()!==4||A.m()!==9||A.an()!==9)?null:(new Float32Array(A.a.buffer,A.f(),GA.length).set(GA),A)}catch{return null}}function Lo(A,e,o,r,t,n,a,c,C,Q,s,g,i,B,E,l){let I=e.length;if(I===0||I>bo)return null;let u=new Float32Array(A.a.buffer,A.g(),I*ye),d=[[r,0],[t,4],[n,8],[a,12],[c,16],[C,20],[Q,24],[s,28],[g,32],[i,36],[E,46],[l,50]];for(let[m,w]of d)for(let p=0;p<I;p++){let f=p*4,S=p*ye+w;u[S]=m[f],u[S+1]=m[f+1],u[S+2]=m[f+2],u[S+3]=m[f+3]}for(let m=0;m<I;m++){let w=m*6,p=m*ye+40;for(let f=0;f<6;f++)u[p+f]=B[w+f]}let D=new Uint8Array(A.a.buffer,A.h(),I);if(D.set(e),A.j(I)!==0)return null;e.set(D),o.fill(0,0,I*2);let h=new Float32Array(I);return h.set(new Float32Array(A.a.buffer,A.i(),I)),h}function be(A,e,o){return Math.max(-6,Math.min(6,(A-e)/o))}function HA(A){let e=Array.from(A).sort((r,t)=>r-t),o=Math.floor(e.length/2);return e.length%2?e[o]:(e[o-1]+e[o])*.5}function No(A){let e=atob(A.replace(/\s/g,"")),o=Uint8Array.from(e,t=>t.charCodeAt(0)),r=cA*2+cA*MA+MA+MA*3+3;if(o.byteLength!==r*4)throw new Error("stone classifier model has invalid length");return new Float32Array(o.buffer)}var Uo=!0,Ke=!0,Ae=null,ot=[[0,0],[-1,0],[1,0],[0,-1],[0,1]];function Yo(A,e,o,r){let t=A.resizedWidth/r.width,n=A.resizedHeight/r.height,a=A.localLineEvidence.map(Q=>({...Q,x:Q.x*t,y:Q.y*n})),c=kt(a,A,t,n),C=[t,0,0,0,n,0,0,0,1];return ot.map(([Q,s])=>{let g=IA(e.gridToSource,[1,0,Q,0,1,s,0,0,1]),i=IA(C,g),B=Qe(c,i,o);return{x:Q,y:s,grid:pt(A.gridLines,g,o),boundary:Ce(A.gridLines,g,o),termination:(Math.min(B[0],B[1])+Math.min(B[2],B[3]))*.5}})}function To(A,e,o){return ot.map(([r,t])=>{let n=IA(e.gridToSource,[1,0,r,0,1,t,0,0,1]);return{x:r,y:t,endpointSides:lr(A,n,1,1,o)}})}function zo(A,e,o){let r=sA(e.gridToSource);if(!r)return[];let t=o-1,n=bt(A.candidates,o),a=n.reduce((C,Q)=>Math.max(C,Q.score),0),c=n.filter(C=>C.score>=a*.7&&C.surroundDrop>=.9&&Math.max(C.horizontalContinuation,C.verticalContinuation)<=.3);return ot.map(([C,Q])=>{let s=0,g=0;for(let i of c){let B=U(r,i.x,i.y),E=B[0]-C,l=B[1]-Q;if(Math.hypot(E-Math.round(E),l-Math.round(l))>.42||E<-.45||E>t+.45||l<-.45||l>t+.45)continue;let u=(.5+i.score)*Math.max(.5,i.surroundDrop),d=Math.min(E,l,t-E,t-l)<.45;s+=u,d&&(g+=u)}return{x:C,y:Q,strictInsideWeight:s,strictBoundaryWeight:g}})}function ht(A,e,o,r){if(e.gridTerminationScore>=.5)return e;let t=To(A,e,o),n=t.find(D=>!D.x&&!D.y),a=null;for(let D of t){if(Math.abs(D.x)+Math.abs(D.y)!==1)continue;let h=D.x?[0,1]:[2,3];if(!h.every(b=>Number.isFinite(D.endpointSides[b])&&Number.isFinite(n.endpointSides[b])))continue;let m=h.reduce((b,G)=>b+D.endpointSides[G]-n.endpointSides[G],0),[w,p]=D.x?e.boardMargins.slice(0,2):e.boardMargins.slice(2,4),f=D.x?Math.max(e.boardSideConfidence[0],e.boardSideConfidence[1]):Math.max(e.boardSideConfidence[2],e.boardSideConfidence[3]),S=Math.abs(w-p)>=.5&&f>=.7&&(D.x||D.y)===Math.sign(p-w),M=e.gridTerminationScore<.2||S,k=M?.05:.15,y=M?.05:.1;m<k||Math.min(...h.map(b=>D.endpointSides[b]))<y||a&&m<=a.gain||(a={x:D.x,y:D.y,gain:m})}if(a)return _e(e,o,a.x,a.y);let c=e;if(!r)return c;let C=zo(r,c,o),Q=C.find(D=>!D.x&&!D.y);if(!Q)return c;let s=null;for(let D of C){if(Math.abs(D.x)+Math.abs(D.y)!==1)continue;let h=D.strictInsideWeight-Q.strictInsideWeight,m=D.strictBoundaryWeight-Q.strictBoundaryWeight;h<.6||m<.5||s&&h<=s.gain||(s={x:D.x,y:D.y,gain:h})}s&&(c=_e(c,o,s.x,s.y));let g=Yo(r,c,o,A),i=g.find(D=>!D.x&&!D.y);if(!i||c.gridTerminationScore>=.5)return c;let[B,E,l,I]=c.boardMargins,u=[{x:Math.abs(B-E)>=.75&&Math.min(c.boardSideConfidence[0],c.boardSideConfidence[1])>=.4?Math.sign(E-B):0,y:0},{x:0,y:Math.abs(l-I)>=.75&&Math.min(c.boardSideConfidence[2],c.boardSideConfidence[3])>=.4?Math.sign(I-l):0}],d=null;for(let D of u){if(!D.x&&!D.y)continue;let h=g.find(w=>w.x===D.x&&w.y===D.y);if(!h)continue;let m=h.termination-i.termination;m<.04||h.boundary<i.boundary-.02||h.grid<i.grid-.02||d&&m<=d.gain||(d={...D,gain:m})}return d&&(c=_e(c,o,d.x,d.y)),c}function _e(A,e,o,r){let t=IA(A.gridToSource,[1,0,o,0,1,r,0,0,1]),[n,a,c,C]=A.boardMargins;return{...A,gridToSource:t,gridCorners:yA(t,e-1),boardMargins:[n+o,a-o,c+r,C-r]}}function ft(A,e,o,r){let t=e-1,n=yA(A.gridToSource,t),a=(E,l)=>Math.hypot(l[0]-E[0],l[1]-E[1]),c=Math.max(a(n[0],n[1]),a(n[1],n[2]),a(n[2],n[3]),a(n[3],n[0]))/t,C=E=>{let l=t+E[0]+E[1],I=t+E[2]+E[3],u=Math.min(1,2048/Math.max(l*c,I*c));return[Math.max(1,Math.round(l*c*u)),Math.max(1,Math.round(I*c*u))]},Q=(E,l,I)=>{let u=[0,0,0,0],d=t+E[0]+E[1],D=t+E[2]+E[3],h=-E[0]+d*.5/l,m=t+E[1]-d*.5/l,w=-E[2]+D*.5/I,p=t+E[3]-D*.5/I,f=S=>S[0]<0||S[0]>o-1||S[1]<0||S[1]>r-1;for(let S=0;S<I;S++){let M=-E[2]+(S+.5)/I*D;f(U(A.gridToSource,h,M))&&u[0]++,f(U(A.gridToSource,m,M))&&u[1]++}for(let S=0;S<l;S++){let M=-E[0]+(S+.5)/l*d;f(U(A.gridToSource,M,w))&&u[2]++,f(U(A.gridToSource,M,p))&&u[3]++}return u},s=[1.3,1.3,1.3,1.3];for(let E=0;E<16;E++){let[l,I]=C(s),u=Q(s,l,I),d=[I,I,l,l],D=-1;for(let h=0;h<4;h++){let m=u[h]/d[h]>=.5;s[h]>.5&&m&&u[h]>(D<0?0:u[D])&&(D=h)}if(D<0)break;s[D]=Math.max(.5,Math.round((s[D]-.2)*10)/10)}let[g,i]=C(s),B=Q(s,g,i);return{margins:s,outsidePixels:B,outsideRatios:[B[0]/i,B[1]/i,B[2]/g,B[3]/g],width:g,height:i}}var UA=72;function Be(A,e,o,r=!0,t=!1){if(o<3)return null;cr(A);let n=e.resizedWidth/A.width,a=e.resizedHeight/A.height,c=bt(e.candidates,o),C=yt(e.candidates,o),Q=r&&e.candidates.length>=o*o*.45&&e.candidates.length>=e.intersectionCandidates.length*2.2,s=nr(e,c,n,a,Q),g=c.map(v=>({x:v.x*n,y:v.y*a,weight:(.5+v.score)*(.5+v.latticeSupport*.5),fitWeight:0})),i=[...e.squareCandidates,...e.darkFrameCandidates],E=i.length>=o*2&&i.length>=e.candidates.length*2&&e.intersectionCandidates.length<o?[...s,...i.map(v=>({x:v.x*n,y:v.y*a,weight:1.2*(.8+v.score),fitWeight:0}))]:s,l=e.lineEvidence.map(v=>({...v,x:v.x*n,y:v.y*a})),I=e.localLineEvidence.map(v=>({...v,x:v.x*n,y:v.y*a})),d=(C.length>=o*o*.3?e.stoneLines:e.connectedLines).map(v=>({...v,x1:v.x1*n,y1:v.y1*a,x2:v.x2*n,y2:v.y2*a})),D=e.gridLines.map(v=>({...v,x1:v.x1*n,y1:v.y1*a,x2:v.x2*n,y2:v.y2*a})),h=e.connectedLines.map(v=>({...v,x1:v.x1*n,y1:v.y1*a,x2:v.x2*n,y2:v.y2*a})),m=kt(I,e,n,a);if(s.length<8)return null;let w=performance.now(),p=ir(s,l,I,e,e.resizedWidth,e.resizedHeight,o,E);if(!p)return null;let f=performance.now()-w,{horizontal:S,vertical:M,horizontalSpacing:k,verticalSpacing:y}=p,b=xA(S,M);if(Math.abs(b)<.15)return null;let G=performance.now(),K=vt(p),P=FA(s,K,[.34,.27,.23]);if(!P)return null;let R=[P],x=e.intersectionCandidates.map(v=>({x:v.x*n,y:v.y*a,weight:.8+v.score,fitWeight:.8+v.score})),z=o===19?jo(s.slice(0,c.length),p):null;z&&R.push(z);let F=(o-2)/(o-1),N=o/(o-1),q=o===13?[[1,F]]:o===19?[[F,1],[1,N]]:[];for(let[v,eA]of q){let lA=FA(s,IA(K,[v,0,0,0,eA,0,0,0,1]),[.6,.45,.32,.24]);lA&&R.push(lA)}let Y=Xo(e.lineLattices,o),j=.65+(19-o)*(.2/10),J=e.lineLattices.length===2&&e.lineLattices.every(v=>v.score>=o*j)&&(Y>=.08||e.lineLattices.every(v=>v.score>=o*.9)&&e.lineLattices.some(v=>v.score<o))?Zo(e.lineLattices,e.resizedWidth,e.resizedHeight,o):null;if(J&&le(yA(J,o-1),e.resizedWidth,e.resizedHeight)){let v=FA(s,J,[.42,.3,.23]);if(v&&R.push(v),o===19&&C.length>=o*o*.3&&Y>=.3){let eA=(o-3)/(o-1);for(let lA of[[1,0,0,0,eA,1,0,0,1],[eA,0,1,0,1,0,0,0,1]]){let BA=FA(s,IA(J,lA),[.42,.3,.23]);BA&&R.push(BA)}}}if(p.linePerspectiveConfidence>=.8){let v=FA(s,K,[.6,.45,.32,.24]);v&&R.push(v)}if(e.candidates.length>=o*o*.8){let v=s.slice(0,c.length),eA=FA(v,K,[.6,.45,.32,.24]),lA=eA?FA(s,eA.transform,[.32,.24]):null;lA&&R.push(lA)}let L=null;for(let v of R){let eA=rt(l,v.transform);for(let lA of xe(v.assigned,o,"column"))for(let BA of xe(v.assigned,o,"row")){let Ie=IA(v.transform,[1,0,lA,0,1,BA,0,0,1]),uo=yA(Ie,o-1);if(!le(uo,e.resizedWidth,e.resizedHeight))continue;let Xe=bA(A,Ie,n,a,o),mo=v.assigned.reduce((Ze,zA)=>Ze+(zA.column>=lA&&zA.column<lA+o&&zA.row>=BA&&zA.row<BA+o?zA.weight:-zA.weight*.8),0),wo=dr(Xe),ho=Xe.reduce((Ze,zA)=>Ze+zA.confidence,0)/4,fo=eA?.score(lA,BA,o)??0,Mo=se(m,Ie,o),po=Ce(D,Ie,o),Et=mo+(wo+ho*.8+fo*1.5+Mo*.6+po*1.5)*Math.max(4,v.assigned.length*.12);(!L||Et>L.score)&&(L={score:Et,transform:Ie,assigned:v.assigned,sides:Xe,horizontalStart:lA,verticalStart:BA})}}if(!L)return null;let V=L.assigned.map(v=>({...v,weight:v.fitWeight,column:v.column-L.horizontalStart,row:v.row-L.verticalStart})).filter(v=>v.column>=0&&v.column<o&&v.row>=0&&v.row<o),$=OA(V);$&&(L.transform=$);for(let v of[.25,.2]){let eA=SA(s,L.transform,v).filter(BA=>BA.column>=0&&BA.column<o&&BA.row>=0&&BA.row<o).map(BA=>({...BA,weight:BA.fitWeight})),lA=OA(eA);if(!lA||eA.length<8)break;V=eA,L.transform=lA}let nA=performance.now()-G,DA=performance.now(),aA=Vo(L.transform,s,I,d,o,e.resizedWidth,e.resizedHeight,p.linePerspectiveEstimate,c.length);L.transform=aA.transform;let gA=performance.now()-DA,kA=performance.now(),mA=e.lineLattices.some(v=>v.orientation==="vertical"&&v.score>=o),XA=e.lineLattices.some(v=>v.orientation==="horizontal"&&v.score>=o),ZA=[mA?2.5:.6,XA?2.5:.6],pA=Br(A,L.transform,s,g,l,D,m,n,a,o,ZA);L.transform=pA.transform,L.sides=pA.sides;let ne=pA.points.reduce((v,eA)=>v+eA.fitWeight,0),qA=s.reduce((v,eA)=>v+eA.fitWeight,0),VA=Math.min(1,pA.points.length/28)*Math.min(1,ne/Math.max(1,qA)),YA=VA<.65?Cr(L.transform,L.sides,o):L.transform;L.transform=YA,YA!==pA.transform&&(L.sides=bA(A,L.transform,n,a,o));let _A=VA<.4?qo(L.transform,e.lineLattices,o):null,H=_A&&x.length>=o*2?FA(x,_A,[.55,.4,.3,.22]):null;H&&H.assigned.length>=o&&(L.transform=H.transform,L.sides=bA(A,L.transform,n,a,o));let W=H?Ho(L.transform,x,g.filter((v,eA)=>Math.max(c[eA].horizontalContinuation,c[eA].verticalContinuation)<=.5),D,e.lineLattices,o):null;W&&(L.transform=W,L.sides=bA(A,L.transform,n,a,o)),V=H?SA(s,L.transform,.3).filter(v=>v.column>=0&&v.column<o&&v.row>=0&&v.row<o):YA===pA.transform?pA.points:SA(s,L.transform,.23).filter(v=>v.column>=0&&v.column<o&&v.row>=0&&v.row<o);let tA=Wo(L.transform,J,L.sides,e.lineLattices,o);tA&&(L.transform=tA,L.sides=bA(A,L.transform,n,a,o),V=SA(s,L.transform,.3).filter(v=>v.column>=0&&v.column<o&&v.row>=0&&v.row<o));let hA=t?_o(L.transform,D,o):null;hA&&(L.transform=hA,L.sides=bA(A,L.transform,n,a,o),V=SA(s,L.transform,.3).filter(v=>v.column>=0&&v.column<o&&v.row>=0&&v.row<o));let oA=[...L.transform],wA=V,fA=$o(A,L.transform,h,g,o,e.resizedWidth,e.resizedHeight,n,a);fA&&(L.transform=fA,L.sides=bA(A,L.transform,n,a,o),V=SA(s,L.transform,.3).filter(v=>v.column>=0&&v.column<o&&v.row>=0&&v.row<o));let vA=Oo(A,L.transform,L.sides,s,g,D,m,n,a,o);vA&&(L.transform=vA.transform,L.sides=vA.sides,V=SA(s,L.transform,.3).filter(v=>v.column>=0&&v.column<o&&v.row>=0&&v.row<o));let NA=performance.now()-kA;if(V=V.map(v=>({...v,weight:v.fitWeight})),V.length<Math.max(8,o))return null;let fe=v=>[v[0]/n,v[1]/n,v[2]/n,v[3]/a,v[4]/a,v[5]/a,v[6],v[7],v[8]],TA=fe(L.transform),ie=fe(oA),$A=yA(TA,o-1),je=yA(ie,o-1),ae=L.sides.map(v=>v.margin),Me=L.sides.map(v=>v.confidence),pe=Me.reduce((v,eA)=>v+eA,0)/4,[Z,AA,rA,KA]=ae,ge=pe>=.28?[U(TA,-Z,-rA),U(TA,o-1+AA,-rA),U(TA,o-1+AA,o-1+KA),U(TA,-Z,o-1+KA)]:void 0,Se=V.reduce((v,eA)=>v+eA.weight,0),Qt=s.reduce((v,eA)=>v+eA.fitWeight,0),lt=Math.min(1,V.length/28)*Math.min(1,Se/Math.max(1,Qt)),lo=wA.reduce((v,eA)=>v+eA.fitWeight,0),Bo=Math.min(1,wA.length/28)*Math.min(1,lo/Math.max(1,Qt)),Bt=se(m,L.transform,o),Eo=se(m,oA,o),Do=Qe(m,L.transform,o);if(Q&&(lt<.6||Bt<.7)){let v=Be(A,e,o,!1,t);return v?{...v,axesMs:f+v.axesMs,initialGridMs:nA+v.initialGridMs,perspectiveMs:gA+v.perspectiveMs,phaseMs:NA+v.phaseMs}:null}return{gridToSource:TA,gridCorners:$A,preBoundaryGridToSource:ie,preBoundaryGridCorners:je,preBoundaryLatticeConfidence:Bo,preBoundaryGridTerminationScore:Eo,preBoundaryInlierCount:wA.length,...ge?{boardCorners:ge}:{},boardMargins:ae,boardSideConfidence:Me,latticeConfidence:lt,boardConfidence:pe,inlierCount:V.length,seedSpacing:[p.horizontalSpacing,p.verticalSpacing],seedAxes:[p.horizontal,p.vertical],stoneGraphSize:z?.assigned.length??0,intersectionGraphSize:0,pairSpacing:p.pairSpacing,seedGain:p.seedGain,seedFitGain:p.seedFitGain,perspectiveWarp:aA.warp,perspectiveGain:aA.gain,linePerspectiveEstimate:p.linePerspectiveEstimate,linePerspectiveConfidence:p.linePerspectiveConfidence,linePerspectiveAxisConfidence:p.linePerspectiveAxisConfidence,lineLatticePerspectiveStrength:Y,stoneResidualScore:Mt(s,c.length,L.transform,o),gridTerminationScore:Bt,gridTerminationSides:Do,axesMs:f,initialGridMs:nA,perspectiveMs:gA,phaseMs:NA}}function Oo(A,e,o,r,t,n,a,c,C,Q){let s=(p,f)=>{let S=p[f*2],M=p[f*2+1];return Math.min(S.confidence,M.confidence)>=.4?Math.abs(S.margin-M.margin):0},g=s(o,0),i=s(o,1),B=se(a,e,Q);if(B>=.5)return null;let E=g>=.75?Math.sign(o[1].margin-o[0].margin):0,l=i>=.75?Math.sign(o[3].margin-o[2].margin):0,I=E?[0,E]:[0],u=l?[0,l]:[0],d=Ce(n,e,Q),D=r.reduce((p,f)=>p+f.weight,0),h=(p,f)=>{let M=SA(r,p,.23).filter(b=>b.column>=0&&b.column<Q&&b.row>=0&&b.row<Q).reduce((b,G)=>b+G.weight,0)/Math.max(1,D),k=St(t,p,Q),y=Math.min(k[0],k[1])+Math.min(k[2],k[3]);return[s(f,0)+s(f,1),se(a,p,Q),Ce(n,p,Q),M+y*y]},m=h(e,o),w=null;for(let p of I)for(let f of u){if(!p&&!f)continue;let S=IA(e,[1,0,p,0,1,f,0,0,1]),M=bA(A,S,c,C,Q),k=h(S,M),y=k[0]<=m[0]-.5&&k[1]>=B-.08,b=Math.abs(p)+Math.abs(f)===1&&k[1]>=B+.08;if(!((y||b)&&k[2]>=d-.05&&k[3]>=m[3]-.08))continue;let K=Math.max(y?m[0]-k[0]:0,b?k[1]-B:0);(!w||K>w.score)&&(w={transform:S,sides:M,quality:k,score:K})}return w?{transform:w.transform,sides:w.sides}:null}function qo(A,e,o){let r=e.find(m=>m.orientation==="vertical");if(!r||r.score<o*.6)return null;let t=o-1,[n,a,c,C]=yA(A,t),Q=C[1]-n[1],s=c[1]-a[1];if(Math.abs(Q)<8||Math.abs(s)<8)return null;let g=(C[0]-n[0])/Q,i=(c[0]-a[0])/s,B=i-g,E=iA(r.slopeLinear*t,-.65,.65);if(Math.abs(E)<Math.abs(B)+.08)return null;let l=(g+i)*.5,I=l-E*.5,u=l+E*.5,d=.5,D=n[0]*(1-d)+C[0]*d,h=a[0]*(1-d)+c[0]*d;return OA([{x:D-I*Q*d,y:n[1],column:0,row:0,weight:1,fitWeight:1},{x:h-u*s*d,y:a[1],column:t,row:0,weight:1,fitWeight:1},{x:h+u*s*(1-d),y:c[1],column:t,row:t,weight:1,fitWeight:1},{x:D+I*Q*(1-d),y:C[1],column:0,row:t,weight:1,fitWeight:1}])}function Ho(A,e,o,r,t,n){let a=t.find(i=>i.orientation==="vertical");if(!a||e.length<n*2)return null;let c=iA(a.slopeLinear*.2,-.008,.008);if(Math.abs(c)<.001)return null;let C=(n-1)*.5,Q=A,s=$e(e,o,r,A,n);for(let i of[-.006,0,.006]){let B=tt(c,i,C);for(let E of[.95,1.05])for(let l of[.95,1.05])for(let I of[-1,0,1])for(let u of[-1,0,1]){let d=IA(B,[E,0,C*(1-E)+I,0,l,C*(1-l)+u,0,0,1]),D=FA(e,IA(A,d),[.6,.45,.32,.24]);if(!D)continue;let h=$e(e,o,r,D.transform,n);h>s&&(Q=D.transform,s=h)}}let g=Q;for(let i of[-1,0,1])for(let B of[-1,0,1]){let E=IA(g,[1,0,i,0,1,B,0,0,1]),l=$e(e,o,r,E,n);l>s&&(Q=E,s=l)}return Q===A?null:Q}function $e(A,e,o,r,t){let n=(s,g)=>{let i=sA(r);if(!i||!s.length)return[0,0];let B=0,E=0;for(let l of s){let[I,u]=U(i,l.x,l.y);if(I<-.5||u<-.5||I>t-.5||u>t-.5)continue;E++;let d=Math.hypot(I-Math.round(I),u-Math.round(u));B+=Math.max(0,1-d/g)}return[B/s.length,E/s.length]},[a,c]=n(A,.23),[C,Q]=n(e,.28);return a*3+c*.3+C+Q*.1+Jo(o,r,t)*1.5}function Jo(A,e,o){let r=sA(e);if(!r||!A.length)return 0;let t=0,n=0;for(let a of A){let c=U(r,a.x1,a.y1),C=U(r,a.x2,a.y2),Q=a.orientation==="horizontal"?c[1]:c[0],s=a.orientation==="horizontal"?C[1]:C[0],g=a.orientation==="horizontal"?c[0]:c[1],i=a.orientation==="horizontal"?C[0]:C[1],B=Math.abs(i-g),E=a.score*Math.min(1,B/6);n+=E;let l=(Q+s)*.5;if(l<-.75||l>o-.25)continue;let I=Math.max(0,1-Math.abs(s-Q)/.35),u=Math.abs(l-Math.round(l));t+=E*I*Math.max(0,1-u/.18)}return t/Math.max(1,n)}function Wo(A,e,o,r,t){if(!e||t!==19||r.length!==2||r.some(E=>E.score<t*.9))return null;let n=sA(A);if(!n)return null;let a=t-1,c=[[0,0],[a,0],[a,a],[0,a]],C=yA(e,a).map((E,l)=>{let I=U(n,E[0],E[1]);return[I[0]-c[l][0],I[1]-c[l][1]]}),Q=C.reduce((E,l)=>E+l[0],0)/4,s=C.reduce((E,l)=>E+l[1],0)/4;if(C.some(E=>Math.hypot(E[0]-Q,E[1]-s)>.25))return null;let g=Math.round(Q),i=Math.round(s);return Math.abs(Q-g)>.2||Math.abs(s-i)>.2||Math.abs(g)+Math.abs(i)!==1?null:(g<0?o[0].confidence<.15&&o[1].confidence>=.5:g>0?o[1].confidence<.15&&o[0].confidence>=.5:i<0?o[2].confidence<.15&&o[3].confidence>=.5:o[3].confidence<.15&&o[2].confidence>=.5)?e:null}function jo(A,e){if(A.length<24)return null;let o=xA(e.horizontal,e.vertical);if(Math.abs(o)<.15)return null;let r=A.map(s=>({horizontal:xA(s,e.vertical)/o,vertical:xA(e.horizontal,s)/o})),t=new Map;for(let s=0;s<A.length;s++)for(let g=s+1;g<A.length;g++){let i=(r[g].horizontal-r[s].horizontal)/e.horizontalSpacing,B=(r[g].vertical-r[s].vertical)/e.verticalSpacing,E=0,l=0,I=1/0;if(Math.abs(Math.abs(i)-1)<=.32&&Math.abs(B)<=.28)E=Math.sign(i),I=Math.abs(Math.abs(i)-1)+Math.abs(B);else if(Math.abs(Math.abs(B)-1)<=.32&&Math.abs(i)<=.28)l=Math.sign(B),I=Math.abs(Math.abs(B)-1)+Math.abs(i);else continue;for(let[u,d]of[[s,1],[g,-1]]){let D=`${u}:${E*d}:${l*d}`,h=t.get(D);(!h||I<h.error)&&t.set(D,{first:s,second:g,column:E,row:l,error:I})}}let n=Array.from({length:A.length},()=>[]),a=new Set;for(let s of t.values()){let g=`${s.first}:${s.second}`;a.has(g)||(a.add(g),n[s.first].push({index:s.second,column:s.column,row:s.row}),n[s.second].push({index:s.first,column:-s.column,row:-s.row}))}let c=[],C=new Uint8Array(A.length);for(let s=0;s<A.length;s++){if(C[s]||n[s].length===0)continue;let g=new Map([[s,[0,0]]]),i=[s];C[s]=1;for(let u=0;u<i.length;u++){let d=i[u],[D,h]=g.get(d);for(let m of n[d]){let w=[D+m.column,h+m.row];g.get(m.index)||(g.set(m.index,w),C[m.index]=1,i.push(m.index))}}let B=new Map;for(let[u,[d,D]]of g){let m={...A[u],column:d,row:D},w=`${d}:${D}`;(B.get(w)?.fitWeight??-1/0)<m.fitWeight&&B.set(w,m)}let E=[...B.values()],l=E.map(u=>u.column),I=E.map(u=>u.row);E.length<12||Math.max(...l)-Math.min(...l)<4||Math.max(...I)-Math.min(...I)<4||E.length>c.length&&(c=E)}let Q=c.length?OA(c):null;return Q?{transform:Q,assigned:c}:null}function Xo(A,e){let o=0;for(let r of A){let t=r.positionLinear+r.positionQuadratic*(2*r.indexStart+1),n=r.indexStart+e-2,a=r.positionLinear+r.positionQuadratic*(2*n+1),c=Math.abs(a-t)/Math.max(1,(Math.abs(t)+Math.abs(a))*.5),C=Math.abs(r.slopeLinear)*(e-1);o=Math.max(o,c,C)}return o}function Zo(A,e,o,r){let t=A.find(C=>C.orientation==="horizontal"),n=A.find(C=>C.orientation==="vertical");if(!t||!n)return null;let a=(C,Q)=>{let s=C.indexStart+Q;return[C.positionOffset+C.positionLinear*s+C.positionQuadratic*s*s,C.slopeOffset+C.slopeLinear*s]},c=[];for(let C=0;C<r;C++){let[Q,s]=a(t,C),g=Q-s*e*.5;for(let i=0;i<r;i++){let[B,E]=a(n,i),l=B-E*o*.5,I=1-s*E;if(Math.abs(I)<.25)continue;let u=(E*g+l)/I,d=s*u+g;c.push({x:u,y:d,weight:1,fitWeight:1,column:i,row:C})}}return c.length>=12?OA(c):null}function Vo(A,e,o,r,t,n,a,c,C){if(o.length<t*8)return{transform:A,warp:[0,0],gain:0};let Q=(S,M)=>{if(!le(yA(S,t-1),n,a))return-1/0;let k=sA(S);if(!k)return-1/0;let y=0,b=0;for(let G of e){let[K,P]=U(k,G.x,G.y);if(b+=G.fitWeight,K<-.25||P<-.25||K>t-.75||P>t-.75)continue;let R=Math.hypot(K-Math.round(K),P-Math.round(P));y+=G.fitWeight*Math.max(0,1-R/.25)}return y/Math.max(1,b)*2.2+(M?pt(r,S,t):wr(o,S,t))*1.4+Mt(e,C,S,t)*.8+or(S,t)*.35},s=[],g=Q(A,!0),i=g,B=0,E=0,l=(S,M)=>{let k=IA(A,tt(S,M,(t-1)*.5)),y=Q(k,!0);s.push({transform:k,horizontal:S,vertical:M,score:y}),y>i&&(i=y,B=S,E=M)},I=[[0,0],c,[c[0]*.5,c[1]*.5]];for(let S of I)for(let M of[-.008,0,.008])for(let k of[-.008,0,.008])l(S[0]+M,S[1]+k);let u=B,d=E;for(let S of[-.002,0,.002])for(let M of[-.002,0,.002])l(u+S,d+M);let D=[{transform:A,horizontal:0,vertical:0,score:g},...I.slice(1).map(([S,M])=>({transform:IA(A,tt(S,M,(t-1)*.5)),horizontal:S,vertical:M,score:0})),...s.sort((S,M)=>M.score-S.score).slice(0,4)],h=D[0],m=Q(A,!1),w=m,p=new Set(["0.000000,0.000000"]);for(let S of D.slice(1)){let M=`${S.horizontal.toFixed(6)},${S.vertical.toFixed(6)}`;if(p.has(M))continue;p.add(M);let k=Q(S.transform,!1);k>m&&(h=S,m=k)}let f=m-w;return f>=.01?{transform:h.transform,warp:[h.horizontal,h.vertical],gain:f}:{transform:A,warp:[0,0],gain:f}}function Mt(A,e,o,r){let t=sA(o);if(!t||e<8)return 0;let n=r-1,a=[],c=0,C=0,Q=0,s=0,g=0;for(let f=0;f<Math.min(e,A.length);f++){let S=A[f],[M,k]=U(t,S.x,S.y);if(M<-.5||k<-.5||M>n+.5||k>n+.5)continue;let y=S.fitWeight,b=M*Math.PI*2,G=k*Math.PI*2;c+=Math.cos(b)*y,C+=Math.sin(b)*y,Q+=Math.cos(G)*y,s+=Math.sin(G)*y,g+=y,a.push([M,k,y])}if(a.length<8||g<=0)return 0;let i=Math.atan2(C,c)/(Math.PI*2),B=Math.atan2(s,Q)/(Math.PI*2),E=Math.hypot(c,C)/g,l=Math.hypot(Q,s)/g,I=0,u=0,d=0,D=0;for(let[f,S,M]of a){let k=(iA(f,0,n)/n-.5)*2,y=(iA(S,0,n)/n-.5)*2,b=f-Math.round(f)-i,G=S-Math.round(S)-B,K=b-Math.round(b),P=G-Math.round(G);I+=k*P*M,u+=k*k*M,d+=y*K*M,D+=y*y*M}let h=I/Math.max(.001,u),m=d/Math.max(.001,D),w=Math.abs(i)*E+Math.abs(B)*l,p=Math.abs(h)*l+Math.abs(m)*E;return 1-iA(w/.28+p/.22,0,1)}function pt(A,e,o){let r=sA(e);if(!r||!A.length)return 0;let t=new Float64Array(o),n=new Float64Array(o),a=o-1;for(let C of A){let Q=U(r,C.x1,C.y1),s=U(r,C.x2,C.y2),g=C.orientation==="horizontal"?Q[0]:Q[1],i=C.orientation==="horizontal"?s[0]:s[1],B=C.orientation==="horizontal"?Q[1]:Q[0],E=C.orientation==="horizontal"?s[1]:s[0],l=Math.round((B+E)*.5);if(l<0||l>=o)continue;let I=Math.max(Math.abs(B-l),Math.abs(E-l));if(I>=.45)continue;let u=iA(g,0,a),d=iA(i,0,a),D=Math.abs(d-u),h=(1-I/.45)*(.4+C.coverage*.6)*Math.min(1,D/Math.max(1,a*.35)),m=C.orientation==="horizontal"?t:n;m[l]=Math.max(m[l],h)}let c=0;for(let C=0;C<o;C++)c+=t[C]+n[C];return c/(o*2)}function Ce(A,e,o){let r=sA(e);if(!r||!A.length)return 0;let t=new Float64Array(4),n=o-1;for(let a of A){let c=U(r,a.x1,a.y1),C=U(r,a.x2,a.y2),Q=a.orientation==="horizontal"?c[0]:c[1],s=a.orientation==="horizontal"?C[0]:C[1],g=a.orientation==="horizontal"?c[1]:c[0],i=a.orientation==="horizontal"?C[1]:C[0],B=Math.round((g+i)*.5);if(B!==0&&B!==n)continue;let E=Math.max(Math.abs(g-B),Math.abs(i-B));if(E>=.35)continue;let l=Math.abs(iA(s,0,n)-iA(Q,0,n)),I=(1-E/.35)*(.4+a.coverage*.6)*Math.min(1,l/Math.max(1,n*.35)),d=(a.orientation==="horizontal"?0:2)+ +(B===n);t[d]=Math.max(t[d],I)}return(Math.min(t[0],t[1])+Math.min(t[2],t[3]))*.5}function _o(A,e,o){let r=sA(A);if(!r)return null;let t=o-1,n=[[],[]];for(let Q of e){if(Q.coverage<.625||Q.pointCount<20||Q.featureSupport<4)continue;let s=U(r,Q.x1,Q.y1),g=U(r,Q.x2,Q.y2),i=Q.orientation==="horizontal",B=i?s[0]:s[1],E=i?g[0]:g[1],l=i?s[1]:s[0],I=i?g[1]:g[0],u=(l+I)*.5,d=Math.round(u),D=u-d,h=Math.abs(iA(E,0,t)-iA(B,0,t));d<0||d>t||Math.abs(D)>=.35||Math.abs(l-I)>=.16||h<t*.35||n[i?1:0].push({index:d,value:D,weight:h/t*Q.coverage*Math.sqrt(Math.max(0,Q.score))})}let a=Q=>{if(new Set(Q.map(l=>l.index)).size<4)return 0;let s=[...Q].sort((l,I)=>l.value-I.value),g=s.reduce((l,I)=>l+I.weight,0),i=0,B=0;for(let l of s)if(i+=l.weight,i>=g*.5){B=l.value;break}return Q.reduce((l,I)=>l+I.weight*Math.abs(I.value-B),0)/Math.max(1e-6,g)<=.075&&Math.abs(B)>=.035?B:0},c=a(n[0]),C=a(n[1]);return c===0&&C===0?null:IA(A,[1,0,c,0,1,C,0,0,1])}function $o(A,e,o,r,t,n,a,c,C){let Q=sA(e);if(!Q||o.length<3)return null;let s=t-1,g=new Array(4);for(let D of o){if(D.coverage<.75||D.pointCount<14||D.featureSupport<4)continue;let h=U(Q,D.x1,D.y1),m=U(Q,D.x2,D.y2),w=D.orientation==="horizontal",p=w?h[0]:h[1],f=w?m[0]:m[1],S=w?h[1]:h[0],M=w?m[1]:m[0],k=(S+M)*.5,y=Math.abs(k)<=Math.abs(k-s)?0:s,b=Math.max(Math.abs(S-y),Math.abs(M-y)),G=Math.abs(iA(f,0,s)-iA(p,0,s));if(b>=.45||G<s*.7)continue;let K=Math.hypot(D.x2-D.x1,D.y2-D.y1);if(K<=1)continue;let P=[(D.y1-D.y2)/K,(D.x2-D.x1)/K,(D.x1*D.y2-D.x2*D.y1)/K],R=(1-b/.45)*(G/s)*D.coverage*Math.sqrt(Math.max(0,D.score)),x=(w?0:2)+ +(y===s);(!g[x]||R>g[x].utility)&&(g[x]={line:D,equation:P,utility:R})}if(g.filter(Boolean).length<3)return null;let i=yA(e,s),B=[[g[0],g[2]],[g[0],g[3]],[g[1],g[3]],[g[1],g[2]]],E=i.map((D,h)=>{let[m,w]=B[h];if(m&&w){let f=er(m.equation,w.equation);if(f)return f}let p=m??w;return p?tr(D,p.equation):D});for(let D=0;D<E.length;D++){let[h,m]=U(Q,E[D][0],E[D][1]),w=D===0||D===3?0:s,p=D<2?0:s;if(Math.hypot(h-w,m-p)>.45)return null}let l=OA(E.map((D,h)=>({x:D[0],y:D[1],column:h===0||h===3?0:s,row:h<2?0:s,weight:1,fitWeight:1})));if(!l||!le(E,n,a))return null;let I=dt(g,e,t);if(dt(g,l,t)<I+.12)return null;let d=g.findIndex(D=>!D);return d>=0?Ar(A,l,r,d,t,c,C)??l:l}function Ar(A,e,o,r,t,n,a){let c=sA(e);if(!c)return null;let C=t-1,Q=o.map(l=>U(c,l.x,l.y)),s=(l,I)=>{if(Q.some(y=>{let b=r<2?y[0]:y[1],G=r<2?y[1]:y[0];return Math.abs(b-l)<.48&&Math.abs(G-I)<.58}))return null;let u=r<2?[l,I]:[I,l],d=r<2?[0,.12]:[.12,0],D=U(e,u[0],u[1]),h=RA(A,D[0]/n,D[1]/a),m=[u[0]-d[0],u[1]-d[1]],w=[u[0]+d[0],u[1]+d[1]],p=U(e,m[0],m[1]),f=U(e,w[0],w[1]),S=RA(A,p[0]/n,p[1]/a),M=RA(A,f[0]/n,f[1]/a);if(!h||!S||!M)return null;let k=y=>y[0]*.25+y[1]*.65+y[2]*.1;return Math.min(k(S),k(M))-k(h)-ce(S,M)*.025},g=(l,I)=>{let u=[];for(let m=0;m<C;m++)for(let w of[.25,.5,.75]){let p=m+w,f=l+(I-l)*p/C,S=r%2===0?f:C+f,M=s(p,S);M!==null&&u.push(M)}u.sort((m,w)=>w-m);let d=u.filter(m=>m>.01).length,D=u.slice(0,Math.max(1,Math.ceil(u.length*.45)));return[D.reduce((m,w)=>m+w,0)/D.length*Math.min(1,d/Math.max(1,u.length*.35)),d]},i=g(0,0),B={start:0,end:0,score:i[0],support:i[1]};for(let l=-.4;l<=.2001;l+=.05)for(let I=-.4;I<=.2001;I+=.05){if(Math.abs(l-I)>.3)continue;let u=g(l,I);u[0]>B.score&&(B={start:l,end:I,score:u[0],support:u[1]})}if(B.support<6||B.score<i[0]*1.2||B.score<i[0]+.003)return null;let E=yA(e,C).map(l=>[l[0],l[1]]);return r===0?(E[0]=U(e,0,B.start),E[1]=U(e,C,B.end)):r===1?(E[3]=U(e,0,C+B.start),E[2]=U(e,C,C+B.end)):r===2?(E[0]=U(e,B.start,0),E[3]=U(e,B.end,C)):(E[1]=U(e,C+B.start,0),E[2]=U(e,C+B.end,C)),OA(E.map((l,I)=>({x:l[0],y:l[1],column:I===0||I===3?0:C,row:I<2?0:C,weight:1,fitWeight:1})))}function dt(A,e,o){let r=sA(e);if(!r)return 0;let t=o-1,n=0,a=0;for(let c=0;c<A.length;c++){let C=A[c];if(!C)continue;let Q=c<2,s=c%2===0?0:t,g=U(r,C.line.x1,C.line.y1),i=U(r,C.line.x2,C.line.y2),B=Q?g[1]:g[0],E=Q?i[1]:i[0],l=Math.max(Math.abs(B-s),Math.abs(E-s));n+=Math.max(0,1-l/.45),a++}return n/Math.max(1,a)}function er(A,e){let o=A[0]*e[1]-e[0]*A[1];return Math.abs(o)<1e-5?null:[(A[1]*e[2]-e[1]*A[2])/o,(A[2]*e[0]-e[2]*A[0])/o]}function tr(A,e){let o=e[0]*A[0]+e[1]*A[1]+e[2];return[A[0]-e[0]*o,A[1]-e[1]*o]}function St(A,e,o){let r=sA(e);if(!r)return[0,0,0,0];let t=o-1,n=[0,0,0,0];for(let a of A){let[c,C]=U(r,a.x,a.y),Q=Math.round(c),s=Math.round(C),g=Math.hypot(c-Q,C-s);if(g>=.35||Q<0||Q>t||s<0||s>t)continue;let i=a.weight*(1-g/.35);s===0&&(n[0]=n[0]+i),s===t&&(n[1]=n[1]+i),Q===0&&(n[2]=n[2]+i),Q===t&&(n[3]=n[3]+i)}return n.map(a=>a/o)}function or(A,e){let o=(e-1)*.5,r=n=>Array.from({length:e-1},(a,c)=>{let C=U(A,n?c:o,n?o:c),Q=U(A,n?c+1:o,n?o:c+1);return Math.hypot(Q[0]-C[0],Q[1]-C[1])}),t=0;for(let n of[r(!0),r(!1)]){let a=n.slice(1).map((c,C)=>c/Math.max(.001,n[C]));for(let c of a)t+=Math.max(0,Math.abs(Math.log(c))-.12);for(let c=1;c<a.length;c++)t+=Math.max(0,Math.abs(Math.log(a[c]/a[c-1]))-.035)*2}return Math.max(0,1-t/Math.max(1,e-2))}function tt(A,e,o){return rr(A,e,o,o)}function rr(A,e,o,r){let t=1-o*A-r*e;return[1+o*A,o*e,-o*o*A-o*r*e,r*A,1+r*e,-o*r*A-r*r*e,A,e,t]}function bt(A,e){return A.length<e*e*.9?A:yt(A,e)}function yt(A,e){let o=A.reduce((t,n)=>Math.max(t,n.score),0),r=A.filter(t=>t.score>=o*.5&&t.surroundDrop>=.84&&Math.max(t.horizontalContinuation,t.verticalContinuation)<=.5);return r.length>=Math.max(12,e*1.5)?r:A}function nr(A,e,o,r,t){let n=t?.55:A.intersectionCandidates.length>=12?1.4:.8,a=t?1.15:A.intersectionCandidates.length>=12?.7:1,c=t?1.1:.8,C=e.map(s=>({x:s.x*o,y:s.y*r,weight:a*(.8+s.score),fitWeight:(.8+s.score)*c})),Q=[...A.intersectionCandidates].sort((s,g)=>g.score-s.score);for(let s of Q){let g={x:s.x*o,y:s.y*r,weight:n*(.8+s.score),fitWeight:n*(.8+s.score)};C.some(i=>Sr(i,g)<3.2**2)||C.push(g)}return C}function kt(A,e,o,r){let t=e.resizedWidth,n=e.resizedHeight,a=new Uint8Array(t*n),c=new Uint8Array(t*n),C=new Uint8Array(t*n),Q=Math.max(.025,e.maxLocalHorizontalScore*.2),s=Math.max(.025,e.maxLocalVerticalScore*.2),g=(i,B,E,l)=>{let I=Math.floor(B),u=Math.floor(E),d=l*l;for(let D=-l;D<=l;D++){let h=u+D;if(!(h<0||h>=n))for(let m=-l;m<=l;m++){let w=I+m;w<0||w>=t||m*m+D*D>d||(i[h*t+w]=1)}}};for(let i of A)i.horizontalScore>=Q&&g(a,i.x,i.y,1),i.verticalScore>=s&&g(c,i.x,i.y,1);for(let i of e.candidates)g(C,i.x*o,i.y*r,Math.max(1,Math.round(i.refinedDiameter*.45)));return{width:t,height:n,horizontal:a,vertical:c,stones:C}}function se(A,e,o){let r=Qe(A,e,o);return(Math.min(r[0],r[1])+Math.min(r[2],r[3]))*.5}function Qe(A,e,o){let r=o-1,t=[0,0,0,0],n=(a,c)=>{let C=Math.floor(c[0]),Q=Math.floor(c[1]);return C>=0&&C<A.width&&Q>=0&&Q<A.height?a[Q*A.width+C]:0};for(let a=0;a<o;a++){let c=n(A.vertical,U(e,a,.5)),C=n(A.vertical,U(e,a,r-.5)),Q=n(A.horizontal,U(e,.5,a)),s=n(A.horizontal,U(e,r-.5,a)),g=c&&!n(A.vertical,U(e,a,-.5)),i=C&&!n(A.vertical,U(e,a,r+.5)),B=Q&&!n(A.horizontal,U(e,-.5,a)),E=s&&!n(A.horizontal,U(e,r+.5,a));t[0]=t[0]+Number(g||n(A.stones,U(e,a,0))),t[1]=t[1]+Number(i||n(A.stones,U(e,a,r))),t[2]=t[2]+Number(B||n(A.stones,U(e,0,a))),t[3]=t[3]+Number(E||n(A.stones,U(e,r,a)))}return t.map(a=>a/o)}function ir(A,e,o,r,t,n,a,c=A){let C=Math.min(42,Math.min(t,n)/Math.max(6,a-1)*2.2),Q=new Float64Array(UA),s=c.length*(c.length-1)/2,g={dx:new Float64Array(s),dy:new Float64Array(s),angle:new Float64Array(s),weight:new Float64Array(s),length:0};for(let P=0;P<c.length;P++)for(let R=P+1;R<c.length;R++){let x=c[R].x-c[P].x,z=c[R].y-c[P].y,F=Math.hypot(x,z);if(F<5.5||F>C)continue;let N=nt(Math.atan2(z,x),Math.PI),q=Math.sqrt(c[P].weight*c[R].weight)/Math.sqrt(F),Y=Math.round(N/Math.PI*UA)%UA;Q[Y]=Q[Y]+q,g.dx[g.length]=x,g.dy[g.length]=z,g.angle[g.length]=N,g.weight[g.length]=q,g.length++}pr(Q);let i=null,B=0;for(let P=0;P<UA;P++)for(let R=P+1;R<UA;R++){let x=xt(P*Math.PI/UA,R*Math.PI/UA);if(x<Math.PI*.3||x>Math.PI*.7)continue;let z=Math.exp(-(((x-Math.PI/2)/.42)**2)),F=Math.sqrt(Q[P]*Q[R])*(.45+.55*z);F>B&&(B=F,i=[P,R])}if(!i)return null;let E=mt(g,i[0]*Math.PI/UA),l=mt(g,i[1]*Math.PI/UA);Math.abs(E[0])<Math.abs(l[0])&&([E,l]=[l,E]),E[0]<0&&(E=[-E[0],-E[1]]),xA(E,l)<0&&(l=[-l[0],-l[1]]);let I=Ge(g,E,C),u=Ge(g,l,C);if(!I.length||!u.length)return null;let d=Ir(r),D=(P,R)=>Pe(P).filter(x=>Math.abs(x-R)<=1.5),h=et(A,o,E,l,D([...I,...d],I[0]),D([...u,...d],u[0])),m=et(A,o,E,l,[I[0]],[u[0]]);if(!h||!m)return null;let w=At(A,e,h,a,t,n),p=At(A,e,m,a,t,n),f=w-p>=.01?h:m,S=w-p>=.01?w:p,M=[I[0],u[0]],k=ke(o,!0,a*5,!0)??ke(o,!0,a*5,!1),y=ke(o,!1,a*5,!0)??ke(o,!1,a*5,!1);if(k&&y&&Math.abs(xA(k,y))>=.15){let P=Ge(g,k,C),R=Ge(g,y,C);if(P.length&&R.length){let x=et(A,o,k,y,D([...P,...d],P[0]),D([...R,...d],R[0]));if(x){let z=At(A,e,x,a,t,n);z>=S+.01&&(f=x,S=z,M=[P[0],R[0]])}}}let{score:b,...G}=f,K=ar(A,o,f,a);return{...G,pairSpacing:M,seedGain:h.score-m.score,seedFitGain:w-p,linePerspectiveEstimate:K.warp,linePerspectiveConfidence:K.confidence,linePerspectiveAxisConfidence:K.axisConfidence}}function ke(A,e,o,r){let t=new Float64Array(81),n=0;for(let Q of A){let s=r?e?Q.strongHorizontalSlope:Q.strongVerticalSlope:e?Q.horizontalSlope:Q.verticalSlope,g=e?Q.horizontalScore:Q.verticalScore,i=r?e?Q.horizontalSlopeConfidence??0:Q.verticalSlopeConfidence??0:1;if(s==null||g<=0)continue;i>=.5&&n++;let B=Math.max(0,Math.min(t.length-1,Math.round((s+.5)*(t.length-1))));t[B]=t[B]+g*g*i*i}if(n<o)return null;Pt(t);let a=0;for(let Q=1;Q<t.length;Q++)t[Q]>t[a]&&(a=Q);if(t[a]<=0)return null;let c=a/(t.length-1)-.5,C=Math.hypot(1,c);return e?[1/C,c/C]:[c/C,1/C]}function ar(A,e,o,r){let t=vt(o),n=sA(t);if(!n||e.length<r*8)return{warp:[0,0],confidence:0,axisConfidence:[0,0]};let a=A.map(u=>U(n,u.x,u.y)),c=[PA(a.map(u=>u[0]),.5),PA(a.map(u=>u[1]),.5)],C=PA(a.map(u=>u[0]),.05)-1,Q=PA(a.map(u=>u[0]),.95)+1,s=PA(a.map(u=>u[1]),.05)-1,g=PA(a.map(u=>u[1]),.95)+1,i=Math.max(1,Math.ceil(e.length/2500)),B=e.filter((u,d)=>d%i===0),E=gr(B,n,c,[C,Q,s,g],r),l=iA((Math.hypot(...E.warp)-1e-4)/2e-4,0,1),I=E.axisConfidence.map(u=>u*l);return{warp:E.warp,confidence:Math.max(...I),axisConfidence:I}}function gr(A,e,o,r,t){let n=new Map,a=new Map,c=(g,i,B,E,l)=>{if(l<=0)return;let I=g.get(i)??{weight:0,coordinate:0,position:0,coordinateSquared:0,coordinatePosition:0,minimum:B,maximum:B};I.weight+=l,I.coordinate+=B*l,I.position+=E*l,I.coordinateSquared+=B*B*l,I.coordinatePosition+=B*E*l,I.minimum=Math.min(I.minimum,B),I.maximum=Math.max(I.maximum,B),g.set(i,I)};for(let g of A){let[i,B]=U(e,g.x,g.y);if(i<r[0]||i>r[1]||B<r[2]||B>r[3])continue;let E=Math.round(i),l=Math.round(B);Math.abs(i-E)<=.48&&c(n,E,B,i,g.verticalScore),Math.abs(B-l)<=.48&&c(a,l,i,B,g.horizontalScore)}let C=(g,i)=>{let B=[];for(let[m,w]of g){let p=m-i,f=w.maximum-w.minimum,S=w.coordinateSquared-w.coordinate*w.coordinate/Math.max(.001,w.weight);if(Math.abs(p)<2.5||f<t*.32||S<.1)continue;let k=(w.coordinatePosition-w.coordinate*w.position/Math.max(.001,w.weight))/S,y=iA(-k/p,-.014,.014);B.push({value:y,weight:w.weight*Math.min(1,f/(t*.75))*Math.min(8,Math.abs(p))})}if(B.length<3)return{warp:0,confidence:0};B.sort((m,w)=>m.value-w.value);let E=B.reduce((m,w)=>m+w.weight,0),l=0,I=0;for(let m of B)if(l+=m.weight,l>=E*.5){I=m.value;break}let u=B.filter(m=>Math.abs(m.value-I)<=.0045),d=u.reduce((m,w)=>m+w.weight,0),D=u.reduce((m,w)=>m+w.value*w.weight,0)/Math.max(.001,d),h=Math.min(1,B.length/8)*d/Math.max(.001,E);return{warp:iA(D,-.014,.014),confidence:h}},Q=C(a,o[1]),s=C(n,o[0]);return{warp:[Q.warp,s.warp],confidence:Math.max(Q.confidence,s.confidence),axisConfidence:[Q.confidence,s.confidence]}}function vt(A){return[A.horizontal[0]*A.horizontalSpacing,A.vertical[0]*A.verticalSpacing,A.horizontal[0]*A.horizontalPhase+A.vertical[0]*A.verticalPhase,A.horizontal[1]*A.horizontalSpacing,A.vertical[1]*A.verticalSpacing,A.horizontal[1]*A.horizontalPhase+A.vertical[1]*A.verticalPhase,0,0,1]}function FA(A,e,o){let r=[...e],t=[];for(let n of o){t=SA(A,r,n);let a=t.length>=8?OA(t):null;if(!a)return null;r=a}return t=SA(A,r,.25),t.length>=8?{transform:r,assigned:t}:null}function At(A,e,o,r,t,n){let a=[o.horizontal[0]*o.horizontalSpacing,o.vertical[0]*o.verticalSpacing,o.horizontal[0]*o.horizontalPhase+o.vertical[0]*o.verticalPhase,o.horizontal[1]*o.horizontalSpacing,o.vertical[1]*o.verticalSpacing,o.horizontal[1]*o.horizontalPhase+o.vertical[1]*o.verticalPhase,0,0,1],c=FA(A,a,[.34,.27,.23]);if(!c)return-1/0;let{transform:C,assigned:Q}=c,s=A.reduce((B,E)=>B+E.weight,0),g=rt(e,C),i=-1/0;for(let B of xe(Q,r,"column"))for(let E of xe(Q,r,"row")){let l=IA(C,[1,0,B,0,1,E,0,0,1]);if(!le(yA(l,r-1),t,n))continue;let I=Q.reduce((d,D)=>d+(D.column>=B&&D.column<B+r&&D.row>=E&&D.row<E+r?D.weight:-D.weight*.8),0),u=g?.score(B,E,r)??0;i=Math.max(i,I/Math.max(1,s)+u*.18)}return i}function Ir(A){let e=[];return A.candidates.some(o=>o.diameter===16&&o.score>=.08)&&e.push(14,15),A.squareCandidates.some(o=>o.size===16&&o.score>=.08)&&e.push(15),e}function et(A,e,o,r,t,n){let a=Uo?uA():null;if(a&&A.length<=a.y()&&e.length<=a.l()&&t.length>0&&t.length<=6&&n.length>0&&n.length<=6){let c=new Float64Array(a.a.buffer,a.z(),A.length*3);A.forEach((Q,s)=>{c[s*3]=Q.x,c[s*3+1]=Q.y,c[s*3+2]=Q.weight});let C=new Float64Array(a.a.buffer,a.A(),e.length*4);if(e.forEach((Q,s)=>{C[s*4]=Q.x,C[s*4+1]=Q.y,C[s*4+2]=Q.horizontalScore,C[s*4+3]=Q.verticalScore}),new Float64Array(a.a.buffer,a.B(),4).set([...o,...r]),new Float64Array(a.a.buffer,a.C(),t.length).set(t),new Float64Array(a.a.buffer,a.D(),n.length).set(n),a.al(A.length,e.length,t.length,n.length)===0){let Q=new Float64Array(a.a.buffer,a.E(),5);return{score:Q[0],horizontal:o,vertical:r,horizontalSpacing:Q[1],verticalSpacing:Q[2],horizontalPhase:Q[3],verticalPhase:Q[4]}}}return sr(A,e,o,r,t,n)}function sr(A,e,o,r,t,n){let a=xA(o,r);if(Math.abs(a)<.15)return null;let c=A.map(s=>({horizontal:xA(s,r)/a,vertical:xA(o,s)/a,weight:s.weight})),C=e.map(s=>({horizontal:xA(s,r)/a,vertical:xA(o,s)/a,horizontalScore:s.horizontalScore,verticalScore:s.verticalScore})),Q=null;for(let s of t.slice(0,6)){let g=Pe([Fe(c.map(i=>({coordinate:i.horizontal,weight:i.weight})),s),Fe(C.map(i=>({coordinate:i.horizontal,weight:i.verticalScore})).filter(i=>i.weight>0),s)],.15);for(let i of n.slice(0,6)){let B=Pe([Fe(c.map(E=>({coordinate:E.vertical,weight:E.weight})),i),Fe(C.map(E=>({coordinate:E.vertical,weight:E.horizontalScore})).filter(E=>E.weight>0),i)],.15);for(let E of g)for(let l of B){let I=c.reduce((m,w)=>{let p=ve(w.horizontal,E,s),f=ve(w.vertical,l,i),S=Math.hypot(p,f);return m+w.weight*Math.max(0,1-S/.32)},0)/Math.max(1,c.reduce((m,w)=>m+w.weight,0)),u=0,d=0;for(let m of C){let w=ve(m.horizontal,E,s),p=ve(m.vertical,l,i);u+=m.verticalScore*Math.max(0,1-w/.2)+m.horizontalScore*Math.max(0,1-p/.2),d+=m.horizontalScore+m.verticalScore}let D=u/Math.max(1,d),h=I+D*2.2;(!Q||h>Q.score)&&(Q={score:h,horizontal:o,vertical:r,horizontalSpacing:s,verticalSpacing:i,horizontalPhase:E,verticalPhase:l})}}}return Q}function cr(A){if(!Ke||Ae===A)return;let e=uA();if(!e||A.width>e.F()||A.height>e.F()){Ae=null;return}new Uint8Array(e.a.buffer,e.G(),A.data.byteLength).set(A.data),Ae=A}function ve(A,e,o){let r=(A-e)/o;return Math.abs(r-Math.round(r))}function mt(A,e){let o=0,r=0;for(let n=0;n<A.length;n++){let a=A.angle[n],c=A.weight[n];xt(a,e)>Math.PI/18||(o+=Math.cos(a*2)*c,r+=Math.sin(a*2)*c)}let t=Math.atan2(r,o)*.5;return[Math.cos(t),Math.sin(t)]}function Ge(A,e,o){let t=new Float64Array(Math.ceil(o*4)+1);for(let a=0;a<A.length;a++){let c=A.dx[a],C=A.dy[a],Q=Math.abs(c*e[0]+C*e[1]),s=Math.abs(c*e[1]-C*e[0]);if(Q<5.5||s>Q*.28)continue;let g=Math.round(Q*4);g<t.length&&(t[g]=t[g]+A.weight[a]/Math.sqrt(Q))}Pt(t);let n=[];for(let a=Math.ceil(5.5*4);a<t.length;a++){let c=t[a]/Math.sqrt(a/4);c<=0||a>0&&t[a]<t[a-1]||a+1<t.length&&t[a]<t[a+1]||n.push({spacing:a/4,score:c})}return n.sort((a,c)=>c.score-a.score),Pe(n.map(a=>a.spacing)).slice(0,4)}function Pe(A,e=.65){let o=[];for(let r of A)Number.isFinite(r)&&!o.some(t=>Math.abs(t-r)<e)&&o.push(r);return o}function Fe(A,e){let o=0,r=0;for(let t of A){let n=t.coordinate/e*Math.PI*2;o+=Math.cos(n)*t.weight,r+=Math.sin(n)*t.weight}return nt(Math.atan2(r,o)/(Math.PI*2)*e,e)}function SA(A,e,o){let r=sA(e);if(!r)return[];let t=[];for(let n of A){let[a,c]=U(r,n.x,n.y),C=Math.round(a),Q=Math.round(c);Math.hypot(a-C,c-Q)>o||t.push({...n,column:C,row:Q})}return t}function OA(A){let e=Array.from({length:8},()=>new Float64Array(8)),o=new Float64Array(8),r=(n,a,c)=>{for(let C=0;C<8;C++){o[C]=o[C]+n[C]*a*c;for(let Q=0;Q<8;Q++)e[C][Q]=e[C][Q]+n[C]*n[Q]*c}};for(let n of A){let{column:a,row:c,weight:C,x:Q,y:s}=n;r([a,c,1,0,0,0,-a*Q,-c*Q],Q,C),r([0,0,0,a,c,1,-a*s,-c*s],s,C)}let t=Mr(e,o);return t?[...t,1]:null}function xe(A,e,o){let r=A.map(c=>c[o]),t=Math.min(...r)-e+1,n=Math.max(...r),a=[];for(let c=t;c<=n;c++){let C=0;for(let Q of A){let s=Q[o];C+=s>=c&&s<c+e?Q.weight:-Q.weight*.8}a.push({start:c,score:C})}return a.sort((c,C)=>C.score-c.score).slice(0,1).map(c=>c.start)}function bA(A,e,o,r,t){let n=Ke?uA():null;if(n&&Ae===A&&(new Float64Array(n.a.buffer,n.H(),9).set(e),n.J(A.width,A.height,o,r,t)===0)){let a=new Float64Array(n.a.buffer,n.I(),12);return Array.from({length:4},(c,C)=>({margin:a[C*3],score:a[C*3+1],confidence:a[C*3+2]}))}return[0,1,2,3].map(a=>hr(A,e,o,r,t,a))}function Cr(A,e,o){let r=o-1,t=[1,0,0,0,1,0,0,0,1],n=!1,a=(c,C,Q,s)=>{if(Math.min(c.confidence,C.confidence)<.75||Math.abs(c.margin-C.margin)<.75)return;let g=c.margin-C.margin;g>0?(t[Q]=1+g/r,t[s]=-g):t[Q]=1-g/r,n=!0};return a(e[0],e[1],0,2),a(e[2],e[3],4,5),n?IA(A,t):A}function Qr(A,e,o,r,t){let n=Ke?uA():null;if(n&&Ae===A&&(new Float64Array(n.a.buffer,n.H(),9).set(e),n.L(A.width,A.height,o,r,t)===0))return Array.from(new Float64Array(n.a.buffer,n.I(),4));let a=t-1;return[0,1,2,3].map(c=>{let C=[];for(let Q=0;Q<a;Q++){let s=Q+.5,[g,i]=Ft(c,0,s,a,.35),B=U(e,g[0],g[1]),E=U(e,i[0],i[1]),l=RA(A,B[0]/o,B[1]/r),I=RA(A,E[0]/o,E[1]/r);l&&I&&C.push(ce(l,I))}return C.length>=a*.6?iA(1-PA(C,.5)/.12,0,1):0})}function lr(A,e,o,r,t){let n=t-1,a=C=>C[0]*.25+C[1]*.65+C[2]*.1,c=(C,Q)=>{let s=U(e,C[0],C[1]),g=Q?[0,.28]:[.28,0],i=U(e,C[0]-g[0],C[1]-g[1]),B=U(e,C[0]+g[0],C[1]+g[1]),E=RA(A,s[0]/o,s[1]/r),l=RA(A,i[0]/o,i[1]/r),I=RA(A,B[0]/o,B[1]/r);return!E||!l||!I?null:Math.max(a(l),a(I))-a(E)};return[0,1,2,3].map(C=>{let Q=[];for(let g=0;g<t;g++){let i=C%2===0?0:n,B=C%2===0?1:-1,E=C<2,l=E?[i+B*.35,g]:[g,i+B*.35],I=E?[i-B*.35,g]:[g,i-B*.35],u=c(l,E),d=c(I,E);u===null||d===null||Q.push(Math.max(0,u)-Math.max(0,d))}Q.sort((g,i)=>i-g);let s=Q.slice(0,Math.max(1,Math.ceil(Q.length*.55)));return s.reduce((g,i)=>g+i,0)/s.length})}function Br(A,e,o,r,t,n,a,c,C,Q,s){let g=o.reduce((b,G)=>b+G.weight,0),i=bA(A,e,c,C,Q),B=Qe(a,e,Q),E=(Math.min(B[0],B[1])+Math.min(B[2],B[3]))*.5,l=(b,G,K,P,R)=>{if(Math.abs(b.margin-G.margin)>=1.25)return[-2,-1,0,1,2];let x=Math.min(b.confidence,G.confidence),z=Math.max(b.confidence,G.confidence);return x<=.1&&z>=.75?[-2,-1,0,1,2]:Math.min(P,R)<=.35&&Math.abs(P-R)>=.15?[-1,0,1]:K>1||z<.5?[-1,0,1]:[0]},I=l(i[0],i[1],s[0],B[2],B[3]),u=l(i[2],i[3],s[1],B[0],B[1]),d=rt(t,e),D=s[0]>1!=s[1]>1,h=[];for(let b of u)for(let G of I){let K=IA(e,[1,0,G,0,1,b,0,0,1]),P=SA(o,K,.23).filter(T=>T.column>=0&&T.column<Q&&T.row>=0&&T.row<Q),R=P.reduce((T,J)=>T+J.weight,0),x=d?.score(G,b,Q)??0,z=Ce(n,K,Q),F=Qe(a,K,Q),N=St(r,K,Q),q=Math.min(N[0],N[1])+Math.min(N[2],N[3]),Y=q*q*8,j=(Math.min(F[2],F[3])*s[0]+Math.min(F[0],F[1])*s[1])*.5;h.push({score:R/Math.max(1,g)*2.2+x*1.5+j+z*1.5+Y,transform:K,points:P,shiftX:G,shiftY:b})}h.sort((b,G)=>G.score-b.score);let m=s[0]>1&&s[1]>1,w=E<.4&&!m&&(Math.abs(i[0].margin-i[1].margin)>=1||Math.abs(i[2].margin-i[3].margin)>=1),p=w?h:h.slice(0,5),f=h.find(b=>b.shiftX===0&&b.shiftY===0);f&&!p.includes(f)&&p.push(f);let S=null;for(let b of p){let G=bA(A,b.transform,c,C,Q),K=mr(G,D?.4:.5),R=Qr(A,b.transform,c,C,Q).reduce((q,Y)=>q+Y,0)/4*.8,x=G.reduce((q,Y)=>q+Y.confidence,0)/4,z=m?Dr(G,i):0,F=w?ur(G,i):0,N=b.score+K*1.7+R+x*.8+z+F*2.5;(!S||N>S.score)&&(S={score:N,transform:b.transform,sides:G,points:b.points})}if(!S)return{transform:e,sides:bA(A,e,c,C,Q),points:[]};let M=S.transform,k=S.sides,y=S.points;for(let b=0;b<1;b++){let G=Er(A,M,k,c,C,Q,y.length);if(G===M)break;let K=sA(G),P=K?o.filter(x=>{let[z,F]=U(K,x.x,x.y);return z>=-1&&F>=-1&&z<=Q&&F<=Q}):o;M=FA(P,G,[.6,.45,.32,.24])?.transform??G,k=bA(A,M,c,C,Q),y=SA(o,M,.23).filter(x=>x.column>=0&&x.column<Q&&x.row>=0&&x.row<Q)}return{transform:M,sides:k,points:y}}function Er(A,e,o,r,t,n,a){if(n<13||Math.max(...o.map(i=>i.confidence))<.2)return e;let c=[o[0].confidence<.2||o[1].confidence<.2,o[2].confidence<.2||o[3].confidence<.2];if(!c[0]&&!c[1])return e;let C=[0,1,2,3].map(i=>c[i>>1]?fr(A,e,r,t,n,i):{margin:-.5,score:0}),Q=[1,0,0,0,1,0,0,0,1],s=n-1,g=(i,B,E,l)=>{let I=C[i],u=C[B],d=I.score-o[i].score,D=u.score-o[B].score,h=a<n*5,m=o[B].confidence>=.2,w=o[i].confidence>=.2,p=o[i].confidence<.2&&I.score>=.075&&d>=.035&&d>=D&&(Math.abs(I.margin)<=1||h&&m),f=o[B].confidence<.2&&u.score>=.075&&D>=.035&&D>d&&(Math.abs(u.margin)<=1||h&&w);if(!p&&!f)return;let S=.75,M=p?-I.margin+S:u.margin-S;o[p?B:i].confidence>=.75?p?(Q[E]=(s-M)/s,Q[l]=M):Q[E]=(s+M)/s:Q[l]=M};return g(0,1,0,2),g(2,3,4,5),Q[2]===0&&Q[5]===0&&Q[0]===1&&Q[4]===1?e:IA(e,Q)}function Dr(A,e){let o=(r,t,n,a)=>Math.abs(n.margin-a.margin)>=2&&Math.min(n.confidence,a.confidence)>=.8&&Math.min(r.confidence,t.confidence)>=.8?Math.max(0,1-Math.abs(r.margin-t.margin)/1.5):0;return o(A[0],A[1],e[0],e[1])+o(A[2],A[3],e[2],e[3])}function ur(A,e){let o=(r,t,n,a)=>Math.abs(n.margin-a.margin)>=1&&Math.min(r.confidence,t.confidence)>=.5?Math.max(0,1-Math.abs(r.margin-t.margin)/1.5):0;return o(A[0],A[1],e[0],e[1])+o(A[2],A[3],e[2],e[3])}function dr(A){let e=(o,r)=>Math.min(o.confidence,r.confidence)>=.5?Math.min(o.confidence,r.confidence)*(1+o.score+r.score):0;return e(A[0],A[1])+e(A[2],A[3])}function mr(A,e=.5){let o=(r,t)=>Math.min(r,t)>=e?Math.min(r,t):0;return(o(A[0].confidence,A[1].confidence)+o(A[2].confidence,A[3].confidence))/2}function rt(A,e){let o=sA(e);if(!o||!A.length)return null;let r=[],t=[],n=0;for(let s of A){let[g,i]=U(o,s.x,s.y);n+=s.horizontalScore+s.verticalScore;let B=Math.abs(i-Math.round(i));if(B<.22){let l=Math.round(i),I=U(e,g-.5,l),u=U(e,g+.5,l),d=(u[1]-I[1])/Math.max(.001,Math.abs(u[0]-I[0])),D=s.horizontalSlopeConfidence??0,h=s.strongHorizontalSlope==null?1:Math.max(0,1-Math.abs(s.strongHorizontalSlope-d)/.22),m=1-D+D*h;r.push([g,s.horizontalScore*(1-B/.22)*(.35+m*.65)])}let E=Math.abs(g-Math.round(g));if(E<.22){let l=Math.round(g),I=U(e,l,i-.5),u=U(e,l,i+.5),d=(u[0]-I[0])/Math.max(.001,Math.abs(u[1]-I[1])),D=s.verticalSlopeConfidence??0,h=s.strongVerticalSlope==null?1:Math.max(0,1-Math.abs(s.strongVerticalSlope-d)/.22),m=1-D+D*h;t.push([i,s.verticalScore*(1-E/.22)*(.35+m*.65)])}}let a=s=>{s.sort((B,E)=>B[0]-E[0]);let g=new Float64Array(s.length),i=new Float64Array(s.length+1);for(let B=0;B<s.length;B++)g[B]=s[B][0],i[B+1]=i[B]+s[B][1];return{coordinates:g,prefix:i}},c=a(r),C=a(t),Q=(s,g,i)=>{let B=0,E=s.coordinates.length;for(;B<E;){let I=B+E>>>1;s.coordinates[I]<g?B=I+1:E=I}let l=B;for(E=s.coordinates.length;B<E;){let I=B+E>>>1;s.coordinates[I]<=i?B=I+1:E=I}return s.prefix[B]-s.prefix[l]};return{score(s,g,i){let B=i-1+.2,E=Q(c,s-.2,s+B),l=Q(C,g-.2,g+B);return(E+l)/Math.max(1,n)}}}function wr(A,e,o){let r=sA(e);if(!r||!A.length)return 0;let t=o-1,n=0,a=0;for(let c of A){let[C,Q]=U(r,c.x,c.y);if(a+=c.horizontalScore+c.verticalScore,C>=-.2&&C<=t+.2){let s=Math.abs(Q-Math.round(Q));if(s<.22){let g=Math.round(Q),i=U(e,C-.5,g),B=U(e,C+.5,g),E=(B[1]-i[1])/Math.max(.001,Math.abs(B[0]-i[0])),l=c.horizontalSlopeConfidence??0,I=c.strongHorizontalSlope==null?1:Math.max(0,1-Math.abs(c.strongHorizontalSlope-E)/.22),u=1-l+l*I;n+=c.horizontalScore*(1-s/.22)*(.35+u*.65)}}if(Q>=-.2&&Q<=t+.2){let s=Math.abs(C-Math.round(C));if(s<.22){let g=Math.round(C),i=U(e,g,Q-.5),B=U(e,g,Q+.5),E=(B[0]-i[0])/Math.max(.001,Math.abs(B[1]-i[1])),l=c.verticalSlopeConfidence??0,I=c.strongVerticalSlope==null?1:Math.max(0,1-Math.abs(c.strongVerticalSlope-E)/.22),u=1-l+l*I;n+=c.verticalScore*(1-s/.22)*(.35+u*.65)}}}return n/Math.max(1,a)}function hr(A,e,o,r,t,n){let a=Gt(A,e,o,r,t,n,Array.from({length:11},(g,i)=>.5+i*.25));a.sort((g,i)=>i.score-g.score);let c=a[0]??{margin:1,score:0},C=PA(a.map(g=>g.score),.55),Q=iA((c.score-.035)/.14,0,1),s=iA((c.score-C)/.08,0,1);return{margin:c.margin,score:c.score,confidence:Q*(.35+.65*s)}}function fr(A,e,o,r,t,n){let a=Ke?uA():null;if(a&&Ae===A&&(new Float64Array(a.a.buffer,a.H(),9).set(e),a.K(A.width,A.height,o,r,t,n)===0)){let C=new Float64Array(a.a.buffer,a.I(),2);return{margin:C[0],score:C[1]}}let c=Gt(A,e,o,r,t,n,Array.from({length:24},(C,Q)=>-.25-Q*.25));return c.sort((C,Q)=>Q.score-C.score),c[0]??{margin:-.5,score:0}}function Gt(A,e,o,r,t,n,a){let c=[];for(let C of a){let Q=[],s=[],g=[],i=[],B=null;for(let d=0;d<28;d++){let D=.35+(t-1-.7)*d/27,[h,m]=Ft(n,C,D,t-1),w=U(e,h[0],h[1]),p=U(e,m[0],m[1]),f=RA(A,w[0]/o,w[1]/r),S=RA(A,p[0]/o,p[1]/r);!f||!S||(g.push(f),i.push(S),Q.push(ce(f,S)),B&&s.push(ce(B,f)),B=f)}if(Q.length<14){c.push({margin:C,score:0});continue}let E=PA(Q,.3),l=ce(wt(g),wt(i)),I=Math.min(E,l*1.35),u=s.length?PA(s,.55):0;c.push({margin:C,score:Math.max(0,I-u*.3)})}return c}function Ft(A,e,o,r,t=.18){return A===0?[[-e+t,o],[-e-t,o]]:A===1?[[r+e-t,o],[r+e+t,o]]:A===2?[[o,-e+t],[o,-e-t]]:[[o,r+e-t],[o,r+e+t]]}function RA(A,e,o){if(e<0||o<0||e>=A.width||o>=A.height)return null;let r=Math.max(0,Math.min(A.width-1,Math.round(e))),n=(Math.max(0,Math.min(A.height-1,Math.round(o)))*A.width+r)*4;return[A.data[n]/255,A.data[n+1]/255,A.data[n+2]/255]}function ce(A,e){let o=A[0]+A[1]+A[2]+.08,r=e[0]+e[1]+e[2]+.08,t=Math.hypot(A[0]/o-e[0]/r,A[1]/o-e[1]/r,A[2]/o-e[2]/r),n=Math.abs(Math.log((.25*A[0]+.65*A[1]+.1*A[2]+.04)/(.25*e[0]+.65*e[1]+.1*e[2]+.04)));return t*1.7+n*.2}function wt(A){return[0,1,2].map(e=>PA(A.map(o=>o[e]),.5))}function le(A,e,o){let r=Math.abs(br(A));if(r<e*o*.045||r>e*o*2.5)return!1;let t=A.map((n,a)=>Math.hypot(n[0]-A[(a+1)%4][0],n[1]-A[(a+1)%4][1]));return Math.min(...t)>Math.min(e,o)*.16&&Math.max(...t)/Math.min(...t)<5}function yA(A,e){return[U(A,0,0),U(A,e,0),U(A,e,e),U(A,0,e)]}function U(A,e,o){let r=A[6]*e+A[7]*o+A[8];return[(A[0]*e+A[1]*o+A[2])/r,(A[3]*e+A[4]*o+A[5])/r]}function sA(A){let[e,o,r,t,n,a,c,C,Q]=A,s=e*(n*Q-a*C)-o*(t*Q-a*c)+r*(t*C-n*c);return Math.abs(s)<1e-10?null:[(n*Q-a*C)/s,(r*C-o*Q)/s,(o*a-r*n)/s,(a*c-t*Q)/s,(e*Q-r*c)/s,(r*t-e*a)/s,(t*C-n*c)/s,(o*c-e*C)/s,(e*n-o*t)/s]}function IA(A,e){return Array.from({length:9},(o,r)=>{let t=Math.floor(r/3),n=r%3;return A[t*3]*e[n]+A[t*3+1]*e[n+3]+A[t*3+2]*e[n+6]})}function Mr(A,e){let o=e.length,r=A.map((t,n)=>new Float64Array([...t,e[n]]));for(let t=0;t<o;t++){let n=t;for(let c=t+1;c<o;c++)Math.abs(r[c][t])>Math.abs(r[n][t])&&(n=c);if(Math.abs(r[n][t])<1e-9)return null;[r[t],r[n]]=[r[n],r[t]];let a=r[t][t];for(let c=t;c<=o;c++)r[t][c]=r[t][c]/a;for(let c=0;c<o;c++){if(c===t)continue;let C=r[c][t];for(let Q=t;Q<=o;Q++)r[c][Q]=r[c][Q]-C*r[t][Q]}}return Float64Array.from(r.map(t=>t[o]))}function pr(A){let e=A.slice();for(let o=0;o<A.length;o++)A[o]=e[o]+.65*(e[(o+A.length-1)%A.length]+e[(o+1)%A.length])+.25*(e[(o+A.length-2)%A.length]+e[(o+2)%A.length])}function Pt(A){let e=A.slice();for(let o=1;o+1<A.length;o++)A[o]=e[o]+.6*(e[o-1]+e[o+1])}function xt(A,e){return Math.abs(nt(A-e+Math.PI/2,Math.PI)-Math.PI/2)}function nt(A,e){return(A%e+e)%e}function xA(A,e){let o="x"in A?A.x:A[0],r="y"in A?A.y:A[1],t="x"in e?e.x:e[0],n="y"in e?e.y:e[1];return o*n-r*t}function Sr(A,e){return(A.x-e.x)**2+(A.y-e.y)**2}function br(A){return A.reduce((e,o,r)=>{let t=A[(r+1)%A.length];return e+o[0]*t[1]-o[1]*t[0]},0)*.5}function PA(A,e){if(!A.length)return 0;let o=[...A].sort((r,t)=>r-t);return o[Math.min(o.length-1,Math.floor((o.length-1)*e))]}function iA(A,e,o){return Math.max(e,Math.min(o,A))}function yr(A,e,o){let r=o/Math.min(A,e);return[Math.max(1,Math.round(A*r)),Math.max(1,Math.round(e*r))]}async function Ee(A,e,o){if(e<=0||o<=0)throw new Error("browser resize dimensions must be positive");let r=performance.now(),t=await createImageBitmap(A,{resizeWidth:e,resizeHeight:o,resizeQuality:"high"}),n=typeof document>"u"?new OffscreenCanvas(e,o):document.createElement("canvas");n.width=e,n.height=o;let a=n.getContext("2d",{alpha:!1});if(!a)throw new Error("2D canvas unavailable for browser resize");return a.drawImage(t,0,0),t.close(),{image:a.getImageData(0,0,e,o),elapsedMs:performance.now()-r}}async function Kt(A,e){let[o,r]=yr(A.width,A.height,e);return Ee(A,o,r)}function Wt(A,e,o=4,r=[]){let t=performance.now(),n=128,a=Math.max(64,Math.round(n*A.height/A.width)),c=Pr(A,n,a),C=r.map(f=>de(c,f[0]/A.width*n,f[1]/A.height*a,n,a)),Q=[...Nt(C,4),...Nt(c)].filter((f,S,M)=>M.findIndex(k=>De(f,k)<.18)===S),s=c.map(f=>+(f.warm>=0&&f.light>=-1.45&&f.light<=.08)),g=Fr(c,s),i=Ut(s,n,a,4),B=[...g?[{seed:g,raw:s}]:[],...Q.map(f=>({seed:f,raw:c.map(S=>+(De(S,f)<=1))}))],E=[],l=g?vr(i,n,a):null,I=l?Tt(l):null;if(I&&g){let f=zt(i,I,n,a),S=it(I),M=Ot(c,I,g,n,a),k=qt(c,I,n,a),y=Math.abs(ue(I))/i.length,b=Math.min(1,y/.28),G=b*1.2+f+S*.6+M.combined*2.4+k.score*3+g.warm*5,K=Rt(I,n,a,A.width,A.height),P=Rt(k.gridCorners,n,a,A.width,A.height);Jt(K,A.width,A.height)&&E.push({quad:K,score:G,support:i.reduce((R,x)=>R+x,0),confidence:Math.min(1,Math.max(0,(G-3)/2.6)),textureScore:k.score,fallbackScore:b*1.2+f+S*.6+M.line*2.4+k.score*3+g.warm*5,shapeGridCorners:P,shapeGridConfidence:k.gridConfidence,method:"scanline"})}for(let{seed:f,raw:S}of B){let M=Ut(S,n,a,S===s?4:2);for(let k of xr(M,n,a,3)){if(k.area<M.length*.035||k.area>M.length*.82)continue;let y=Kr(k.cells.map(P=>[P%n+.5,Math.floor(P/n)+.5]));if(y.length<4)continue;let b=Rr(y);if(!b)continue;let G=Tt(b),K=Lr(c,G,f,n,a);for(let P of K?[G,K]:[G]){let R=Math.abs(ue(P));if(R<M.length*.06||R>M.length*1.08)continue;let x=zt(M,P,n,a),z=it(P);if(x<.3||z<.13)continue;let F=Ot(c,P,f,n,a),N=qt(c,P,n,a),q=N.score,Y=R/M.length,j=Math.min(1,Y/.28),T=j*1.2+x+z*.6+F.combined*2.4+q*3+f.warm*5,J=j*1.2+x+z*.6+F.line*2.4+q*3+f.warm*5,L=P.map($=>[$[0]/n*A.width,$[1]/a*A.height]),V=N.gridCorners.map($=>[$[0]/n*A.width,$[1]/a*A.height]);Jt(L,A.width,A.height)&&E.push({quad:L,score:T,support:k.area,confidence:Math.min(1,Math.max(0,(T-3)/2.6)),textureScore:q,fallbackScore:J,shapeGridCorners:V,shapeGridConfidence:N.gridConfidence,method:"component"})}}}let u=performance.now()-t,d=Math.hypot(A.width,A.height),D=[],h=[...E].sort((f,S)=>S.score-f.score),m=[...E].sort((f,S)=>S.fallbackScore-f.fallbackScore),w=[h[0],m[0],h[1],...h].filter(f=>f!==void 0);for(let f of w)if(!(f.confidence<.08||D.some(S=>f.quad.reduce((M,k,y)=>M+Math.hypot(k[0]-S.quad[y][0],k[1]-S.quad[y][1]),0)/4<d*.045))&&(D.push(f),D.length>=o))break;let p=h.find(f=>f.method==="component")?.quad;return D.flatMap(f=>{let S=f.method==="scanline"&&p?kr(f.quad,p):[0,1,2,3],M=S.map(b=>f.quad[b]),k=S.map(b=>f.shapeGridCorners[b]),y=Le(M,e-1);return y?[{gridToSource:y,gridCorners:M,support:f.support,extentSupport:f.support,analysisMs:u,source:"color",confidence:f.confidence,score:f.score,textureScore:f.textureScore,shapeGridCorners:k,shapeGridConfidence:f.shapeGridConfidence,method:f.method}]:[]})}function kr(A,e){let o=[];for(let r=0;r<4;r++)o.push([0,1,2,3].map(t=>(t+r)%4)),o.push([0,3,2,1].map(t=>(t+r)%4));return o.reduce((r,t)=>{let n=t.reduce((a,c,C)=>{let Q=A[c],s=e[C];return a+Math.hypot(Q[0]-s[0],Q[1]-s[1])},0);return n<r.score?{order:t,score:n}:r},{order:o[0],score:1/0}).order}function Rt(A,e,o,r,t){return A.map(n=>[n[0]/e*r,n[1]/o*t])}function vr(A,e,o){let r=[];for(let g=0;g<o;g++){let i=Lt(A,g*e,1,e);i&&i.length>=e*.3&&i.length<e*.98&&r.push({independent:g+.5,low:i.start,high:i.end})}let t=[];for(let g=0;g<e;g++){let i=Lt(A,g,e,o);i&&i.length>=o*.3&&i.length<o*.98&&t.push({independent:g+.5,low:i.start,high:i.end})}if(r.length<o*.25||t.length<e*.25)return null;let n=Re(r.map(g=>[g.independent,g.low])),a=Re(r.map(g=>[g.independent,g.high])),c=Re(t.map(g=>[g.independent,g.low])),C=Re(t.map(g=>[g.independent,g.high]));if(!n||!a||!c||!C)return null;let Q=(g,i)=>{let B=1-g[0]*i[0];if(Math.abs(B)<.08)return null;let E=(i[0]*g[1]+i[1])/B;return[g[0]*E+g[1],E]},s=[Q(n,c),Q(a,c),Q(a,C),Q(n,C)];return s.every(g=>g!==null)?s:null}function Lt(A,e,o,r){let t=0,n=0,a=0,c=0;for(let C=0;C<=r;C++){if(C<r&&A[e+C*o]){c||(a=C),c++;continue}c>n&&(t=a,n=c),c=0}return n?{start:t+.5,end:t+n-.5,length:n}:null}function Re(A){let e=A,o=null;for(let r=0;r<3;r++){if(o=Gr(e),!o||e.length<8)return null;let t=e.map(c=>Math.abs(c[1]-o[0]*c[0]-o[1])),n=[...t].sort((c,C)=>c-C),a=Math.max(1.5,n[Math.floor(n.length*.7)]*1.8);e=e.filter((c,C)=>t[C]<=a)}return o}function Gr(A){if(A.length<2)return null;let e=A.reduce((n,a)=>n+a[0],0)/A.length,o=A.reduce((n,a)=>n+a[1],0)/A.length,r=0,t=0;for(let n of A)r+=(n[0]-e)*(n[1]-o),t+=(n[0]-e)**2;return t>1e-6?[r/t,o-r/t*e]:null}function Fr(A,e){let o=0,r=0,t=0,n=0;for(let a=0;a<A.length;a++){if(!e[a])continue;let c=A[a];o++,r+=c.warm,t+=c.redGreen,n+=c.light}return o<A.length*.03?null:{warm:r/o,redGreen:t/o,light:n/o}}function Pr(A,e,o){let r=[];for(let t=0;t<o;t++){let n=Math.min(A.height-1,Math.floor((t+.5)/o*A.height));for(let a=0;a<e;a++){let c=Math.min(A.width-1,Math.floor((a+.5)/e*A.width)),C=(n*A.width+c)*4,Q=A.data[C]/255,s=A.data[C+1]/255,g=A.data[C+2]/255,i=Math.max(.12,Q+s+g);r.push({warm:(Q+s-g*2)/i,redGreen:(Q-s)/i,light:Math.log(.08+i/3)})}}return r}function Nt(A,e=12){let o=new Map;for(let r of A){if(r.warm<.08||r.light<-1.35||r.light>.04)continue;let t=Math.max(0,Math.min(11,Math.floor((r.warm+.05)*13))),n=Math.max(0,Math.min(9,Math.floor((r.redGreen+.18)*24))),a=Math.max(0,Math.min(7,Math.floor((r.light+1.35)*5.7))),c=t*80+n*8+a,C=o.get(c)??{count:0,warm:0,redGreen:0,light:0};C.count++,C.warm+=r.warm,C.redGreen+=r.redGreen,C.light+=r.light,o.set(c,C)}return[...o.values()].filter(r=>r.count>=A.length*.004).sort((r,t)=>t.count-r.count).slice(0,e).map(r=>({warm:r.warm/r.count,redGreen:r.redGreen/r.count,light:r.light/r.count}))}function De(A,e){let o=(A.warm-e.warm)/.105,r=(A.redGreen-e.redGreen)/.075,t=(A.light-e.light)/.52;return o*o+r*r+t*t}function Ut(A,e,o,r){let t=Uint8Array.from(A);for(let n=0;n<r;n++)t=Yt(t,e,o,!0);for(let n=0;n<r;n++)t=Yt(t,e,o,!1);return t}function Yt(A,e,o,r){let t=new Uint8Array(A.length);for(let n=0;n<o;n++)for(let a=0;a<e;a++){let c=r?0:1;for(let C=-1;C<=1;C++)for(let Q=-1;Q<=1;Q++){let s=a+Q,g=n+C,i=s>=0&&s<e&&g>=0&&g<o?A[g*e+s]:0;c=r?Math.max(c,i):Math.min(c,i)}t[n*e+a]=c}return t}function xr(A,e,o,r){let t=new Uint8Array(A.length),n=new Int32Array(A.length),a=[];for(let c=0;c<A.length;c++){if(!A[c]||t[c])continue;let C=0,Q=1;n[0]=c,t[c]=1;let s=[];for(;C<Q;){let g=n[C++];s.push(g);let i=Math.floor(g/e),B=g-i*e;for(let E=-1;E<=1;E++)for(let l=-1;l<=1;l++){if(!l&&!E)continue;let I=B+l,u=i+E;if(I<0||I>=e||u<0||u>=o)continue;let d=u*e+I;!A[d]||t[d]||(t[d]=1,n[Q++]=d)}}a.push({cells:s,area:s.length,seedSupport:s.length})}return a.sort((c,C)=>C.area-c.area).slice(0,r)}function Kr(A){let e=[...A].sort((a,c)=>a[0]-c[0]||a[1]-c[1]),o=(a,c,C)=>(c[0]-a[0])*(C[1]-a[1])-(c[1]-a[1])*(C[0]-a[0]),r=a=>{let c=[];for(let C of a){for(;c.length>=2&&o(c.at(-2),c.at(-1),C)<=0;)c.pop();c.push(C)}return c},t=r(e),n=r(e.reverse());return t.pop(),n.pop(),[...t,...n]}function Rr(A){let e=[...A];for(;e.length>4;){let o=0,r=1/0;for(let t=0;t<e.length;t++){let n=e[(t+e.length-1)%e.length],a=e[t],c=e[(t+1)%e.length],C=Math.abs((a[0]-n[0])*(c[1]-n[1])-(a[1]-n[1])*(c[0]-n[0]));C<r&&(r=C,o=t)}e.splice(o,1)}return e.length===4?e:null}function Tt(A){let e=[A.reduce((n,a)=>n+a[0],0)/4,A.reduce((n,a)=>n+a[1],0)/4],o=[...A].sort((n,a)=>Math.atan2(n[1]-e[1],n[0]-e[0])-Math.atan2(a[1]-e[1],a[0]-e[0])),r=0;for(let n=1;n<o.length;n++)o[n][0]+o[n][1]<o[r][0]+o[r][1]&&(r=n);let t=o.map((n,a)=>o[(r+a)%4]);return ue(t)>0?t:[t[0],t[3],t[2],t[1]]}function ue(A){return A.reduce((e,o,r)=>{let t=A[(r+1)%A.length];return e+o[0]*t[1]-t[0]*o[1]},0)*.5}function it(A){let e=A.map((o,r)=>{let t=A[(r+1)%4];return Math.hypot(t[0]-o[0],t[1]-o[1])});return Math.min(...e)/Math.max(...e)}function zt(A,e,o,r){let t=Math.max(0,Math.floor(Math.min(...e.map(s=>s[0])))),n=Math.min(o-1,Math.ceil(Math.max(...e.map(s=>s[0])))),a=Math.max(0,Math.floor(Math.min(...e.map(s=>s[1])))),c=Math.min(r-1,Math.ceil(Math.max(...e.map(s=>s[1])))),C=0,Q=0;for(let s=a;s<=c;s++)for(let g=t;g<=n;g++)Tr(g+.5,s+.5,e)&&(C++,Q+=A[s*o+g]);return Q/Math.max(1,C)}function Lr(A,e,o,r,t){let n=[e.reduce((s,g)=>s+g[0],0)/4,e.reduce((s,g)=>s+g[1],0)/4],a=e.map((s,g)=>{let i=e[(g+1)%4],B=Math.atan2(i[1]-s[1],i[0]-s[0]),E=[(s[0]+i[0])*.5,(s[1]+i[1])*.5],l=jt(s,i),I=at(A,l,o,r,t);for(let u=-12;u<=12;u+=3){let d=B+u*Math.PI/180,D=[Math.cos(d),Math.sin(d)],h=[-D[1],D[0]];(n[0]-E[0])*h[0]+(n[1]-E[1])*h[1]<0&&(h=[-h[0],-h[1]]);let m=Math.max(0,(n[0]-E[0])*h[0]+(n[1]-E[1])*h[1]),w=Math.min(Math.max(r,t)*.38,m*.82);for(let p=0;p<=w;p+=1.5){let f=[E[0]+h[0]*p,E[1]+h[1]*p],S={a:h[0],b:h[1],c:-(h[0]*f[0]+h[1]*f[1])},M=at(A,S,o,r,t);M>I&&(l=S,I=M)}}return l}),c=a.map((s,g)=>Nr(a[(g+3)%4],s));if(c.some(s=>!s))return null;let C=c;return Math.abs(ue(C))>=r*t*.055&&it(C)>=.12?C:null}function jt(A,e){let o=Math.max(1e-6,Math.hypot(e[0]-A[0],e[1]-A[1])),r=-(e[1]-A[1])/o,t=(e[0]-A[0])/o;return{a:r,b:t,c:-(r*A[0]+t*A[1])}}function Nr(A,e){let o=A.a*e.b-e.a*A.b;return Math.abs(o)<1e-5?null:[(A.b*e.c-e.b*A.c)/o,(A.c*e.a-e.c*A.a)/o]}function at(A,e,o,r,t){let n=[-e.b,e.a],a=[-e.a*e.c,-e.b*e.c],c=Math.abs(n[0])*r+Math.abs(n[1])*t,C=0,Q=0,s=0;for(let g=-c*.45;g<=c*.45;g+=1.5){let i=a[0]+n[0]*g,B=a[1]+n[1]*g;if(i<2||i>=r-2||B<2||B>=t-2)continue;let E=de(A,i+e.a*2,B+e.b*2,r,t),l=de(A,i-e.a*2,B-e.b*2,r,t),I=Yr(E,l),u=Math.max(0,Math.min(2,De(l,o))-Math.min(2,De(E,o)));C+=Math.min(2,I)*.55+u*.45,Q+=+(I>=.32),s++}return s?C/s*.7+Q/s*.3:0}function Ot(A,e,o,r,t){let n=e.reduce((c,C,Q)=>c+at(A,jt(C,e[(Q+1)%4]),o,r,t),0)/4,a=Ur(A,e,o,r,t);return{combined:n*.3+a*.7,line:n}}function Ur(A,e,o,r,t){let n=e.map((c,C)=>{let Q=e[(C+1)%4],s=Q[0]-c[0],g=Q[1]-c[1],i=Math.max(1e-6,Math.hypot(s,g)),B=[-g/i,s/i],E=0,l=0;for(let I=2;I<22;I++){let u=I/23,d=c[0]+s*u,D=c[1]+g*u,h=p=>De(de(A,d+B[0]*p,D+B[1]*p,r,t),o),m=Math.min(h(2),h(4)),w=(h(-2)+h(-4))*.5;m>1.6||(E+=Math.max(0,Math.min(1,(w-m)/1.2)),l++)}return E/Math.max(5,l)});return n.reduce((c,C)=>c+C,0)/4*.55+Math.min(...n)*.45}function de(A,e,o,r,t){let n=Math.max(0,Math.min(r-1,Math.round(e))),a=Math.max(0,Math.min(t-1,Math.round(o)));return A[a*r+n]}function Yr(A,e){return Math.abs(A.warm-e.warm)/.1+Math.abs(A.redGreen-e.redGreen)/.075+Math.abs(A.light-e.light)/.45}function Tr(A,e,o){let r=0;for(let t=0;t<4;t++){let n=o[t],a=o[(t+1)%4],c=(a[0]-n[0])*(e-n[1])-(a[1]-n[1])*(A-n[0]);if(Math.abs(c)<1e-6)continue;let C=Math.sign(c);if(r&&C!==r)return!1;r=C}return!0}function qt(A,e,o,r){let n=Le(e,1);if(!n)return{score:0,gridCorners:e,gridConfidence:0};let a=new Float32Array(9216);for(let m=0;m<96;m++){let w=(m+.5)/96;for(let p=0;p<96;p++){let f=(p+.5)/96,S=n[6]*f+n[7]*w+n[8],M=(n[0]*f+n[1]*w+n[2])/S,k=(n[3]*f+n[4]*w+n[5])/S;a[m*96+p]=de(A,M,k,o,r).light}}let c=new Float32Array(96),C=new Float32Array(96),Q=0,s=0;for(let m=3;m<93;m++)for(let w=3;w<93;w++){let p=m*96+w,f=a[p-2],S=a[p+2],M=a[p-192],k=a[p+192],y=a[p];C[w]=C[w]+Math.max(0,(f+S)*.5-y),c[m]=c[m]+Math.max(0,(M+k)*.5-y);let b=Math.abs(y*2-f-S),G=Math.abs(y*2-M-k),K=Math.abs(y*4-a[p-192-2]-a[p-192+2]-a[p+192-2]-a[p+192+2])*.5,P=Math.max(b,G,K),R=Math.min(b,G,K);P>=.12&&(Q+=R/P*Math.min(1,P/.35),s++)}let g=Ht(c),i=Ht(C),B=Math.sqrt(g.score*i.score),E=Q/Math.max(24,s),l=(m,w)=>(m.phase+w*m.spacing+.5)/96,I=(m,w)=>{let p=n[6]*m+n[7]*w+n[8];return[(n[0]*m+n[1]*w+n[2])/p,(n[3]*m+n[4]*w+n[5])/p]},u=l(i,0),d=l(i,18),D=l(g,0),h=l(g,18);return{score:Math.min(1,B*.82+E*.18),gridCorners:[I(u,D),I(d,D),I(d,h),I(u,h)],gridConfidence:B}}function Ht(A){let e=0;for(let n of A)e+=n;e/=A.length;let o=0;for(let n of A)o+=(n-e)**2;if(o<1e-5)return{score:0,phase:2,spacing:5};let r=Math.sqrt(o/A.length),t={score:0,phase:2,spacing:5};for(let n=3.4;n<=5.41;n+=.2){let a=A.length-1-n*18;for(let c=1;c<=a;c+=1){let C=0,Q=0;for(let i=0;i<19;i++){let B=Math.round(c+i*n),E=Math.max(A[Math.max(0,B-1)],A[B],A[Math.min(A.length-1,B+1)]);C+=E,Q+=+(E>=e+r*.15)}let g=Math.max(0,Math.min(1,(C/19-e)/Math.max(1e-6,r*1.5)))*.65+Q/19*.35;g>t.score&&(t={score:g,phase:c,spacing:n})}}return t}function Jt(A,e,o){let r=Math.abs(ue(A));if(r<e*o*.055||r>e*o*1.15)return!1;let t=A.map((n,a)=>{let c=A[(a+1)%4],C=A[(a+2)%4];return(c[0]-n[0])*(C[1]-c[1])-(c[1]-n[1])*(C[0]-c[0])});return t.every(n=>n>0)||t.every(n=>n<0)}function Le(A,e){let[o,r,t,n]=A,a=r[0]-t[0],c=n[0]-t[0],C=o[0]-r[0]+t[0]-n[0],Q=r[1]-t[1],s=n[1]-t[1],g=o[1]-r[1]+t[1]-n[1],i=a*s-c*Q;if(Math.abs(i)<1e-8||e<=0)return null;let B=(C*s-c*g)/i,E=(a*g-C*Q)/i;return[(r[0]-o[0]+B*r[0])/e,(n[0]-o[0]+E*n[0])/e,o[0],(r[1]-o[1]+B*r[1])/e,(n[1]-o[1]+E*n[1])/e,o[1],B/e,E/e,1]}function Zt(A,e,o){let r=Or(e.gridToSource);if(!r)return{stone:0,line:0,combined:0};let t=o-1,n=(d,D)=>{let h=r[6]*d+r[7]*D+r[8];return[(r[0]*d+r[1]*D+r[2])/h,(r[3]*d+r[4]*D+r[5])/h]},a=A.candidates.flatMap(d=>{if(d.surroundDrop<.45||Math.max(d.horizontalContinuation,d.verticalContinuation)>=.62)return[];let D=n(d.x,d.y);return D[0]>=-2&&D[0]<=t+2&&D[1]>=-2&&D[1]<=t+2?[{point:D,weight:.5+d.score}]:[]}),c=a.map(({point:d,weight:D})=>({value:d[0],weight:D})),C=a.map(({point:d,weight:D})=>({value:d[1],weight:D})),Q=Ne(c,t),s=Ne(C,t),g=zr(a,Q,s,t),i=[],B=[];for(let d of A.gridLines){let D=n(d.x1,d.y1),h=n(d.x2,d.y2),m=h[0]-D[0],w=h[1]-D[1],p=Math.hypot(m,w);if(p<.7)continue;let f=Math.max(Math.abs(m),Math.abs(w))/p;if(f<.88)continue;let S=Math.min(3,p)*d.coverage*d.score*f**3;Math.abs(w)>Math.abs(m)?i.push({value:(D[0]+h[0])*.5,weight:S}):B.push({value:(D[1]+h[1])*.5,weight:S})}let E=Ne(i,t),l=Ne(B,t),I=Math.sqrt(E.score*l.score),u=Math.sqrt(Xt(Q,E)*Xt(s,l));return{stone:g,line:I,combined:Math.max(g,I)*.75+Math.min(g,I)*.15+u*Math.min(g,I)*.1}}function Ne(A,e){if(A.length<4)return{score:0,phase:0,spacing:1};let o={score:0,phase:0,spacing:1};for(let r=.7;r<=1.02;r+=.025){let t=e-e*r+1.5;for(let n=-1.5;n<=t;n+=r/12){let a=0,c=0,C=new Set,Q=1/0,s=-1/0;for(let E of A){let l=Math.round((E.value-n)/r);if(l<0||l>e)continue;let I=Math.abs(E.value-n-l*r)/r,u=Math.max(0,1-I/.3)**2;a+=E.weight*u,c+=E.weight,u>=.35&&C.add(l),Q=Math.min(Q,l),s=Math.max(s,l)}if(c<=0)continue;let g=Math.min(1,C.size/8),i=s>=Q?Math.min(1,(s-Q)/Math.max(6,e*.55)):0,B=a/c*Math.sqrt(g*i);B>o.score&&(o={score:B,phase:n,spacing:r})}}return o}function zr(A,e,o,r){if(!e.score||!o.score)return 0;let t=0,n=0;for(let a of A){let c=(Q,s)=>{let g=Math.round((Q-s.phase)/s.spacing);return g<0||g>r?1:Math.abs(Q-s.phase-g*s.spacing)/s.spacing},C=Math.hypot(c(a.point[0],e),c(a.point[1],o));t+=a.weight*Math.max(0,1-C/.38)**2,n+=a.weight}return t/Math.max(1e-6,n)*Math.sqrt(e.score*o.score)}function Xt(A,e){if(!A.score||!e.score)return 0;let o=1-Math.min(1,Math.abs(A.spacing-e.spacing)/.15),r=Math.abs(A.phase-e.phase),t=1-Math.min(1,Math.min(r,Math.abs(r-A.spacing))/.25);return o*t}function Or(A){let[e,o,r,t,n,a,c,C,Q]=A,s=e*(n*Q-a*C)-o*(t*Q-a*c)+r*(t*C-n*c);return Math.abs(s)<1e-9?null:[(n*Q-a*C)/s,(r*C-o*Q)/s,(o*a-r*n)/s,(a*c-t*Q)/s,(e*Q-r*c)/s,(r*t-e*a)/s,(t*C-n*c)/s,(o*c-e*C)/s,(e*n-o*t)/s]}var It="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/",ee="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_";function qr(A){let e=new Uint8Array(Math.ceil(A.length*6/8)),o=0,r=0,t=0;for(let n of A){let a=ee.indexOf(n);if(a<0)throw new Error(`Invalid URL-safe character: ${n}`);o=o<<6|a,r+=6,r>=8&&(r-=8,e[t++]=o>>r&255,o&=(1<<r)-1)}return r>0&&(e[t]=o<<8-r&255),e}function Hr(A,e){let o="",r=0,t=0;for(let n of A)for(r=r<<8|n,t+=8;t>=6;)t-=6,o+=ee[r>>t&63],r&=(1<<t)-1;if(e){if(o.at(-1)!==ee[0])throw new Error("Invalid URL-safe length marker");o=o.slice(0,-1)}return o}function Jr(A){let e=0,o=-1;for(let t=0;t<A.length;t++){let n=A.charCodeAt(t);n!==13&&n!==10&&n!==32&&(e++,o=t)}return e%4===1&&o>=0&&A.charCodeAt(o)===61?[A.slice(0,o)+A.slice(o+1),!0]:[A,!1]}var gt=(()=>{let A=new Array(256);A.fill(-2,0,256);let e=It.length;for(let o=0;o<e;++o)A[It.charCodeAt(o)]=o;return A[ee.charCodeAt(62)]=62,A[ee.charCodeAt(63)]=63,A[13]=-1,A[10]=-1,A[32]=-1,A[10]=-1,A[61]=0,A})(),te=class A{static fromString(e,o="utf8",r={}){if(o!=="urlsafe")return A.encode(Buffer.from(e,o),r);let t=A.encode(qr(e),r);return e.length%4===3&&(t+="="),t}static toString(e,o="utf8"){if(o!=="urlsafe")return Buffer.from(A.decode(e)).toString(o);let[r,t]=Jr(e);return Hr(A.decode(r),t)}static encode(e,{lineSize:o=0,noPadding:r=!1,urlSafe:t=!1}={}){let n=e.length;if(n===0)return"";let a=t?ee:It,c=n%3,C=n-c,Q=Math.floor(n/3)*4+(c>0?4:0);r&&c>0&&(Q-=3-c);let s=o>>2;s>0&&(Q+=Math.floor((Q-1)/(s<<2))<<1);let g=new Array(Q),i=0,B=0,E=0;for(;B<C;){let l=e[B++]%256<<16&16777215|e[B++]%256<<8&16777215|e[B++]%256;g[i++]=a.charCodeAt(l>>18),g[i++]=a.charCodeAt(l>>12&63),g[i++]=a.charCodeAt(l>>6&63),g[i++]=a.charCodeAt(l&63),s>0&&++E===s&&i<Q-2&&(g[i++]=13,g[i++]=10,E=0)}if(c===1){let l=e[B]%256;g[i++]=a.charCodeAt(l>>2),g[i++]=a.charCodeAt(l<<4&63),r||(g[i++]=61,g[i++]=61)}else if(c===2){let l=e[B]%256,I=e[B+1]%256;g[i++]=a.charCodeAt(l>>2),g[i++]=a.charCodeAt((l<<4|I>>4)&63),g[i++]=a.charCodeAt(I<<2&63),r||(g[i++]=61)}return String.fromCharCode(...g)}static decode(e){let o=e.length;if(o===0)return[];let r=0;for(let C=0;C<o;C++){let Q=gt[e.charCodeAt(C)];if(Q<0&&(r++,Q===-2))throw new Error(`Invalid character: ${e[C]}`)}let t=(o-r)%4;if(t===1)throw new Error("Size of Base 64 characters in Input must be a multiple of 4. Input: $input");t>1&&(e+="=".repeat(4-t),o=e.length);let n=0;for(let C=o-1;C>=0;C--){let Q=e.charCodeAt(C);if(gt[Q]>0)break;Q===61&&n++}let a=((o-r)*6>>3)-n,c=new Array(a);for(let C=0,Q=0;Q<a;){let s=0;for(let g=4;g>0;){let i=gt[e.charCodeAt(C++)];i>=0&&(s=s<<6&16777215|i,g--)}c[Q++]=s>>16,Q<a&&(c[Q++]=s>>8&255,Q<a&&(c[Q++]=s&255))}return c}};var JA=class A{i=0;j=0;S=new Array(256);static fromString(e,o=2,r="utf8"){return new A([...Buffer.from(e,r),0],o)}constructor(e,o=2){for(let t=0;t<256;++t)this.S[t]=t;let r=e.length;for(let t=0;t<o;++t){let n=0;for(let a=0;a<256;++a){let c=e[a%r];n=n+this.S[a]+c&255;let C=this.S[a];this.S[a]=this.S[n],this.S[n]=C}}}xorBytes(e){let o,r=e.length;for(let t=0;t<r;++t)this.i=this.i+1&255,this.j=this.j+this.S[this.i]&255,o=this.S[this.i],this.S[this.i]=this.S[this.j],this.S[this.j]=o,e[t]^=this.S[this.S[this.i]+this.S[this.j]&255]}encryptBytes(e){let o,r=e.length;for(let t=0;t<r;++t)this.i=this.i+1&255,this.j=this.j+this.S[this.i]&255,o=this.S[this.i],this.S[this.i]=this.S[this.j],this.S[this.j]=o,e[t]^=this.S[this.S[this.i]+this.S[this.j]&255],this.j=this.j+e[t]&255}decryptBytes(e){let o,r=e.length;for(let t=0;t<r;++t){this.i=this.i+1&255,this.j=this.j+this.S[this.i]&255,o=this.S[this.i],this.S[this.i]=this.S[this.j],this.S[this.j]=o;let n=e[t];e[t]^=this.S[this.S[this.i]+this.S[this.j]&255],this.j=this.j+n&255}}nextByte(){this.i=this.i+1&255,this.j=this.j+this.S[this.i]&255;let e=this.S[this.i];return this.S[this.i]=this.S[this.j],this.S[this.j]=e,this.S[this.S[this.i]+this.S[this.j]&255]}nextInt(e){let o=e,r=this.nextByte();do r=r<<8|this.nextByte(),r>=e&&(r%=e),o>>=6;while(o!==0);return r}};var Wr=[11,13,17,19];function jr(A){return A.length%4===1&&A.endsWith("=")?[A.slice(0,-1),!0]:[A,!1]}function Xr(A){let e=new JA([A.length,...Wr],3);return A.map(o=>{let[r,t]=jr(o),n=te.decode(r);e.decryptBytes(n);let a=te.encode(n,{noPadding:!0,urlSafe:!0});return t&&(a+="="),te.toString(a,"urlsafe")})}function Ue(A,...e){try{let o=typeof A!="string",r=o?A:globalThis,t=o?e:[A,...e],n=r;for(let a of Xr(t)){if(n==null)return;n=n[a]}return n}catch{return}}var Zr=globalThis;Zr.Buffer??={from:A=>new TextEncoder().encode(A)};function Vr(){let A=JA.fromString(String(Ue("MyK2sqMa","cV6RWJa"))+Ue("1Nwd6tiERW")).S;return Uint8Array.from(A)}var st=!0,_r=!0,$r=!0;function io(){let A=uA()?.ai()??0;return Number.isFinite(A)&&A>0?A:0}function ao(){return uA()?.aj()===1}function we(A){return A===9?100:A===13?180:256}var An=19,en=256,Vt=1.3;function go(A){let e=A-1+Vt*2,o=An-1+Vt*2;return Math.max(1,Math.round(en*e/o))}var Te=10,oe=16,me=oe-Te+1,CA=`#version 300 es
4
+ const vec2 positions[3] = vec2[3](vec2(-1.0, -1.0), vec2(3.0, -1.0), vec2(-1.0, 3.0)); void main() { gl_Position = vec4(positions[gl_VertexID], 0.0, 1.0); }`,tn=`#version 300 es
5
+ precision highp float; precision highp int; uniform sampler2D sourceImage; uniform ivec2 sourceSize; uniform ivec2 outputSize; out vec4 outputColor; vec3 sampleImage(vec2 point) { ivec2 pixel = clamp(ivec2(floor(point + 0.5)), ivec2(0), sourceSize - ivec2(1)); return texelFetch(sourceImage, pixel, 0).rgb; } vec2 direction(int index) { if (index == 0) return vec2(1.0, 0.0); if (index == 1) return vec2(0.70710678, 0.70710678); if (index == 2) return vec2(0.0, 1.0); if (index == 3) return vec2(-0.70710678, 0.70710678); if (index == 4) return vec2(-1.0, 0.0); if (index == 5) return vec2(-0.70710678, -0.70710678); if (index == 6) return vec2(0.0, -1.0); return vec2(0.70710678, -0.70710678); } void main() { vec2 center = gl_FragCoord.xy / vec2(outputSize) * vec2(sourceSize); float bestWhite = 0.0; float bestBlack = 0.0; float bestSize = 0.0; float bestWarmth = 0.0; for (int size = 4; size <= 9; ++size) { float radius = float(size) * 0.5; float white = 0.0; float black = 0.0; float whiteCoverage = 0.0; float blackCoverage = 0.0; float warmth = 0.0; for (int index = 0; index < 8; ++index) { vec2 axis = direction(index); vec3 inner = sampleImage(center + axis * radius * 0.30); vec3 outer = sampleImage(center + axis * radius * 1.20); float whiteContrast = inner.b - outer.b; float blackContrast = outer.g - inner.g; white += max(0.0, whiteContrast); black += max(0.0, blackContrast); whiteCoverage += step(0.025, whiteContrast); blackCoverage += step(0.025, blackContrast); warmth += max( 0.0, (outer.r + outer.g - 2.0 * outer.b) / (outer.r + outer.g + outer.b + 0.1) ); } white = white / 8.0 * smoothstep(0.5, 0.875, whiteCoverage / 8.0); black = black / 8.0 * smoothstep(0.5, 0.875, blackCoverage / 8.0); float score = max(white, black); if (score > max(bestWhite, bestBlack)) { bestWhite = white; bestBlack = black; bestSize = float(size); bestWarmth = warmth / 8.0; } } float boardSupport = 0.35 + 0.65 * smoothstep(0.02, 0.18, bestWarmth); outputColor = vec4( bestWhite, bestBlack, bestSize, max(bestWhite, bestBlack) * boardSupport ); }`,on=`#version 300 es
6
+ precision highp float; precision highp int; uniform sampler2D lineImage; uniform ivec2 imageSize; out vec4 outputColor; vec2 lineScores(float packed) { float encoded = floor(floor(packed) / 256.0); return vec2(floor(encoded / 256.0), mod(encoded, 256.0)) / 255.0; } vec2 lineSlopes(float packed) { float encoded = floor(floor(packed) / 256.0); float localDirections = floor(encoded / 81.0); return vec2( floor(localDirections / 9.0) / 8.0 - 0.5, mod(localDirections, 9.0) / 8.0 - 0.5 ); } float arm(ivec2 center, ivec2 direction, bool horizontal) { float total = 0.0; for (int distance = 1; distance <= 4; ++distance) { float best = 0.0; for (int offset = -2; offset <= 2; ++offset) { ivec2 point = center + direction * distance + (horizontal ? ivec2(0, offset) : ivec2(offset, 0)); vec4 packed = texelFetch(lineImage, point, 0); vec2 scores = lineScores(packed.r); vec2 slopes = lineSlopes(packed.g); float projected = horizontal ? float(point.y) + slopes.x * float(center.x - point.x) : float(point.x) + slopes.y * float(center.y - point.y); float alignment = max( 0.0, 1.0 - abs(projected - float(horizontal ? center.y : center.x)) / 1.5 ); best = max( best, (horizontal ? scores.x : scores.y) * (0.35 + alignment * 0.65) ); } total += best; } return total * 0.25; } void main() { ivec2 center = ivec2(gl_FragCoord.xy); if (center.x < 5 || center.y < 5 || center.x + 5 >= imageSize.x || center.y + 5 >= imageSize.y) { outputColor = vec4(0.0); return; } outputColor = vec4( arm(center, ivec2(-1, 0), true), arm(center, ivec2(1, 0), true), arm(center, ivec2(0, -1), false), arm(center, ivec2(0, 1), false) ); }`,rn=`#version 300 es
7
+ precision highp float; precision highp int; uniform sampler2D sourceImage; uniform ivec2 outputSize; uniform float positiveSums[7]; uniform float negativeWeights[7]; uniform float squareInnerWeights[7]; uniform float squareBorderWeights[7]; uniform int squareKernelMode; uniform int colorFeatureMode; uniform int intersectionMode; uniform int lineKernelMode; uniform int postprocessEnabled; uniform int stoneMinimumWindow; uniform int stoneMaximumWindow; uniform int squareMinimumWindow; uniform int squareMaximumWindow; uniform int postprocessWhiteMode; uniform int postprocessBlackMode; uniform float postprocessWhiteSquarePenalty; uniform float postprocessBlackSquarePenalty; layout(location = 0) out vec4 outputColor; float circleCoverage(vec2 point, float radius) { return clamp(radius + 0.5 - length(point), 0.0, 1.0); } float whiteSignal(vec3 color) { if (colorFeatureMode == 1) return color.b - 0.175 * (color.r + color.g); if (colorFeatureMode == 2) return color.b / (color.r + color.g + color.b + 0.05); return color.b; } float blackSignal(vec3 color) { return colorFeatureMode == 0 ? color.g : dot(color, vec3(0.25, 0.65, 0.10)); } float packDetection(float score, float size, float kind) { return score > 0.0 ? kind * 32.0 + size + min(score, 0.999) : 0.0; } float packCandidate(float score, float size) { return score > 0.0 ? size + min(score, 0.999) : 0.0; } float packLineFeatures(float horizontal, float vertical, float horizontalEdge, float verticalEdge) { float horizontalCode = floor(clamp(horizontal, 0.0, 1.0) * 255.0 + 0.5); float verticalCode = floor(clamp(vertical, 0.0, 1.0) * 255.0 + 0.5); float horizontalEdgeCode = floor(clamp(horizontalEdge, 0.0, 1.0) * 15.0 + 0.5); float verticalEdgeCode = floor(clamp(verticalEdge, 0.0, 1.0) * 15.0 + 0.5); return ((horizontalCode * 256.0 + verticalCode) * 16.0 + horizontalEdgeCode) * 16.0 + verticalEdgeCode; } float packLineAux(vec2 clean, vec2 wide) { vec4 codes = floor(clamp(vec4(clean, wide), 0.0, 1.0) * 63.0 + 0.5); return ((codes.x * 64.0 + codes.y) * 64.0 + codes.z) * 64.0 + codes.w; } float packIntersection(float score, float horizontal, float vertical) { float horizontalCode = floor(clamp(horizontal, 0.0, 1.0) * 63.0 + 0.5); float verticalCode = floor(clamp(vertical, 0.0, 1.0) * 63.0 + 0.5); return horizontalCode * 64.0 + verticalCode + min(score, 0.999); } void main() { ivec2 center = ivec2(gl_FragCoord.xy); if (center.x < 2 || center.y < 2 || center.x + 2 >= outputSize.x || center.y + 2 >= outputSize.y) { outputColor = vec4(0.0); return; } float localHorizontal = 0.0; float localVertical = 0.0; vec3 upperColor = vec3(0.0); vec3 lowerColor = vec3(0.0); vec3 leftColor = vec3(0.0); vec3 rightColor = vec3(0.0); for (int localY = -1; localY <= 1; ++localY) { for (int localX = -1; localX <= 1; ++localX) { vec3 localColor = texelFetch(sourceImage, center + ivec2(localX, localY), 0).rgb; float green = localColor.g; localHorizontal += green * (localY == 0 ? -1.0 / 3.0 : 1.0 / 6.0); localVertical += green * (localX == 0 ? -1.0 / 3.0 : 1.0 / 6.0); if (localY == -1) upperColor += localColor / 3.0; if (localY == 1) lowerColor += localColor / 3.0; if (localX == -1) leftColor += localColor / 3.0; if (localX == 1) rightColor += localColor / 3.0; } } float wideHorizontal = 0.0; float wideVertical = 0.0; float orientedHorizontal[3]; float orientedVertical[3]; for (int direction = 0; direction < 3; ++direction) { orientedHorizontal[direction] = 0.0; orientedVertical[direction] = 0.0; } for (int localY = -2; localY <= 2; ++localY) { for (int localX = -2; localX <= 2; ++localX) { float green = texelFetch(sourceImage, center + ivec2(localX, localY), 0).g; wideHorizontal += green * (localY == 0 ? -0.2 : 0.05); wideVertical += green * (localX == 0 ? -0.2 : 0.05); for (int direction = 0; direction < 3; ++direction) { float slope = float(direction - 1) * 0.5; int horizontalCenter = int(round(slope * float(localX))); int verticalCenter = int(round(slope * float(localY))); if (localY == horizontalCenter) orientedHorizontal[direction] -= green * 0.2; if (abs(localY - horizontalCenter) == 1) orientedHorizontal[direction] += green * 0.1; if (localX == verticalCenter) orientedVertical[direction] -= green * 0.2; if (abs(localX - verticalCenter) == 1) orientedVertical[direction] += green * 0.1; } } } float horizontalEdge = length(upperColor - lowerColor) / 1.7320508; float verticalEdge = length(leftColor - rightColor) / 1.7320508; vec2 wideLines = max(vec2(wideHorizontal, wideVertical), vec2(0.0)); vec2 cleanLines = max(vec2( max(max(orientedHorizontal[0], orientedHorizontal[1]), orientedHorizontal[2]), max(max(orientedVertical[0], orientedVertical[1]), orientedVertical[2]) ) - vec2(horizontalEdge, verticalEdge) * 0.25, vec2(0.0)); if (lineKernelMode == 0) { localHorizontal = sqrt(max(localHorizontal, 0.0) * max(wideHorizontal, 0.0)); localVertical = sqrt(max(localVertical, 0.0) * max(wideVertical, 0.0)); } else if (lineKernelMode == 1) { localHorizontal = max(wideHorizontal, 0.0); localVertical = max(wideVertical, 0.0); } else { localHorizontal = max(max(orientedHorizontal[0], orientedHorizontal[1]), orientedHorizontal[2]); localVertical = max(max(orientedVertical[0], orientedVertical[1]), orientedVertical[2]); if (lineKernelMode == 3) { localHorizontal = max(localHorizontal - horizontalEdge * 0.25, 0.0); localVertical = max(localVertical - verticalEdge * 0.25, 0.0); } } float packedLocalLines = packLineFeatures( max(localHorizontal, 0.0), max(localVertical, 0.0), horizontalEdge, verticalEdge ); if (center.x < 8 || center.y < 8 || center.x + 8 >= outputSize.x || center.y + 8 >= outputSize.y) { outputColor = vec4(0.0, packedLocalLines, packLineAux(cleanLines, wideLines), 0.0); return; } float whiteResponses[7]; float blackResponses[7]; float squareResponses[7]; bool needsBlack[7]; for (int scaleIndex = 0; scaleIndex < 7; ++scaleIndex) { whiteResponses[scaleIndex] = 0.0; blackResponses[scaleIndex] = 0.0; squareResponses[scaleIndex] = 0.0; needsBlack[scaleIndex] = false; } for (int offsetY = -8; offsetY <= 8; ++offsetY) { for (int offsetX = -8; offsetX <= 8; ++offsetX) { vec3 color = texelFetch(sourceImage, center + ivec2(offsetX, offsetY), 0).rgb; for (int scaleIndex = 0; scaleIndex < 7; ++scaleIndex) { int size = 16 - scaleIndex; bool stoneWindow = size >= stoneMinimumWindow && size <= stoneMaximumWindow; bool squareWindow = size >= squareMinimumWindow && size <= squareMaximumWindow; if (!stoneWindow && !squareWindow) continue; int first = -(size / 2); if (offsetX < first || offsetY < first || offsetX >= first + size || offsetY >= first + size) continue; bool border = offsetX == first || offsetY == first || offsetX == first + size - 1 || offsetY == first + size - 1; float centerShift = (size % 2 == 0) ? 0.5 : 0.0; vec2 relative = vec2(offsetX, offsetY) + vec2(centerShift); float radius = float(size - 2) * 0.5; float distance = length(relative); float positive = circleCoverage(relative, radius); float positiveWeight = positive * ((positive > 0.0 && positive < 1.0) ? 2.0 : 1.0); float backgroundWeight = distance < radius + 1.5 ? 2.0 : 1.0; float weight = positive > 0.0 ? (border ? 0.0 : positiveWeight) : -negativeWeights[scaleIndex] * backgroundWeight; if (stoneWindow) { whiteResponses[scaleIndex] += whiteSignal(color) * weight; } int edgeDistance = min( min(offsetX - first, first + size - 1 - offsetX), min(offsetY - first, first + size - 1 - offsetY) ); bool squareNegative = squareKernelMode == 0 ? edgeDistance < 2 : edgeDistance == 0; bool squareZero = squareKernelMode == 1 && edgeDistance == 1; float squareWeight = squareZero ? 0.0 : (squareNegative ? -squareBorderWeights[scaleIndex] : squareInnerWeights[scaleIndex]); if (squareWindow) squareResponses[scaleIndex] += color.g * squareWeight; } } } float bestWhite = 0.0; float bestBlack = 0.0; float bestSquare = 0.0; float bestWhiteSize = 0.0; float bestBlackSize = 0.0; float bestSquareSize = 0.0; float bestDarkSquare = 0.0; float bestDarkSquareSize = 0.0; bool anyBlack = false; for (int scaleIndex = 0; scaleIndex < 7; ++scaleIndex) { int size = 16 - scaleIndex; bool stoneWindow = size >= stoneMinimumWindow && size <= stoneMaximumWindow; bool squareWindow = size >= squareMinimumWindow && size <= squareMaximumWindow; float white = whiteResponses[scaleIndex] / positiveSums[scaleIndex]; float square = squareResponses[scaleIndex] / positiveSums[scaleIndex]; if (postprocessEnabled == 1) { if (stoneWindow && white > bestWhite) { bestWhite = white; bestWhiteSize = float(size); } if (squareWindow && square > bestSquare) { bestSquare = square; bestSquareSize = float(size); } if (stoneWindow && white <= 0.0) { needsBlack[scaleIndex] = true; anyBlack = true; } } else if (white > 0.0) { float shapedWhite = white; float shapedSquare = square; if (postprocessWhiteMode == 1) { if (white > bestWhite) { bestWhite = white; bestWhiteSize = float(16 - scaleIndex); } if (square > bestSquare) { bestSquare = square; bestSquareSize = float(16 - scaleIndex); } } else if (shapedSquare > shapedWhite) { if (shapedSquare > bestSquare) { bestSquare = shapedSquare; bestSquareSize = float(16 - scaleIndex); } } else if (shapedWhite > bestWhite) { bestWhite = shapedWhite; bestWhiteSize = float(16 - scaleIndex); } } else { needsBlack[scaleIndex] = true; anyBlack = true; } } if (anyBlack) { for (int offsetY = -8; offsetY <= 8; ++offsetY) { for (int offsetX = -8; offsetX <= 8; ++offsetX) { vec3 color = texelFetch(sourceImage, center + ivec2(offsetX, offsetY), 0).rgb; for (int scaleIndex = 0; scaleIndex < 7; ++scaleIndex) { if (!needsBlack[scaleIndex]) continue; int size = 16 - scaleIndex; int first = -(size / 2); if (offsetX < first || offsetY < first || offsetX >= first + size || offsetY >= first + size) continue; bool border = offsetX == first || offsetY == first || offsetX == first + size - 1 || offsetY == first + size - 1; float centerShift = (size % 2 == 0) ? 0.5 : 0.0; vec2 relative = vec2(offsetX, offsetY) + vec2(centerShift); float radius = float(size - 2) * 0.5; float distance = length(relative); float positive = circleCoverage(relative, radius); float positiveWeight = positive * ((positive > 0.0 && positive < 1.0) ? 2.0 : 1.0); float backgroundWeight = distance < radius + 1.5 ? 2.0 : 1.0; float weight = positive > 0.0 ? (border ? 0.0 : positiveWeight) : -negativeWeights[scaleIndex] * backgroundWeight; blackResponses[scaleIndex] += -blackSignal(color) * weight; } } } for (int scaleIndex = 0; scaleIndex < 7; ++scaleIndex) { int size = 16 - scaleIndex; bool squareWindow = size >= squareMinimumWindow && size <= squareMaximumWindow; if (postprocessEnabled == 0 && !needsBlack[scaleIndex]) continue; float black = blackResponses[scaleIndex] / positiveSums[scaleIndex]; float darkSquare = -squareResponses[scaleIndex] / positiveSums[scaleIndex]; float shapedBlack = black; float shapedDarkSquare = darkSquare; if (postprocessBlackMode == 1) { if (needsBlack[scaleIndex] && black > bestBlack) { bestBlack = black; bestBlackSize = float(16 - scaleIndex); } if (squareWindow && darkSquare > bestDarkSquare) { bestDarkSquare = darkSquare; bestDarkSquareSize = float(16 - scaleIndex); } } else if (postprocessEnabled == 1) { if (needsBlack[scaleIndex] && black > bestBlack) { bestBlack = black; bestBlackSize = float(16 - scaleIndex); } if (squareWindow && darkSquare > bestDarkSquare) { bestDarkSquare = darkSquare; bestDarkSquareSize = float(16 - scaleIndex); } } else { if (shapedDarkSquare > bestDarkSquare) { bestDarkSquare = shapedDarkSquare; bestDarkSquareSize = float(16 - scaleIndex); } if (shapedBlack > bestBlack) { bestBlack = shapedBlack; bestBlackSize = float(16 - scaleIndex); } } } } float rawWhite = bestWhite; float rawSquare = bestSquare; float rawBlack = bestBlack; float rawDarkSquare = bestDarkSquare; if (postprocessWhiteMode == 1) { bestWhite = max(rawWhite - max(rawSquare, 0.0) * postprocessWhiteSquarePenalty, 0.0); bestSquare = max(rawSquare - max(rawWhite, 0.0) * postprocessWhiteSquarePenalty, 0.0); } if (postprocessBlackMode == 1) { bestBlack = max( rawBlack - max(rawDarkSquare, 0.0) * postprocessBlackSquarePenalty, 0.0 ); bestDarkSquare = max( rawDarkSquare - max(rawBlack, 0.0) * postprocessBlackSquarePenalty, 0.0 ); } float bestIntersection = 0.0; float packedIntersection = 0.0; if (postprocessEnabled == 0 && max(max(bestWhite, bestBlack), bestSquare) <= 0.055) { float combined = 0.0; vec2 leftArms = vec2(0.0); vec2 rightArms = vec2(0.0); vec2 upperArms = vec2(0.0); vec2 lowerArms = vec2(0.0); float crossBackground = 0.0; for (int offsetY = -4; offsetY <= 3; ++offsetY) { for (int offsetX = -4; offsetX <= 3; ++offsetX) { if (intersectionMode == 0 && (abs(offsetX) > 3 || abs(offsetY) > 3)) continue; vec3 crossColor = texelFetch(sourceImage, center + ivec2(offsetX, offsetY), 0).rgb; float green = crossColor.g; if (intersectionMode == 0) { bool line = offsetX == 0 || offsetY == 0; combined += green * (line ? -1.0 / 13.0 : 1.0 / 36.0); } else if (intersectionMode == 1) { bool negative = offsetX == -1 || offsetY == -1; bool zero = !negative && (offsetX == 0 || offsetY == 0); combined += green * (zero ? 0.0 : (negative ? -1.0 / 15.0 : 1.0 / 36.0)); } else { if ((offsetY == -1 || offsetY == 0) && offsetX >= -4 && offsetX <= -2) { leftArms[offsetY + 1] += green / 3.0; } if ((offsetY == -1 || offsetY == 0) && offsetX >= 1 && offsetX <= 3) { rightArms[offsetY + 1] += green / 3.0; } if ((offsetX == -1 || offsetX == 0) && offsetY >= -4 && offsetY <= -2) { upperArms[offsetX + 1] += green / 3.0; } if ((offsetX == -1 || offsetX == 0) && offsetY >= 1 && offsetY <= 3) { lowerArms[offsetX + 1] += green / 3.0; } if (offsetX != -1 && offsetX != 0 && offsetY != -1 && offsetY != 0) { crossBackground += green / 36.0; } } } } if (intersectionMode == 2) { float horizontal = max( min(crossBackground - leftArms.x, crossBackground - rightArms.x), min(crossBackground - leftArms.y, crossBackground - rightArms.y) ); float vertical = max( min(crossBackground - upperArms.x, crossBackground - lowerArms.x), min(crossBackground - upperArms.y, crossBackground - lowerArms.y) ); float cross = min(max(horizontal, 0.0), max(vertical, 0.0)); packedIntersection = packIntersection(cross, max(horizontal, 0.0), max(vertical, 0.0)); } else { bestIntersection = max(combined, 0.0); } } float bestScore = bestBlack; float bestSize = bestBlackSize; float bestKind = 1.0; if (bestWhite > bestScore) { bestScore = bestWhite; bestSize = bestWhiteSize; bestKind = 2.0; } if ((postprocessBlackMode == 1 && bestDarkSquare > bestScore) || (postprocessBlackMode == 0 && bestDarkSquare > bestScore * 1.2)) { bestScore = bestDarkSquare; bestSize = bestDarkSquareSize; bestKind = 3.0; } if (bestSquare > bestScore) { bestScore = bestSquare; bestSize = bestSquareSize; bestKind = 4.0; } outputColor = vec4( packDetection(bestScore, bestSize, bestKind), packedLocalLines, packLineAux(cleanLines, wideLines), intersectionMode == 2 ? packedIntersection : packCandidate(bestIntersection, intersectionMode == 0 ? 7.0 : 8.0) ); }`,nn=`#version 300 es
8
+ precision highp float; precision highp int; uniform sampler2D scoreImage; uniform ivec2 imageSize; uniform int lineMergeMode; uniform float stoneNmsRatio; layout(location = 0) out vec4 outputColor; layout(location = 1) out vec4 metadataColor; int candidateGroup(vec4 value) { int candidateKind = int(floor(value.r / 32.0)); return candidateKind >= 3 ? 1 : 0; } float candidateScore(vec4 value, int kind) { return value.r > 0.0 && candidateGroup(value) == kind ? fract(value.r) : 0.0; } float candidateSize(vec4 value, int kind) { return candidateGroup(value) == kind ? mod(floor(value.r), 32.0) : 0.0; } int candidateType(vec4 value) { return int(floor(value.r / 32.0)); } float matchingCandidateScore(vec4 value, int type) { return candidateType(value) == type ? fract(value.r) : 0.0; } float inferredGridSize(vec4 value) { float size = mod(floor(value.r), 32.0); return candidateGroup(value) == 0 ? size - 1.0 : size; } float latticeVote(vec4 value, int expectedGroup, float expectedGrid, float centerScore) { if (value.r <= 0.0 || candidateGroup(value) != expectedGroup) return 0.0; float sizeAgreement = 1.0 - smoothstep(1.0, 3.0, abs(inferredGridSize(value) - expectedGrid)); return min(fract(value.r) / max(centerScore, 0.000001), 1.0) * sizeAgreement; } float packCandidateStructure(float drop, float horizontal, float vertical, float lattice) { vec4 codes = floor(clamp(vec4(drop, horizontal, vertical, lattice), 0.0, 1.0) * 63.0 + 0.5); return ((codes.x * 64.0 + codes.y) * 64.0 + codes.z) * 64.0 + codes.w; } vec2 lineScores(float packed) { float encoded = floor(packed); encoded = floor(encoded / 256.0); return vec2(floor(encoded / 256.0), mod(encoded, 256.0)) / 255.0; } vec2 edgeScores(float packed) { float encoded = floor(packed); float vertical = mod(encoded, 16.0); encoded = floor(encoded / 16.0); float horizontal = mod(encoded, 16.0); return vec2(horizontal, vertical) / 15.0; } vec4 lineAux(float packed) { float encoded = floor(packed + 0.5); float wideVertical = mod(encoded, 64.0); encoded = floor(encoded / 64.0); float wideHorizontal = mod(encoded, 64.0); encoded = floor(encoded / 64.0); float cleanVertical = mod(encoded, 64.0); float cleanHorizontal = mod(floor(encoded / 64.0), 64.0); return vec4(cleanHorizontal, cleanVertical, wideHorizontal, wideVertical) / 63.0; } vec2 directionLineScores(vec4 value) { vec2 base = lineScores(value.g); vec4 auxiliary = lineAux(value.b); vec2 clean = auxiliary.xy; vec2 wide = auxiliary.zw; if (lineMergeMode == 1) return max(base, clean); if (lineMergeMode == 2) return max(max(base, clean), wide * 0.5); if (lineMergeMode == 3) return clean; return base; } float packLineFeatures(vec2 scores, vec2 edges) { vec2 codes = floor(clamp(scores, 0.0, 1.0) * 255.0 + 0.5); vec2 edgeCodes = floor(clamp(edges, 0.0, 1.0) * 15.0 + 0.5); return ((codes.x * 256.0 + codes.y) * 16.0 + edgeCodes.x) * 16.0 + edgeCodes.y; } float packLineSlopes( float horizontal, float vertical, float strongHorizontal, float strongVertical, float horizontalConfidence, float verticalConfidence ) { vec2 localDirections = floor( (clamp(vec2(horizontal, vertical), -0.5, 0.5) + 0.5) * 8.0 + 0.5 ); vec2 strongDirections = floor( (clamp(vec2(strongHorizontal, strongVertical), -0.5, 0.5) + 0.5) * 8.0 + 0.5 ); vec2 confidences = floor(clamp(vec2(horizontalConfidence, verticalConfidence), 0.0, 1.0) * 15.0 + 0.5); float localPair = localDirections.x * 9.0 + localDirections.y; float strongPair = strongDirections.x * 9.0 + strongDirections.y; return (localPair * 81.0 + strongPair) * 256.0 + confidences.x * 16.0 + confidences.y; } bool otherWins( float otherScore, int otherKind, ivec2 otherPoint, float currentScore, int currentKind, ivec2 currentPoint ) { if (otherScore > currentScore + 0.000001) return true; if (abs(otherScore - currentScore) > 0.000001) return false; if (otherKind != currentKind) return otherKind < currentKind; return otherPoint.y < currentPoint.y || (otherPoint.y == currentPoint.y && otherPoint.x < currentPoint.x); } bool overlaps(float distanceSquared, int firstKind, float firstSize, int secondKind, float secondSize) { float largerSize = max(firstSize, secondSize); float limit = firstKind == 0 && secondKind == 0 ? largerSize * stoneNmsRatio : firstKind != secondKind ? largerSize * 0.25 : largerSize * 0.5; return distanceSquared < limit * limit; } float pairedVisibleLineVote(float firstLine, float secondLine) { return min(firstLine, secondLine); } float pairedOccludedLineVote(float firstLine, float secondLine, float firstStone, float secondStone) { float firstOccluded = firstLine * smoothstep(0.08, 0.18, secondStone); float secondOccluded = secondLine * smoothstep(0.08, 0.18, firstStone); return max(firstOccluded, secondOccluded) * 0.35; } void main() { ivec2 center = ivec2(gl_FragCoord.xy); vec4 current = texelFetch(scoreImage, center, 0); bool keep[3]; float weightSums[3]; float sizeSums[3]; float horizontalMoments[2]; float verticalMoments[2]; vec2 currentLines = lineScores(current.g); int currentType = candidateType(current); int currentGroup = candidateGroup(current); float currentCandidateScore = matchingCandidateScore(current, currentType); float currentGridSize = inferredGridSize(current); float horizontalDirections[9]; float verticalDirections[9]; float localHorizontalDirections[9]; float localVerticalDirections[9]; float horizontalDirectionWeights[9]; float verticalDirectionWeights[9]; float horizontalDirectionSupports[9]; float verticalDirectionSupports[9]; for (int direction = 0; direction < 9; ++direction) { horizontalDirections[direction] = 0.0; verticalDirections[direction] = 0.0; localHorizontalDirections[direction] = 0.0; localVerticalDirections[direction] = 0.0; horizontalDirectionWeights[direction] = 0.0; verticalDirectionWeights[direction] = 0.0; horizontalDirectionSupports[direction] = 0.0; verticalDirectionSupports[direction] = 0.0; } for (int kind = 0; kind < 2; ++kind) keep[kind] = candidateScore(current, kind) > 0.0; for (int kind = 0; kind < 2; ++kind) { float score = candidateScore(current, kind); float size = candidateSize(current, kind); weightSums[kind] = score; sizeSums[kind] = score * size; if (kind == 0) { float baseMoment = score * size * size * 0.0625; horizontalMoments[kind] = baseMoment; verticalMoments[kind] = baseMoment; } } for (int offsetY = -8; offsetY <= 8; ++offsetY) { for (int offsetX = -8; offsetX <= 8; ++offsetX) { ivec2 otherPoint = center + ivec2(offsetX, offsetY); if (otherPoint.x < 0 || otherPoint.y < 0 || otherPoint.x >= imageSize.x || otherPoint.y >= imageSize.y) continue; vec4 other = texelFetch(scoreImage, otherPoint, 0); vec2 otherLines = directionLineScores(other); if (currentLines.x > 0.0 && abs(offsetX) >= 2) { float slope = float(offsetY) / float(offsetX); if (abs(slope) <= 0.56) { int direction = clamp(int(floor((slope + 0.5) * 8.0 + 0.5)), 0, 8); localHorizontalDirections[direction] += otherLines.x * float(abs(offsetX)); } } if (currentLines.y > 0.0 && abs(offsetY) >= 2) { float slope = float(offsetX) / float(offsetY); if (abs(slope) <= 0.56) { int direction = clamp(int(floor((slope + 0.5) * 8.0 + 0.5)), 0, 8); localVerticalDirections[direction] += otherLines.y * float(abs(offsetY)); } } float distanceSquared = float(offsetX * offsetX + offsetY * offsetY); for (int currentKind = 0; currentKind < 2; ++currentKind) { if (!keep[currentKind]) continue; float currentScore = candidateScore(current, currentKind); float currentSize = candidateSize(current, currentKind); for (int otherKind = 0; otherKind < 2; ++otherKind) { if (offsetX == 0 && offsetY == 0 && currentKind == otherKind) continue; float otherScore = candidateScore(other, otherKind); if (otherScore <= 0.0) continue; float otherSize = candidateSize(other, otherKind); if (!overlaps(distanceSquared, currentKind, currentSize, otherKind, otherSize)) continue; if (otherWins(otherScore, otherKind, otherPoint, currentScore, currentKind, center)) { keep[currentKind] = false; break; } else if (currentKind == otherKind) { weightSums[currentKind] += otherScore; sizeSums[currentKind] += otherScore * otherSize; if (currentKind == 0) { horizontalMoments[currentKind] += otherScore * float(offsetX * offsetX); verticalMoments[currentKind] += otherScore * float(offsetY * offsetY); } } } } } } if (currentLines.x > 0.0 || currentLines.y > 0.0) { for (int direction = 0; direction < 9; ++direction) { float slope = float(direction) / 8.0 - 0.5; for (int major = 2; major <= 12; ++major) { int minor = int(round(slope * float(major))); if (abs(minor) * 2 >= major) continue; float directionWeight = float(major - abs(minor)); if (currentLines.x > 0.0) { ivec2 rightPoint = center + ivec2(major, minor); ivec2 leftPoint = center - ivec2(major, minor); if (rightPoint.x < imageSize.x && rightPoint.y >= 0 && rightPoint.y < imageSize.y && leftPoint.x >= 0 && leftPoint.y >= 0 && leftPoint.y < imageSize.y) { vec4 rightValue = texelFetch(scoreImage, rightPoint, 0); vec4 leftValue = texelFetch(scoreImage, leftPoint, 0); float rightScore = directionLineScores(rightValue).x; float leftScore = directionLineScores(leftValue).x; float visibleVote = pairedVisibleLineVote(leftScore, rightScore); float occludedVote = pairedOccludedLineVote( leftScore, rightScore, candidateScore(leftValue, 0), candidateScore(rightValue, 0) ); float vote = max(visibleVote, occludedVote); horizontalDirections[direction] += vote * directionWeight; horizontalDirectionWeights[direction] += directionWeight; float supportThreshold = max(currentLines.x * 0.2, 1.5 / 255.0); if (visibleVote >= supportThreshold) { horizontalDirectionSupports[direction] += 1.0; } else if (occludedVote >= supportThreshold) { horizontalDirectionSupports[direction] += 0.5; } } } if (currentLines.y > 0.0) { ivec2 downPoint = center + ivec2(minor, major); ivec2 upPoint = center - ivec2(minor, major); if (downPoint.x >= 0 && downPoint.x < imageSize.x && downPoint.y < imageSize.y && upPoint.x >= 0 && upPoint.x < imageSize.x && upPoint.y >= 0) { vec4 downValue = texelFetch(scoreImage, downPoint, 0); vec4 upValue = texelFetch(scoreImage, upPoint, 0); float downScore = directionLineScores(downValue).y; float upScore = directionLineScores(upValue).y; float visibleVote = pairedVisibleLineVote(upScore, downScore); float occludedVote = pairedOccludedLineVote( upScore, downScore, candidateScore(upValue, 0), candidateScore(downValue, 0) ); float vote = max(visibleVote, occludedVote); verticalDirections[direction] += vote * directionWeight; verticalDirectionWeights[direction] += directionWeight; float supportThreshold = max(currentLines.y * 0.2, 1.5 / 255.0); if (visibleVote >= supportThreshold) { verticalDirectionSupports[direction] += 1.0; } else if (occludedVote >= supportThreshold) { verticalDirectionSupports[direction] += 0.5; } } } } } } vec2 localLines = currentLines; vec2 filteredLines = localLines; ivec2 maximumPoint = imageSize - ivec2(1); vec2 upperLines = lineScores(texelFetch(scoreImage, clamp(center + ivec2(0, -1), ivec2(0), maximumPoint), 0).g); vec2 lowerLines = lineScores(texelFetch(scoreImage, clamp(center + ivec2(0, 1), ivec2(0), maximumPoint), 0).g); vec2 leftLines = lineScores(texelFetch(scoreImage, clamp(center + ivec2(-1, 0), ivec2(0), maximumPoint), 0).g); vec2 rightLines = lineScores(texelFetch(scoreImage, clamp(center + ivec2(1, 0), ivec2(0), maximumPoint), 0).g); if (upperLines.x >= localLines.x || lowerLines.x > localLines.x) filteredLines.x = 0.0; if (leftLines.y >= localLines.y || rightLines.y > localLines.y) filteredLines.y = 0.0; float surroundDrop = 0.0; float horizontalContinuation = 0.0; float verticalContinuation = 0.0; float latticeSupport = 0.0; if (currentCandidateScore > 0.0) { int halfSize = max(3, int(floor(candidateSize(current, currentGroup) * 0.5 + 0.5))); int diagonal = max(2, int(floor(float(halfSize) * 0.70710678 + 0.5))); float left = matchingCandidateScore( texelFetch(scoreImage, clamp(center + ivec2(-halfSize, 0), ivec2(0), maximumPoint), 0), currentType ); float right = matchingCandidateScore( texelFetch(scoreImage, clamp(center + ivec2(halfSize, 0), ivec2(0), maximumPoint), 0), currentType ); float upper = matchingCandidateScore( texelFetch(scoreImage, clamp(center + ivec2(0, -halfSize), ivec2(0), maximumPoint), 0), currentType ); float lower = matchingCandidateScore( texelFetch(scoreImage, clamp(center + ivec2(0, halfSize), ivec2(0), maximumPoint), 0), currentType ); float diagonalSum = 0.0; float oppositePhase = 0.0; for (int yDirection = -1; yDirection <= 1; yDirection += 2) { for (int xDirection = -1; xDirection <= 1; xDirection += 2) { vec4 diagonalValue = texelFetch( scoreImage, clamp(center + ivec2(xDirection * diagonal, yDirection * diagonal), ivec2(0), maximumPoint), 0 ); diagonalSum += matchingCandidateScore(diagonalValue, currentType); oppositePhase += latticeVote( diagonalValue, 1 - currentGroup, currentGridSize, currentCandidateScore ); } } float ringMean = (left + right + upper + lower + diagonalSum) / 8.0; surroundDrop = clamp(1.0 - ringMean / currentCandidateScore, 0.0, 1.0); horizontalContinuation = clamp(min(left, right) / currentCandidateScore, 0.0, 1.0); verticalContinuation = clamp(min(upper, lower) / currentCandidateScore, 0.0, 1.0); int gridOffset = max(1, int(floor(currentGridSize + 0.5))); float samePhase = 0.0; for (int direction = -1; direction <= 1; direction += 2) { samePhase += latticeVote( texelFetch( scoreImage, clamp(center + ivec2(direction * gridOffset, 0), ivec2(0), maximumPoint), 0 ), currentGroup, currentGridSize, currentCandidateScore ); samePhase += latticeVote( texelFetch( scoreImage, clamp(center + ivec2(0, direction * gridOffset), ivec2(0), maximumPoint), 0 ), currentGroup, currentGridSize, currentCandidateScore ); } latticeSupport = clamp(max(samePhase, oppositePhase) * 0.25, 0.0, 1.0); } outputColor = vec4( keep[candidateGroup(current)] ? current.r : 0.0, packLineFeatures(filteredLines, edgeScores(current.g)), current.b, current.a ); int activeKind = candidateGroup(current); float refinedSize = keep[activeKind] ? sizeSums[activeKind] / max(weightSums[activeKind], 0.000001) : 0.0; float orientationTotal = horizontalMoments[0] + verticalMoments[0]; float orientation = activeKind == 0 && keep[0] ? (horizontalMoments[0] - verticalMoments[0]) / max(orientationTotal, 0.000001) : 0.0; int horizontalDirection = 4; int verticalDirection = 4; int localHorizontalDirection = 4; int localVerticalDirection = 4; float horizontalStrength = 0.0; float verticalStrength = 0.0; float horizontalTotalStrength = 0.0; float verticalTotalStrength = 0.0; for (int direction = 0; direction < 9; ++direction) { float horizontalDirectionStrength = horizontalDirections[direction] / max(horizontalDirectionWeights[direction], 0.000001); float verticalDirectionStrength = verticalDirections[direction] / max(verticalDirectionWeights[direction], 0.000001); horizontalTotalStrength += horizontalDirectionStrength; verticalTotalStrength += verticalDirectionStrength; if (horizontalDirectionStrength > horizontalStrength) { horizontalStrength = horizontalDirectionStrength; horizontalDirection = direction; } if (verticalDirectionStrength > verticalStrength) { verticalStrength = verticalDirectionStrength; verticalDirection = direction; } if (localHorizontalDirections[direction] > localHorizontalDirections[localHorizontalDirection]) { localHorizontalDirection = direction; } if (localVerticalDirections[direction] > localVerticalDirections[localVerticalDirection]) { localVerticalDirection = direction; } } float horizontalSlope = float(localHorizontalDirection) / 8.0 - 0.5; float verticalSlope = float(localVerticalDirection) / 8.0 - 0.5; float strongHorizontalSlope = float(horizontalDirection) / 8.0 - 0.5; float strongVerticalSlope = float(verticalDirection) / 8.0 - 0.5; float horizontalDominance = horizontalStrength / max(horizontalTotalStrength, 0.000001); float verticalDominance = verticalStrength / max(verticalTotalStrength, 0.000001); float horizontalConfidence = horizontalStrength / max(currentLines.x, 1.0 / 255.0) * smoothstep(0.14, 0.35, horizontalDominance) * step(7.0, horizontalDirectionSupports[horizontalDirection]); float verticalConfidence = verticalStrength / max(currentLines.y, 1.0 / 255.0) * smoothstep(0.14, 0.35, verticalDominance) * step(7.0, verticalDirectionSupports[verticalDirection]); metadataColor = vec4( refinedSize, packLineSlopes( horizontalSlope, verticalSlope, strongHorizontalSlope, strongVerticalSlope, horizontalConfidence, verticalConfidence ), packCandidateStructure( surroundDrop, horizontalContinuation, verticalContinuation, latticeSupport ), orientation * 0.5 + 0.5 ); }`,an=`#version 300 es
9
+ precision highp float; precision highp int; uniform sampler2D scoreImage; uniform sampler2D filteredImage; uniform sampler2D metadataImage; uniform ivec2 imageSize; uniform int lineSuppressionMode; layout(location = 0) out vec4 candidateColor; layout(location = 1) out vec4 typedLineColor; int candidateKind(float packed) { return int(floor(packed / 32.0)); } float candidateScore(float packed) { return fract(packed); } float candidateSize(float packed) { return mod(floor(packed), 32.0); } vec4 candidateStructure(float packed) { float encoded = floor(packed + 0.5); float lattice = mod(encoded, 64.0); encoded = floor(encoded / 64.0); float vertical = mod(encoded, 64.0); encoded = floor(encoded / 64.0); float horizontal = mod(encoded, 64.0); float drop = mod(floor(encoded / 64.0), 64.0); return vec4(drop, horizontal, vertical, lattice) / 63.0; } vec2 lineScores(float packed) { float encoded = floor(packed / 256.0); return vec2(floor(encoded / 256.0), mod(encoded, 256.0)) / 255.0; } vec2 edgeScores(float packed) { float encoded = floor(packed); float vertical = mod(encoded, 16.0); encoded = floor(encoded / 16.0); float horizontal = mod(encoded, 16.0); return vec2(horizontal, vertical) / 15.0; } vec4 lineAux(float packed) { float encoded = floor(packed + 0.5); float wideVertical = mod(encoded, 64.0); encoded = floor(encoded / 64.0); float wideHorizontal = mod(encoded, 64.0); encoded = floor(encoded / 64.0); float cleanVertical = mod(encoded, 64.0); float cleanHorizontal = mod(floor(encoded / 64.0), 64.0); return vec4(cleanHorizontal, cleanVertical, wideHorizontal, wideVertical) / 63.0; } vec2 lineConfidences(float packed) { float confidencePair = mod(floor(packed + 0.5), 256.0); return vec2(floor(confidencePair / 16.0), mod(confidencePair, 16.0)) / 15.0; } float packLineFeatures(vec2 scores, vec2 edges) { vec2 codes = floor(clamp(scores, 0.0, 1.0) * 255.0 + 0.5); vec2 edgeCodes = floor(clamp(edges, 0.0, 1.0) * 15.0 + 0.5); return ((codes.x * 256.0 + codes.y) * 16.0 + edgeCodes.x) * 16.0 + edgeCodes.y; } float packTypes(vec4 weights, float lineScore) { vec4 codes = floor(clamp(weights, 0.0, 1.0) * 15.0 + 0.5); float typeCode = ((codes.x * 16.0 + codes.y) * 16.0 + codes.z) * 16.0 + codes.w; return typeCode * 64.0 + floor(clamp(lineScore, 0.0, 1.0) * 63.0 + 0.5); } vec4 classifyLine( ivec2 center, bool horizontal, float lineScore, float cleanScore, float lineConfidence, float edgeScore, out float adjustedScore, out float hardDeleted ) { float stoneEdge = 0.0; float squareEdge = 0.0; float boardBand = 0.0; float negativeSquareBoundary = 0.0; float positiveSquareBoundary = 0.0; float bandBoundary = 0.0; float compactStoneBoundary = 0.0; float stoneCenterSupport = 0.0; float confirmedStoneEdge = 0.0; for (int offset = -8; offset <= 8; ++offset) { ivec2 point = center + (horizontal ? ivec2(0, offset) : ivec2(offset, 0)); if (point.x < 0 || point.y < 0 || point.x >= imageSize.x || point.y >= imageSize.y) continue; vec4 candidate = texelFetch(filteredImage, point, 0); vec4 metadata = texelFetch(metadataImage, point, 0); int kind = candidateKind(candidate.r); float score = candidateScore(candidate.r); float stone = kind == 1 || kind == 2 ? score : 0.0; float stoneStrength = smoothstep(0.055, 0.30, stone); float diameter = candidateSize(candidate.r); float radius = max(3.0, (diameter - 2.0) * 0.5); float ring = 1.0 - smoothstep(1.0, 2.5, abs(abs(float(offset)) - radius)); float outsideCenter = step(diameter * 0.36, abs(float(offset))); float stoneRing = stoneStrength * ring * outsideCenter; stoneEdge = max(stoneEdge, stoneRing); float square = kind == 3 || kind == 4 ? score : 0.0; float squareStrength = smoothstep(0.055, 0.30, square); float halfSide = max(3.0, candidateSize(candidate.r) * 0.5); float squareRing = 1.0 - smoothstep(1.0, 2.5, abs(abs(float(offset)) - halfSide)); squareEdge = max(squareEdge, squareStrength * squareRing); vec4 structure = candidateStructure(metadata.b); float directionalContinuation = horizontal ? structure.y : structure.z; float maximumContinuation = max(structure.y, structure.z); float directionalBand = smoothstep(0.35, 0.75, directionalContinuation); float isolated = 1.0 - smoothstep(0.25, 0.60, maximumContinuation); float candidateStrength = smoothstep(0.055, 0.30, score); float squareBoundary = squareStrength * squareRing * max(isolated, directionalBand); if (offset < 0) negativeSquareBoundary = max(negativeSquareBoundary, squareBoundary); if (offset > 0) positiveSquareBoundary = max(positiveSquareBoundary, squareBoundary); bandBoundary = max( bandBoundary, candidateStrength * ring * directionalBand ); compactStoneBoundary = max( compactStoneBoundary, stoneStrength * ring * isolated * smoothstep(0.65, 0.90, structure.x) ); confirmedStoneEdge = max( confirmedStoneEdge, step(0.035, stoneRing) ); float centerTolerance = max(1.5, diameter * 0.35); float centerAlignment = 1.0 - smoothstep( centerTolerance * 0.5, centerTolerance, abs(float(offset)) ); stoneCenterSupport = max( stoneCenterSupport, stoneStrength * isolated * smoothstep(0.45, 0.80, structure.x) * centerAlignment ); float orientation = metadata.a * 2.0 - 1.0; float tangent = horizontal ? max(orientation, 0.0) : max(-orientation, 0.0); float nearLine = 1.0 - smoothstep(1.5, 4.0, abs(float(offset))); boardBand = max(boardBand, smoothstep(0.06, 0.22, stone) * smoothstep(0.12, 0.42, tangent) * nearLine); } float pairedSquareBoundary = min(negativeSquareBoundary, positiveSquareBoundary); float reinforcement = max( pairedSquareBoundary, bandBoundary ); float suppressionStrength = lineSuppressionMode == 0 ? 0.35 : (lineSuppressionMode == 1 ? 0.65 : (lineSuppressionMode == 2 ? 0.85 : 1.0)); float stoneEdgeSuppression = compactStoneBoundary * suppressionStrength * (1.0 - stoneCenterSupport * 0.85); adjustedScore = max( lineScore * (1.0 - stoneEdgeSuppression), reinforcement * 0.45 ); hardDeleted = lineSuppressionMode == 3 && confirmedStoneEdge > 0.5 ? 1.0 : 0.0; if (hardDeleted > 0.5) adjustedScore = 0.0; float grid = adjustedScore * max(max(squareEdge, reinforcement), (1.0 - edgeScore) * 0.65); grid = max(grid, cleanScore * (0.35 + 0.65 * lineConfidence)); grid = max(grid, adjustedScore * stoneCenterSupport * 0.75); float stone = hardDeleted > 0.5 ? 1.0 : min(14.0 / 15.0, max(lineScore, adjustedScore) * stoneEdge); float board = adjustedScore * edgeScore * (0.35 + 0.65 * boardBand); float known = max(grid, max(stone, board)); float unknown = adjustedScore * (1.0 - clamp(known, 0.0, 1.0)); return vec4(grid, stone, board, unknown); } void main() { ivec2 center = ivec2(gl_FragCoord.xy); vec4 filtered = texelFetch(filteredImage, center, 0); vec4 metadata = texelFetch(metadataImage, center, 0); vec2 lines = lineScores(filtered.g); vec4 auxiliaryLines = lineAux(texelFetch(scoreImage, center, 0).b); vec2 cleanLines = auxiliaryLines.xy; vec2 confidences = lineConfidences(metadata.g); vec2 edges = edgeScores(texelFetch(scoreImage, center, 0).g); float legacyLines = floor(filtered.a); float legacyHorizontal = floor(legacyLines / 64.0); float legacyVertical = mod(legacyLines, 64.0); float adjustedHorizontal = 0.0; float adjustedVertical = 0.0; float deletedHorizontal = 0.0; float deletedVertical = 0.0; vec4 horizontalTypes = classifyLine( center, true, lines.x, cleanLines.x, confidences.x, edges.x, adjustedHorizontal, deletedHorizontal ); vec4 verticalTypes = classifyLine( center, false, lines.y, cleanLines.y, confidences.y, edges.y, adjustedVertical, deletedVertical ); candidateColor = vec4(filtered.r, metadata.r, metadata.a, metadata.b); typedLineColor = vec4( packLineFeatures(vec2(adjustedHorizontal, adjustedVertical), edges), metadata.g, packTypes(horizontalTypes, legacyHorizontal / 63.0), packTypes(verticalTypes, legacyVertical / 63.0) ); }`,gn=`#version 300 es
10
+ precision highp float; precision highp int; uniform sampler2D candidateImage; uniform ivec2 imageSize; out vec4 outputColor; int candidateKind(float packed) { return int(floor(packed / 32.0)); } float candidateScore(float packed) { return fract(packed); } float candidateSize(float packed) { return mod(floor(packed), 32.0); } void main() { ivec2 center = ivec2(gl_FragCoord.xy); float verticalRadius = 0.0; for (int offsetX = -8; offsetX <= 8; ++offsetX) { ivec2 point = center + ivec2(offsetX, 0); if (point.x < 0 || point.x >= imageSize.x) continue; vec4 candidate = texelFetch(candidateImage, point, 0); int kind = candidateKind(candidate.r); if ((kind != 1 && kind != 2) || candidateScore(candidate.r) < 0.055) continue; float radius = max(candidate.g, candidateSize(candidate.r)) * 0.515; float remainder = radius * radius - float(offsetX * offsetX); if (remainder > 0.0) verticalRadius = max(verticalRadius, sqrt(remainder)); } outputColor = vec4(verticalRadius, 0.0, 0.0, 0.0); }`,In=`#version 300 es
11
+ precision highp float; precision highp int; uniform sampler2D stoneMaskImage; uniform sampler2D lineImage; uniform ivec2 imageSize; out vec4 outputColor; vec2 lineScores(float packed) { float encoded = floor(packed / 256.0); return vec2(floor(encoded / 256.0), mod(encoded, 256.0)) / 255.0; } vec2 edgeScores(float packed) { float encoded = floor(packed); float vertical = mod(encoded, 16.0); encoded = floor(encoded / 16.0); float horizontal = mod(encoded, 16.0); return vec2(horizontal, vertical) / 15.0; } float packLineFeatures(vec2 scores, vec2 edges) { vec2 codes = floor(clamp(scores, 0.0, 1.0) * 255.0 + 0.5); vec2 edgeCodes = floor(clamp(edges, 0.0, 1.0) * 15.0 + 0.5); return ((codes.x * 256.0 + codes.y) * 16.0 + edgeCodes.x) * 16.0 + edgeCodes.y; } float packStoneEdge(float packed) { float lineCode = mod(floor(packed + 0.5), 64.0); return 15.0 * 256.0 * 64.0 + lineCode; } void main() { ivec2 center = ivec2(gl_FragCoord.xy); vec4 lines = texelFetch(lineImage, center, 0); if (max(lineScores(lines.r).x, lineScores(lines.r).y) <= 0.0) { outputColor = lines; return; } bool covered = false; for (int offsetY = -8; offsetY <= 8; ++offsetY) { int row = center.y + offsetY; if (row < 0 || row >= imageSize.y) continue; float radius = texelFetch(stoneMaskImage, ivec2(center.x, row), 0).r; if (abs(float(offsetY)) < radius) covered = true; } outputColor = covered ? vec4(packLineFeatures(vec2(0.0), edgeScores(lines.r)), lines.g, packStoneEdge(lines.b), packStoneEdge(lines.a)) : lines; }`,sn=`#version 300 es
12
+ precision highp float; uniform sampler2D sourceImage; uniform vec2 sourceSize; uniform vec2 outputSize; uniform vec2 gridMinimum; uniform vec2 gridExtent; uniform mat3 gridToSource; out vec4 outputColor; void main() { vec2 gridPoint = gl_FragCoord.xy / outputSize * gridExtent + gridMinimum; vec3 projected = gridToSource * vec3(gridPoint, 1.0); vec2 sourcePoint = projected.xy / projected.z; vec2 halfTexel = 0.5 / sourceSize; vec2 sourceUv = clamp((sourcePoint + 0.5) / sourceSize, halfTexel, vec2(1.0) - halfTexel); outputColor = texture(sourceImage, sourceUv); }`,cn=`#version 300 es
13
+ precision highp float; precision highp int; uniform sampler2D sourceImage; uniform sampler2D candidateImage; uniform vec2 imageSize; uniform int lineCount; uniform vec4 margins; layout(location = 0) out vec4 scoreColor; layout(location = 1) out vec4 offsetColor; layout(location = 2) out vec4 appearanceColor; layout(location = 3) out vec4 backgroundColor; layout(location = 4) out vec4 candidateShapeColor; layout(location = 5) out vec4 lineVisibilityColor; layout(location = 6) out vec4 shapePeakColor; layout(location = 7) out vec4 robustColor; vec3 sampleImage(vec2 point) { return texture(sourceImage, (point + 0.5) / imageSize).rgb; } vec4 sampleCandidate(vec2 point) { return texture(candidateImage, (point + 0.5) / imageSize); } int candidateKind(vec4 candidate) { return int(floor(candidate.r / 32.0)); } float candidateScore(vec4 candidate, int expectedKind) { return candidateKind(candidate) == expectedKind ? fract(candidate.r) : 0.0; } float cross11Response(vec2 center) { float response = 0.0; const float backgroundWeight = 39.0 / 64.0; for (int offsetY = -5; offsetY <= 5; ++offsetY) { for (int offsetX = -5; offsetX <= 5; ++offsetX) { bool centerAxis = offsetX == 0 || offsetY == 0; bool centerBand = abs(offsetX) <= 1 || abs(offsetY) <= 1; float weight = centerAxis ? -1.0 : centerBand ? -0.5 : backgroundWeight; response += sampleImage( center + vec2(float(offsetX), float(offsetY)) ).g * weight; } } return max(response / 39.0, 0.0); } float packLightMoment(vec2 moment) { vec2 codes = floor( (clamp(moment, vec2(-1.0), vec2(1.0)) * 0.5 + 0.5) * 255.0 + 0.5 ); return (codes.x * 256.0 + codes.y) / 65536.0; } float pack3x8(vec3 values) { vec3 codes = floor(clamp(values, vec3(0.0), vec3(1.0)) * 255.0 + 0.5); return codes.x + codes.y * 256.0 + codes.z * 65536.0; } float pack2x12(vec2 values) { vec2 codes = floor(clamp(values, vec2(0.0), vec2(1.0)) * 4095.0 + 0.5); return codes.x + codes.y * 4096.0; } float packCoverage(float coverage) { return floor(clamp(coverage, 0.0, 1.0) * 12.0 + 0.5); } void main() { vec2 grid = gl_FragCoord.xy - 0.5; vec2 extent = vec2( float(lineCount - 1) + margins.x + margins.y, float(lineCount - 1) + margins.z + margins.w ); vec2 center = (grid + vec2(margins.x, margins.z)) / extent * imageSize - 0.5; float spacing = 0.5 * (imageSize.x / extent.x + imageSize.y / extent.y); const float pi = 3.14159265358979323846; vec4 smallScores = vec4(0.0); for (int radiusIndex = 0; radiusIndex < 4; ++radiusIndex) { float radius = spacing * (0.10 + 0.05 * float(radiusIndex)); float sum = 0.0; float squared = 0.0; float covered = 0.0; for (int angleIndex = 0; angleIndex < 12; ++angleIndex) { float angle = 2.0 * pi * float(angleIndex) / 12.0; vec2 direction = vec2(cos(angle), sin(angle)); float response = max( sampleImage(center + direction * radius * 1.30).g - sampleImage(center + direction * radius * 0.35).g, 0.0 ); sum += response; squared += response * response; covered += step(0.035, response); } float mean = sum / 12.0; float variation = sqrt(max(squared / 12.0 - mean * mean, 0.0)); smallScores[radiusIndex] = mean * (0.25 + 0.75 * covered / 12.0) / (1.0 + 0.20 * variation / (mean + 0.01)); } vec3 background = vec3(0.0); for (int yDirection = -1; yDirection <= 1; yDirection += 2) { for (int xDirection = -1; xDirection <= 1; xDirection += 2) { background += sampleImage( center + vec2(float(xDirection), float(yDirection)) * spacing * 0.5 ); } } background *= 0.25; float bestBlack = 0.0; float bestWhite = 0.0; float fixedBlack = 0.0; float fixedWhite = 0.0; float bestBlackRadiusIndex = 0.0; float bestWhiteRadiusIndex = 0.0; float fixedBlackRadiusIndex = 0.0; float fixedWhiteRadiusIndex = 0.0; vec2 bestBlackOffset = vec2(0.0); vec2 bestWhiteOffset = vec2(0.0); vec3 blackScaleScores = vec3(0.0); vec3 whiteScaleScores = vec3(0.0); for (int offsetY = -2; offsetY <= 2; ++offsetY) { for (int offsetX = -2; offsetX <= 2; ++offsetX) { vec2 offset = vec2(float(offsetX), float(offsetY)) * 0.25; vec2 candidateCenter = center + offset * spacing; for (int radiusIndex = 0; radiusIndex < 3; ++radiusIndex) { float radius = spacing * (0.36 + 0.07 * float(radiusIndex)); float blackSum = 0.0; float whiteSum = 0.0; float blackSquared = 0.0; float whiteSquared = 0.0; float blackCovered = 0.0; float whiteCovered = 0.0; for (int angleIndex = 0; angleIndex < 12; ++angleIndex) { float angle = 2.0 * pi * float(angleIndex) / 12.0; vec2 direction = vec2(cos(angle), sin(angle)); vec3 inner = sampleImage(candidateCenter + direction * radius * 0.68); vec3 outer = sampleImage(candidateCenter + direction * radius * 1.16); float black = max(outer.g - inner.g, 0.0); float white = max(inner.b - outer.b, 0.0); blackSum += black; whiteSum += white; blackSquared += black * black; whiteSquared += white * white; blackCovered += step(0.035, black); whiteCovered += step(0.035, white); } float blackMean = blackSum / 12.0; float whiteMean = whiteSum / 12.0; float blackCoverage = blackCovered / 12.0; float whiteCoverage = whiteCovered / 12.0; float blackVariation = sqrt(max(blackSquared / 12.0 - blackMean * blackMean, 0.0)); float whiteVariation = sqrt(max(whiteSquared / 12.0 - whiteMean * whiteMean, 0.0)); float blackScore = blackMean * (0.25 + 0.75 * blackCoverage) / (1.0 + 0.20 * blackVariation / (blackMean + 0.01)); float whiteScore = whiteMean * (0.25 + 0.75 * whiteCoverage) / (1.0 + 0.20 * whiteVariation / (whiteMean + 0.01)); if (radiusIndex == 0) { blackScaleScores.x = max(blackScaleScores.x, blackScore); whiteScaleScores.x = max(whiteScaleScores.x, whiteScore); } else if (radiusIndex == 1) { blackScaleScores.y = max(blackScaleScores.y, blackScore); whiteScaleScores.y = max(whiteScaleScores.y, whiteScore); } else { blackScaleScores.z = max(blackScaleScores.z, blackScore); whiteScaleScores.z = max(whiteScaleScores.z, whiteScore); } if (offsetX == 0 && offsetY == 0) { if (blackScore > fixedBlack) { fixedBlack = blackScore; fixedBlackRadiusIndex = float(radiusIndex); } if (whiteScore > fixedWhite) { fixedWhite = whiteScore; fixedWhiteRadiusIndex = float(radiusIndex); } } if (blackScore > bestBlack) { bestBlack = blackScore; bestBlackOffset = offset; bestBlackRadiusIndex = float(radiusIndex); } if (whiteScore > bestWhite) { bestWhite = whiteScore; bestWhiteOffset = offset; bestWhiteRadiusIndex = float(radiusIndex); } } } } vec3 fixedInner = vec3(0.0); vec3 blackInner = vec3(0.0); vec3 whiteInner = vec3(0.0); for (int angleIndex = 0; angleIndex < 8; ++angleIndex) { float angle = 2.0 * pi * (float(angleIndex) + 0.5) / 8.0; vec2 direction = vec2(cos(angle), sin(angle)) * spacing * 0.22; fixedInner += sampleImage(center + direction); blackInner += sampleImage(center + bestBlackOffset * spacing + direction); whiteInner += sampleImage(center + bestWhiteOffset * spacing + direction); } fixedInner /= 8.0; blackInner /= 8.0; whiteInner /= 8.0; float horizontalLineVisibility = 0.0; float verticalLineVisibility = 0.0; float lineSideOffset = max(1.5, spacing * 0.12); for (int direction = -2; direction <= 2; ++direction) { if (direction == 0) continue; float along = float(direction) * spacing * 0.14; float horizontalLine = sampleImage(center + vec2(along, 0.0)).g; float horizontalSides = 0.5 * ( sampleImage(center + vec2(along, -lineSideOffset)).g + sampleImage(center + vec2(along, lineSideOffset)).g ); horizontalLineVisibility += max(horizontalSides - horizontalLine, 0.0) * 0.25; float verticalLine = sampleImage(center + vec2(0.0, along)).g; float verticalSides = 0.5 * ( sampleImage(center + vec2(-lineSideOffset, along)).g + sampleImage(center + vec2(lineSideOffset, along)).g ); verticalLineVisibility += max(verticalSides - verticalLine, 0.0) * 0.25; } float blackCircleSum = 0.0; float whiteCircleSum = 0.0; float blackCircleCovered = 0.0; float whiteCircleCovered = 0.0; vec2 blackFirstMoment = vec2(0.0); vec2 whiteFirstMoment = vec2(0.0); vec2 blackSecondMoment = vec2(0.0); vec2 whiteSecondMoment = vec2(0.0); vec2 blackFourthMoment = vec2(0.0); vec2 whiteFourthMoment = vec2(0.0); float blackInnerSum = 0.0; float whiteInnerSum = 0.0; float blackInnerMinimum = 1.0; float whiteInnerMinimum = 1.0; float blackInnerMaximum = 0.0; float whiteInnerMaximum = 0.0; float blackRadius = spacing * (0.36 + 0.07 * bestBlackRadiusIndex); float whiteRadius = spacing * (0.36 + 0.07 * bestWhiteRadiusIndex); for (int angleIndex = 0; angleIndex < 12; ++angleIndex) { float angle = 2.0 * pi * float(angleIndex) / 12.0; vec2 direction = vec2(cos(angle), sin(angle)); vec3 blackInnerSample = sampleImage( center + bestBlackOffset * spacing + direction * blackRadius * 0.68 ); vec3 blackOuterSample = sampleImage( center + bestBlackOffset * spacing + direction * blackRadius * 1.16 ); vec3 whiteInnerSample = sampleImage( center + bestWhiteOffset * spacing + direction * whiteRadius * 0.68 ); vec3 whiteOuterSample = sampleImage( center + bestWhiteOffset * spacing + direction * whiteRadius * 1.16 ); float blackResponse = max(blackOuterSample.g - blackInnerSample.g, 0.0); float whiteResponse = max(whiteInnerSample.b - whiteOuterSample.b, 0.0); blackCircleSum += blackResponse; whiteCircleSum += whiteResponse; blackCircleCovered += step(0.035, blackResponse); whiteCircleCovered += step(0.035, whiteResponse); blackFirstMoment += vec2(cos(angle), sin(angle)) * blackResponse; whiteFirstMoment += vec2(cos(angle), sin(angle)) * whiteResponse; blackSecondMoment += vec2(cos(2.0 * angle), sin(2.0 * angle)) * blackResponse; whiteSecondMoment += vec2(cos(2.0 * angle), sin(2.0 * angle)) * whiteResponse; blackFourthMoment += vec2(cos(4.0 * angle), sin(4.0 * angle)) * blackResponse; whiteFourthMoment += vec2(cos(4.0 * angle), sin(4.0 * angle)) * whiteResponse; blackInnerSum += blackInnerSample.g; whiteInnerSum += whiteInnerSample.b; blackInnerMinimum = min(blackInnerMinimum, blackInnerSample.g); whiteInnerMinimum = min(whiteInnerMinimum, whiteInnerSample.b); blackInnerMaximum = max(blackInnerMaximum, blackInnerSample.g); whiteInnerMaximum = max(whiteInnerMaximum, whiteInnerSample.b); } float robustBlackInner = (blackInnerSum - blackInnerMinimum - blackInnerMaximum) / 10.0; float robustWhiteInner = (whiteInnerSum - whiteInnerMinimum - whiteInnerMaximum) / 10.0; float blackAnisotropy = max( max(length(blackFirstMoment), length(blackSecondMoment)), length(blackFourthMoment) ) / max(blackCircleSum, 0.000001); float whiteAnisotropy = max( max(length(whiteFirstMoment), length(whiteSecondMoment)), length(whiteFourthMoment) ) / max(whiteCircleSum, 0.000001); float blackClosure = clamp(1.0 - blackAnisotropy, 0.0, 1.0); float whiteClosure = clamp(1.0 - whiteAnisotropy, 0.0, 1.0); float blackCoverage = blackCircleCovered / 12.0; float whiteCoverage = whiteCircleCovered / 12.0; float blackPeak = 0.0; float whitePeak = 0.0; float blackSquarePeak = 0.0; float whiteSquarePeak = 0.0; vec2 blackSearchCenter = center + bestBlackOffset * spacing; vec2 whiteSearchCenter = center + bestWhiteOffset * spacing; vec2 blackPeakDelta = vec2(0.0); vec2 whitePeakDelta = vec2(0.0); for (int localY = -2; localY <= 2; ++localY) { for (int localX = -2; localX <= 2; ++localX) { vec2 delta = vec2(float(localX), float(localY)); vec4 blackCandidate = sampleCandidate(blackSearchCenter + delta); vec4 whiteCandidate = sampleCandidate(whiteSearchCenter + delta); float blackCandidateScore = candidateScore(blackCandidate, 1); float whiteCandidateScore = candidateScore(whiteCandidate, 2); if (blackCandidateScore > blackPeak) { blackPeak = blackCandidateScore; blackPeakDelta = delta; } if (whiteCandidateScore > whitePeak) { whitePeak = whiteCandidateScore; whitePeakDelta = delta; } blackSquarePeak = max(blackSquarePeak, candidateScore(blackCandidate, 3)); whiteSquarePeak = max(whiteSquarePeak, candidateScore(whiteCandidate, 4)); } } float crossPeak = cross11Response(center); vec2 blackPeakPoint = blackSearchCenter + blackPeakDelta; vec2 whitePeakPoint = whiteSearchCenter + whitePeakDelta; float continuationRadius = spacing * 0.42; float blackHorizontal = min( candidateScore(sampleCandidate(blackPeakPoint + vec2(-continuationRadius, 0.0)), 1), candidateScore(sampleCandidate(blackPeakPoint + vec2(continuationRadius, 0.0)), 1) ); float blackVertical = min( candidateScore(sampleCandidate(blackPeakPoint + vec2(0.0, -continuationRadius)), 1), candidateScore(sampleCandidate(blackPeakPoint + vec2(0.0, continuationRadius)), 1) ); float blackHorizontalBand = blackHorizontal / max(blackPeak, 0.000001); float blackVerticalBand = blackVertical / max(blackPeak, 0.000001); float whiteSquareRatio = whiteSquarePeak / max(whitePeak + whiteSquarePeak, 0.000001); scoreColor = vec4( bestBlackRadiusIndex + clamp(bestBlack, 0.0, 0.999), bestWhiteRadiusIndex + clamp(bestWhite, 0.0, 0.999), fixedBlackRadiusIndex + clamp(fixedBlack, 0.0, 0.999), fixedWhiteRadiusIndex + clamp(fixedWhite, 0.0, 0.999) ); offsetColor = (vec4(bestBlackOffset, bestWhiteOffset) + 0.5) * 4.0 + clamp(smallScores, 0.0, 0.999); appearanceColor = vec4(fixedInner, background.r); backgroundColor = vec4( floor(vec2(blackClosure, whiteClosure) * 255.0 + 0.5), packCoverage(blackCoverage), packCoverage(whiteCoverage) ) + min(vec4(background.gb, blackInner.g, whiteInner.b), vec4(0.999)); candidateShapeColor = clamp( vec4(blackHorizontalBand, blackVerticalBand, crossPeak, whiteSquareRatio), 0.0, 1.0 ); lineVisibilityColor = vec4( horizontalLineVisibility, verticalLineVisibility, min(horizontalLineVisibility, verticalLineVisibility), max(horizontalLineVisibility, verticalLineVisibility) ); shapePeakColor = vec4( blackPeak, whitePeak, floor(clamp(blackSquarePeak, 0.0, 1.0) * 255.0 + 0.5) + packLightMoment(blackFirstMoment / max(blackCircleSum, 0.000001)), packLightMoment(whiteFirstMoment / max(whiteCircleSum, 0.000001)) ); robustColor = vec4( pack3x8(blackScaleScores), pack3x8(whiteScaleScores), pack2x12(vec2(robustBlackInner, robustWhiteInner)), pack2x12(vec2( blackInnerMaximum - robustBlackInner, robustWhiteInner - whiteInnerMinimum )) ); }`,Cn=`#version 300 es
14
+ precision highp float; precision highp int; uniform sampler2D scoreImage; uniform sampler2D offsetImage; uniform int lineCount; uniform float minimumDistanceRatio; layout(location = 0) out vec4 ownershipColor; float candidateScore(ivec2 point, int color) { return fract(texelFetch(scoreImage, point, 0)[color]); } vec2 candidateOffset(ivec2 point, int color) { vec4 packed = texelFetch(offsetImage, point, 0); int base = color * 2; return floor(vec2(packed[base], packed[base + 1]) + 0.000001) * 0.25 - 0.5; } bool otherWins( float otherScore, ivec2 otherPoint, int otherColor, float currentScore, ivec2 currentPoint, int currentColor ) { if (otherScore > currentScore + 0.000001) return true; if (abs(otherScore - currentScore) > 0.000001) return false; if (otherPoint.y != currentPoint.y) return otherPoint.y < currentPoint.y; if (otherPoint.x != currentPoint.x) return otherPoint.x < currentPoint.x; return otherColor < currentColor; } void main() { ivec2 point = ivec2(gl_FragCoord.xy); vec2 kept = vec2(1.0); vec2 scores = vec2(candidateScore(point, 0), candidateScore(point, 1)); float limitSquared = minimumDistanceRatio * minimumDistanceRatio; for (int color = 0; color < 2; ++color) { vec2 center = vec2(point) + candidateOffset(point, color); for (int offsetY = -1; offsetY <= 1; ++offsetY) { for (int offsetX = -1; offsetX <= 1; ++offsetX) { ivec2 otherPoint = point + ivec2(offsetX, offsetY); if (otherPoint.x < 0 || otherPoint.y < 0 || otherPoint.x >= lineCount || otherPoint.y >= lineCount) continue; for (int otherColor = 0; otherColor < 2; ++otherColor) { if (otherPoint == point && otherColor == color) continue; vec2 otherCenter = vec2(otherPoint) + candidateOffset(otherPoint, otherColor); vec2 delta = center - otherCenter; if (dot(delta, delta) >= limitSquared) continue; float otherScore = candidateScore(otherPoint, otherColor); if (otherWins( otherScore, otherPoint, otherColor, scores[color], point, color )) { kept[color] = 0.0; } } } } } ownershipColor = vec4(kept, scores); }`,Qn=`#version 300 es
15
+ precision highp float; uniform sampler2D sourceImage; uniform vec2 imageSize; uniform int lineCount; uniform vec4 margins; uniform vec2 expectedOffset; out vec4 outputColor; vec3 sampleImage(vec2 point) { return texture(sourceImage, (point + 0.5) / imageSize).rgb; } void main() { vec2 grid = gl_FragCoord.xy - 0.5; vec2 extent = vec2( float(lineCount - 1) + margins.x + margins.y, float(lineCount - 1) + margins.z + margins.w ); vec2 base = (grid + vec2(margins.x, margins.z)) / extent * imageSize - 0.5; float spacing = 0.5 * (imageSize.x / extent.x + imageSize.y / extent.y); const float pi = 3.14159265358979323846; float background = 0.0; for (int yDirection = -1; yDirection <= 1; yDirection += 2) { for (int xDirection = -1; xDirection <= 1; xDirection += 2) { background += sampleImage( base + vec2(float(xDirection), float(yDirection)) * spacing * 0.5 ).g; } } background *= 0.25; float bestScore = 0.0; float bestCenterScore = 0.0; float bestRim = 0.0; vec2 bestOffset = expectedOffset; for (int offsetY = -1; offsetY <= 1; ++offsetY) { for (int offsetX = -1; offsetX <= 1; ++offsetX) { vec2 offset = clamp( expectedOffset + vec2(float(offsetX), float(offsetY)) * 0.20, vec2(-0.45), vec2(0.45) ); vec2 center = base + offset * spacing; for (int radiusIndex = 0; radiusIndex < 3; ++radiusIndex) { float radius = spacing * (0.36 + 0.07 * float(radiusIndex)); float sum = 0.0; float squared = 0.0; float covered = 0.0; float rim[12]; for (int angleIndex = 0; angleIndex < 12; ++angleIndex) { float angle = 2.0 * pi * float(angleIndex) / 12.0; vec2 direction = vec2(cos(angle), sin(angle)); float inner = sampleImage(center + direction * radius * 0.68).g; float outer = sampleImage(center + direction * radius * 1.16).g; float response = max(outer - inner, 0.0); sum += response; squared += response * response; covered += step(0.035, response); rim[angleIndex] = clamp( (background - inner) / max(background, 0.05), 0.0, 1.0 ); } float mean = sum / 12.0; float variation = sqrt(max(squared / 12.0 - mean * mean, 0.0)); float score = mean * (0.25 + 0.75 * covered / 12.0) / (1.0 + 0.20 * variation / (mean + 0.01)); float rimPairs = 0.0; for (int angleIndex = 0; angleIndex < 6; ++angleIndex) { rimPairs += min(rim[angleIndex], rim[angleIndex + 6]); } float centerScore = (score + 0.02) * (0.25 + rimPairs / 6.0); if (centerScore > bestCenterScore) { bestCenterScore = centerScore; bestScore = score; bestRim = rimPairs / 6.0; bestOffset = offset; } } } } outputColor = vec4(bestScore, bestRim, bestOffset); }`,LA=13,ln=.7,_t=.4,Bn=`#version 300 es
16
+ precision highp float; uniform sampler2D sourceImage; uniform sampler2D seedImage; uniform vec2 imageSize; uniform int lineCount; uniform vec4 margins; out vec4 outputColor; vec3 sampleImage(vec2 point) { return texture(sourceImage, (point + 0.5) / imageSize).rgb; } void main() { vec2 grid = gl_FragCoord.xy - 0.5; vec2 extent = vec2( float(lineCount - 1) + margins.x + margins.y, float(lineCount - 1) + margins.z + margins.w ); float spacing = 0.5 * (imageSize.x / extent.x + imageSize.y / extent.y); vec4 seed = texelFetch(seedImage, ivec2(grid), 0); vec2 base = ( grid + vec2(margins.x, margins.z) ) / extent * imageSize - 0.5; vec2 center = base + seed.ba * spacing; vec3 corners = ( sampleImage(center + vec2(-0.58, -0.58) * spacing) + sampleImage(center + vec2(0.58, -0.58) * spacing) + sampleImage(center + vec2(-0.58, 0.58) * spacing) + sampleImage(center + vec2(0.58, 0.58) * spacing) ) * 0.25; vec2 top[5]; for (int rank = 0; rank < 5; ++rank) top[rank] = vec2(0.0); for (int sampleY = 0; sampleY < 5; ++sampleY) { for (int sampleX = 0; sampleX < 5; ++sampleX) { vec2 sampleOffset = ( vec2(float(sampleX), float(sampleY)) / 4.0 - 0.5 ) * 0.90; vec3 sampleValue = sampleImage(center + sampleOffset * spacing); vec2 contrast = max( vec2(corners.g - sampleValue.g, sampleValue.b - corners.b), vec2(0.0) ); for (int rank = 0; rank < 5; ++rank) { bvec2 replace = greaterThan(contrast, top[rank]); vec2 displaced = top[rank]; top[rank] = mix(top[rank], contrast, replace); contrast = mix(contrast, displaced, replace); } } } outputColor = vec4(corners.g, corners.b, top[4] + 0.03); }`,En=`#version 300 es
17
+ precision highp float; precision highp int; uniform sampler2D sourceImage; uniform sampler2D seedImage; uniform sampler2D seedStatsImage; uniform vec2 imageSize; uniform int lineCount; uniform vec4 margins; out vec4 outputColor; vec3 sampleImage(vec2 point) { return texture(sourceImage, (point + 0.5) / imageSize).rgb; } vec2 normalizeSample(vec2 center, vec2 delta, float spacing, vec4 stats) { vec3 value = sampleImage(center + delta * spacing); return clamp( vec2(stats.r - value.g, value.b - stats.g) / stats.ba, vec2(-1.0), vec2(2.0) ); } void main() { vec2 extent = vec2( float(lineCount - 1) + margins.x + margins.y, float(lineCount - 1) + margins.z + margins.w ); float spacing = 0.5 * (imageSize.x / extent.x + imageSize.y / extent.y); vec2 delta = ((gl_FragCoord.xy - 0.5) / 12.0 - 0.5) * 1.2; vec2 sum = vec2(0.0); vec2 count = vec2(0.0); for (int row = 0; row < 19; ++row) { if (row >= lineCount) break; for (int column = 0; column < 19; ++column) { if (column >= lineCount) break; vec4 seed = texelFetch(seedImage, ivec2(column, row), 0); if (seed.r + seed.g < 0.5) continue; vec2 base = ( vec2(float(column), float(row)) + vec2(margins.x, margins.z) ) / extent * imageSize - 0.5; vec4 stats = texelFetch(seedStatsImage, ivec2(column, row), 0); vec2 value = normalizeSample( base + seed.ba * spacing, delta, spacing, stats ); sum += value * seed.rg; count += seed.rg; } } outputColor = vec4(sum / max(count, vec2(1.0)), count); }`,Dn=`#version 300 es
18
+ precision highp float; precision highp int; uniform sampler2D sourceImage; uniform sampler2D seedImage; uniform sampler2D seedStatsImage; uniform sampler2D templateImage; uniform vec2 imageSize; uniform int lineCount; uniform vec4 margins; out vec4 outputColor; vec3 sampleImage(vec2 point) { return texture(sourceImage, (point + 0.5) / imageSize).rgb; } vec2 normalizeSample(vec2 center, vec2 delta, float spacing, vec4 stats) { vec3 value = sampleImage(center + delta * spacing); return clamp( vec2(stats.r - value.g, value.b - stats.g) / stats.ba, vec2(-1.0), vec2(2.0) ); } void main() { vec2 extent = vec2( float(lineCount - 1) + margins.x + margins.y, float(lineCount - 1) + margins.z + margins.w ); float spacing = 0.5 * (imageSize.x / extent.x + imageSize.y / extent.y); vec2 delta = ((gl_FragCoord.xy - 0.5) / 12.0 - 0.5) * 1.2; vec2 expected = texelFetch( templateImage, ivec2(gl_FragCoord.xy - 0.5), 0 ).rg; vec2 sum = vec2(0.0); vec2 count = vec2(0.0); for (int row = 0; row < 19; ++row) { if (row >= lineCount) break; for (int column = 0; column < 19; ++column) { if (column >= lineCount) break; vec4 seed = texelFetch(seedImage, ivec2(column, row), 0); if (seed.r + seed.g < 0.5) continue; vec2 base = ( vec2(float(column), float(row)) + vec2(margins.x, margins.z) ) / extent * imageSize - 0.5; vec4 stats = texelFetch(seedStatsImage, ivec2(column, row), 0); vec2 difference = abs( normalizeSample( base + seed.ba * spacing, delta, spacing, stats ) - expected ); sum += difference * seed.rg; count += seed.rg; } } outputColor = vec4(sum / max(count, vec2(1.0)), count); }`,un=`#version 300 es
19
+ precision highp float; precision highp int; uniform sampler2D sourceImage; uniform sampler2D seedImage; uniform sampler2D seedStatsImage; uniform sampler2D templateImage; uniform sampler2D residualImage; uniform vec2 imageSize; uniform int lineCount; uniform vec4 margins; out vec4 outputColor; vec3 sampleImage(vec2 point) { return texture(sourceImage, (point + 0.5) / imageSize).rgb; } void main() { ivec2 grid = ivec2(gl_FragCoord.xy - 0.5); vec4 seed = texelFetch(seedImage, grid, 0); if (seed.r + seed.g < 0.5) { outputColor = vec4(1000.0); return; } vec2 extent = vec2( float(lineCount - 1) + margins.x + margins.y, float(lineCount - 1) + margins.z + margins.w ); float spacing = 0.5 * (imageSize.x / extent.x + imageSize.y / extent.y); vec2 base = ( vec2(grid) + vec2(margins.x, margins.z) ) / extent * imageSize - 0.5; vec2 center = base + seed.ba * spacing; vec4 stats = texelFetch(seedStatsImage, grid, 0); vec2 error = vec2(0.0); vec2 weightSum = vec2(0.0); for (int y = 0; y < 13; ++y) { for (int x = 0; x < 13; ++x) { ivec2 point = ivec2(x, y); vec2 expected = texelFetch(templateImage, point, 0).rg; vec2 residual = texelFetch(residualImage, point, 0).rg; vec2 weight = min(vec2(1.0) / (residual + 0.03), vec2(33.333)); vec2 delta = (vec2(float(x), float(y)) / 12.0 - 0.5) * 1.2; vec3 value = sampleImage(center + delta * spacing); vec2 normalized = clamp( vec2(stats.r - value.g, value.b - stats.g) / stats.ba, vec2(-1.0), vec2(2.0) ); error += weight * abs(normalized - expected); weightSum += weight; } } outputColor = vec4(error / weightSum, 0.0, 0.0); }`,dn=`#version 300 es
20
+ precision highp float; precision highp int; uniform sampler2D sourceImage; uniform sampler2D seedImage; uniform sampler2D seedStatsImage; uniform vec2 imageSize; uniform int lineCount; uniform vec4 margins; out vec4 outputColor; vec3 sampleImage(vec2 point) { return texture(sourceImage, (point + 0.5) / imageSize).rgb; } vec2 normalizeSample(vec2 center, vec2 delta, float spacing, vec4 stats) { vec3 value = sampleImage(center + delta * spacing); return clamp( vec2(stats.r - value.g, value.b - stats.g) / stats.ba, vec2(-1.0), vec2(2.0) ); } void main() { float blackHistogram[32]; float whiteHistogram[32]; for (int bin = 0; bin < 32; ++bin) { blackHistogram[bin] = 0.0; whiteHistogram[bin] = 0.0; } vec2 extent = vec2( float(lineCount - 1) + margins.x + margins.y, float(lineCount - 1) + margins.z + margins.w ); float spacing = 0.5 * (imageSize.x / extent.x + imageSize.y / extent.y); vec2 delta = ((gl_FragCoord.xy - 0.5) / 12.0 - 0.5) * 1.2; vec2 count = vec2(0.0); for (int row = 0; row < 19; ++row) { if (row >= lineCount) break; for (int column = 0; column < 19; ++column) { if (column >= lineCount) break; vec4 seed = texelFetch(seedImage, ivec2(column, row), 0); if (seed.r + seed.g < 0.5) continue; vec2 base = ( vec2(float(column), float(row)) + vec2(margins.x, margins.z) ) / extent * imageSize - 0.5; vec4 stats = texelFetch(seedStatsImage, ivec2(column, row), 0); vec2 value = normalizeSample( base + seed.ba * spacing, delta, spacing, stats ); ivec2 bin = ivec2(floor((value + 1.0) / 3.0 * 31.0 + 0.5)); blackHistogram[bin.x] += seed.r; whiteHistogram[bin.y] += seed.g; count += seed.rg; } } vec2 cumulative = vec2(0.0); vec2 median = vec2(-1.0); bvec2 found = bvec2(false); for (int bin = 0; bin < 32; ++bin) { cumulative += vec2(blackHistogram[bin], whiteHistogram[bin]); float value = float(bin) / 31.0 * 3.0 - 1.0; if (!found.x && cumulative.x >= count.x * 0.5) { median.x = value; found.x = true; } if (!found.y && cumulative.y >= count.y * 0.5) { median.y = value; found.y = true; } } outputColor = vec4(median, count); }`,mn=`#version 300 es
21
+ precision highp float; precision highp int; uniform sampler2D sourceImage; uniform sampler2D templateImage; uniform sampler2D residualImage; uniform vec2 imageSize; uniform int lineCount; uniform vec4 margins; uniform vec3 blackOffsetX; uniform vec3 blackOffsetY; uniform vec3 whiteOffsetX; uniform vec3 whiteOffsetY; layout(location = 0) out vec4 matchColor; layout(location = 1) out vec4 whiteOffsetColor; vec3 sampleImage(vec2 point) { return texture(sourceImage, (point + 0.5) / imageSize).rgb; } float matchAt(vec2 center, float spacing, int color) { vec3 corners = ( sampleImage(center + vec2(-0.58, -0.58) * spacing) + sampleImage(center + vec2(0.58, -0.58) * spacing) + sampleImage(center + vec2(-0.58, 0.58) * spacing) + sampleImage(center + vec2(0.58, 0.58) * spacing) ) * 0.25; float top[5]; for (int rank = 0; rank < 5; ++rank) top[rank] = 0.0; for (int sampleY = 0; sampleY < 5; ++sampleY) { for (int sampleX = 0; sampleX < 5; ++sampleX) { vec2 sampleOffset = ( vec2(float(sampleX), float(sampleY)) / 4.0 - 0.5 ) * 0.90; vec3 sampleValue = sampleImage(center + sampleOffset * spacing); float contrast = color == 0 ? max(corners.g - sampleValue.g, 0.0) : max(sampleValue.b - corners.b, 0.0); for (int rank = 0; rank < 5; ++rank) { if (contrast > top[rank]) { float displaced = top[rank]; top[rank] = contrast; contrast = displaced; } } } } float scale = top[4] + 0.03; float error = 0.0; float weightSum = 0.0; for (int y = 0; y < 13; ++y) { for (int x = 0; x < 13; ++x) { ivec2 point = ivec2(x, y); vec2 expected = texelFetch(templateImage, point, 0).rg; vec2 residual = texelFetch(residualImage, point, 0).rg; float expectedValue = color == 0 ? expected.r : expected.g; float residualValue = color == 0 ? residual.r : residual.g; float weight = min(1.0 / (residualValue + 0.03), 33.333); vec2 delta = (vec2(float(x), float(y)) / 12.0 - 0.5) * 1.2; vec3 value = sampleImage(center + delta * spacing); float normalized = color == 0 ? (corners.g - value.g) / scale : (value.b - corners.b) / scale; error += weight * abs(clamp(normalized, -1.0, 2.0) - expectedValue); weightSum += weight; } } return error / weightSum; } void main() { vec2 grid = gl_FragCoord.xy - 0.5; vec2 normalizedGrid = grid / float(lineCount - 1) - 0.5; vec3 coordinate = vec3(1.0, normalizedGrid); vec2 blackExpected = vec2( dot(blackOffsetX, coordinate), dot(blackOffsetY, coordinate) ); vec2 whiteExpected = vec2( dot(whiteOffsetX, coordinate), dot(whiteOffsetY, coordinate) ); vec2 extent = vec2( float(lineCount - 1) + margins.x + margins.y, float(lineCount - 1) + margins.z + margins.w ); vec2 base = (grid + vec2(margins.x, margins.z)) / extent * imageSize - 0.5; float spacing = 0.5 * (imageSize.x / extent.x + imageSize.y / extent.y); float bestBlack = 1000.0; float bestWhite = 1000.0; vec2 bestBlackOffset = blackExpected; vec2 bestWhiteOffset = whiteExpected; for (int offsetY = -1; offsetY <= 1; ++offsetY) { for (int offsetX = -1; offsetX <= 1; ++offsetX) { vec2 delta = vec2(float(offsetX), float(offsetY)) * 0.20; vec2 blackOffset = clamp(blackExpected + delta, vec2(-0.45), vec2(0.45)); vec2 whiteOffset = clamp(whiteExpected + delta, vec2(-0.45), vec2(0.45)); float black = matchAt(base + blackOffset * spacing, spacing, 0); float white = matchAt(base + whiteOffset * spacing, spacing, 1); if (black < bestBlack) { bestBlack = black; bestBlackOffset = blackOffset; } if (white < bestWhite) { bestWhite = white; bestWhiteOffset = whiteOffset; } } } matchColor = vec4(bestBlack, bestWhite, bestBlackOffset); whiteOffsetColor = vec4(bestWhiteOffset, 0.0, 0.0); }`,ze=class A{constructor(e,o={}){this.gl=e;this.options={squareKernelMode:o.squareKernelMode??2,colorFeatureMode:o.colorFeatureMode??0,intersectionMode:o.intersectionMode??2,lineKernelMode:o.lineKernelMode??0,lineMergeMode:o.lineMergeMode??0,lineSuppressionMode:o.lineSuppressionMode??3},this.normalization=xn(this.options.squareKernelMode),this.program=QA(e,CA,rn),this.shapeDensityProgram=QA(e,CA,tn),this.intersectionArmsProgram=QA(e,CA,on),this.filterProgram=QA(e,CA,nn),this.lineClassifyProgram=QA(e,CA,an),this.stoneMaskProgram=QA(e,CA,gn),this.lineCleanupProgram=QA(e,CA,In),this.rectifyProgram=QA(e,CA,sn),this.gridCircleProgram=QA(e,CA,cn),this.gridBlackValidationProgram=QA(e,CA,Qn),this.gridTemplateStatsProgram=QA(e,CA,Bn),this.gridTemplateBuildProgram=QA(e,CA,En),this.gridTemplateResidualProgram=QA(e,CA,Dn),this.gridTemplateSeedErrorProgram=QA(e,CA,un),this.gridTemplateMedianProgram=QA(e,CA,dn),this.gridTemplateMatchProgram=QA(e,CA,mn),this.gridOwnershipProgram=QA(e,CA,Cn);let r=e.createVertexArray();if(!r)throw new Error("failed to create WebGL2 vertex array");this.vertexArray=r,e.bindVertexArray(r),e.disable(e.BLEND),e.disable(e.DEPTH_TEST),e.disable(e.CULL_FACE)}gl;program;shapeDensityProgram;intersectionArmsProgram;filterProgram;lineClassifyProgram;stoneMaskProgram;lineCleanupProgram;rectifyProgram;gridCircleProgram;gridBlackValidationProgram;gridTemplateStatsProgram;gridTemplateBuildProgram;gridTemplateResidualProgram;gridTemplateSeedErrorProgram;gridTemplateMedianProgram;gridTemplateMatchProgram;gridOwnershipProgram;vertexArray;normalization;options;static isBrowserSupported(){if(typeof document>"u"||typeof WebGL2RenderingContext>"u")return!1;let e=document.createElement("canvas").getContext("webgl2"),o=!!e?.getExtension("EXT_color_buffer_float");return e?.getExtension("WEBGL_lose_context")?.loseContext(),o}static createBrowser(e={}){if(typeof document>"u")return null;let o=document.createElement("canvas").getContext("webgl2",{alpha:!1,antialias:!1,depth:!1,stencil:!1,preserveDrawingBuffer:!1,premultipliedAlpha:!1});return!o||!o.getExtension("EXT_color_buffer_float")?null:new A(o,e)}detect(e,o,r,t=o,n=r,a=19,c=!1,C=!1,Q=!1){if(e.byteLength!==o*r*4)throw new Error("WebGL2 input must be contiguous RGBA8");if(o<=0||r<=0)throw new Error("WebGL2 input dimensions must be positive");if(t<=0||n<=0)throw new Error("WebGL2 source dimensions must be positive");let s=o,g=r,i=this.gl,B=performance.now(),E=_(i,i.RGBA8,o,r,i.RGBA,i.UNSIGNED_BYTE,e,i.NEAREST),l;if(Q){let q=128/Math.min(o,r),Y=Math.max(1,Math.round(o*q)),j=Math.max(1,Math.round(r*q)),T=_(i,i.RGBA32F,Y,j,i.RGBA,i.FLOAT,null,i.NEAREST),J=EA(i,T,"RGBA32F shape density"),L=performance.now();i.bindFramebuffer(i.FRAMEBUFFER,J),i.viewport(0,0,Y,j),i.useProgram(this.shapeDensityProgram),X(i,this.shapeDensityProgram,"sourceImage",E,0),i.uniform2i(O(i,this.shapeDensityProgram,"sourceSize"),o,r),i.uniform2i(O(i,this.shapeDensityProgram,"outputSize"),Y,j),i.drawArrays(i.TRIANGLES,0,3);let V=performance.now()-L,$=new Float32Array(Y*j*4),nA=performance.now();i.readBuffer(i.COLOR_ATTACHMENT0),i.readPixels(0,0,Y,j,i.RGBA,i.FLOAT,$);let DA=performance.now()-nA;i.deleteFramebuffer(J),i.deleteTexture(T),l={width:Y,height:j,raw:$,gpuMs:V,readbackMs:DA}}let I=_(i,i.RGBA32F,s,g,i.RGBA,i.FLOAT,null,i.NEAREST),u=EA(i,I,"RGBA32F convolution");i.bindFramebuffer(i.FRAMEBUFFER,u),i.viewport(0,0,s,g),i.useProgram(this.program),X(i,this.program,"sourceImage",E,0),i.uniform2i(O(i,this.program,"outputSize"),s,g),i.uniform1fv(O(i,this.program,"positiveSums"),this.normalization.positiveSums),i.uniform1fv(O(i,this.program,"negativeWeights"),this.normalization.negativeWeights),i.uniform1fv(O(i,this.program,"squareInnerWeights"),this.normalization.squareInnerWeights),i.uniform1fv(O(i,this.program,"squareBorderWeights"),this.normalization.squareBorderWeights),i.uniform1i(O(i,this.program,"squareKernelMode"),this.options.squareKernelMode),i.uniform1i(O(i,this.program,"colorFeatureMode"),this.options.colorFeatureMode),i.uniform1i(O(i,this.program,"intersectionMode"),this.options.intersectionMode),i.uniform1i(O(i,this.program,"lineKernelMode"),this.options.lineKernelMode),i.uniform1i(O(i,this.program,"postprocessEnabled"),0),i.uniform1i(O(i,this.program,"stoneMinimumWindow"),Te),i.uniform1i(O(i,this.program,"stoneMaximumWindow"),oe),i.uniform1i(O(i,this.program,"squareMinimumWindow"),Te),i.uniform1i(O(i,this.program,"squareMaximumWindow"),oe),i.uniform1i(O(i,this.program,"postprocessWhiteMode"),0),i.uniform1i(O(i,this.program,"postprocessBlackMode"),0),i.uniform1f(O(i,this.program,"postprocessWhiteSquarePenalty"),0),i.uniform1f(O(i,this.program,"postprocessBlackSquarePenalty"),0),i.drawArrays(i.TRIANGLES,0,3);let d,D=0;if(c){let q=performance.now(),Y=new Float32Array(s*g*4);i.readBuffer(i.COLOR_ATTACHMENT0),i.readPixels(0,0,s,g,i.RGBA,i.FLOAT,Y),D=performance.now()-q,d={width:s,height:g,raw:Y}}Hn(i,E,i.RGBA32F,s,g,i.RGBA,i.FLOAT,i.NEAREST);let h=_(i,i.RGBA32F,s,g,i.RGBA,i.FLOAT,null,i.NEAREST);dA(i,u,E,"RGBA32F filtered scores",i.COLOR_ATTACHMENT0),dA(i,u,h,"RGBA32F filter metadata",i.COLOR_ATTACHMENT1),i.drawBuffers([i.COLOR_ATTACHMENT0,i.COLOR_ATTACHMENT1]),i.viewport(0,0,s,g),i.useProgram(this.filterProgram),X(i,this.filterProgram,"scoreImage",I,0),i.uniform2i(O(i,this.filterProgram,"imageSize"),s,g),i.uniform1i(O(i,this.filterProgram,"lineMergeMode"),this.options.lineMergeMode),i.uniform1f(O(i,this.filterProgram,"stoneNmsRatio"),.5),i.drawArrays(i.TRIANGLES,0,3);let m;if(C){let q=new Float32Array(s*g*4),Y=new Float32Array(s*g*4);i.readBuffer(i.COLOR_ATTACHMENT0),i.readPixels(0,0,s,g,i.RGBA,i.FLOAT,q),i.readBuffer(i.COLOR_ATTACHMENT1),i.readPixels(0,0,s,g,i.RGBA,i.FLOAT,Y),m={filtered:q,metadata:Y}}let w=_(i,i.RGBA32F,s,g,i.RGBA,i.FLOAT,null,i.NEAREST),p=_(i,i.RGBA32F,s,g,i.RGBA,i.FLOAT,null,i.NEAREST);dA(i,u,w,"RGBA32F final candidates",i.COLOR_ATTACHMENT0),dA(i,u,p,"RGBA32F typed lines",i.COLOR_ATTACHMENT1),i.drawBuffers([i.COLOR_ATTACHMENT0,i.COLOR_ATTACHMENT1]),i.useProgram(this.lineClassifyProgram),X(i,this.lineClassifyProgram,"scoreImage",I,0),X(i,this.lineClassifyProgram,"filteredImage",E,1),X(i,this.lineClassifyProgram,"metadataImage",h,2),i.uniform2i(O(i,this.lineClassifyProgram,"imageSize"),s,g),i.uniform1i(O(i,this.lineClassifyProgram,"lineSuppressionMode"),this.options.lineSuppressionMode),i.drawArrays(i.TRIANGLES,0,3);let f=null,S=null;this.options.lineSuppressionMode===3&&(f=EA(i,h,"RGBA32F stone mask"),i.bindFramebuffer(i.FRAMEBUFFER,f),i.drawBuffers([i.COLOR_ATTACHMENT0]),i.useProgram(this.stoneMaskProgram),X(i,this.stoneMaskProgram,"candidateImage",w,0),i.uniform2i(O(i,this.stoneMaskProgram,"imageSize"),s,g),i.drawArrays(i.TRIANGLES,0,3),S=EA(i,I,"RGBA32F cleaned lines"),i.bindFramebuffer(i.FRAMEBUFFER,S),i.drawBuffers([i.COLOR_ATTACHMENT0]),i.useProgram(this.lineCleanupProgram),X(i,this.lineCleanupProgram,"stoneMaskImage",h,0),X(i,this.lineCleanupProgram,"lineImage",p,1),i.uniform2i(O(i,this.lineCleanupProgram,"imageSize"),s,g),i.drawArrays(i.TRIANGLES,0,3));let M=_(i,i.RGBA32F,s,g,i.RGBA,i.FLOAT,null,i.NEAREST),k=EA(i,M,"RGBA32F intersection arms");i.bindFramebuffer(i.FRAMEBUFFER,k),i.viewport(0,0,s,g),i.useProgram(this.intersectionArmsProgram),X(i,this.intersectionArmsProgram,"lineImage",S?I:p,0),i.uniform2i(O(i,this.intersectionArmsProgram,"imageSize"),s,g),i.drawArrays(i.TRIANGLES,0,3);let y=performance.now()-B,b=new Float32Array(s*g*4),G=new Float32Array(s*g*4),K=new Float32Array(s*g*4),P=performance.now();i.bindFramebuffer(i.FRAMEBUFFER,u),i.readBuffer(i.COLOR_ATTACHMENT0),i.readPixels(0,0,s,g,i.RGBA,i.FLOAT,b),S?(i.bindFramebuffer(i.FRAMEBUFFER,S),i.readBuffer(i.COLOR_ATTACHMENT0)):i.readBuffer(i.COLOR_ATTACHMENT1),i.readPixels(0,0,s,g,i.RGBA,i.FLOAT,G),i.bindFramebuffer(i.FRAMEBUFFER,k),i.readBuffer(i.COLOR_ATTACHMENT0),i.readPixels(0,0,s,g,i.RGBA,i.FLOAT,K);let R=i.getError(),x=performance.now()-P;if(f&&i.deleteFramebuffer(f),S&&i.deleteFramebuffer(S),i.deleteFramebuffer(k),i.deleteFramebuffer(u),i.deleteTexture(E),i.deleteTexture(h),i.deleteTexture(I),i.deleteTexture(w),i.deleteTexture(p),i.deleteTexture(M),R!==i.NO_ERROR)throw new Error(`WebGL2 convolution readback failed: 0x${R.toString(16)}`);let z=performance.now(),F=Rn(b,G,K,s,g,t,n,this.options.intersectionMode,a),N=performance.now()-z;return{candidates:F.candidates,squareCandidates:F.squareCandidates,darkFrameCandidates:F.darkFrameCandidates,intersectionCandidates:F.intersectionCandidates,lineEvidence:F.lineEvidence,localLineEvidence:F.localLineEvidence,typedLineEvidence:F.typedLineEvidence,connectedLines:F.connectedLines,perspectiveLines:F.perspectiveLines,gridLines:F.gridLines,lineLattices:F.lineLattices,stoneLines:F.stoneLines,resizedWidth:s,resizedHeight:g,uploadAndGpuMs:y,readbackMs:x,candidateScanMs:N,candidateDecodeMs:F.candidateDecodeMs,intersectionScanMs:F.intersectionScanMs,lineConnectMs:F.lineConnectMs,lineCandidateConnectMs:F.lineCandidateConnectMs,lineFeatureSupportMs:F.lineFeatureSupportMs,lineStoneRowsMs:F.lineStoneRowsMs,linePerspectiveSelectMs:F.linePerspectiveSelectMs,lineLatticeSelectMs:F.lineLatticeSelectMs,maxBlackScore:F.maxBlackScore,maxWhiteScore:F.maxWhiteScore,maxSquareScore:F.maxSquareScore,maxIntersectionScore:F.maxIntersectionScore,maxLocalHorizontalScore:F.maxLocalHorizontalScore,maxLocalVerticalScore:F.maxLocalVerticalScore,...d?{firstShader:d}:{},...l?{shapeDensity:l}:{},...m?{lineAnalysis:{...m,finalLines:G}}:{},firstShaderReadbackMs:D}}rectify(e,o,r,t,n,a,c,C){if(e.byteLength!==o*r*4)throw new Error("WebGL2 input must be contiguous RGBA8");if(t.length!==9)throw new Error("grid transform must contain nine values");let Q=this.gl;if(a<=0||c<=0)throw new Error("rectification output dimensions must be positive");let s=performance.now(),g=_(Q,Q.RGBA8,o,r,Q.RGBA,Q.UNSIGNED_BYTE,e,Q.LINEAR),i=_(Q,Q.RGBA8,a,c,Q.RGBA,Q.UNSIGNED_BYTE,null,Q.LINEAR),B=EA(Q,i,"RGBA8 rectification");Q.bindFramebuffer(Q.FRAMEBUFFER,B),Q.drawBuffers([Q.COLOR_ATTACHMENT0]),Q.viewport(0,0,a,c),Q.useProgram(this.rectifyProgram),X(Q,this.rectifyProgram,"sourceImage",g,0),Q.uniform2f(O(Q,this.rectifyProgram,"sourceSize"),o,r),Q.uniform2f(O(Q,this.rectifyProgram,"outputSize"),a,c),Q.uniform2f(O(Q,this.rectifyProgram,"gridMinimum"),-C[0],-C[2]),Q.uniform2f(O(Q,this.rectifyProgram,"gridExtent"),n-1+C[0]+C[1],n-1+C[2]+C[3]),Q.uniformMatrix3fv(O(Q,this.rectifyProgram,"gridToSource"),!1,new Float32Array([t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8]])),Q.drawArrays(Q.TRIANGLES,0,3);let E=new Uint8Array(a*c*4);Q.readPixels(0,0,a,c,Q.RGBA,Q.UNSIGNED_BYTE,E);let l=Q.getError();if(Q.deleteFramebuffer(B),Q.deleteTexture(g),Q.deleteTexture(i),l!==Q.NO_ERROR)throw new Error(`WebGL2 rectification readback failed: 0x${l.toString(16)}`);let I=new Uint8ClampedArray(E.length);return I.set(E),{data:I,width:a,height:c,elapsedMs:performance.now()-s}}postprocess(e,o,r,t,n,a,c=.25,C=-1,Q=.75,s=!1){if(e.byteLength!==o*r*4)throw new Error("postprocess input must be contiguous RGBA8");if(t<3||t>19)throw new Error("postprocess line count must be 3..19");if(a.gridToSource.length!==9||a.width<=0||a.height<=0)throw new Error("postprocess source bounds are invalid");let g=t-1+n[0]+n[1],i=t-1+n[2]+n[3],B=(o/g+r/i)*.5,{stone:E,square:l}=vn(B);if(![c,C].every(Z=>Number.isFinite(Z)&&Z>=-1&&Z<=2))throw new Error("postprocess penalties must be -1..2");if(!Number.isFinite(Q)||Q<.6||Q>.9)throw new Error("postprocess minimum stone distance ratio must be 0.6..0.9");let I=this.gl,u=_(I,I.RGBA8,o,r,I.RGBA,I.UNSIGNED_BYTE,e,I.NEAREST),d=_(I,I.RGBA32F,o,r,I.RGBA,I.FLOAT,null,I.NEAREST),D=EA(I,d,"RGBA32F postprocess convolution"),h=performance.now();I.bindFramebuffer(I.FRAMEBUFFER,D),I.drawBuffers([I.COLOR_ATTACHMENT0]),I.viewport(0,0,o,r),I.useProgram(this.program),X(I,this.program,"sourceImage",u,0),I.uniform2i(O(I,this.program,"outputSize"),o,r),I.uniform1fv(O(I,this.program,"positiveSums"),this.normalization.positiveSums),I.uniform1fv(O(I,this.program,"negativeWeights"),this.normalization.negativeWeights),I.uniform1fv(O(I,this.program,"squareInnerWeights"),this.normalization.squareInnerWeights),I.uniform1fv(O(I,this.program,"squareBorderWeights"),this.normalization.squareBorderWeights),I.uniform1i(O(I,this.program,"squareKernelMode"),this.options.squareKernelMode),I.uniform1i(O(I,this.program,"colorFeatureMode"),this.options.colorFeatureMode),I.uniform1i(O(I,this.program,"intersectionMode"),this.options.intersectionMode),I.uniform1i(O(I,this.program,"lineKernelMode"),this.options.lineKernelMode),I.uniform1i(O(I,this.program,"postprocessEnabled"),1),I.uniform1i(O(I,this.program,"stoneMinimumWindow"),E[0]),I.uniform1i(O(I,this.program,"stoneMaximumWindow"),E[1]),I.uniform1i(O(I,this.program,"squareMinimumWindow"),l[0]),I.uniform1i(O(I,this.program,"squareMaximumWindow"),l[1]),I.uniform1i(O(I,this.program,"postprocessWhiteMode"),c<0?0:1),I.uniform1i(O(I,this.program,"postprocessBlackMode"),C<0?0:1),I.uniform1f(O(I,this.program,"postprocessWhiteSquarePenalty"),Math.max(c,0)),I.uniform1f(O(I,this.program,"postprocessBlackSquarePenalty"),Math.max(C,0)),I.drawArrays(I.TRIANGLES,0,3);let m=new Float32Array(o*r*4);I.readBuffer(I.COLOR_ATTACHMENT0),I.readPixels(0,0,o,r,I.RGBA,I.FLOAT,m);let w=_(I,I.RGBA32F,t,t,I.RGBA,I.FLOAT,null,I.NEAREST),p=_(I,I.RGBA32F,t,t,I.RGBA,I.FLOAT,null,I.NEAREST),f=_(I,I.RGBA32F,t,t,I.RGBA,I.FLOAT,null,I.NEAREST),S=_(I,I.RGBA32F,t,t,I.RGBA,I.FLOAT,null,I.NEAREST),M=_(I,I.RGBA32F,t,t,I.RGBA,I.FLOAT,null,I.NEAREST),k=_(I,I.RGBA32F,t,t,I.RGBA,I.FLOAT,null,I.NEAREST),y=_(I,I.RGBA32F,t,t,I.RGBA,I.FLOAT,null,I.NEAREST),b=_(I,I.RGBA32F,t,t,I.RGBA,I.FLOAT,null,I.NEAREST),G=EA(I,w,"RGBA32F grid circle scores");dA(I,G,p,"RGBA32F grid circle offsets",I.COLOR_ATTACHMENT1),dA(I,G,f,"RGBA32F grid appearance",I.COLOR_ATTACHMENT2),dA(I,G,S,"RGBA32F grid background",I.COLOR_ATTACHMENT3),dA(I,G,M,"RGBA32F grid candidate shapes",I.COLOR_ATTACHMENT4),dA(I,G,k,"RGBA32F grid line visibility",I.COLOR_ATTACHMENT5),dA(I,G,y,"RGBA32F grid shape peaks",I.COLOR_ATTACHMENT6),dA(I,G,b,"RGBA32F grid robust features",I.COLOR_ATTACHMENT7),I.drawBuffers([I.COLOR_ATTACHMENT0,I.COLOR_ATTACHMENT1,I.COLOR_ATTACHMENT2,I.COLOR_ATTACHMENT3,I.COLOR_ATTACHMENT4,I.COLOR_ATTACHMENT5,I.COLOR_ATTACHMENT6,I.COLOR_ATTACHMENT7]),I.viewport(0,0,t,t),I.useProgram(this.gridCircleProgram),X(I,this.gridCircleProgram,"sourceImage",u,0),X(I,this.gridCircleProgram,"candidateImage",d,1),I.uniform2f(O(I,this.gridCircleProgram,"imageSize"),o,r),I.uniform1i(O(I,this.gridCircleProgram,"lineCount"),t),I.uniform4f(O(I,this.gridCircleProgram,"margins"),...n),I.drawArrays(I.TRIANGLES,0,3);let K=new Float32Array(t*t*4),P=new Float32Array(t*t*4),R=new Float32Array(t*t*4),x=new Float32Array(t*t*4),z=new Float32Array(t*t*4),F=new Float32Array(t*t*4),N=new Float32Array(t*t*4),q=new Float32Array(t*t*4);I.readBuffer(I.COLOR_ATTACHMENT0),I.readPixels(0,0,t,t,I.RGBA,I.FLOAT,K),I.readBuffer(I.COLOR_ATTACHMENT1),I.readPixels(0,0,t,t,I.RGBA,I.FLOAT,P),I.readBuffer(I.COLOR_ATTACHMENT2),I.readPixels(0,0,t,t,I.RGBA,I.FLOAT,R),I.readBuffer(I.COLOR_ATTACHMENT3),I.readPixels(0,0,t,t,I.RGBA,I.FLOAT,x),I.readBuffer(I.COLOR_ATTACHMENT4),I.readPixels(0,0,t,t,I.RGBA,I.FLOAT,z),I.readBuffer(I.COLOR_ATTACHMENT5),I.readPixels(0,0,t,t,I.RGBA,I.FLOAT,F),I.readBuffer(I.COLOR_ATTACHMENT6),I.readPixels(0,0,t,t,I.RGBA,I.FLOAT,N),I.readBuffer(I.COLOR_ATTACHMENT7),I.readPixels(0,0,t,t,I.RGBA,I.FLOAT,q);let Y=fn(K,P),j=_(I,I.RGBA32F,t,t,I.RGBA,I.FLOAT,null,I.NEAREST),T=EA(I,j,"RGBA32F grid black validation");I.bindFramebuffer(I.FRAMEBUFFER,T),I.drawBuffers([I.COLOR_ATTACHMENT0]),I.viewport(0,0,t,t),I.useProgram(this.gridBlackValidationProgram),X(I,this.gridBlackValidationProgram,"sourceImage",u,0),I.uniform2f(O(I,this.gridBlackValidationProgram,"imageSize"),o,r),I.uniform1i(O(I,this.gridBlackValidationProgram,"lineCount"),t),I.uniform4f(O(I,this.gridBlackValidationProgram,"margins"),...n),I.uniform2f(O(I,this.gridBlackValidationProgram,"expectedOffset"),Y[0],Y[1]),I.drawArrays(I.TRIANGLES,0,3);let J=new Float32Array(t*t*4);I.readPixels(0,0,t,t,I.RGBA,I.FLOAT,J),I.deleteFramebuffer(T),I.deleteTexture(j);let L=_(I,I.RGBA32F,t,t,I.RGBA,I.FLOAT,null,I.NEAREST),V=EA(I,L,"RGBA32F grid stone ownership");I.bindFramebuffer(I.FRAMEBUFFER,V),I.drawBuffers([I.COLOR_ATTACHMENT0]),I.viewport(0,0,t,t),I.useProgram(this.gridOwnershipProgram),X(I,this.gridOwnershipProgram,"scoreImage",w,0),X(I,this.gridOwnershipProgram,"offsetImage",p,1),I.uniform1i(O(I,this.gridOwnershipProgram,"lineCount"),t),I.uniform1f(O(I,this.gridOwnershipProgram,"minimumDistanceRatio"),Q),I.drawArrays(I.TRIANGLES,0,3);let $=new Float32Array(t*t*4);I.readPixels(0,0,t,t,I.RGBA,I.FLOAT,$),I.deleteFramebuffer(V),I.deleteTexture(L);let nA=new Float32Array(t*t*4);for(let Z=0;Z<t*t;Z++)for(let AA=0;AA<2;AA++){let rA=Z*4+AA+2,KA=N[rA],ge=Math.floor(KA+1e-6),Se=Math.min(65535,Math.max(0,Math.round((KA-ge)*65536)));N[rA]=ge/255,nA[Z*4+AA*2]=Math.floor(Se/256)/255*2-1,nA[Z*4+AA*2+1]=Se%256/255*2-1}let DA=new Uint8Array(t*t*4);for(let Z=0;Z<K.length;Z++){let AA=K[Z],rA=Math.floor(AA+1e-6);DA[Z]=rA,K[Z]=AA-rA}let aA=new Float32Array(t*t*4);for(let Z=0;Z<P.length;Z++){let AA=P[Z],rA=Math.floor(AA+1e-6);P[Z]=rA*.25-.5,aA[Z]=AA-rA}let gA=new Float32Array(t*t*4);for(let Z=0;Z<x.length;Z++){let AA=x[Z],rA=Math.floor(AA+1e-6);Z%4>=2?gA[Z]=rA/12:gA[Z]=rA/255,x[Z]=AA-rA}let kA=new Float32Array(t*t*6),mA=new Float32Array(t*t*4);for(let Z=0;Z<t*t;Z++){for(let AA=0;AA<2;AA++){let rA=Math.round(q[Z*4+AA]);for(let KA=0;KA<3;KA++)kA[Z*6+AA*3+KA]=rA%256/255,rA=Math.floor(rA/256)}for(let AA=0;AA<2;AA++){let rA=Math.round(q[Z*4+AA+2]);mA[Z*4+AA*2]=rA%4096/4095,mA[Z*4+AA*2+1]=Math.floor(rA/4096)/4095}}I.deleteFramebuffer(G),I.deleteTexture(w),I.deleteTexture(p),I.deleteTexture(f),I.deleteTexture(S),I.deleteTexture(M),I.deleteTexture(k),I.deleteTexture(y),I.deleteTexture(b),I.bindFramebuffer(I.FRAMEBUFFER,D),I.viewport(0,0,o,r);let XA=_(I,I.RGBA32F,o,r,I.RGBA,I.FLOAT,null,I.NEAREST),ZA=_(I,I.RGBA32F,o,r,I.RGBA,I.FLOAT,null,I.NEAREST);dA(I,D,XA,"RGBA32F postprocess filtered",I.COLOR_ATTACHMENT0),dA(I,D,ZA,"RGBA32F postprocess metadata",I.COLOR_ATTACHMENT1),I.drawBuffers([I.COLOR_ATTACHMENT0,I.COLOR_ATTACHMENT1]),I.useProgram(this.filterProgram),X(I,this.filterProgram,"scoreImage",d,0),I.uniform2i(O(I,this.filterProgram,"imageSize"),o,r),I.uniform1i(O(I,this.filterProgram,"lineMergeMode"),this.options.lineMergeMode),I.uniform1f(O(I,this.filterProgram,"stoneNmsRatio"),Q),I.drawArrays(I.TRIANGLES,0,3);let pA=performance.now()-h,ne=performance.now(),qA=new Float32Array(o*r*4);I.readBuffer(I.COLOR_ATTACHMENT0),I.readPixels(0,0,o,r,I.RGBA,I.FLOAT,qA);let VA=performance.now()-ne,YA=I.getError();if(YA!==I.NO_ERROR)throw new Error(`WebGL2 postprocess readback failed: 0x${YA.toString(16)}`);let _A=performance.now(),{values:H,offsets:W}=Gn(qA,m,o,r,t,n),tA=H.slice(),hA=W.slice(),oA=ut(H,W,K,P,R,x,aA,DA,gA,z,F,nA,kA,mA,J),wA=Pn(H,W,t,a);hn(H,W,tA,hA,P);let fA=wn(H,W,s);Mn(H,W,J);let vA=H.slice(),NA=W.slice();yn(H,W,oA,K,J,t,Q);let fe=performance.now()-_A,TA=performance.now(),ie=H.slice(),$A=this.matchGridTemplates(u,o,r,t,n,H,W,tA,K,P),je=performance.now(),ae=pn(H,W,tA,vA,NA,P,ie,$A.errors,$A.offsets,t,Q),Me=fe+performance.now()-je,pe=0;return pA+=performance.now()-TA,I.deleteFramebuffer(D),I.deleteTexture(u),I.deleteTexture(d),I.deleteTexture(XA),I.deleteTexture(ZA),{first:{width:o,height:r,candidates:m},second:{width:o,height:r,candidates:qA},gridScores:K,gridOffsets:P,gridAppearance:R,gridBackground:x,gridClassMargins:oA,gridSmallCircleScores:aA,gridCircleSizes:DA,gridCircleShapes:gA,gridCandidateShapes:z,gridLineVisibility:F,gridShapePeaks:N,gridLightMoments:nA,gridScaleResponses:kA,gridRobustAppearance:mA,gridBlackValidation:J,gridTemplateErrors:$A.errors,gridTemplateOffsets:$A.offsets,gridOwnership:$,gridInitialValues:tA,gridClassifiedValues:vA,gridClassifiedOffsets:NA,gridTemplateSeedValues:ie,values:H,offsets:W,encodedBoard:ae.encodedBoard,lineCount:t,gridSpacing:B,stoneWindowRange:E,squareWindowRange:l,whiteSquarePenalty:c,blackSquarePenalty:C,removedOutsideSource:wA,removedPhysicalConflicts:pe,resolvedPhysicalConflicts:ae.resolvedPhysicalConflicts,stoneOffsetVariance:fA,gpuSubmitMs:pA,readbackMs:VA,cpuMs:Me}}matchGridTemplates(e,o,r,t,n,a,c,C,Q,s){let g=this.gl,i=new Float32Array(t*t*4);for(let x=0;x<a.length;x++){let z=a[x];z!==1&&z!==2||(i[x*4+z-1]=1,i[x*4+2]=c[x*2],i[x*4+3]=c[x*2+1])}let B=_(g,g.RGBA32F,t,t,g.RGBA,g.FLOAT,i,g.NEAREST),E=_(g,g.RGBA32F,t,t,g.RGBA,g.FLOAT,null,g.NEAREST),l=EA(g,E,"RGBA32F stone template seed statistics");g.bindFramebuffer(g.FRAMEBUFFER,l),g.drawBuffers([g.COLOR_ATTACHMENT0]),g.viewport(0,0,t,t),g.useProgram(this.gridTemplateStatsProgram),X(g,this.gridTemplateStatsProgram,"sourceImage",e,0),X(g,this.gridTemplateStatsProgram,"seedImage",B,1),WA(g,this.gridTemplateStatsProgram,o,r,t,n),g.drawArrays(g.TRIANGLES,0,3);let I=_(g,g.RGBA32F,LA,LA,g.RGBA,g.FLOAT,null,g.NEAREST),u=EA(g,I,"RGBA32F stone templates");g.bindFramebuffer(g.FRAMEBUFFER,u),g.drawBuffers([g.COLOR_ATTACHMENT0]),g.viewport(0,0,LA,LA),g.useProgram(this.gridTemplateBuildProgram),X(g,this.gridTemplateBuildProgram,"sourceImage",e,0),X(g,this.gridTemplateBuildProgram,"seedImage",B,1),X(g,this.gridTemplateBuildProgram,"seedStatsImage",E,2),WA(g,this.gridTemplateBuildProgram,o,r,t,n),g.drawArrays(g.TRIANGLES,0,3);let d=_(g,g.RGBA32F,LA,LA,g.RGBA,g.FLOAT,null,g.NEAREST),D=EA(g,d,"RGBA32F stone template residuals");g.bindFramebuffer(g.FRAMEBUFFER,D),g.drawBuffers([g.COLOR_ATTACHMENT0]),g.useProgram(this.gridTemplateResidualProgram),X(g,this.gridTemplateResidualProgram,"sourceImage",e,0),X(g,this.gridTemplateResidualProgram,"seedImage",B,1),X(g,this.gridTemplateResidualProgram,"seedStatsImage",E,2),X(g,this.gridTemplateResidualProgram,"templateImage",I,3),WA(g,this.gridTemplateResidualProgram,o,r,t,n),g.drawArrays(g.TRIANGLES,0,3);let h=_(g,g.RGBA32F,LA,LA,g.RGBA,g.FLOAT,null,g.NEAREST),m=EA(g,h,"RGBA32F robust stone templates"),w=_(g,g.RGBA32F,t,t,g.RGBA,g.FLOAT,null,g.NEAREST),p=EA(g,w,"RGBA32F stone template seed errors");g.bindFramebuffer(g.FRAMEBUFFER,p),g.drawBuffers([g.COLOR_ATTACHMENT0]),g.viewport(0,0,t,t),g.useProgram(this.gridTemplateSeedErrorProgram),X(g,this.gridTemplateSeedErrorProgram,"sourceImage",e,0),X(g,this.gridTemplateSeedErrorProgram,"seedImage",B,1),X(g,this.gridTemplateSeedErrorProgram,"seedStatsImage",E,2),X(g,this.gridTemplateSeedErrorProgram,"templateImage",I,3),X(g,this.gridTemplateSeedErrorProgram,"residualImage",d,4),WA(g,this.gridTemplateSeedErrorProgram,o,r,t,n),g.drawArrays(g.TRIANGLES,0,3);let f=new Float32Array(t*t*4);g.readPixels(0,0,t,t,g.RGBA,g.FLOAT,f);for(let x=0;x<2;x++){let z=Array.from({length:t*t},(N,q)=>q).filter(N=>i[N*4+x]>.5).map(N=>f[N*4+x]);if(z.length<5)continue;let F=kn(z,ln);for(let N=0;N<t*t;N++)i[N*4+x]>.5&&f[N*4+x]>F&&(i[N*4+x]=0)}g.bindTexture(g.TEXTURE_2D,B),g.texSubImage2D(g.TEXTURE_2D,0,0,0,t,t,g.RGBA,g.FLOAT,i),g.bindFramebuffer(g.FRAMEBUFFER,m),g.drawBuffers([g.COLOR_ATTACHMENT0]),g.viewport(0,0,LA,LA),g.useProgram(this.gridTemplateMedianProgram),X(g,this.gridTemplateMedianProgram,"sourceImage",e,0),X(g,this.gridTemplateMedianProgram,"seedImage",B,1),X(g,this.gridTemplateMedianProgram,"seedStatsImage",E,2),WA(g,this.gridTemplateMedianProgram,o,r,t,n),g.drawArrays(g.TRIANGLES,0,3),g.bindFramebuffer(g.FRAMEBUFFER,D),g.drawBuffers([g.COLOR_ATTACHMENT0]),g.useProgram(this.gridTemplateResidualProgram),X(g,this.gridTemplateResidualProgram,"sourceImage",e,0),X(g,this.gridTemplateResidualProgram,"seedImage",B,1),X(g,this.gridTemplateResidualProgram,"seedStatsImage",E,2),X(g,this.gridTemplateResidualProgram,"templateImage",h,3),WA(g,this.gridTemplateResidualProgram,o,r,t,n),g.drawArrays(g.TRIANGLES,0,3);let S=_(g,g.RGBA32F,t,t,g.RGBA,g.FLOAT,null,g.NEAREST),M=_(g,g.RGBA32F,t,t,g.RGBA,g.FLOAT,null,g.NEAREST),k=EA(g,S,"RGBA32F stone template matches");dA(g,k,M,"RGBA32F white template offsets",g.COLOR_ATTACHMENT1),g.bindFramebuffer(g.FRAMEBUFFER,k),g.drawBuffers([g.COLOR_ATTACHMENT0,g.COLOR_ATTACHMENT1]),g.viewport(0,0,t,t),g.useProgram(this.gridTemplateMatchProgram),X(g,this.gridTemplateMatchProgram,"sourceImage",e,0),X(g,this.gridTemplateMatchProgram,"templateImage",h,1),X(g,this.gridTemplateMatchProgram,"residualImage",d,2),WA(g,this.gridTemplateMatchProgram,o,r,t,n);let y=Ao(C,Q,s,t,1),b=Ao(C,Q,s,t,2);for(let[x,z]of[["blackOffsetX",y.x],["blackOffsetY",y.y],["whiteOffsetX",b.x],["whiteOffsetY",b.y]])g.uniform3f(O(g,this.gridTemplateMatchProgram,x),z[0],z[1],z[2]);g.drawArrays(g.TRIANGLES,0,3);let G=new Float32Array(t*t*4),K=new Float32Array(t*t*4);g.readBuffer(g.COLOR_ATTACHMENT0),g.readPixels(0,0,t,t,g.RGBA,g.FLOAT,G),g.readBuffer(g.COLOR_ATTACHMENT1),g.readPixels(0,0,t,t,g.RGBA,g.FLOAT,K);let P=new Float32Array(t*t*2),R=new Float32Array(t*t*4);for(let x=0;x<t*t;x++)P[x*2]=G[x*4],P[x*2+1]=G[x*4+1],R[x*4]=G[x*4+2],R[x*4+1]=G[x*4+3],R[x*4+2]=K[x*4],R[x*4+3]=K[x*4+1];return g.deleteFramebuffer(l),g.deleteFramebuffer(u),g.deleteFramebuffer(D),g.deleteFramebuffer(p),g.deleteFramebuffer(m),g.deleteFramebuffer(k),g.deleteTexture(B),g.deleteTexture(E),g.deleteTexture(I),g.deleteTexture(d),g.deleteTexture(w),g.deleteTexture(h),g.deleteTexture(S),g.deleteTexture(M),{errors:P,offsets:R}}dispose(){this.gl.deleteProgram(this.program),this.gl.deleteProgram(this.filterProgram),this.gl.deleteProgram(this.lineClassifyProgram),this.gl.deleteProgram(this.stoneMaskProgram),this.gl.deleteProgram(this.lineCleanupProgram),this.gl.deleteProgram(this.rectifyProgram),this.gl.deleteProgram(this.gridCircleProgram),this.gl.deleteProgram(this.gridBlackValidationProgram),this.gl.deleteProgram(this.gridTemplateStatsProgram),this.gl.deleteProgram(this.gridTemplateBuildProgram),this.gl.deleteProgram(this.gridTemplateResidualProgram),this.gl.deleteProgram(this.gridTemplateSeedErrorProgram),this.gl.deleteProgram(this.gridTemplateMedianProgram),this.gl.deleteProgram(this.gridTemplateMatchProgram),this.gl.deleteProgram(this.gridOwnershipProgram),this.gl.deleteVertexArray(this.vertexArray),this.gl.getExtension("WEBGL_lose_context")?.loseContext()}};function wn(A,e,o){let r=uA();if(!r||e.length!==A.length*2)return null;let t=r.a.buffer;new Uint8Array(t,r.ae(),A.length).set(A),new Float32Array(t,r.af(),e.length).set(e);let n=r.ag(),a=Vr();new Uint8Array(t,n,a.length).set(a);let c=r.ah(A.length,4,n,Number(o));return Number.isFinite(c)&&c>=0?c:null}function hn(A,e,o,r,t){for(let n=0;n<A.length;n++){let a=A[n];if(a!==1&&a!==2)continue;if(o[n]!==0){e[n*2]=r[n*2],e[n*2+1]=r[n*2+1];continue}let c=n*4+(a-1)*2;e[n*2]=t[c],e[n*2+1]=t[c+1]}}function fn(A,e){let o=0;for(let a=0;a<A.length;a+=4)o=Math.max(o,A[a]%1);let r=[],t=[],n=Math.max(.08,o*.55);for(let a=0;a<A.length;a+=4)A[a]%1<n||(r.push(Math.floor(e[a]+1e-6)*.25-.5),t.push(Math.floor(e[a+1]+1e-6)*.25-.5));return[jA(r),jA(t)]}function Mn(A,e,o){for(let r=0;r<A.length;r++)A[r]===1&&(e[r*2]=o[r*4+2],e[r*2+1]=o[r*4+3])}function pn(A,e,o,r,t,n,a,c,C,Q,s){let g=$r?uA():null,i=Q*Q;if(g&&A.length===i&&e.length===i*2&&o.length===i&&r.length===i&&t.length===i*2&&n.length===i*4&&a.length===i&&c.length===i*2&&C.length===i*4){let B=g.a.buffer;if(new Uint8Array(B,g.V(),i).set(o),new Uint8Array(B,g.W(),i).set(r),new Float32Array(B,g.X(),i*2).set(t),new Float32Array(B,g.Y(),i*4).set(n),new Uint8Array(B,g.Z(),i).set(a),new Float32Array(B,g.aa(),i*2).set(c),new Float32Array(B,g.ab(),i*4).set(C),g.ak(Q,s)===0){A.set(new Uint8Array(B,g.T(),i)),e.set(new Float32Array(B,g.U(),i*2));let E=new Uint32Array(B,g.ad(),2),l=E[1];if(l<=i){let I=new Uint8Array(l);return I.set(new Uint8Array(B,g.ac(),l)),{resolvedPhysicalConflicts:E[0],encodedBoard:I}}}}return{resolvedPhysicalConflicts:Sn(A,e,o,r,t,n,a,c,C,Q,s),encodedBoard:null}}function Sn(A,e,o,r,t,n,a,c,C,Q,s){let g=bn(a,C,Q),i=l=>{let I=l%Q/(Q-1)-.5,u=Math.floor(l/Q)/(Q-1)-.5;return[g.x[0]+g.x[1]*I+g.x[2]*u,g.y[0]+g.y[1]*I+g.y[2]*u]};for(let l=0;l<A.length;l++){let I=r[l],u=o[l];if(I!==0&&u!==0){let w=3-I,p=c[l*2+I-1],f=c[l*2+u-1],S=c[l*2+w-1];u!==I&&f<p*_t?I=u:u===I&&S<p*_t&&(I=w)}if(A[l]=I,I===0){e[l*2]=0,e[l*2+1]=0;continue}let d=l*4+(I-1)*2,D=I===r[l]?t[l*2]:n[d],h=I===r[l]?t[l*2+1]:n[d+1],m=i(l);e[l*2]=$t(C[d],D,m[0]),e[l*2+1]=$t(C[d+1],h,m[1])}let B=new Uint8Array(A.length),E=()=>{let l=new Uint8Array(A.length),I=s*s;for(let u=0;u<A.length;u++){if(A[u]===0)continue;let d=u%Q,D=Math.floor(u/Q);for(let h=-1;h<=1;h++)for(let m=-1;m<=1;m++){let w=d+m,p=D+h;if(w<0||w>=Q||p<0||p>=Q)continue;let f=p*Q+w;if(f<=u||A[f]===0)continue;let S=d+e[u*2]-w-e[f*2],M=D+e[u*2+1]-p-e[f*2+1];S*S+M*M>=I||(l[u]=1,l[f]=1)}}return l};for(let l=0;l<4;l++){let I=E();if(!I.some(Boolean))break;for(let u=0;u<A.length;u++)I[u]&&([e[u*2],e[u*2+1]]=i(u),B[u]=1)}if(E().some(Boolean))for(let l=0;l<A.length;l++)A[l]!==0&&([e[l*2],e[l*2+1]]=i(l),B[l]=1);return E().some(Boolean)&&e.fill(0),B.reduce((l,I)=>l+I,0)}function $t(A,e,o){return Math.max(Math.min(A,e),Math.min(Math.max(A,e),o))}function bn(A,e,o){let r=[[0,0,0],[0,0,0],[0,0,0]],t=[0,0,0],n=[0,0,0],a=[],c=[],C=0;for(let s=0;s<A.length;s++){let g=A[s];if(g!==1&&g!==2)continue;let i=s%o/(o-1)-.5,B=Math.floor(s/o)/(o-1)-.5,E=[1,i,B],l=s*4+(g-1)*2,I=e[l],u=e[l+1];a.push(I),c.push(u),C++;for(let d=0;d<3;d++){t[d]+=E[d]*I,n[d]+=E[d]*u;for(let D=0;D<3;D++)r[d][D]+=E[d]*E[D]}}let Q=s=>[jA(s),0,0];return C<3?{x:Q(a),y:Q(c)}:{x:Oe(r.map(s=>[...s]),t)??Q(a),y:Oe(r.map(s=>[...s]),n)??Q(c)}}function yn(A,e,o,r,t,n,a){let c=a*a,C=0,Q=0;for(let s=0;s<3;s++){let g=!1;for(let i=0;i<A.length;i++){if(A[i]===0)continue;let B=i%n,E=Math.floor(i/n),l=B+e[i*2],I=E+e[i*2+1],u=!1;for(let d=-1;d<=1&&!u;d++)for(let D=-1;D<=1;D++){let h=B+D,m=E+d;if(h<0||h>=n||m<0||m>=n)continue;let w=m*n+h;if(w<=i||A[w]===0)continue;let p=l-h-e[w*2],f=I-m-e[w*2+1];if(p*p+f*f>=c)continue;let S=b=>A[b]===1?t[b*4]:r[b*4+1],M=S(i),k=S(w),y=M!==k?M>k?w:i:o[i]>=o[w]?w:i;if(A[y]=0,e[y*2]=0,e[y*2+1]=0,C++,g=!0,u=y===i,u)break}}if(!g)break}return{removed:C,resolved:Q}}function jA(A){return A.length?(A.sort((e,o)=>e-o),A[Math.floor((A.length-1)*.5)]):0}function kn(A,e){return A.length?(A.sort((o,r)=>o-r),A[Math.floor((A.length-1)*e)]):0}function WA(A,e,o,r,t,n){A.uniform2f(O(A,e,"imageSize"),o,r),A.uniform1i(O(A,e,"lineCount"),t),A.uniform4f(O(A,e,"margins"),...n)}function Ao(A,e,o,r,t){let n=t-1,a=Array.from(A.entries()).filter(([,B])=>B===t).map(([B])=>e[B*4+n]),c=jA(a),C=[];for(let B=0;B<A.length;B++)A[B]!==t||e[B*4+n]<c||C.push([B%r/(r-1)-.5,Math.floor(B/r)/(r-1)-.5,o[B*4+n*2],o[B*4+n*2+1]]);let Q=()=>[jA(C.map(B=>B[2])),0,0];if(C.length<3)return{x:Q(),y:[jA(C.map(B=>B[3])),0,0]};let s=[[0,0,0],[0,0,0],[0,0,0]],g=[0,0,0],i=[0,0,0];for(let[B,E,l,I]of C){let u=[1,B,E];for(let d=0;d<3;d++){g[d]+=u[d]*l,i[d]+=u[d]*I;for(let D=0;D<3;D++)s[d][D]+=u[d]*u[D]}}return{x:Oe(s,g)??Q(),y:Oe(s,i)??[jA(C.map(B=>B[3])),0,0]}}function Oe(A,e){let o=A.map((r,t)=>[...r,e[t]]);for(let r=0;r<3;r++){let t=r;for(let a=r+1;a<3;a++)Math.abs(o[a][r])>Math.abs(o[t][r])&&(t=a);[o[r],o[t]]=[o[t],o[r]];let n=o[r][r];if(Math.abs(n)<1e-8)return null;for(let a=r;a<4;a++)o[r][a]/=n;for(let a=0;a<3;a++){if(a===r)continue;let c=o[a][r];for(let C=r;C<4;C++)o[a][C]-=c*o[r][C]}}return[o[0][3],o[1][3],o[2][3]]}function vn(A){let e=o=>{let r=Math.max(Te,Math.min(oe,Math.floor(o))),t=Math.max(r,Math.min(oe,Math.ceil(o)));return[r,t]};return{stone:e(A+1),square:e(A)}}function Gn(A,e,o,r,t,n){let a=_r?uA():null;return a&&o<=a.M()&&r<=a.M()&&A.length===o*r*4&&e.length===A.length&&(new Float32Array(a.a.buffer,a.N(),A.length).set(A),new Float32Array(a.a.buffer,a.O(),e.length).set(e),new Float64Array(a.a.buffer,a.P(),4).set(n),a.S(o,r,t)===0)?{values:new Uint8Array(a.a.buffer,a.Q(),t*t).slice(),offsets:new Float32Array(a.a.buffer,a.R(),t*t*2).slice()}:Fn(A,e,o,r,t,n)}function Fn(A,e,o,r,t,n){let a=new Uint8Array(t*t),c=new Float32Array(t*t*2),C=new Float32Array(t*t),Q=new Float32Array(t*t),s=new Float32Array(t*t*2),g=new Float32Array(t*t*2),i=t-1+n[0]+n[1],B=t-1+n[2]+n[3];for(let I=1;I+1<r;I++)for(let u=1;u+1<o;u++){let d=qe(A[(I*o+u)*4]);if(d.kind!==1&&d.kind!==2||d.score<.055)continue;let D=(u+.5)/o*i-n[0],h=(I+.5)/r*B-n[2],m=Math.round(D),w=Math.round(h);if(m<0||m>=t||w<0||w>=t)continue;let p=D-m,f=h-w,S=p*p+f*f;if(S>=.36)continue;let M=w*t+m,k=Math.max(0,d.score-S*.4),y=d.kind===1?C:Q,b=d.kind===1?s:g;k<=y[M]||(y[M]=k,b[M*2]=p,b[M*2+1]=f)}let E=Math.max(.055,Math.max(...C)*.3),l=Math.max(.04,Math.max(...Q)*.2);for(let I=0;I<a.length;I++){let u=C[I],d=Q[I];if(u<E&&d<l)continue;let D=u>=E&&u>=d?1:2;a[I]=D;let h=D===1?s:g;c[I*2]=h[I*2],c[I*2+1]=h[I*2+1]}for(let I=1;I+1<r;I++)for(let u=1;u+1<o;u++){let d=qe(e[(I*o+u)*4]);if(d.kind!==1&&d.kind!==2)continue;let D=(u+.5)/o*i-n[0],h=(I+.5)/r*B-n[2],m=Math.round(D),w=Math.round(h);if(m<0||m>=t||w<0||w>=t)continue;let p=w*t+m;if(a[p]!==0)continue;let f=D-m,S=h-w,M=f*f+S*S;if(M>=.25)continue;let k=Math.max(0,d.score-M*.4),y=d.kind===1?C:Q,b=d.kind===1?s:g;k<=y[p]||(y[p]=k,b[p*2]=f,b[p*2+1]=S)}for(let I=0;I<a.length;I++){if(a[I]!==0)continue;let u=C[I],d=Q[I];if(u<E+.06&&d<l+.06)continue;let D=u>=E+.06&&u>=d?1:2,h=D===1?s:g,m=I%t+h[I*2],w=Math.floor(I/t)+h[I*2+1],p=!1;for(let f=0;f<a.length;f++){if(a[f]===0)continue;let S=f%t+c[f*2],M=Math.floor(f/t)+c[f*2+1],k=m-S,y=w-M;if(k*k+y*y<.1849){p=!0;break}}p||(a[I]=D,c[I*2]=h[I*2],c[I*2+1]=h[I*2+1])}return{values:a,offsets:c}}function Pn(A,e,o,r){let t=r.gridToSource,n=0;for(let a=0;a<A.length;a++){if(A[a]===0)continue;let c=a%o+e[a*2],C=Math.floor(a/o)+e[a*2+1],Q=t[6]*c+t[7]*C+t[8],s=(t[0]*c+t[1]*C+t[2])/Q,g=(t[3]*c+t[4]*C+t[5])/Q;Number.isFinite(s)&&Number.isFinite(g)&&s>=0&&s<r.width&&g>=0&&g<r.height||(A[a]=0,e[a*2]=0,e[a*2+1]=0,n++)}return n}function xn(A){let e=new Float32Array(me),o=new Float32Array(me),r=new Float32Array(me),t=new Float32Array(me);for(let n=0;n<me;n++){let a=oe-n,c=-Math.floor(a/2),C=a%2===0?.5:0,Q=(a-2)/2,s=0,g=0;for(let d=c;d<c+a;d++)for(let D=c;D<c+a;D++){let h=Math.hypot(D+C,d+C),m=Math.max(0,Math.min(1,Q+.5-h)),w=D===c||d===c||D===c+a-1||d===c+a-1;m>0?w||(s+=m*(m<1?2:1)):g+=h<Q+1.5?2:1}if(s<=0||g<=0)throw new Error(`invalid convolution kernel ${a}`);e[n]=s,o[n]=s/g;let i=s-o[n]*g;if(Math.abs(i)>1e-5)throw new Error(`convolution kernel ${a} is not zero-sum`);let E=(A===0||A===1?a-4:a-2)**2,l=A===0?a**2-(a-4)**2:a**2-(a-2)**2;r[n]=s/E,t[n]=s/l;let I=r[n]*E-t[n]*l,u=r[n]*E+t[n]*l;if(Math.abs(I)>1e-5||Math.abs(u-2*s)>1e-5)throw new Error(`square convolution kernel ${a} is not normalized`)}return{positiveSums:e,negativeWeights:o,squareInnerWeights:r,squareBorderWeights:t}}function Kn(A,e,o,r,t,n){let a=st?uA():null,c=o*r;if(!a||c>a.q()||A.length!==c*4||e.length!==c*4||(new Float32Array(a.a.buffer,a.r(),A.length).set(A),new Float32Array(a.a.buffer,a.s(),e.length).set(e),a.x(o,r,t,n)!==0))return null;let C=new Float64Array(a.a.buffer,a.w(),11);return{candidateIndices:new Uint32Array(a.a.buffer,a.t(),C[0]),lineIndices:new Uint32Array(a.a.buffer,a.u(),C[1]),localIndices:new Uint32Array(a.a.buffer,a.v(),C[2]),maxWhiteScore:C[3],maxBlackScore:C[4],maxSquareScore:C[5],maxDarkFrameScore:C[6],maxLocalHorizontalScore:C[7],maxLocalVerticalScore:C[8],stoneCandidateCount:C[9],squareCandidateCount:C[10]}}function Rn(A,e,o,r,t,n,a,c,C){let Q=performance.now(),s=Kn(A,e,r,t,c,C),g=0,i=0,B=0,E=0,l=0,I=0,u=0,d=0,D=0;if(s)g=s.maxWhiteScore,i=s.maxBlackScore,B=s.maxSquareScore,E=s.maxDarkFrameScore,I=s.maxLocalHorizontalScore,u=s.maxLocalVerticalScore,d=s.stoneCandidateCount,D=s.squareCandidateCount;else for(let H=0;H<r*t;H++){let W=qe(A[H*4]);W.kind===1&&(i=Math.max(i,W.score),W.score>=.055&&d++),W.kind===2&&(g=Math.max(g,W.score),W.score>=.055&&d++),W.kind===3&&(E=Math.max(E,W.score),W.score>=.055&&D++),W.kind===4&&(B=Math.max(B,W.score),W.score>=.055&&D++);let tA=oo(e[H*4]);I=Math.max(I,tA.horizontalScore),u=Math.max(u,tA.verticalScore)}let h=Math.max(.055,g*.16),m=Math.max(.055,i*.16),w=Math.max(.055,B*.16),p=Math.max(.055,E*.16),f=[],S=[],M=[],k=[],y=[],b=[],G=0,K=0;if(!s&&c===2)for(let H=0;H<r*t;H++){let W=ro(e[H*4+2],e[H*4+3]);G=Math.max(G,W.horizontalScore),K=Math.max(K,W.verticalScore)}let P=Math.max(.04,G*.2),R=Math.max(.04,K*.2),x=D>=C*2&&D>=d*2,z=x?.06:1,F=Math.max(.025,Math.min(z,I*.2)),N=Math.max(.025,Math.min(z,u*.2)),q=H=>[(H%r+.5)*n/r,(Math.floor(H/r)+.5)*a/t],Y=(H,W)=>{let[tA,hA]=q(H),oA=qe(A[H*4]),wA=qn(A[H*4+3]);if(oA.kind===1||oA.kind===2){let fA=oA.kind,{score:vA,size:NA}=oA;(W||vA>=(fA===2?h:m))&&f.push({x:tA,y:hA,color:fA,score:vA,diameter:NA,refinedDiameter:A[H*4+1],orientation:A[H*4+2]*2-1,...wA})}oA.kind===3&&(W||oA.score>=p)&&M.push({x:tA,y:hA,color:1,score:oA.score,size:oA.size,refinedSize:A[H*4+1],...wA}),oA.kind===4&&(W||oA.score>=w)&&S.push({x:tA,y:hA,color:2,score:oA.score,size:oA.size,refinedSize:A[H*4+1],...wA})},j=(H,W)=>{if(c!==2)return;let tA=e[H*4+2],hA=e[H*4+3],oA=ro(tA,hA),wA=Ye(tA).stoneEdge>=1?0:oA.horizontalScore,fA=Ye(hA).stoneEdge>=1?0:oA.verticalScore;if(!W&&wA<P&&fA<R)return;let[vA,NA]=q(H);k.push({x:vA,y:NA,horizontalScore:wA,verticalScore:fA})},T=(H,W)=>{let tA=oo(e[H*4]);if(!W&&tA.horizontalScore<F&&tA.verticalScore<N)return;let[hA,oA]=q(H),wA=On(e[H*4+1]),fA={x:hA,y:oA,...tA,...wA};y.push(fA),b.push({...fA,horizontalTypes:Ye(e[H*4+2]),verticalTypes:Ye(e[H*4+3])})};if(s)s.candidateIndices.forEach(H=>Y(H,!0)),s.lineIndices.forEach(H=>j(H,!0)),s.localIndices.forEach(H=>T(H,!0));else for(let H=1;H+1<t;H++)for(let W=1;W+1<r;W++){let tA=H*r+W;Y(tA,!1),j(tA,!1),T(tA,!1)}let J=performance.now()-Q,L=performance.now(),V=x?Math.min(I,.25):I,$=x?Math.min(u,.25):u,nA=zn(o,r,t,n,a,V,$,f),DA=performance.now()-L,aA=performance.now(),{connectedLines:gA,perspectiveLines:kA,gridLines:mA,lineLattices:XA,stoneLines:ZA,lineCandidateConnectMs:pA,lineFeatureSupportMs:ne,lineStoneRowsMs:qA,linePerspectiveSelectMs:VA,lineLatticeSelectMs:YA}=Ln(y,r,t,n,a,I,u,C,[...f,...nA],f),_A=performance.now()-aA;return l=nA.reduce((H,W)=>Math.max(H,W.score),0),{candidates:f,squareCandidates:S,darkFrameCandidates:M,intersectionCandidates:nA,lineEvidence:k,localLineEvidence:y,typedLineEvidence:b,connectedLines:gA,perspectiveLines:kA,gridLines:mA,lineLattices:XA,stoneLines:ZA,maxBlackScore:i,maxWhiteScore:g,maxSquareScore:B,maxIntersectionScore:l,maxLocalHorizontalScore:I,maxLocalVerticalScore:u,candidateDecodeMs:J,intersectionScanMs:DA,lineConnectMs:_A,lineCandidateConnectMs:pA,lineFeatureSupportMs:ne,lineStoneRowsMs:qA,linePerspectiveSelectMs:VA,lineLatticeSelectMs:YA}}function Ln(A,e,o,r,t,n,a,c,C,Q){let s=performance.now(),g=Nn(A,e,o,r,t,n,a,c),i=performance.now()-s,B=[],E=[],l=[],I=[],u=0,d=0,D=0,h=0;for(let m of["horizontal","vertical"]){let w=g.filter(K=>K.orientation===m),p=performance.now();for(let K of w){let P=K.x1/r*e,R=K.y1/t*o,x=K.x2/r*e,z=K.y2/t*o,F=Math.hypot(x-P,z-R);K.featureSupport=C.reduce((N,q)=>{let Y=q.x/r*e,j=q.y/t*o,T=Math.abs((x-P)*(R-j)-(P-Y)*(z-R))/F;return N+ +(T<=2.25)},0)}u+=performance.now()-p;let f=performance.now(),S=Un(Q,m,e,o,r,t,c);d+=performance.now()-f,I.push(...S);let M=Q.length>=c*c*.9?S:[...w,...S],k=performance.now(),y=Yn(M,m,e,o,r,t);D+=performance.now()-k,B.push(...y);let b=performance.now(),G=Tn(y,m,e,o,r,t,c);h+=performance.now()-b,E.push(...G.lines),G.model&&l.push(G.model)}return{connectedLines:g,perspectiveLines:B,gridLines:E,lineLattices:l,stoneLines:I,lineCandidateConnectMs:i,lineFeatureSupportMs:u,lineStoneRowsMs:d,linePerspectiveSelectMs:D,lineLatticeSelectMs:h}}function Nn(A,e,o,r,t,n,a,c){let C=st?uA():null;if(!C||A.length>C.l())return eo(A,e,o,r,t,n,a,c);let Q=new Float64Array(C.a.buffer,C.n(),A.length*4);for(let B=0;B<A.length;B++){let E=A[B],l=B*4;Q[l]=E.x,Q[l+1]=E.y,Q[l+2]=E.horizontalScore,Q[l+3]=E.verticalScore}let s=C.p(A.length,e,o,r,t,n,a,c);if(s<0)return eo(A,e,o,r,t,n,a,c);let g=C.m(),i=new Float64Array(C.a.buffer,C.o(),s*g);return Array.from({length:s},(B,E)=>{let l=E*g;return{orientation:i[l]===0?"horizontal":"vertical",x1:i[l+1],y1:i[l+2],x2:i[l+3],y2:i[l+4],slope:i[l+5],score:i[l+6],featureSupport:0,coverage:i[l+7],pointCount:i[l+8]}})}function eo(A,e,o,r,t,n,a,c){let g=[];for(let i of["horizontal","vertical"]){let B=i==="horizontal"?e:o,E=i==="horizontal"?o:e,l=i==="horizontal"?n:a;if(l<=0)continue;let I=Math.ceil(B*.5)+2,u=E+I*2+1,d=new Float32Array(17*u),D=new Float64Array(A.length),h=new Float64Array(A.length),m=new Float64Array(A.length),w=0;for(let M of A){let k=(i==="horizontal"?M.x/r*e:M.y/t*o)-.5,y=(i==="horizontal"?M.y/t*o:M.x/r*e)-.5,b=i==="horizontal"?M.horizontalScore:M.verticalScore;if(b<=0)continue;let G=b/l;D[w]=k,h[w]=y,m[w]=G,w++;for(let K=0;K<17;K++){let P=-.5+K*.0625,R=y-P*k+I,x=Math.floor(R),z=R-x;x>=0&&x<u&&(d[K*u+x]+=G*(1-z)),x+1>=0&&x+1<u&&(d[K*u+x+1]+=G*z)}}let p=[];for(let M=0;M<17;M++)for(let k=1;k+1<u;k++){let y=M*u+k,b=d[y];b<2.5||b<d[y-1]||b<d[y+1]||p.push({slope:-.5+M*.0625,intercept:k-I,vote:b})}p.sort((M,k)=>k.vote-M.vote);let f=[],S=new Uint32Array(w);for(let M of p.slice(0,c*20)){let k=M.slope,y=M.intercept;for(let T=0;T<2;T++){let J=0,L=0,V=0,$=0,nA=0;for(let aA=0;aA<w;aA++){let gA=D[aA],kA=h[aA],mA=m[aA];Math.abs(kA-(k*gA+y))>1.35||(J+=mA,L+=gA*mA,V+=kA*mA,$+=gA*gA*mA,nA+=gA*kA*mA)}let DA=J*$-L*L;if(J<=0||Math.abs(DA)<1e-6)break;k=Math.max(-.55,Math.min(.55,(J*nA-L*V)/DA)),y=(V-k*L)/J}let b=0;for(let T=0;T<w;T++)Math.abs(h[T]-(k*D[T]+y))<=1.35&&(S[b++]=T);if(b<6)continue;let G=B,K=0,P=0;for(let T=0;T<b;T++){let J=S[T],L=D[J];G=Math.min(G,L),K=Math.max(K,L),P+=m[J]}let R=K-G;if(R<B*.16)continue;let x=new Uint8Array(8);for(let T=0;T<b;T++){let J=D[S[T]],L=Math.max(0,Math.min(7,Math.floor((J-G)/Math.max(R,1)*8)));x[L]=1}let z=x.reduce((T,J)=>T+J,0)/x.length;if(z<.375)continue;let F=k*(B*.5)+y;if(f.some(T=>{let J=i==="horizontal"?(T.y1+T.y2)*.5:(T.x1+T.x2)*.5,L=i==="horizontal"?t/o:r/e;return Math.abs(J-F*L)<2.25*L&&Math.abs(T.slope-k)<.07}))continue;let N=k*G+y,q=k*K+y,Y=r/e,j=t/o;if(f.push({orientation:i,x1:(i==="horizontal"?G:N)*Y,y1:(i==="horizontal"?N:G)*j,x2:(i==="horizontal"?K:q)*Y,y2:(i==="horizontal"?q:K)*j,slope:k,score:P*Math.sqrt(R/B)*z,featureSupport:0,coverage:z,pointCount:b}),f.length>=c*5)break}g.push(...f)}return g}function Un(A,e,o,r,t,n,a){if(A.length<a*3)return[];let c=17,C=e==="horizontal"?o:r,Q=e==="horizontal"?r:o,s=Math.ceil(C*.5)+3,g=Q+s*2+1,i=new Float32Array(c*g),B=new Float64Array(A.length),E=new Float64Array(A.length),l=new Float64Array(A.length);for(let d=0;d<A.length;d++){let D=A[d],h=e==="horizontal"?D.x/t*o:D.y/n*r,m=e==="horizontal"?D.y/n*r:D.x/t*o,w=(.45+D.score)*(.65+.35*D.latticeSupport)*(.65+.35*D.surroundDrop);B[d]=h,E[d]=m,l[d]=w;for(let p=0;p<c;p++){let f=-.5+p/(c-1),S=m-f*h+s,M=Math.floor(S),k=S-M;M>=0&&M<g&&(i[p*g+M]+=w*(1-k)),M+1>=0&&M+1<g&&(i[p*g+M+1]+=w*k)}}let I=[];for(let d=0;d<c;d++)for(let D=1;D+1<g;D++){let h=d*g+D,m=i[h];m<2.2||m<i[h-1]||m<i[h+1]||I.push({slope:-.5+d/(c-1),intercept:D-s,vote:m})}I.sort((d,D)=>D.vote-d.vote);let u=[];for(let d of I.slice(0,a*10)){let D=d.slope,h=d.intercept;for(let P=0;P<2;P++){let R=0,x=0,z=0,F=0,N=0;for(let Y=0;Y<A.length;Y++){if(Math.abs(E[Y]-(D*B[Y]+h))>2.2)continue;let j=l[Y];R+=j,x+=B[Y]*j,z+=E[Y]*j,F+=B[Y]*B[Y]*j,N+=B[Y]*E[Y]*j}let q=R*F-x*x;if(R<=0||Math.abs(q)<1e-6)break;D=Math.max(-.55,Math.min(.55,(R*N-x*z)/q)),h=(z-D*x)/R}let m=C,w=0,p=0,f=0;for(let P=0;P<A.length;P++)Math.abs(E[P]-(D*B[P]+h))>2.2||(m=Math.min(m,B[P]),w=Math.max(w,B[P]),p++,f+=l[P]);let S=w-m;if(p<4||S<C*.12)continue;let M=D*C*.5+h;if(u.some(P=>{let R=e==="horizontal"?(P.y1+P.y2)*.5/n*r:(P.x1+P.x2)*.5/t*o;return Math.abs(R-M)<2.2&&Math.abs(P.slope-D)<.07}))continue;let k=D*m+h,y=D*w+h,b=t/o,G=n/r,K=Math.min(1,S/(C*.45));if(u.push({orientation:e,x1:(e==="horizontal"?m:k)*b,y1:(e==="horizontal"?k:m)*G,x2:(e==="horizontal"?w:y)*b,y2:(e==="horizontal"?y:w)*G,slope:D,score:f*K,featureSupport:p,coverage:K,pointCount:p}),u.length>=a*2)break}return u}function Yn(A,e,o,r,t,n){if(A.length<3)return[...A];let a=e==="horizontal"?t*.5:n*.5,c=e==="horizontal"?r/n:o/t,C=A.map(l=>{let I=e==="horizontal"?l.x1:l.y1,u=e==="horizontal"?l.x2:l.y2,d=e==="horizontal"?l.y1:l.x1,D=e==="horizontal"?l.y2:l.x2,h=(a-I)/Math.max(1e-6,u-I);return{line:l,position:(d+(D-d)*h)*c}}),Q=[...C].sort((l,I)=>I.line.score*I.line.coverage-l.line.score*l.line.coverage).slice(0,28),s=[...C].sort((l,I)=>l.position-I.position),g=[...Q];for(let l of[s[0],s.at(-1)])l&&!g.includes(l)&&g.push(l);let i=Math.max(...A.map(l=>l.score)),B=-1/0,E=[];for(let l=0;l<g.length;l++)for(let I=l+1;I<g.length;I++){let u=g[l],d=g[I],D=d.position-u.position;if(Math.abs(D)<6)continue;let h=(d.line.slope-u.line.slope)/D;if(Math.abs(h)>.006)continue;let m=u.line.slope-h*u.position,w=new Map,p=1/0,f=-1/0;for(let M of C){let k=Math.abs(M.line.slope-(h*M.position+m));if(k>.045)continue;let y=Math.max(0,1-k/.045),b=(.45+.55*M.line.score/i)*M.line.coverage,G=y*b,K=Math.round(M.position/2.5);G>(w.get(K)?.vote??0)&&w.set(K,{line:M.line,vote:G,position:M.position})}let S=0;for(let M of w.values())S+=M.vote,p=Math.min(p,M.position),f=Math.max(f,M.position);S*=.6+.4*Math.min(1,(f-p)/(e==="horizontal"?r:o)),S>B&&(B=S,E=[...w.values()].map(M=>M.line))}return E.length>=3?E:[...A]}function Tn(A,e,o,r,t,n,a){let c=st?uA():null;if(!c||A.length>c.am())return to(A,e,o,r,t,n,a);let C=c.an(),Q=new Float64Array(c.a.buffer,c.ao(),A.length*C);for(let B=0;B<A.length;B++){let E=A[B],l=B*C;Q[l]=E.x1,Q[l+1]=E.y1,Q[l+2]=E.x2,Q[l+3]=E.y2,Q[l+4]=E.slope,Q[l+5]=E.score,Q[l+6]=E.featureSupport,Q[l+7]=E.coverage,Q[l+8]=E.pointCount}let s=c.ar(A.length,e==="horizontal"?0:1,o,r,t,n,a);if(s<0)return to(A,e,o,r,t,n,a);let g=new Uint32Array(c.a.buffer,c.ap(),s),i=new Float64Array(c.a.buffer,c.aq(),8);return{lines:Array.from(g,B=>A[B]),model:i[0]===0?null:{orientation:e,positionOffset:i[1],positionLinear:i[2],positionQuadratic:i[3],slopeOffset:i[4],slopeLinear:i[5],indexStart:i[6],score:i[7]}}}function to(A,e,o,r,t,n,a){if(A.length<3)return{lines:[...A],model:null};let c=e==="horizontal"?r/n:o/t,C=e==="horizontal"?t*.5:n*.5,Q=D=>{let h=e==="horizontal"?D.x1:D.y1,m=e==="horizontal"?D.x2:D.y2,w=e==="horizontal"?D.y1:D.x1,p=e==="horizontal"?D.y2:D.x2,f=Math.abs(m-h)<1e-6?.5:(C-h)/(m-h);return(w+(p-w)*f)*c},s=A.map(D=>({line:D,position:Q(D)})),g=Math.max(...A.map(D=>D.score)),i=Math.max(1,...A.map(D=>D.featureSupport)),B=[...s].sort((D,h)=>h.line.score*h.line.coverage-D.line.score*D.line.coverage).slice(0,8),E=[...s].sort((D,h)=>D.position-h.position),l=[...B];for(let D of[E[0],E.at(-1)])D&&!l.includes(D)&&l.push(D);l.sort((D,h)=>D.position-h.position);let I=-1/0,u=[],d=null;for(let D=0;D+2<l.length;D++)for(let h=D+1;h+1<l.length;h++)for(let m=h+1;m<l.length;m++){let w=l[D],p=l[h],f=l[m],S=f.position-w.position;if(!(S<11))for(let M=2;M<a;M++){let k=Math.max(1,Math.min(M-1,Math.round(M*(p.position-w.position)/S))),y=k*M*(M-k);if(y===0)continue;let b=p.position-w.position,G=f.position-w.position,K=(b*M*M-G*k*k)/y,P=(k*G-M*b)/y,R=S/M;if(R<5.5||R>22)continue;let x=(f.line.slope-w.line.slope)/M;if(Math.abs(p.line.slope-(w.line.slope+x*k))>.065)continue;let z=Y=>w.position+K*Y+P*Y*Y,F=Y=>K+P*(2*Y+1),N=new Map;for(let Y of s){let j=(Y.position-w.position)/R;for(let aA=0;aA<3;aA++){let gA=K+2*P*j;if(Math.abs(gA)<.25)break;j-=(z(j)-Y.position)/gA}let T=Math.round(j),J=Math.abs(F(T));if(J<7.5||J>24)continue;let L=Math.abs(j-T);if(L>.38)continue;let V=Math.max(0,Math.exp(-8*L*L)-.45*Math.exp(-24*(L-.5)**2)),$=Math.abs(Y.line.slope-(w.line.slope+x*T));if($>.075)continue;let nA=Math.max(0,1-$/.075),DA=V*nA*(.2+.25*Y.line.score/g+.35*Y.line.featureSupport/i+.2*Y.line.coverage);DA>(N.get(T)?.utility??0)&&N.set(T,{line:Y.line,utility:DA})}let q=[...N.keys()].sort((Y,j)=>Y-j);for(let Y of q){let j=Y+a-1,T=F(Y),J=F(j);if(T<7.5||J<7.5||Math.max(T,J)/Math.min(T,J)>1.8)continue;let L=q.filter($=>$>=Y&&$<=j);if(L.length<3)continue;let V=L.reduce(($,nA)=>$+N.get(nA).utility,0)+L.length*.45;V<=I||(I=V,u=L.map($=>N.get($).line),d={orientation:e,positionOffset:w.position,positionLinear:K,positionQuadratic:P,slopeOffset:w.line.slope,slopeLinear:x,indexStart:Y,score:V})}}}return{lines:u,model:d}}function zn(A,e,o,r,t,n,a,c){if(n<=0||a<=0)return[];let C=new Float32Array(e*o),Q=0;for(let E=5;E+5<o;E++)for(let l=5;l+5<e;l++){let I=(E*e+l)*4,u=Math.min(A[I],A[I+1])/n,d=Math.min(A[I+2],A[I+3])/a,D=Math.min(u,d);C[E*e+l]=D,Q=Math.max(Q,D)}let s=Math.max(.1,Q*.18),g=[];for(let E=6;E+6<o;E++)for(let l=6;l+6<e;l++){let I=C[E*e+l];if(I<s)continue;let u=!0;for(let d=-2;d<=2&&u;d++)for(let D=-2;D<=2;D++){if(D===0&&d===0)continue;let h=C[(E+d)*e+l+D];if(h>I||h===I&&(d<0||d===0&&D<0)){u=!1;break}}u&&g.push({x:(l+.5)*r/e,y:(E+.5)*t/o,score:I,size:8})}let i=g.filter(E=>!c.some(l=>{let I=(E.x-l.x)*e/r,u=(E.y-l.y)*o/t,d=Math.max(3,(l.refinedDiameter||l.diameter)*.48);return I*I+u*u<=d*d}));i.sort((E,l)=>l.score-E.score);let B=[];for(let E of i)B.some(l=>{let I=(E.x-l.x)*e/r,u=(E.y-l.y)*o/t;return I*I+u*u<2.5**2})||B.push(E);return B}function oo(A){let e=Math.floor(Math.floor(A)/256);return{horizontalScore:Math.floor(e/256)/255,verticalScore:e%256/255}}function On(A){let e=Math.floor(A),o=e%256,r=o%16/15,t=Math.floor(o/16)/15;e=Math.floor(e/256);let n=e%81,a=Math.floor(e/81);return{horizontalSlope:Math.floor(a/9)/8-.5,verticalSlope:a%9/8-.5,strongHorizontalSlope:Math.floor(n/9)/8-.5,strongVerticalSlope:n%9/8-.5,horizontalSlopeConfidence:t,verticalSlopeConfidence:r}}function ro(A,e){return{horizontalScore:Math.floor(A)%64/63,verticalScore:Math.floor(e)%64/63}}function Ye(A){let e=Math.floor(Math.floor(A)/64),o=e%16;e=Math.floor(e/16);let r=e%16;e=Math.floor(e/16);let t=e%16;return{grid:Math.floor(e/16)%16/15,stoneEdge:t/15,boardEdge:r/15,unknown:o/15}}function qn(A){let e=Math.floor(A+.5),o=e%64;e=Math.floor(e/64);let r=e%64;e=Math.floor(e/64);let t=e%64;return{surroundDrop:Math.floor(e/64)%64/63,horizontalContinuation:t/63,verticalContinuation:r/63,latticeSupport:o/63}}function qe(A){let e=Math.floor(A),o=Math.floor(e/32);return{kind:o>=1&&o<=4?o:0,score:A-e,size:e%32}}function QA(A,e,o){let r=no(A,A.VERTEX_SHADER,e),t=no(A,A.FRAGMENT_SHADER,o),n=A.createProgram();if(!n)throw new Error("failed to create WebGL2 program");if(A.attachShader(n,r),A.attachShader(n,t),A.linkProgram(n),A.deleteShader(r),A.deleteShader(t),!A.getProgramParameter(n,A.LINK_STATUS)){let a=A.getProgramInfoLog(n)??"unknown link error";throw A.deleteProgram(n),new Error(`WebGL2 program link failed: ${a}`)}return n}function no(A,e,o){let r=A.createShader(e);if(!r)throw new Error("failed to create WebGL2 shader");if(A.shaderSource(r,o),A.compileShader(r),!A.getShaderParameter(r,A.COMPILE_STATUS)){let t=A.getShaderInfoLog(r)??"unknown compile error";throw A.deleteShader(r),new Error(`WebGL2 shader compile failed: ${t}`)}return r}function _(A,e,o,r,t,n,a,c){let C=A.createTexture();if(!C)throw new Error("failed to create WebGL2 texture");return A.bindTexture(A.TEXTURE_2D,C),A.texParameteri(A.TEXTURE_2D,A.TEXTURE_MIN_FILTER,c),A.texParameteri(A.TEXTURE_2D,A.TEXTURE_MAG_FILTER,c),A.texParameteri(A.TEXTURE_2D,A.TEXTURE_WRAP_S,A.CLAMP_TO_EDGE),A.texParameteri(A.TEXTURE_2D,A.TEXTURE_WRAP_T,A.CLAMP_TO_EDGE),A.texImage2D(A.TEXTURE_2D,0,e,o,r,0,t,n,a),C}function Hn(A,e,o,r,t,n,a,c){A.bindTexture(A.TEXTURE_2D,e),A.texParameteri(A.TEXTURE_2D,A.TEXTURE_MIN_FILTER,c),A.texParameteri(A.TEXTURE_2D,A.TEXTURE_MAG_FILTER,c),A.texImage2D(A.TEXTURE_2D,0,o,r,t,0,n,a,null)}function EA(A,e,o){let r=A.createFramebuffer();if(!r)throw new Error("failed to create WebGL2 framebuffer");return A.bindFramebuffer(A.FRAMEBUFFER,r),dA(A,r,e,o),r}function dA(A,e,o,r,t=A.COLOR_ATTACHMENT0){A.bindFramebuffer(A.FRAMEBUFFER,e),A.framebufferTexture2D(A.FRAMEBUFFER,t,A.TEXTURE_2D,o,0);let n=A.checkFramebufferStatus(A.FRAMEBUFFER);if(n!==A.FRAMEBUFFER_COMPLETE)throw new Error(`WebGL2 ${r} framebuffer is incomplete: 0x${n.toString(16)}`)}function X(A,e,o,r,t){A.activeTexture(A.TEXTURE0+t),A.bindTexture(A.TEXTURE_2D,r),A.uniform1i(O(A,e,o),t)}function O(A,e,o){let r=A.getUniformLocation(e,o);if(r===null)throw new Error(`missing WebGL2 uniform ${o}`);return r}var Jn=5,Wn=7,He=.5,jn=.2,Xn=768,Zn=.3,Vn=1.5,_n=.35;function so(A){return A.latticeConfidence>=.5&&A.gridTerminationScore<Zn&&Math.min(...A.gridTerminationSides)===0}function $n(A){return A.latticeConfidence>=.3&&A.gridTerminationScore<.1&&A.boardConfidence<.1&&Math.min(...A.gridTerminationSides)===0}function Ai(A){return!A||A.latticeConfidence<.5||so(A)||ei(A)}function ei(A){let[e,o,r,t]=A.boardMargins,[n,a,c,C]=A.boardSideConfidence;return Math.abs(e-o)>=1&&Math.abs(r-t)>=1&&Math.max(n,a)>=.75&&Math.max(c,C)>=.75}async function co(A,e,o,r,t,n=!1){if(!n&&!Ai(t))return null;let a=performance.now(),c=t?{gridToSource:t.gridToSource,gridCorners:t.gridCorners,support:t.inlierCount,extentSupport:t.inlierCount,analysisMs:0,source:"color",confidence:t.latticeConfidence,score:t.latticeConfidence,textureScore:0,shapeGridCorners:t.gridCorners,shapeGridConfidence:t.latticeConfidence,method:"webgl"}:null,C=t?so(t):!1,Q=ct(r),s=t?.latticeConfidence&&t.latticeConfidence>=.5?t.gridCorners:void 0,g=m=>{let w=m.geometry.latticeConfidence-(t?.latticeConfidence??0),p=ct(m.detection)-Q;return m.distortion<=3&&m.geometry.latticeConfidence>=.5&&(p>=-.015||!!(t&&Io(m.geometry,t)))&&(!t||w>=.05||w>=.03&&p>=0)},i=c&&(C||t&&$n(t))?await he(A,e,o,c,s):null,B=i?g(i):!1;if(i&&(C||B))return{...i,accepted:B,elapsedMs:performance.now()-a};let E=C?[]:Wt(e,o,12,ti(r,e)).map(m=>({estimate:m,evidence:Zt(r,m,o)})),l=[...E].sort((m,w)=>w.evidence.stone*w.evidence.line-m.evidence.stone*m.evidence.line)[0],I=E.find(m=>m.estimate.method==="scanline"),u=C?c?[c]:[]:[E[0],E[1],l,I,...E.slice(2)].flatMap((m,w,p)=>m&&p.indexOf(m)===w?[m.estimate]:[]).slice(0,4);if(!u.length)return null;let d=null,D=-1/0;for(let m of u){let w=await he(A,e,o,m,s);if(!w)continue;if(w.geometry.latticeConfidence<.55&&m.shapeGridConfidence>=.7){let y=Le(m.shapeGridCorners,o-1),b=y?await he(A,e,o,{...m,gridToSource:y,gridCorners:m.shapeGridCorners},s):null;b&&b.geometry.latticeConfidence>=.6&&b.geometry.latticeConfidence>=w.geometry.latticeConfidence+.15&&(w=b)}let p=w.distortion>Vn||w.geometry.latticeConfidence<_n||w.geometry.gridTerminationScore<.2||w.recoverableOutsideCorner?await he(A,e,o,oi(w),s,!0):null,f=!!(p&&p.distortion<w.distortion&&p.geometry.latticeConfidence>=w.geometry.latticeConfidence*.75),S=p?ri(w,p,f):w,M=ct(S.detection),k=S.geometry.latticeConfidence+S.geometry.gridTerminationScore*.12+M*.12+m.confidence*.04;if(k>D&&(D=k,d=S),S.geometry.latticeConfidence>=.5&&(!t||S.geometry.latticeConfidence>=t.latticeConfidence+.05)&&(M>=Q-.015||t&&Io(S.geometry,t)))break}if(!d)return null;let h=g(d);return!h&&!C&&c&&(i??=await he(A,e,o,c,s),i&&g(i)&&(d=i,h=!0)),{...d,accepted:h,elapsedMs:performance.now()-a}}function ti(A,e){let o=A.shapeDensity;if(!o)return[];let{width:r,height:t,raw:n}=o,a=0;for(let s=3;s<n.length;s+=4)a=Math.max(a,n[s]);let c=[],C=Math.max(.025,a*.32);for(let s=2;s+2<t;s++)for(let g=2;g+2<r;g++){let i=(s*r+g)*4,B=n[i+3];if(B<C)continue;let E=!0;for(let l=-2;l<=2&&E;l++)for(let I=-2;I<=2;I++)if(!(!I&&!l)&&n[((s+l)*r+g+I)*4+3]>B){E=!1;break}E&&c.push({x:g,y:s,size:Math.floor(n[i+2]),score:B})}c.sort((s,g)=>g.score-s.score);let Q=[];for(let s of c.slice(0,96)){let g=Math.max(2,s.size*.62);for(let i=0;i<8;i++){let B=i*Math.PI/4;Q.push([(s.x+.5+Math.cos(B)*g)/r*e.width,(s.y+.5+Math.sin(B)*g)/t*e.height])}}return Q}function Io(A,e){let o=A.latticeConfidence-e.latticeConfidence;return A.boardConfidence>=.7&&(A.latticeConfidence>=.6&&o>=.35&&A.gridTerminationScore>=.5||A.latticeConfidence>=.7&&o>=.4&&A.gridTerminationScore>=.35)}async function he(A,e,o,r,t,n=!1){let a=performance.now(),c=(T,J)=>Math.hypot(J[0]-T[0],J[1]-T[1]),C=(c(r.gridCorners[0],r.gridCorners[1])+c(r.gridCorners[3],r.gridCorners[2]))*.5,Q=(c(r.gridCorners[0],r.gridCorners[3])+c(r.gridCorners[1],r.gridCorners[2]))*.5,s=o-1,g=ni(r.gridToSource,s,e.width,e.height,t);if(!g)return null;let i=s+g[0]+g[1],B=s+g[2]+g[3],E=Math.max(512/Math.min(i,B),Math.min(1536/Math.max(i,B),Math.sqrt(C*Q)/s)),l=Math.max(1,Math.round(i*E)),I=Math.max(1,Math.round(B*E)),u=new Uint8Array(e.data.buffer,e.data.byteOffset,e.data.byteLength),d=A.rectify(u,e.width,e.height,r.gridToSource,o,l,I,g),D=new ImageData(d.data,l,I),h=D,m=await Ee(h,Math.round(we(o)*i/s),Math.round(we(o)*B/s)),w=A.detect(new Uint8Array(m.image.data.buffer,m.image.data.byteOffset,m.image.data.byteLength),m.image.width,m.image.height,l,I,o,!1,!1),p=performance.now(),f=Be(h,w,o,!0,n),S=performance.now()-p;if(!f)return null;let M=Ct(r.gridToSource,[i/l,0,-g[0],0,B/I,-g[2],0,0,1]),k=T=>re(M,T[0],T[1]),y=f.gridCorners.some(T=>{if(T[0]>=0&&T[0]<=l-1&&T[1]>=0&&T[1]<=I-1)return!1;let J=k(T);return J[0]>=0&&J[0]<=e.width-1&&J[1]>=0&&J[1]<=e.height-1}),b={...f,gridToSource:Ct(M,f.gridToSource),gridCorners:f.gridCorners.map(k),preBoundaryGridToSource:Ct(M,f.preBoundaryGridToSource),preBoundaryGridCorners:f.preBoundaryGridCorners.map(k),...f.boardCorners?{boardCorners:f.boardCorners.map(k)}:{}},G=(T,J)=>Math.hypot(J[0]-T[0],J[1]-T[1]),K=G(f.gridCorners[0],f.gridCorners[3]),P=G(f.gridCorners[1],f.gridCorners[2]),R=G(f.gridCorners[0],f.gridCorners[1]),x=G(f.gridCorners[3],f.gridCorners[2]),z=(T,J)=>Math.max(T/Math.max(J,1e-6),J/Math.max(T,1e-6)),F=z(K,P)*z(R,x),N=d.elapsedMs,q=r.analysisMs,Y=N+w.uploadAndGpuMs+w.readbackMs,j=q+w.candidateScanMs+S;return{geometry:b,firstPassGridCorners:b.gridCorners,firstPassPreBoundaryGridCorners:b.preBoundaryGridCorners,firstPassPreBoundaryLatticeConfidence:b.preBoundaryLatticeConfidence,firstPassPreBoundaryGridTerminationScore:b.preBoundaryGridTerminationScore,firstPassPreBoundaryInlierCount:b.preBoundaryInlierCount,detection:w,image:h,displayImage:D,estimate:r,deformationMs:N,resizeMs:m.elapsedMs,geometryMs:S,analysisMs:q,preprocessGpuMs:Y,preprocessCpuMs:j,distortion:F,passCount:1,passElapsedMs:[performance.now()-a],margins:g,stages:[{geometry:b,detection:w,image:h,displayImage:D}],recoverableOutsideCorner:y}}function oi(A){return{gridToSource:A.geometry.gridToSource,gridCorners:A.geometry.gridCorners,support:A.geometry.inlierCount,extentSupport:A.geometry.inlierCount,analysisMs:0,source:"color",confidence:A.geometry.latticeConfidence,score:A.geometry.latticeConfidence,textureScore:0,shapeGridCorners:A.geometry.gridCorners,shapeGridConfidence:A.geometry.latticeConfidence,method:"webgl"}}function ri(A,e,o){let r=!o||A.geometry.latticeConfidence>=.6&&A.geometry.gridTerminationScore>=.5;return{...o?e:A,geometry:r?A.geometry:e.geometry,firstPassGridCorners:A.firstPassGridCorners,firstPassPreBoundaryGridCorners:A.firstPassPreBoundaryGridCorners,firstPassPreBoundaryLatticeConfidence:A.firstPassPreBoundaryLatticeConfidence,firstPassPreBoundaryGridTerminationScore:A.firstPassPreBoundaryGridTerminationScore,firstPassPreBoundaryInlierCount:A.firstPassPreBoundaryInlierCount,deformationMs:A.deformationMs+e.deformationMs,resizeMs:A.resizeMs+e.resizeMs,geometryMs:A.geometryMs+e.geometryMs,analysisMs:A.analysisMs+e.analysisMs,preprocessGpuMs:A.preprocessGpuMs+e.preprocessGpuMs,preprocessCpuMs:A.preprocessCpuMs+e.preprocessCpuMs,passCount:A.passCount+e.passCount,passElapsedMs:[...A.passElapsedMs,...e.passElapsedMs],stages:[...A.stages,...e.stages]}}function ni(A,e,o,r,t){let n=Math.max(1,Math.min(o,r)),a=Math.min(e*.25,Math.max(0,Xn/n-1)*2),c=(t?Jn:Wn)+a,C=[c,c,c,c],Q=[He,He,He,He],s=ii(A);if(s&&t){for(let B of t){if(B[0]<0||B[0]>o-1||B[1]<0||B[1]>r-1)continue;let[E,l]=re(s,B[0],B[1]);Q[0]=Math.max(Q[0],-E+.5),Q[1]=Math.max(Q[1],E-e+.5),Q[2]=Math.max(Q[2],-l+.5),Q[3]=Math.max(Q[3],l-e+.5)}if(Q.some(B=>B>e*.75))return null;for(let B=0;B<C.length;B++)C[B]=Math.max(C[B],Q[B])}let g=256,i=B=>B[0]<0||B[0]>o-1||B[1]<0||B[1]>r-1;for(let B=0;B<92;B++){let E=e+C[0]+C[1],l=e+C[2]+C[3],I=-C[0],u=e+C[1],d=-C[2],D=e+C[3],h=[!0,!0,!0,!0];for(let w=0;w<g;w++){let p=(w+.5)/g,f=-C[0]+p*E,S=-C[2]+p*l;h[0]&&=i(re(A,I,S)),h[1]&&=i(re(A,u,S)),h[2]&&=i(re(A,f,d)),h[3]&&=i(re(A,f,D))}let m=h.findIndex((w,p)=>w&&C[p]>Q[p]);if(m<0)break;C[m]=Math.max(Q[m],Math.round((C[m]-jn)*10)/10)}return C}function ct(A){let e=A.candidates.filter(C=>C.surroundDrop>=.45&&Math.max(C.horizontalContinuation,C.verticalContinuation)<.62);if(e.length<8)return 0;let o=e.map(C=>C.refinedDiameter).sort((C,Q)=>C-Q),r=o[Math.floor(o.length*.5)],t=o.map(C=>Math.abs(C-r)).sort((C,Q)=>C-Q),n=t[Math.floor(t.length*.5)]/Math.max(1,r),a=e.reduce((C,Q)=>C+Math.abs(Q.orientation),0)/e.length;return e.reduce((C,Q)=>C+Q.surroundDrop,0)/e.length-a*.5-n}function Ct(A,e){return Array.from({length:9},(o,r)=>{let t=Math.floor(r/3),n=r%3;return A[t*3]*e[n]+A[t*3+1]*e[n+3]+A[t*3+2]*e[n+6]})}function ii(A){let[e,o,r,t,n,a,c,C,Q]=A,s=e*(n*Q-a*C)-o*(t*Q-a*c)+r*(t*C-n*c);return Math.abs(s)<1e-9?null:[(n*Q-a*C)/s,(r*C-o*Q)/s,(o*a-r*n)/s,(a*c-t*Q)/s,(e*Q-r*c)/s,(r*t-e*a)/s,(t*C-n*c)/s,(o*c-e*C)/s,(e*n-o*t)/s]}function re(A,e,o){let r=A[6]*e+A[7]*o+A[8];return[(A[0]*e+A[1]*o+A[2])/r,(A[3]*e+A[4]*o+A[5])/r]}var Je=null,Co=Promise.resolve();self.addEventListener("message",A=>{Co=Co.then(()=>ai(A.data))});async function ai(A){try{globalThis.uluSCheck=A.sCheck?"enabled":"";let e=await ci(A.image),o=await gi(e,A);if(!o){self.postMessage({id:A.id,e:!0});return}if(o.length===0){self.postMessage({id:A.id,s:!0});return}let r=o.buffer;self.postMessage({id:A.id,lineCount:A.lineCount,encoded:r},[r])}catch{self.postMessage({id:A.id,e:!0})}}async function gi(A,e){let o=await Qo(A,e,!1);if(!o)return null;let r=io();if(!(r>0))return o.encoded;let t=Ii(A,o.geometry.gridToSource,e.lineCount,r);return t?(await Qo(t,e,!0))?.encoded??null:ao()?new Uint8Array:o.encoded}async function Qo(A,e,o){let r=e.lineCount,t=si();if(!t)throw new Error("Worker WebGL2 floating-point rendering is unavailable");let n=await Kt(A,we(r)),a=t.detect(new Uint8Array(n.image.data.buffer,n.image.data.byteOffset,n.image.data.byteLength),n.image.width,n.image.height,A.width,A.height,r,!1,!1,!0),c=Be(A,a,r),C=e.disableReprocess?null:await co(t,A,r,a,c),Q=C?.accepted?C.geometry:c,s=Q?ht(A,Q,r,a):null;if(!s)return null;let g=ft(s,r,A.width,A.height),i=t.rectify(new Uint8Array(A.data.buffer,A.data.byteOffset,A.data.byteLength),A.width,A.height,s.gridToSource,r,g.width,g.height,g.margins),B=go(r)/Math.min(g.width,g.height),E=await Ee(new ImageData(i.data,i.width,i.height),Math.max(1,Math.round(i.width*B)),Math.max(1,Math.round(i.height*B))),l=t.postprocess(new Uint8Array(E.image.data.buffer,E.image.data.byteOffset,E.image.data.byteLength),E.image.width,E.image.height,r,g.margins,{gridToSource:s.gridToSource,width:A.width,height:A.height},void 0,void 0,void 0,o);return l.encodedBoard?{encoded:l.encodedBoard,geometry:s}:null}function Ii(A,e,o,r){let t=o-1,n=[We(e,-r,-r),We(e,t+r,-r),We(e,t+r,t+r),We(e,-r,t+r)];if(n.some(i=>!i.every(Number.isFinite)))return null;let a=Math.max(0,Math.floor(Math.min(...n.map(i=>i[0])))),c=Math.max(0,Math.floor(Math.min(...n.map(i=>i[1])))),C=Math.min(A.width,Math.ceil(Math.max(...n.map(i=>i[0])))+1),Q=Math.min(A.height,Math.ceil(Math.max(...n.map(i=>i[1])))+1);if(a===0&&c===0&&C===A.width&&Q===A.height||C<=a||Q<=c)return null;let g=new OffscreenCanvas(A.width,A.height).getContext("2d",{alpha:!1});return g?(g.putImageData(A,0,0),g.getImageData(a,c,C-a,Q-c)):null}function We(A,e,o){let r=A[6]*e+A[7]*o+A[8];return[(A[0]*e+A[1]*o+A[2])/r,(A[3]*e+A[4]*o+A[5])/r]}function si(){if(Je)return Je;let A=new OffscreenCanvas(1,1).getContext("webgl2",{alpha:!1,antialias:!1,depth:!1,stencil:!1,preserveDrawingBuffer:!1,premultipliedAlpha:!1});return!A||!A.getExtension("EXT_color_buffer_float")?null:(Je=new ze(A),Je)}async function ci(A){let e=await createImageBitmap(A);try{if(e.width<1||e.height<1||Math.max(e.width,e.height)>2048)throw new Error("image dimensions are unsupported");let r=new OffscreenCanvas(e.width,e.height).getContext("2d",{alpha:!1});if(!r)throw new Error("2D canvas is unavailable");return r.drawImage(e,0,0),r.getImageData(0,0,e.width,e.height)}finally{e.close()}}