{"_id":"@coffeeandfun/maths-captcha","_rev":"5-850b61c12bd390d237e4f13f844dfd64","name":"@coffeeandfun/maths-captcha","dist-tags":{"latest":"3.1.6"},"versions":{"1.0.0":{"name":"@coffeeandfun/maths-captcha","version":"1.0.0","keywords":["maths","captcha","math","verification","human","verification","math-based","captcha","Node.js","captcha","random","math","question","generator","math","security","check","simple","captcha","form","protection","math","question","validation","math","problem","solver","user","verification","bot","prevention","CAPTCHA","alternative","math","challenge"],"author":{"name":"Coffee & Fun LLC"},"license":"MIT","_id":"@coffeeandfun/maths-captcha@1.0.0","maintainers":[{"name":"robertjgabriel","email":"robert_gabriel@outlook.com"}],"homepage":"https://github.com/coffee-and-fun/maths-captcha#readme","bugs":{"url":"https://github.com/coffee-and-fun/maths-captcha/issues"},"dist":{"shasum":"9ef511a753dddd51b17cea764f3afc5169f2053c","tarball":"https://registry.npmjs.org/@coffeeandfun/maths-captcha/-/maths-captcha-1.0.0.tgz","fileCount":7,"integrity":"sha512-D7KyVBAY7AxMxql8goTj8Pn5ONYYQI8VO7nnDfrjJowH8Ok1nGMr2eZsJBa8Ion6UJ3Cvi9Scnz9/U1gFJPJ2g==","signatures":[{"sig":"MEUCIBkqqshp3v9vNPeCXt6kWmb79G8nWRtnlL8faqJlrFsSAiEAtmVwjonOAXm4KqRGHvT25SSZ2yw9rs3dxjxHWU41wl8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":7538},"main":"index.js","gitHead":"77787cedc310fcb3ffd641ac745e1d2e9aab84ea","scripts":{"test":"jest"},"_npmUser":{"name":"robertjgabriel","email":"robert_gabriel@outlook.com"},"repository":{"url":"git+https://github.com/coffee-and-fun/maths-captcha.git","type":"git"},"_npmVersion":"10.2.4","description":"Maths-Captcha is a simple Node.js module that generates random math questions to verify human interaction. It creates math problems like addition, subtraction, multiplication, and division, and checks if the user's answer is correct. Ideal for adding a qu","directories":{},"_nodeVersion":"21.5.0","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0"},"_npmOperationalInternal":{"tmp":"tmp/maths-captcha_1.0.0_1729717987081_0.7757277130323073","host":"s3://npm-registry-packages"}},"1.2.2":{"name":"@coffeeandfun/maths-captcha","version":"1.2.2","keywords":["maths","captcha","math","verification","human","verification","math-based","captcha","Node.js","captcha","random","math","question","generator","math","security","check","simple","captcha","form","protection","math","question","validation","math","problem","solver","user","verification","bot","prevention","CAPTCHA","alternative","math","challenge"],"author":{"name":"Coffee & Fun LLC"},"license":"MIT","_id":"@coffeeandfun/maths-captcha@1.2.2","maintainers":[{"name":"robertjgabriel","email":"robert_gabriel@outlook.com"}],"homepage":"https://github.com/coffee-and-fun/maths-captcha#readme","bugs":{"url":"https://github.com/coffee-and-fun/maths-captcha/issues"},"dist":{"shasum":"e12c0bfc614c9f5451d6b99bfa9a2c1e2f9266e3","tarball":"https://registry.npmjs.org/@coffeeandfun/maths-captcha/-/maths-captcha-1.2.2.tgz","fileCount":7,"integrity":"sha512-94WYnX4DfcmjD0Y/ME0adUYNQknmDqoTLU2xqwvuNtCODtYUFbx/ZIvMFnCFHC8KP/ysUpSzJHx3BIlXGGFq/g==","signatures":[{"sig":"MEQCICA64Q3hB8k804eN8DeM5YKWQ55ByQoiN53BPBs1606oAiBMPFK+tpXpw2/Ub8A7GBt4mqghdbU0am7OPlMHGqbLqA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":18491},"main":"index.js","type":"module","gitHead":"2fde1b66a1936724b386de08d868839a58dfc3b1","scripts":{"test":"jest"},"_npmUser":{"name":"robertjgabriel","email":"robert_gabriel@outlook.com"},"repository":{"url":"git+https://github.com/coffee-and-fun/maths-captcha.git","type":"git"},"_npmVersion":"10.9.0","description":"Maths-Captcha is a simple Node.js module that generates random math questions to verify human interaction. It creates math problems like addition, subtraction, multiplication, and division, and checks if the user's answer is correct. Ideal for adding a qu","directories":{},"_nodeVersion":"22.11.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0"},"_npmOperationalInternal":{"tmp":"tmp/maths-captcha_1.2.2_1747541162295_0.5865191619049204","host":"s3://npm-registry-packages-npm-production"}},"1.2.3":{"name":"@coffeeandfun/maths-captcha","version":"1.2.3","keywords":["maths","captcha","math","verification","human","verification","math-based","captcha","Node.js","captcha","random","math","question","generator","math","security","check","simple","captcha","form","protection","math","question","validation","math","problem","solver","user","verification","bot","prevention","CAPTCHA","alternative","math","challenge"],"author":{"name":"Coffee & Fun LLC"},"license":"MIT","_id":"@coffeeandfun/maths-captcha@1.2.3","maintainers":[{"name":"robertjgabriel","email":"robert_gabriel@outlook.com"}],"homepage":"https://github.com/coffee-and-fun/maths-captcha#readme","bugs":{"url":"https://github.com/coffee-and-fun/maths-captcha/issues"},"dist":{"shasum":"bbd505fc455a1ef0859c8452063c6034a11d185b","tarball":"https://registry.npmjs.org/@coffeeandfun/maths-captcha/-/maths-captcha-1.2.3.tgz","fileCount":7,"integrity":"sha512-kW94bRN1BerbuOnHrwUJxiBSHA61H2qvZO53STmgiM2DUTOow82YTJ83UK6ntjpPOxGZGoo8Exz4LxGHzmcstQ==","signatures":[{"sig":"MEUCIQCIFDORtovu8jl3vpgiFzMKJNDCVEu7iALwQvU6BWFDMAIgXVjgCxPn/GI+hypYbP2cNDNYANhLjawGU8MBYagmxCs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":18475},"main":"index.js","type":"module","gitHead":"2fde1b66a1936724b386de08d868839a58dfc3b1","scripts":{"test":"jest"},"_npmUser":{"name":"robertjgabriel","email":"robert_gabriel@outlook.com"},"repository":{"url":"git+https://github.com/coffee-and-fun/maths-captcha.git","type":"git"},"_npmVersion":"10.9.0","description":"Maths-Captcha is a simple Node.js module that generates random math questions to verify human interaction. It creates math problems like addition, subtraction, multiplication, and division, and checks if the user's answer is correct. Ideal for adding a qu","directories":{},"_nodeVersion":"22.11.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0"},"_npmOperationalInternal":{"tmp":"tmp/maths-captcha_1.2.3_1747542359542_0.11724692859433739","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@coffeeandfun/maths-captcha","version":"2.0.0","keywords":["maths","captcha","math","verification","human","verification","math-based","captcha","Node.js","captcha","random","math","question","generator","math","security","check","simple","captcha","form","protection","math","question","validation","math","problem","solver","user","verification","bot","prevention","CAPTCHA","alternative","math","challenge"],"author":{"name":"Coffee & Fun LLC"},"license":"MIT","_id":"@coffeeandfun/maths-captcha@2.0.0","maintainers":[{"name":"robertjgabriel","email":"robert_gabriel@outlook.com"}],"homepage":"https://github.com/coffee-and-fun/maths-captcha#readme","bugs":{"url":"https://github.com/coffee-and-fun/maths-captcha/issues"},"dist":{"shasum":"463aa3770380b4d1f1ed0cc5b08fa01b58e44584","tarball":"https://registry.npmjs.org/@coffeeandfun/maths-captcha/-/maths-captcha-2.0.0.tgz","fileCount":10,"integrity":"sha512-iK0GkO2LRu7hWLRJSQOlXNajw7L+P3azDzjeAcjsNdce7O3SMAk7kL8YR/9BxsUu0jolvHeZvdXPppipyI8zlw==","signatures":[{"sig":"MEYCIQDDbePmlIBNIRNlx6LKD+FUI903cyzyHuy39PC9xCCkwgIhAMPEw/4+towZSp6N7xXYPTLjmxZKEvzET6KclNWMTZAF","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":49681},"main":"index.js","type":"module","gitHead":"aeb2d79318fb9cc0b63ae8fdd8ce416420e7b69f","scripts":{"v1":"NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest v1.test.js","v2":"NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest v1.test.js","test":"NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest","format":"npx prettier . --write"},"_npmUser":{"name":"robertjgabriel","email":"robert_gabriel@outlook.com"},"repository":{"url":"git+https://github.com/coffee-and-fun/maths-captcha.git","type":"git"},"_npmVersion":"10.9.0","description":"Maths-Captcha is a simple Node.js module that generates random math questions to verify human interaction. It creates math problems like addition, subtraction, multiplication, and division, and checks if the user's answer is correct. Ideal for adding a qu","directories":{},"_nodeVersion":"22.11.0","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0"},"_npmOperationalInternal":{"tmp":"tmp/maths-captcha_2.0.0_1752653205557_0.40691471295134907","host":"s3://npm-registry-packages-npm-production"}},"3.1.6":{"name":"@coffeeandfun/maths-captcha","version":"3.1.6","description":"Maths-Captcha is a simple Node.js module that generates random math questions to verify human interaction. It creates math problems like addition, subtraction, multiplication, division, powers, percentages, sequences, and algebra, and checks if the user's","main":"index.js","types":"./index.d.ts","type":"module","exports":{".":{"types":"./index.d.ts","import":"./index.js"}},"engines":{"node":">=16"},"scripts":{"format":"npx prettier . --write","test":"NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest","v1":"NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest v1.test.js","v2":"NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest v2.test.js","v3":"NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest v3.test.js"},"keywords":["maths","captcha","math","verification","human","math-based","Node.js","random","question","generator","security","check","simple","form","protection","validation","problem","solver","user","bot","prevention","CAPTCHA","alternative","challenge","algebra","percentage","sequence","powers","pemdas"],"repository":{"type":"git","url":"git+https://github.com/coffee-and-fun/maths-captcha.git"},"bugs":{"url":"https://github.com/coffee-and-fun/maths-captcha/issues"},"homepage":"https://github.com/coffee-and-fun/maths-captcha#readme","author":{"name":"Coffee & Fun LLC"},"license":"MIT","devDependencies":{"jest":"^29.7.0"},"gitHead":"667073c959939be85dd377f14d5f7c2f8fb93970","_id":"@coffeeandfun/maths-captcha@3.1.6","_nodeVersion":"20.20.2","_npmVersion":"11.12.1","dist":{"integrity":"sha512-/+Go610XKA2P/CYAxPHsuimOgVtLJqiPt/jhCL5ghXswugwlAwH1+Qo72Z7Mkvxsu/0OdjBvdNaMrz8WXwLiSQ==","shasum":"d58c325311efaeb39f726c84545cda0ac95a1311","tarball":"https://registry.npmjs.org/@coffeeandfun/maths-captcha/-/maths-captcha-3.1.6.tgz","fileCount":18,"unpackedSize":42980,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@coffeeandfun%2fmaths-captcha@3.1.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBdB3zxqAviBa1WiE2c8hbpvooUvQZgpU1x4mRQeQ4afAiEAyZOkPYEDRHEzzB3GxfY4YJlVtJbcNORvhi3AeVZ4OSQ="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:eca94047-722f-4758-9e93-6de1f2d5232a"}},"directories":{},"maintainers":[{"name":"robertjgabriel","email":"robert_gabriel@outlook.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/maths-captcha_3.1.6_1776655458874_0.2682517235365729"},"_hasShrinkwrap":false}},"time":{"created":"2024-10-23T21:13:06.971Z","modified":"2026-04-20T03:24:19.253Z","1.0.0":"2024-10-23T21:13:07.267Z","1.2.2":"2025-05-18T04:06:02.472Z","1.2.3":"2025-05-18T04:25:59.725Z","2.0.0":"2025-07-16T08:06:45.720Z","3.1.6":"2026-04-20T03:24:18.998Z"},"bugs":{"url":"https://github.com/coffee-and-fun/maths-captcha/issues"},"author":{"name":"Coffee & Fun LLC"},"license":"MIT","homepage":"https://github.com/coffee-and-fun/maths-captcha#readme","keywords":["maths","captcha","math","verification","human","math-based","Node.js","random","question","generator","security","check","simple","form","protection","validation","problem","solver","user","bot","prevention","CAPTCHA","alternative","challenge","algebra","percentage","sequence","powers","pemdas"],"repository":{"type":"git","url":"git+https://github.com/coffee-and-fun/maths-captcha.git"},"description":"Maths-Captcha is a simple Node.js module that generates random math questions to verify human interaction. It creates math problems like addition, subtraction, multiplication, division, powers, percentages, sequences, and algebra, and checks if the user's","maintainers":[{"name":"robertjgabriel","email":"robert_gabriel@outlook.com"}],"readme":"# 🧮 @coffeeandfun/maths-captcha\n\nA small Node.js library that generates simple maths questions and checks the answers. Use it as a friendly alternative to image based CAPTCHAs. ✨\n\nExamples of what it can ask:\n\n- `7 + 3`\n- `25% of 80`\n- `√64`\n- `2x + 3 = 11`\n- `2, 4, 6, 8, ?`\n\nIt runs in plain JavaScript. There are no servers to call, no images to load, and no fonts to download.\n\n---\n\n## 📦 Install\n\n```bash\nnpm install @coffeeandfun/maths-captcha\n```\n\nRequires Node.js 16 or newer.\n\n---\n\n## 🚀 Quick start\n\n```js\nimport {\n  generateRandomMathQuestion,\n  validateAnswer,\n} from '@coffeeandfun/maths-captcha';\n\nconst question = generateRandomMathQuestion();\nconsole.log(question.question);\n// \"7 + 3\"\n\nconst isCorrect = validateAnswer(question, '10');\nconsole.log(isCorrect);\n// true\n```\n\nThat's the whole loop: generate a question, show it to the user, then check what they typed.\n\n---\n\n## 📝 What you get back\n\nEvery question is a plain object with the same shape:\n\n```js\n{\n  question: '7 + 3',     // The text to show the user\n  answer: '10',          // The correct answer as a string\n  numericAnswer: 10,     // The correct answer as a number\n  operation: '+',        // The operator or category\n  operands: [7, 3],      // The numbers used to build the question\n  type: 'arithmetic',    // Which question type produced it\n}\n```\n\nSome types add a `style` field (for example, `square`, `cube`, `geometric`).\n\n---\n\n## 🎲 Question types\n\nBy default the library only asks basic arithmetic. You can switch on more types when you want harder or more varied questions.\n\n| Type         | Example          | Notes                                |\n| ------------ | ---------------- | ------------------------------------ |\n| `arithmetic` | `7 + 3`          | `+` `-` `*` `/` and `%` (modulo)     |\n| `power`      | `5^2`, `√64`     | Squares, cubes, perfect square roots |\n| `percentage` | `25% of 80`      | Always whole-number answers          |\n| `pemdas`     | `(2 + 3) * 4`    | Order of operations                  |\n| `solve-x`    | `2x + 3 = 11`    | Solve for `x`                        |\n| `sequence`   | `2, 4, 6, 8, ?`  | Arithmetic and geometric patterns    |\n\nTurn on extra types with `setConfig`:\n\n```js\nimport {\n  setConfig,\n  generateRandomMathQuestion,\n} from '@coffeeandfun/maths-captcha';\n\nsetConfig({\n  QUESTION_TYPES: ['arithmetic', 'power', 'percentage', 'solve-x'],\n});\n\nconst question = generateRandomMathQuestion();\n// e.g. { question: '√64', answer: '8', type: 'power', style: 'sqrt', ... }\n```\n\n---\n\n## ✅ Checking answers\n\nThere are three ways to check an answer. Pick the one that fits how strict you want to be.\n\n### `validateAnswer(question, userAnswer)`\n\nStrict. Whole numbers must be typed as whole numbers.\n\n```js\nvalidateAnswer({ answer: '15' }, '15');    // ✅ true\nvalidateAnswer({ answer: '15' }, '15.0');  // ❌ false\nvalidateAnswer({ answer: '15' }, '16');    // ❌ false\n```\n\n### `validateAnswerFlexible(question, userAnswer)`\n\nFriendly. Accepts the same number written different ways.\n\n```js\nconst q = { answer: '4.00', numericAnswer: 4, operation: '/' };\n\nvalidateAnswerFlexible(q, '4');     // ✅ true\nvalidateAnswerFlexible(q, '4.0');   // ✅ true\nvalidateAnswerFlexible(q, '4.00');  // ✅ true\nvalidateAnswerFlexible(q, '3.99');  // ❌ false\n```\n\n### `validateAnswerWithFeedback(question, userAnswer)`\n\nReturns an object that explains the result. Useful when you want to show the user why their answer was wrong.\n\n```js\nvalidateAnswerWithFeedback(question, 'abc');\n// {\n//   isValid: false,\n//   reason: 'Invalid numeric format',\n//   userInput: 'abc',\n//   expected: '10'\n// }\n```\n\n### Batch checks\n\nIf you have many answers to check at once:\n\n```js\nvalidateAnswers([\n  { question: q1, answer: '10' },\n  { question: q2, answer: '7' },\n]);\n// [\n//   { question: '5 + 5', isValid: true, expectedAnswer: '10' },\n//   { question: '14 - 7', isValid: true, expectedAnswer: '7' },\n// ]\n```\n\n---\n\n## ⚙️ Configuration\n\n```js\nimport {\n  setConfig,\n  getConfig,\n  resetConfig,\n} from '@coffeeandfun/maths-captcha';\n\nsetConfig({\n  DIVISION_PRECISION: 3,\n  NUMBER_RANGE: { min: 1, max: 50 },\n  OPERATIONS: ['+', '-', '*'],\n  QUESTION_TYPES: ['arithmetic', 'power'],\n  AVOID_NEGATIVE_RESULTS: true,\n  AVOID_DIVISION_BY_ZERO: true,\n});\n\ngetConfig();   // Read the current settings\nresetConfig(); // Restore the defaults\n```\n\n### Default settings\n\n| Option                   | Default                |\n| ------------------------ | ---------------------- |\n| `DIVISION_PRECISION`     | `2`                    |\n| `NUMBER_RANGE`           | `{ min: 1, max: 100 }` |\n| `OPERATIONS`             | `['+', '-', '*', '/']` |\n| `QUESTION_TYPES`         | `['arithmetic']`       |\n| `AVOID_NEGATIVE_RESULTS` | `true`                 |\n| `AVOID_DIVISION_BY_ZERO` | `true`                 |\n| `MAX_ATTEMPTS`           | `10`                   |\n| `TOLERANCE`              | `1e-10`                |\n\n### Difficulty examples\n\nEasy mode for kids:\n\n```js\nsetConfig({\n  QUESTION_TYPES: ['arithmetic'],\n  OPERATIONS: ['+'],\n  NUMBER_RANGE: { min: 1, max: 10 },\n});\n```\n\nHarder mode for adults:\n\n```js\nsetConfig({\n  QUESTION_TYPES: ['arithmetic', 'pemdas', 'solve-x', 'sequence'],\n  NUMBER_RANGE: { min: 1, max: 50 },\n});\n```\n\n---\n\n## 📚 Generating in bulk\n\n```js\nimport { generateMultipleQuestions } from '@coffeeandfun/maths-captcha';\n\nconst ten = generateMultipleQuestions(10);\n```\n\n## 🎯 Generating with limits\n\nIf you need a question that fits specific bounds:\n\n```js\nimport { generateQuestionWithConstraints } from '@coffeeandfun/maths-captcha';\n\nconst easy = generateQuestionWithConstraints({\n  operations: ['+'],\n  numberRange: { min: 1, max: 10 },\n  maxResult: 20,\n});\n```\n\nIf the library cannot produce a question that fits, it throws. Wrap the call in a `try` block if you want to handle that.\n\n---\n\n## 🔌 Adding your own question type\n\nYou can plug in your own generator. It just needs to return a question object in the standard shape.\n\n```js\nimport {\n  registerQuestionType,\n  setConfig,\n  generateRandomMathQuestion,\n} from '@coffeeandfun/maths-captcha';\n\nregisterQuestionType('double', () => {\n  const n = Math.floor(Math.random() * 20) + 1;\n  return {\n    question: `Double ${n}`,\n    answer: String(n * 2),\n    numericAnswer: n * 2,\n    operation: 'custom',\n    operands: [n],\n    type: 'double',\n  };\n});\n\nsetConfig({ QUESTION_TYPES: ['double'] });\n\ngenerateRandomMathQuestion();\n// { question: 'Double 7', answer: '14', ... }\n```\n\nTo remove it later:\n\n```js\nimport { unregisterQuestionType } from '@coffeeandfun/maths-captcha';\nunregisterQuestionType('double');\n```\n\nTo see every type that is currently available:\n\n```js\nimport { listQuestionTypes } from '@coffeeandfun/maths-captcha';\nlistQuestionTypes();\n// ['arithmetic', 'power', 'percentage', 'pemdas', 'solve-x', 'sequence', 'double']\n```\n\n---\n\n## 🌐 Using it with Express\n\nGenerate the question on the server and store it in the session. Validate the answer on the server too. Never trust the client to check itself.\n\n```js\nimport express from 'express';\nimport session from 'express-session';\nimport {\n  generateRandomMathQuestion,\n  validateAnswer,\n} from '@coffeeandfun/maths-captcha';\n\nconst app = express();\napp.use(express.json());\napp.use(session({\n  secret: 'change-me',\n  resave: false,\n  saveUninitialized: true,\n}));\n\napp.get('/captcha', (req, res) => {\n  const question = generateRandomMathQuestion();\n  req.session.captcha = question;\n  res.json({ question: question.question });\n});\n\napp.post('/verify', (req, res) => {\n  const correct = validateAnswer(req.session.captcha, req.body.answer);\n  res.json({ correct });\n});\n```\n\n---\n\n## 📖 API reference\n\n### Generators\n\n| Function                                              | What it does                                      |\n| ----------------------------------------------------- | ------------------------------------------------- |\n| `generateRandomMathQuestion(precisionOrConfig?)`      | Returns one question.                             |\n| `generateMultipleQuestions(count, precisionOrConfig?)`| Returns an array of questions.                    |\n| `generateQuestionWithConstraints(constraints)`        | Returns a question that fits the given limits.    |\n| `registerQuestionType(name, generator)`               | Adds your own question type.                      |\n| `unregisterQuestionType(name)`                        | Removes a custom question type.                   |\n| `listQuestionTypes()`                                 | Lists every available type.                       |\n\n### Validators\n\n| Function                                  | What it does                                     |\n| ----------------------------------------- | ------------------------------------------------ |\n| `validateAnswer(question, answer)`        | Strict check. Returns `true` or `false`.         |\n| `validateAnswerStrict(question, answer)`  | The same as `validateAnswer`. Kept for clarity.  |\n| `validateAnswerFlexible(question, answer)`| Accepts equivalent decimal forms.                |\n| `validateAnswerWithFeedback(question, a)` | Returns an object explaining the result.         |\n| `validateAnswers(pairs)`                  | Checks many `{ question, answer }` pairs at once.|\n| `checkIfSolvedCorrectly(question, answer)`| Alias for `validateAnswer`.                      |\n\n### Configuration\n\n| Function          | What it does                                |\n| ----------------- | ------------------------------------------- |\n| `getConfig()`     | Returns a copy of the current settings.     |\n| `setConfig(obj)`  | Merges `obj` into the active settings.      |\n| `resetConfig()`   | Restores the default settings.              |\n\n### Helpers\n\n| Function                          | What it does                                                           |\n| --------------------------------- | ---------------------------------------------------------------------- |\n| `getQuestionStats(question)`      | Returns `{ operands, result, operation, difficulty, hasDecimals }`.    |\n| `calculateDifficulty(question)`   | Returns a difficulty score from 1 to 10.                               |\n| `normalizeNumericString(value)`   | Trims trailing zeros from a numeric string. For example, `5.00` → `5`. |\n\n---\n\n## 🧪 Testing\n\n```bash\nnpm test       # Run every test\nnpm run v1     # Run only the version 1 tests\nnpm run v2     # Run only the version 2 tests\nnpm run v3     # Run only the version 3 tests\n```\n\nThe library ships with 87 tests covering question generation, every validator, edge cases, and the new question types.\n\n---\n\n## ⬆️ Upgrading from version 2\n\nVersion 3 is a clean rewrite split into small modules. The public API is the same, so existing code keeps working without changes. The new features (extra question types, custom generators, `resetConfig`) are opt in.\n\nIf you only ever called `generateRandomMathQuestion` and `validateAnswer`, you do not need to change anything.\n\n---\n\n## 📄 License\n\nMIT. See [LICENSE](LICENSE). 🧡\n","readmeFilename":"README.md"}