{"ScriptPreparationCode":"var max = Math.max.bind(Math);\r\nvar min = Math.min.bind(Math);\r\n\r\nfunction between(a, x, b) {\r\n return a \u003C= x \u0026\u0026 x \u003C= b;\r\n}\r\n\r\nfunction intersect_1d(start1, end1, start2, end2) {\r\n const c1 = between(start1, start2, end1) ? 1 : 0;\r\n const c2 = between(start1, end2, end1) ? 2 : 0;\r\n const c3 = between(start2, start1, end2) ? 4 : 0;\r\n const c4 = between(start2, end1, end2) ? 8 : 0;\r\n const _case = c1 | c2 | c3 | c4;\r\n\r\n switch (_case) {\r\n case 0: return [NaN, NaN];\r\n case 1: return [start2, start2];\r\n case 2: return [end2, end2];\r\n case 3: return [start2, end2];\r\n case 4: return [start1, start1];\r\n case 5: return [min(start1, start2), max(start1, start2)];\r\n case 6: return [min(start1, end2), max(start1, end2)];\r\n case 7: return [min(start1, start2), max(start1, end2)];\r\n case 8: return [end1, end1];\r\n case 9: return [min(end1, start2), max(end1, start2)];\r\n case 10: return [min(end1, end2), max(end1, end2)];\r\n case 11: return [min(end1, start2), max(end1, end2)];\r\n case 12: return [start1, end1];\r\n case 13: return [min(start1, start2), max(end1, start2)];\r\n case 14: return [min(start1, end2), max(end1, end2)];\r\n case 15: return [start1, end2];\r\n default: return [NaN, NaN];\r\n }\r\n}\r\n\r\nfunction intersect_2d(A, B) {\r\n const [top, bottom] = intersect_2d(A.top, A.bottom, B.top, B.bottom);\r\n const [left, right] = intersect_2d(A.left, A.right, B.left, B.right);\r\n\r\n if (isNaN(top) || isNaN(bottom) || isNaN(left) || isNaN(right) || (top === bottom) || (left === right)) {\r\n return [];\r\n }\r\n\r\n return [{ left, top, right, bottom }];\r\n}\r\n\r\nfunction clip(A, B) {\r\n var rectangles = []; \r\n\r\n if (A.top \u003C B.top) {\r\n rectangles.push({ left: A.left, top: A.top, right: A.right, bottom: B.top }); \r\n }\r\n if (A.left \u003C B.left) {\r\n rectangles.push({ left: A.left, top: max(A.top, B.top), right: B.left, bottom: min(A.bottom, B.bottom) }); \r\n }\r\n if (A.right \u003E B.right) {\r\n rectangles.push({ left: B.right, top: max(A.top, B.top), right: A.right, bottom: min(A.bottom, B.bottom) }); \r\n }\r\n if (A.bottom \u003E B.bottom) {\r\n rectangles.push({ left: A.left, top: B.bottom, right: A.right, bottom: A.bottom }); \r\n }\r\n\r\n return rectangles; \r\n}\r\n\r\nfunction overlap(A, B) {\r\n const rA = clip(A, B).map(rect =\u003E ({ rect, owner: 1 }));\r\n const rB = clip(B, A).map(rect =\u003E ({ rect, owner: 2 }));\r\n const rAB = intersect_2d(A, B).map(rect =\u003E ({ rect, owner: 3 }));\r\n\r\n return rA.concat(rB).concat(rAB);\r\n}","TestCases":[{"Name":"full overlap check","Code":"overlap({\r\n left: Math.random(),\r\n top: Math.random(),\r\n right: Math.random(),\r\n bottom: Math.random(),\r\n}, {\r\n left: Math.random(),\r\n top: Math.random(),\r\n right: Math.random(),\r\n bottom: Math.random(), \r\n});","IsDeferred":false},{"Name":"one-side clipping","Code":"clip({\r\n left: Math.random(),\r\n top: Math.random(),\r\n right: Math.random(),\r\n bottom: Math.random(),\r\n}, {\r\n left: Math.random(),\r\n top: Math.random(),\r\n right: Math.random(),\r\n bottom: Math.random(), \r\n});","IsDeferred":false}]}