UNPKG

saintest

Version:
1 lines 22.9 kB
{"version":3,"file":"index.min.cjs","sources":["../src/lib/ui.js","../src/lib/expect.js","../src/index.js"],"sourcesContent":["export const style = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n italic: '\\x1b[3m',\n underline: '\\x1b[4m',\n fg: (n) => `\\x1b[38;5;${n}m`,\n bg: (n) => `\\x1b[48;5;${n}m`\n}\n\nexport const colors = {\n success: 35,\n error: 203,\n text: 245,\n highlight: 7,\n warning: 214,\n info: 39\n}\n","import { style, colors } from './ui.js'\n\nfunction formatDiff(actual, expected) {\n return `\\n ${style.fg(colors.success)}+ Expected: ${JSON.stringify(expected)}${style.reset}\n ${style.fg(colors.error)}- Received: ${JSON.stringify(actual)}${style.reset}`\n}\n\nexport function expect(actual) {\n return {\n toBe(expected) {\n if (actual !== expected) {\n throw new Error(\n `Expected ${JSON.stringify(actual)} to be ${JSON.stringify(expected)}${formatDiff(\n actual,\n expected\n )}`\n )\n }\n },\n\n toEqual(expected) {\n if (JSON.stringify(actual) !== JSON.stringify(expected)) {\n throw new Error(`Expected deep equality${formatDiff(actual, expected)}`)\n }\n },\n\n toThrow(expectedError) {\n let threw = false\n let thrownError = null\n try {\n actual()\n } catch (error) {\n threw = true\n thrownError = error\n }\n if (!threw) {\n throw new Error('Expected function to throw an error')\n }\n if (expectedError && thrownError.message !== expectedError) {\n throw new Error(\n `Expected error message \"${expectedError}\" but got \"${thrownError.message}\"`\n )\n }\n },\n\n toBeGreaterThan(expected) {\n if (!(actual > expected)) {\n throw new Error(`Expected ${actual} to be greater than ${expected}`)\n }\n },\n\n toBeLessThan(expected) {\n if (!(actual < expected)) {\n throw new Error(`Expected ${actual} to be less than ${expected}`)\n }\n },\n\n toContain(item) {\n if (!actual.includes(item)) {\n throw new Error(`Expected ${JSON.stringify(actual)} to contain ${JSON.stringify(item)}`)\n }\n },\n\n toHaveLength(length) {\n if (actual.length !== length) {\n throw new Error(`Expected length of ${actual.length} to be ${length}`)\n }\n },\n\n toBeInstanceOf(constructor) {\n if (!(actual instanceof constructor)) {\n throw new Error(`Expected ${actual} to be instance of ${constructor.name}`)\n }\n },\n\n toBeTruthy() {\n if (!actual) {\n throw new Error(`Expected ${actual} to be truthy`)\n }\n },\n\n toBeFalsy() {\n if (actual) {\n throw new Error(`Expected ${actual} to be falsy`)\n }\n },\n\n toBeNull() {\n if (actual !== null) {\n throw new Error(`Expected ${actual} to be null`)\n }\n },\n\n toBeUndefined() {\n if (actual !== undefined) {\n throw new Error(`Expected ${actual} to be undefined`)\n }\n },\n\n toBeDefined() {\n if (actual === undefined) {\n throw new Error('Expected value to be defined')\n }\n },\n\n toBeNaN() {\n if (!Number.isNaN(actual)) {\n throw new Error(`Expected ${actual} to be NaN`)\n }\n },\n\n toMatch(regex) {\n if (!regex.test(actual)) {\n throw new Error(`Expected ${actual} to match ${regex}`)\n }\n },\n\n not: {\n toBe(expected) {\n if (actual === expected) {\n throw new Error(\n `Expected ${JSON.stringify(actual)} not to be ${JSON.stringify(expected)}`\n )\n }\n },\n\n toEqual(expected) {\n if (JSON.stringify(actual) === JSON.stringify(expected)) {\n throw new Error(`Expected values not to be deeply equal${formatDiff(actual, expected)}`)\n }\n },\n\n toBeInstanceOf(constructor) {\n if (actual instanceof constructor) {\n throw new Error(`Expected ${actual} not to be instance of ${constructor.name}`)\n }\n },\n\n toMatch(regex) {\n if (regex.test(actual)) {\n throw new Error(`Expected ${actual} not to match ${regex}`)\n }\n },\n\n toContain(item) {\n if (actual.includes(item)) {\n throw new Error(\n `Expected ${JSON.stringify(actual)} not to contain ${JSON.stringify(item)}`\n )\n }\n },\n\n toBeTruthy() {\n if (actual) {\n throw new Error(`Expected ${actual} not to be truthy`)\n }\n },\n\n toBeFalsy() {\n if (!actual) {\n throw new Error(`Expected ${actual} not to be falsy`)\n }\n },\n\n toBeNull() {\n if (actual === null) {\n throw new Error('Expected value not to be null')\n }\n },\n\n toBeUndefined() {\n if (actual === undefined) {\n throw new Error('Expected value not to be undefined')\n }\n },\n\n toBeDefined() {\n if (actual !== undefined) {\n throw new Error('Expected value to be undefined')\n }\n },\n\n toBeNaN() {\n if (Number.isNaN(actual)) {\n throw new Error('Expected value not to be NaN')\n }\n },\n\n toHaveLength(length) {\n if (actual.length === length) {\n throw new Error(`Expected length not to be ${length}`)\n }\n },\n\n toBeGreaterThan(expected) {\n if (actual > expected) {\n throw new Error(`Expected ${actual} not to be greater than ${expected}`)\n }\n },\n\n toBeLessThan(expected) {\n if (actual < expected) {\n throw new Error(`Expected ${actual} not to be less than ${expected}`)\n }\n },\n\n toHaveProperty(propertyPath, value) {\n const properties = propertyPath.split('.')\n let currentObject = actual\n\n try {\n for (const property of properties) {\n currentObject = currentObject[property]\n }\n\n if (value === undefined) {\n throw new Error(`Expected object not to have property \"${propertyPath}\"`)\n }\n\n if (currentObject === value) {\n throw new Error(\n `Expected property \"${propertyPath}\" not to have value ${JSON.stringify(value)}`\n )\n }\n } catch (e) {\n // Property path doesn't exist, which is what we want for negative case\n return\n }\n },\n\n toThrow(expectedError) {\n try {\n actual()\n // If we get here, the function didn't throw, which is what we want\n } catch (error) {\n if (!expectedError) {\n throw new Error('Expected function not to throw an error')\n }\n if (error.message === expectedError) {\n throw new Error(`Expected function not to throw error \"${expectedError}\"`)\n }\n }\n },\n\n toBeCloseTo(expected, precision = 2) {\n const multiplier = Math.pow(10, precision)\n const roundedActual = Math.round(actual * multiplier)\n const roundedExpected = Math.round(expected * multiplier)\n\n if (roundedActual === roundedExpected) {\n throw new Error(\n `Expected ${actual} not to be close to ${expected} with precision of ${precision} decimal points`\n )\n }\n }\n },\n\n toHaveProperty(propertyPath, value) {\n const properties = propertyPath.split('.')\n let currentObject = actual\n\n for (const property of properties) {\n if (!(property in currentObject)) {\n throw new Error(`Expected object to have property \"${propertyPath}\"`)\n }\n currentObject = currentObject[property]\n }\n\n if (value !== undefined && currentObject !== value) {\n throw new Error(\n `Expected property \"${propertyPath}\" to have value ${JSON.stringify(\n value\n )}, got ${JSON.stringify(currentObject)}`\n )\n }\n },\n\n toBeCloseTo(expected, precision = 2) {\n const multiplier = Math.pow(10, precision)\n const roundedActual = Math.round(actual * multiplier)\n const roundedExpected = Math.round(expected * multiplier)\n\n if (roundedActual !== roundedExpected) {\n throw new Error(\n `Expected ${actual} to be close to ${expected} with precision of ${precision} decimal points`\n )\n }\n }\n }\n}\n","import { style, colors } from './lib/ui.js'\nimport { expect } from './lib/expect.js'\nexport const testSuites = []\nexport const defaultSuite = {\n name: 'Standalone Tests',\n tests: [],\n beforeEach: null,\n afterEach: null,\n beforeAll: null,\n afterAll: null\n}\nexport let currentSuite = null\nlet totalTests = 0\nlet passedTests = 0\nlet failedTests = 0\nlet skippedTests = 0\nlet startTime = 0\n\nconst getExecutionTime = () => {\n const endTime = performance.now()\n return ((endTime - startTime) / 1000).toFixed(3)\n}\n\nexport function describe(name, fn) {\n const suite = {\n name,\n tests: [],\n beforeEach: null,\n afterEach: null,\n beforeAll: null,\n afterAll: null\n }\n\n testSuites.push(suite)\n const previousSuite = currentSuite\n currentSuite = suite\n fn()\n currentSuite = previousSuite\n}\n\nexport function beforeEach(fn) {\n if (currentSuite) {\n currentSuite.beforeEach = fn\n } else {\n defaultSuite.beforeEach = fn\n }\n}\n\nexport function afterEach(fn) {\n if (currentSuite) {\n currentSuite.afterEach = fn\n } else {\n defaultSuite.afterEach = fn\n }\n}\n\nexport function beforeAll(fn) {\n if (currentSuite) {\n currentSuite.beforeAll = fn\n } else {\n defaultSuite.beforeAll = fn\n }\n}\n\nexport function afterAll(fn) {\n if (currentSuite) {\n currentSuite.afterAll = fn\n } else {\n defaultSuite.afterAll = fn\n }\n}\n\nexport function it(name, fn) {\n const test = {\n name,\n fn,\n skip: false,\n only: false,\n timeout: 100\n }\n\n if (currentSuite) {\n currentSuite.tests.push(test)\n } else {\n defaultSuite.tests.push(test)\n }\n totalTests++\n return {\n skip: () => {\n test.skip = true\n totalTests--\n skippedTests++\n },\n only: () => {\n test.only = true\n },\n timeout: (ms) => {\n test.timeout = ms\n }\n }\n}\n\nexport function test(name, fn) {\n return it(name, fn)\n}\n\nasync function runTest(test, suite) {\n if (test.skip) {\n console.log(\n ` ${style.fg(colors.warning)}○${style.reset} ` +\n `${style.fg(colors.text)}${test.name} ${style.italic}(skipped)${style.reset}`\n )\n return { status: 'skipped' }\n }\n\n try {\n if (suite.beforeEach) await suite.beforeEach()\n\n const testPromise = Promise.race([\n Promise.resolve(test.fn()),\n new Promise((_, reject) =>\n setTimeout(() => reject(new Error(`Test timed out after ${test.timeout}ms`)), test.timeout)\n )\n ])\n\n await testPromise\n if (suite.afterEach) await suite.afterEach()\n\n console.log(\n ` ${style.fg(colors.success)}✓${style.reset} ` +\n `${style.fg(colors.highlight)}${test.name}${style.reset}`\n )\n return { status: 'passed' }\n } catch (error) {\n console.log(\n ` ${style.fg(colors.error)}✗${style.reset} ` +\n `${style.fg(colors.text)}${test.name}${style.reset}`\n )\n console.log(`${style.fg(colors.text)} ${error.message}${style.reset}`)\n return { status: 'failed' }\n }\n}\n\nasync function runSuite(suite) {\n if (suite.tests.length === 0) return\n\n let suitePassed = 0\n let suiteFailed = 0\n let suiteSkipped = 0\n\n console.log(\n `\\n${style.fg(colors.success)}${suite.name}${style.fg(colors.text)} ` +\n `[${suite.tests.length} tests]${style.reset}\\n`\n )\n\n try {\n if (suite.beforeAll) await suite.beforeAll()\n\n const onlyTests = suite.tests.filter((t) => t.only)\n const testsToRun = onlyTests.length > 0 ? onlyTests : suite.tests\n\n for (const test of testsToRun) {\n const result = await runTest(test, suite)\n switch (result.status) {\n case 'passed':\n suitePassed++\n passedTests++\n break\n case 'failed':\n suiteFailed++\n failedTests++\n break\n case 'skipped':\n suiteSkipped++\n break\n }\n }\n\n if (suite.afterAll) await suite.afterAll()\n\n const suiteTotal = suitePassed + suiteFailed + suiteSkipped\n const suitePassedPercentage = ((suitePassed / (suiteTotal - suiteSkipped)) * 100).toFixed(2)\n\n console.log(`\\n Suite Summary:`)\n console.log(\n ` ${style.fg(colors.success)}${suitePassedPercentage}%${style.reset} ` +\n `${style.fg(colors.text)}passing${style.reset}`\n )\n console.log(\n ` ${style.fg(colors.success)}${suitePassed} passed${style.reset}` +\n ` · ` +\n `${style.fg(colors.error)}${suiteFailed} failed${style.reset}` +\n ` · ` +\n `${style.fg(colors.warning)}${suiteSkipped} skipped${style.reset}` +\n ` · ` +\n `${style.fg(colors.text)}${suiteTotal} total${style.reset}`\n )\n } catch (error) {\n console.error(`${style.fg(colors.error)}Suite Error: ${error.message}${style.reset}`)\n }\n}\n\nexport async function run() {\n startTime = performance.now()\n\n if (defaultSuite.tests.length > 0) {\n await runSuite(defaultSuite)\n }\n\n for (const suite of testSuites) {\n await runSuite(suite)\n }\n\n const executionTime = getExecutionTime()\n const totalTestCount = passedTests + failedTests + skippedTests\n const passedPercentage = ((passedTests / (totalTestCount - skippedTests)) * 100).toFixed(2)\n\n if (testSuites.length > 0 || defaultSuite.tests.length > 0) {\n console.log('\\nFinal Test Results:')\n console.log(\n `${style.fg(colors.success)}${passedPercentage}%${style.reset} ` +\n `${style.fg(colors.text)}of all tests passing${style.reset}`\n )\n\n console.log(\n `${style.fg(colors.success)}${passedTests} passed${style.reset}` +\n ` · ` +\n `${style.fg(colors.error)}${failedTests} failed${style.reset}` +\n ` · ` +\n `${style.fg(colors.warning)}${skippedTests} skipped${style.reset}` +\n ` · ` +\n `${style.fg(colors.text)}${totalTestCount} total${style.reset}`\n )\n\n console.log(`${style.fg(colors.text)}Total Time: ${executionTime}s${style.reset}\\n`)\n }\n}\n\nexport { expect } from './lib/expect.js'\nexport default {\n expect,\n it,\n test,\n describe,\n beforeEach,\n afterEach,\n beforeAll,\n afterAll,\n run,\n testSuites,\n defaultSuite,\n currentSuite\n}\n"],"names":["style","n","colors","formatDiff","actual","expected","JSON","stringify","expect","toBe","Error","toEqual","toThrow","expectedError","threw","thrownError","error","message","toBeGreaterThan","toBeLessThan","toContain","item","includes","toHaveLength","length","toBeInstanceOf","constructor","name","toBeTruthy","toBeFalsy","toBeNull","toBeUndefined","undefined","toBeDefined","toBeNaN","Number","isNaN","toMatch","regex","test","not","toHaveProperty","propertyPath","value","properties","split","currentObject","property","e","toBeCloseTo","precision","multiplier","Math","pow","round","testSuites","defaultSuite","tests","beforeEach","afterEach","beforeAll","afterAll","currentSuite","passedTests","failedTests","skippedTests","startTime","describe","fn","suite","push","previousSuite","it","skip","only","timeout","ms","async","runTest","console","log","status","testPromise","Promise","race","resolve","_","reject","setTimeout","runSuite","suitePassed","suiteFailed","suiteSkipped","onlyTests","filter","t","testsToRun","suiteTotal","suitePassedPercentage","toFixed","run","performance","now","executionTime","totalTestCount","passedPercentage","index"],"mappings":";;;;oEAAO,MAAMA,EACJ,OADIA,EAMNC,GAAM,UAAaA,KAIbC,EACF,GADEA,EAEJ,IAFIA,EAGL,ICXR,SAASC,EAAWC,EAAQC,GAC1B,MAAO,SAASL,EAASE,iBAA8BI,KAAKC,UAAUF,KAAYL,UAC9EA,EAASE,iBAA4BI,KAAKC,UAAUH,KAAUJ,GACpE,CAEO,SAASQ,EAAOJ,GACrB,MAAO,CACL,IAAAK,CAAKJ,GACH,GAAID,IAAWC,EACb,MAAM,IAAIK,MACR,YAAYJ,KAAKC,UAAUH,YAAiBE,KAAKC,UAAUF,KAAYF,EACrEC,EACAC,KAIP,EAED,OAAAM,CAAQN,GACN,GAAIC,KAAKC,UAAUH,KAAYE,KAAKC,UAAUF,GAC5C,MAAM,IAAIK,MAAM,yBAAyBP,EAAWC,EAAQC,KAE/D,EAED,OAAAO,CAAQC,GACN,IAAIC,GAAQ,EACRC,EAAc,KAClB,IACEX,GACD,CAAC,MAAOY,GACPF,GAAQ,EACRC,EAAcC,CACtB,CACM,IAAKF,EACH,MAAM,IAAIJ,MAAM,uCAElB,GAAIG,GAAiBE,EAAYE,UAAYJ,EAC3C,MAAM,IAAIH,MACR,2BAA2BG,eAA2BE,EAAYE,WAGvE,EAED,eAAAC,CAAgBb,GACd,KAAMD,EAASC,GACb,MAAM,IAAIK,MAAM,YAAYN,wBAA6BC,IAE5D,EAED,YAAAc,CAAad,GACX,KAAMD,EAASC,GACb,MAAM,IAAIK,MAAM,YAAYN,qBAA0BC,IAEzD,EAED,SAAAe,CAAUC,GACR,IAAKjB,EAAOkB,SAASD,GACnB,MAAM,IAAIX,MAAM,YAAYJ,KAAKC,UAAUH,iBAAsBE,KAAKC,UAAUc,KAEnF,EAED,YAAAE,CAAaC,GACX,GAAIpB,EAAOoB,SAAWA,EACpB,MAAM,IAAId,MAAM,sBAAsBN,EAAOoB,gBAAgBA,IAEhE,EAED,cAAAC,CAAeC,GACb,KAAMtB,aAAkBsB,GACtB,MAAM,IAAIhB,MAAM,YAAYN,uBAA4BsB,EAAYC,OAEvE,EAED,UAAAC,GACE,IAAKxB,EACH,MAAM,IAAIM,MAAM,YAAYN,iBAE/B,EAED,SAAAyB,GACE,GAAIzB,EACF,MAAM,IAAIM,MAAM,YAAYN,gBAE/B,EAED,QAAA0B,GACE,GAAe,OAAX1B,EACF,MAAM,IAAIM,MAAM,YAAYN,eAE/B,EAED,aAAA2B,GACE,QAAeC,IAAX5B,EACF,MAAM,IAAIM,MAAM,YAAYN,oBAE/B,EAED,WAAA6B,GACE,QAAeD,IAAX5B,EACF,MAAM,IAAIM,MAAM,+BAEnB,EAED,OAAAwB,GACE,IAAKC,OAAOC,MAAMhC,GAChB,MAAM,IAAIM,MAAM,YAAYN,cAE/B,EAED,OAAAiC,CAAQC,GACN,IAAKA,EAAMC,KAAKnC,GACd,MAAM,IAAIM,MAAM,YAAYN,cAAmBkC,IAElD,EAEDE,IAAK,CACH,IAAA/B,CAAKJ,GACH,GAAID,IAAWC,EACb,MAAM,IAAIK,MACR,YAAYJ,KAAKC,UAAUH,gBAAqBE,KAAKC,UAAUF,KAGpE,EAED,OAAAM,CAAQN,GACN,GAAIC,KAAKC,UAAUH,KAAYE,KAAKC,UAAUF,GAC5C,MAAM,IAAIK,MAAM,yCAAyCP,EAAWC,EAAQC,KAE/E,EAED,cAAAoB,CAAeC,GACb,GAAItB,aAAkBsB,EACpB,MAAM,IAAIhB,MAAM,YAAYN,2BAAgCsB,EAAYC,OAE3E,EAED,OAAAU,CAAQC,GACN,GAAIA,EAAMC,KAAKnC,GACb,MAAM,IAAIM,MAAM,YAAYN,kBAAuBkC,IAEtD,EAED,SAAAlB,CAAUC,GACR,GAAIjB,EAAOkB,SAASD,GAClB,MAAM,IAAIX,MACR,YAAYJ,KAAKC,UAAUH,qBAA0BE,KAAKC,UAAUc,KAGzE,EAED,UAAAO,GACE,GAAIxB,EACF,MAAM,IAAIM,MAAM,YAAYN,qBAE/B,EAED,SAAAyB,GACE,IAAKzB,EACH,MAAM,IAAIM,MAAM,YAAYN,oBAE/B,EAED,QAAA0B,GACE,GAAe,OAAX1B,EACF,MAAM,IAAIM,MAAM,gCAEnB,EAED,aAAAqB,GACE,QAAeC,IAAX5B,EACF,MAAM,IAAIM,MAAM,qCAEnB,EAED,WAAAuB,GACE,QAAeD,IAAX5B,EACF,MAAM,IAAIM,MAAM,iCAEnB,EAED,OAAAwB,GACE,GAAIC,OAAOC,MAAMhC,GACf,MAAM,IAAIM,MAAM,+BAEnB,EAED,YAAAa,CAAaC,GACX,GAAIpB,EAAOoB,SAAWA,EACpB,MAAM,IAAId,MAAM,6BAA6Bc,IAEhD,EAED,eAAAN,CAAgBb,GACd,GAAID,EAASC,EACX,MAAM,IAAIK,MAAM,YAAYN,4BAAiCC,IAEhE,EAED,YAAAc,CAAad,GACX,GAAID,EAASC,EACX,MAAM,IAAIK,MAAM,YAAYN,yBAA8BC,IAE7D,EAED,cAAAoC,CAAeC,EAAcC,GAC3B,MAAMC,EAAaF,EAAaG,MAAM,KACtC,IAAIC,EAAgB1C,EAEpB,IACE,IAAK,MAAM2C,KAAYH,EACrBE,EAAgBA,EAAcC,GAGhC,QAAcf,IAAVW,EACF,MAAM,IAAIjC,MAAM,yCAAyCgC,MAG3D,GAAII,IAAkBH,EACpB,MAAM,IAAIjC,MACR,sBAAsBgC,wBAAmCpC,KAAKC,UAAUoC,KAG7E,CAAC,MAAOK,GAEP,MACV,CACO,EAED,OAAApC,CAAQC,GACN,IACET,GAED,CAAC,MAAOY,GACP,IAAKH,EACH,MAAM,IAAIH,MAAM,2CAElB,GAAIM,EAAMC,UAAYJ,EACpB,MAAM,IAAIH,MAAM,yCAAyCG,KAErE,CACO,EAED,WAAAoC,CAAY5C,EAAU6C,EAAY,GAChC,MAAMC,EAAaC,KAAKC,IAAI,GAAIH,GAIhC,GAHsBE,KAAKE,MAAMlD,EAAS+C,KAClBC,KAAKE,MAAMjD,EAAW8C,GAG5C,MAAM,IAAIzC,MACR,YAAYN,wBAA6BC,uBAA8B6C,mBAGnF,GAGI,cAAAT,CAAeC,EAAcC,GAC3B,MAAMC,EAAaF,EAAaG,MAAM,KACtC,IAAIC,EAAgB1C,EAEpB,IAAK,MAAM2C,KAAYH,EAAY,CACjC,KAAMG,KAAYD,GAChB,MAAM,IAAIpC,MAAM,qCAAqCgC,MAEvDI,EAAgBA,EAAcC,EACtC,CAEM,QAAcf,IAAVW,GAAuBG,IAAkBH,EAC3C,MAAM,IAAIjC,MACR,sBAAsBgC,oBAA+BpC,KAAKC,UACxDoC,WACQrC,KAAKC,UAAUuC,KAG9B,EAED,WAAAG,CAAY5C,EAAU6C,EAAY,GAChC,MAAMC,EAAaC,KAAKC,IAAI,GAAIH,GAIhC,GAHsBE,KAAKE,MAAMlD,EAAS+C,KAClBC,KAAKE,MAAMjD,EAAW8C,GAG5C,MAAM,IAAIzC,MACR,YAAYN,oBAAyBC,uBAA8B6C,mBAG7E,EAEA,CC/RY,MAACK,EAAa,GACbC,EAAe,CAC1B7B,KAAM,mBACN8B,MAAO,GACPC,WAAY,KACZC,UAAW,KACXC,UAAW,KACXC,SAAU,MAEDC,QAAAA,aAAe,KAE1B,IAAIC,EAAc,EACdC,EAAc,EACdC,EAAe,EACfC,EAAY,EAOT,SAASC,EAASxC,EAAMyC,GAC7B,MAAMC,EAAQ,CACZ1C,OACA8B,MAAO,GACPC,WAAY,KACZC,UAAW,KACXC,UAAW,KACXC,SAAU,MAGZN,EAAWe,KAAKD,GAChB,MAAME,EAAgBT,QAAAA,aACtBA,qBAAeO,EACfD,IACAN,qBAAeS,CACjB,CAEO,SAASb,EAAWU,GACrBN,qBACFA,QAAAA,aAAaJ,WAAaU,EAE1BZ,EAAaE,WAAaU,CAE9B,CAEO,SAAST,EAAUS,GACpBN,qBACFA,QAAAA,aAAaH,UAAYS,EAEzBZ,EAAaG,UAAYS,CAE7B,CAEO,SAASR,EAAUQ,GACpBN,qBACFA,QAAAA,aAAaF,UAAYQ,EAEzBZ,EAAaI,UAAYQ,CAE7B,CAEO,SAASP,EAASO,GACnBN,qBACFA,QAAAA,aAAaD,SAAWO,EAExBZ,EAAaK,SAAWO,CAE5B,CAEO,SAASI,EAAG7C,EAAMyC,GACvB,MAAM7B,EAAO,CACXZ,OACAyC,KACAK,MAAM,EACNC,MAAM,EACNC,QAAS,KASX,OANIb,qBACFA,qBAAaL,MAAMa,KAAK/B,GAExBiB,EAAaC,MAAMa,KAAK/B,GAGnB,CACLkC,KAAM,KACJlC,EAAKkC,MAAO,EAEZR,GAAY,EAEdS,KAAM,KACJnC,EAAKmC,MAAO,CAAA,EAEdC,QAAUC,IACRrC,EAAKoC,QAAUC,CAAA,EAGrB,CAEO,SAASrC,EAAKZ,EAAMyC,GACzB,OAAOI,EAAG7C,EAAMyC,EAClB,CAEAS,eAAeC,EAAQvC,EAAM8B,GAC3B,GAAI9B,EAAKkC,KAKP,OAJAM,QAAQC,IACN,KAAKhF,EF9FA,QE8F4BA,KAC5BA,EAASE,KAAeqC,EAAKZ,qBAAgC3B,KAE7D,CAAEiF,OAAQ,WAGnB,IACMZ,EAAMX,kBAAkBW,EAAMX,aAElC,MAAMwB,EAAcC,QAAQC,KAAK,CAC/BD,QAAQE,QAAQ9C,EAAK6B,MACrB,IAAIe,SAAQ,CAACG,EAAGC,IACdC,YAAW,IAAMD,EAAO,IAAI7E,MAAM,wBAAwB6B,EAAKoC,eAAepC,EAAKoC,aAWvF,aAPMO,EACFb,EAAMV,iBAAiBU,EAAMV,YAEjCoB,QAAQC,IACN,KAAKhF,EAASE,MAAmBF,KAC5BA,EFpHE,KEoH2BuC,EAAKZ,OAAO3B,KAEzC,CAAEiF,OAAQ,SAClB,CAAC,MAAOjE,GAMP,OALA+D,QAAQC,IACN,KAAKhF,EAASE,MAAiBF,KAC1BA,EAASE,KAAeqC,EAAKZ,OAAO3B,KAE3C+E,QAAQC,IAAI,GAAGhF,EAASE,SAAmBc,EAAMC,UAAUjB,KACpD,CAAEiF,OAAQ,SACrB,CACA,CAEAJ,eAAeY,EAASpB,GACtB,GAA2B,IAAvBA,EAAMZ,MAAMjC,OAAc,OAE9B,IAAIkE,EAAc,EACdC,EAAc,EACdC,EAAe,EAEnBb,QAAQC,IACN,KAAKhF,EAASE,KAAkBmE,EAAM1C,OAAO3B,EAASE,OAChDmE,EAAMZ,MAAMjC,gBAAgBxB,OAGpC,IACMqE,EAAMT,iBAAiBS,EAAMT,YAEjC,MAAMiC,EAAYxB,EAAMZ,MAAMqC,QAAQC,GAAMA,EAAErB,OACxCsB,EAAaH,EAAUrE,OAAS,EAAIqE,EAAYxB,EAAMZ,MAE5D,IAAK,MAAMlB,KAAQyD,EAEjB,cADqBlB,EAAQvC,EAAM8B,IACpBY,QACb,IAAK,SACHS,IACA3B,IACA,MACF,IAAK,SACH4B,IACA3B,IACA,MACF,IAAK,UACH4B,IAKFvB,EAAMR,gBAAgBQ,EAAMR,WAEhC,MAAMoC,EAAaP,EAAcC,EAAcC,EACzCM,GAA0BR,GAAeO,EAAaL,GAAiB,KAAKO,QAAQ,GAE1FpB,QAAQC,IAAI,sBACZD,QAAQC,IACN,KAAKhF,EAASE,KAAkBgG,KAAyBlG,KACpDA,EAASE,YAAsBF,KAEtC+E,QAAQC,IACN,KAAKhF,EAASE,KAAkBwF,WAAqB1F,OAEhDA,EAASE,KAAgByF,WAAqB3F,OAE9CA,EFlLA,OEkL2B4F,YAAuB5F,OAElDA,EAASE,KAAe+F,UAAmBjG,IAEnD,CAAC,MAAOgB,GACP+D,QAAQ/D,MAAM,GAAGhB,EAASE,kBAA6Bc,EAAMC,UAAUjB,IAC3E,CACA,CAEO6E,eAAeuB,IACpBlC,EAAYmC,YAAYC,MAEpB9C,EAAaC,MAAMjC,OAAS,SACxBiE,EAASjC,GAGjB,IAAK,MAAMa,KAASd,QACZkC,EAASpB,GAGjB,MAAMkC,IAlMUF,YAAYC,MACTpC,GAAa,KAAMiC,QAAQ,GAkMxCK,EAAiBzC,EAAcC,EAAcC,EAC7CwC,GAAqB1C,GAAeyC,EAAiBvC,GAAiB,KAAKkC,QAAQ,IAErF5C,EAAW/B,OAAS,GAAKgC,EAAaC,MAAMjC,OAAS,KACvDuD,QAAQC,IAAI,yBACZD,QAAQC,IACN,GAAGhF,EAASE,KAAkBuG,KAAoBzG,KAC7CA,EAASE,yBAAmCF,KAGnD+E,QAAQC,IACN,GAAGhF,EAASE,KAAkB6D,WAAqB/D,OAE9CA,EAASE,KAAgB8D,WAAqBhE,OAE9CA,EFtNA,OEsN2BiE,YAAuBjE,OAElDA,EAASE,KAAesG,UAAuBxG,KAGtD+E,QAAQC,IAAI,GAAGhF,EAASE,iBAA2BqG,KAAiBvG,OAExE,CAGA,IAAe0G,EAAA,CACblG,SACAgE,KACAjC,OACA4B,WACAT,aACAC,YACAC,YACAC,WACAuC,MACA7C,aACAC,eACAM,aAAAA,QAAAA"}