From fd897ec2ffdc47617de125b1562c58dcfc9c0301 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 25 Jan 2026 23:32:42 +0000 Subject: [PATCH 1/2] feat(js/ts): add 1014 new coding drill problems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - JavaScript: added 512 new problems (226 → 738 total) - Async/Await & Promises patterns - Functional Programming concepts - DOM & Browser APIs - Error Handling & Control Flow - RegEx & String Parsing - TypeScript: added 502 new problems (176 → 678 total) - Advanced Generics patterns - Utility Types usage - Class & OOP Patterns - Function Types & Overloads - Module & Declaration Patterns Difficulty distribution balanced across easy/medium/hard levels. --- lib/problems/javascript.ts | 7090 ++++++++++++++++++++++++++++- lib/problems/typescript.ts | 8840 ++++++++++++++++++++++++++++++++++++ 2 files changed, 15929 insertions(+), 1 deletion(-) diff --git a/lib/problems/javascript.ts b/lib/problems/javascript.ts index a358131..19f5be2 100644 --- a/lib/problems/javascript.ts +++ b/lib/problems/javascript.ts @@ -2883,7 +2883,7 @@ const setY = new Set([4, 5, 6, 7, 8]);`, sample: '[...new Set([...[...setX].filter(x => !setY.has(x)), ...[...setY].filter(x => !setX.has(x))])]', hints: ['Find elements in X not in Y', 'Find elements in Y not in X', 'Combine both results'], validPatterns: [ - /\[\s*\.\.\.\[\s*\.\.\.setX\s*\]\.filter[^]]*\.\.\.\[\s*\.\.\.setY\s*\]\.filter/, + /\[\s*\.\.\.\[\s*\.\.\.setX\s*\]\.filter[\s\S]*\.\.\.\[\s*\.\.\.setY\s*\]\.filter/, /filter\s*\(\s*\w+\s*=>\s*!set[XY]\.has\s*\(\s*\w+\s*\)\s*\)/, ], tags: ['Set', 'symmetric-difference', 'filter', 'has'], @@ -3798,6 +3798,7094 @@ const logs = [];`, ], tags: ['Proxy', 'Reflect', 'logging'], }, + // ======================================== + // REGULAR EXPRESSIONS & STRING PARSING + // ======================================== + { + id: 'js-regex-001', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Test for Digits', + text: 'Use a regex to test if the string contains any digit. Return true or false.', + setup: 'const str = "Hello World 123";', + setupCode: 'const str = "Hello World 123";', + expected: true, + sample: '/\\d/.test(str)', + hints: ['Use \\d to match digits', 'The .test() method returns a boolean'], + tags: ['regex', 'test', 'digits'], + }, + { + id: 'js-regex-002', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Match All Digits', + text: 'Use a regex to find all digits in the string. Return an array of matches.', + setup: 'const str = "abc123def456";', + setupCode: 'const str = "abc123def456";', + expected: ['1', '2', '3', '4', '5', '6'], + sample: 'str.match(/\\d/g)', + hints: ['Use the g flag for global matching', 'Use \\d to match digits'], + tags: ['regex', 'match', 'global-flag'], + }, + { + id: 'js-regex-003', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Case Insensitive Match', + text: 'Test if the string contains "hello" regardless of case.', + setup: 'const str = "HELLO World";', + setupCode: 'const str = "HELLO World";', + expected: true, + sample: '/hello/i.test(str)', + hints: ['Use the i flag for case insensitive matching', 'The pattern should be lowercase'], + tags: ['regex', 'test', 'case-insensitive'], + }, + { + id: 'js-regex-004', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Match Word Characters', + text: 'Find all word characters (letters, digits, underscore) in the string.', + setup: 'const str = "Hi! @user_123";', + setupCode: 'const str = "Hi! @user_123";', + expected: ['H', 'i', 'u', 's', 'e', 'r', '_', '1', '2', '3'], + sample: 'str.match(/\\w/g)', + hints: ['Use \\w to match word characters', 'Word characters include a-z, A-Z, 0-9, and _'], + tags: ['regex', 'match', 'word-characters'], + }, + { + id: 'js-regex-005', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Match Whitespace', + text: 'Count the number of whitespace characters in the string.', + setup: 'const str = "Hello World Test";', + setupCode: 'const str = "Hello World Test";', + expected: 3, + sample: '(str.match(/\\s/g) || []).length', + hints: ['Use \\s to match whitespace', 'Handle the case where match returns null'], + tags: ['regex', 'match', 'whitespace'], + }, + { + id: 'js-regex-006', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Start of String Match', + text: 'Test if the string starts with "Hello".', + setup: 'const str = "Hello World";', + setupCode: 'const str = "Hello World";', + expected: true, + sample: '/^Hello/.test(str)', + hints: ['Use ^ to match the start of a string', 'The ^ anchor asserts position at start'], + tags: ['regex', 'test', 'anchor'], + }, + { + id: 'js-regex-007', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'End of String Match', + text: 'Test if the string ends with a digit.', + setup: 'const str = "Order #123";', + setupCode: 'const str = "Order #123";', + expected: true, + sample: '/\\d$/.test(str)', + hints: ['Use $ to match the end of a string', 'Combine with \\d to match a digit at the end'], + tags: ['regex', 'test', 'anchor'], + }, + { + id: 'js-regex-008', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Match One or More', + text: 'Find sequences of one or more digits in the string.', + setup: 'const str = "abc123def45ghi6";', + setupCode: 'const str = "abc123def45ghi6";', + expected: ['123', '45', '6'], + sample: 'str.match(/\\d+/g)', + hints: ['Use + quantifier for one or more', 'Use g flag to find all matches'], + tags: ['regex', 'match', 'quantifier'], + }, + { + id: 'js-regex-009', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Match Zero or More', + text: 'Match "go" followed by zero or more "o" characters. Find all matches.', + setup: 'const str = "go goo gooo goooo";', + setupCode: 'const str = "go goo gooo goooo";', + expected: ['go', 'goo', 'gooo', 'goooo'], + sample: 'str.match(/goo*/g)', + hints: ['Use * quantifier for zero or more', 'The pattern goo* matches g followed by one or more o'], + tags: ['regex', 'match', 'quantifier'], + }, + { + id: 'js-regex-010', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Optional Character', + text: 'Match both "color" and "colour" in the string.', + setup: 'const str = "color and colour are both valid";', + setupCode: 'const str = "color and colour are both valid";', + expected: ['color', 'colour'], + sample: 'str.match(/colou?r/g)', + hints: ['Use ? for optional character', 'The u is optional in the pattern'], + tags: ['regex', 'match', 'quantifier'], + }, + { + id: 'js-regex-011', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Character Set', + text: 'Match all vowels in the string (case insensitive).', + setup: 'const str = "Hello World";', + setupCode: 'const str = "Hello World";', + expected: ['e', 'o', 'o'], + sample: 'str.match(/[aeiou]/gi)', + hints: ['Use [] for character set', 'Use i flag for case insensitive'], + tags: ['regex', 'match', 'character-class'], + }, + { + id: 'js-regex-012', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Negated Character Set', + text: 'Match all non-vowel characters (consonants and others).', + setup: 'const str = "Hello";', + setupCode: 'const str = "Hello";', + expected: ['H', 'l', 'l'], + sample: 'str.match(/[^aeiou]/gi)', + hints: ['Use [^] for negated set', 'This matches anything NOT in the set'], + tags: ['regex', 'match', 'character-class'], + }, + { + id: 'js-regex-013', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Range in Character Set', + text: 'Match all lowercase letters from a to m.', + setup: 'const str = "programming";', + setupCode: 'const str = "programming";', + expected: ['g', 'a', 'm', 'm', 'i', 'g'], + sample: 'str.match(/[a-m]/g)', + hints: ['Use - to define a range in character set', '[a-m] matches letters a through m'], + tags: ['regex', 'match', 'character-class'], + }, + { + id: 'js-regex-014', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Dot Wildcard', + text: 'Match any 3-character pattern that starts with "c" and ends with "t".', + setup: 'const str = "cat cot cut cart";', + setupCode: 'const str = "cat cot cut cart";', + expected: ['cat', 'cot', 'cut'], + sample: 'str.match(/c.t/g)', + hints: ['Use . to match any character', 'The dot matches exactly one character'], + tags: ['regex', 'match', 'wildcard'], + }, + { + id: 'js-regex-015', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Escape Special Character', + text: 'Test if the string contains a literal dot.', + setup: 'const str = "file.txt";', + setupCode: 'const str = "file.txt";', + expected: true, + sample: '/\\./.test(str)', + hints: ['Escape the dot with backslash', '\\. matches a literal dot'], + tags: ['regex', 'test', 'escape'], + }, + { + id: 'js-regex-016', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Word Boundary', + text: 'Test if the word "cat" exists as a whole word (not part of another word).', + setup: 'const str = "I have a cat and a caterpillar";', + setupCode: 'const str = "I have a cat and a caterpillar";', + expected: true, + sample: '/\\bcat\\b/.test(str)', + hints: ['Use \\b for word boundary', 'Word boundary matches between word and non-word characters'], + tags: ['regex', 'test', 'boundary'], + }, + { + id: 'js-regex-017', + category: 'String Parsing', + difficulty: 'easy', + title: 'Split on Whitespace', + text: 'Split the string into words using regex to handle multiple spaces.', + setup: 'const str = "Hello World Test";', + setupCode: 'const str = "Hello World Test";', + expected: ['Hello', 'World', 'Test'], + sample: 'str.split(/\\s+/)', + hints: ['Use \\s+ to match one or more whitespace', 'split() can take a regex'], + tags: ['regex', 'split', 'whitespace'], + }, + { + id: 'js-regex-018', + category: 'String Parsing', + difficulty: 'easy', + title: 'Replace All Digits', + text: 'Replace all digits in the string with "X".', + setup: 'const str = "Phone: 123-456-7890";', + setupCode: 'const str = "Phone: 123-456-7890";', + expected: 'Phone: XXX-XXX-XXXX', + sample: 'str.replace(/\\d/g, "X")', + hints: ['Use replace with g flag', 'Replace each digit individually'], + tags: ['regex', 'replace', 'global'], + }, + { + id: 'js-regex-019', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Match Exact Count', + text: 'Match exactly 3 consecutive digits.', + setup: 'const str = "12 123 1234 12345";', + setupCode: 'const str = "12 123 1234 12345";', + expected: ['123', '123', '123'], + sample: 'str.match(/\\d{3}/g)', + hints: ['Use {n} for exact count', '{3} means exactly 3 occurrences'], + tags: ['regex', 'match', 'quantifier'], + }, + { + id: 'js-regex-020', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Match Range Count', + text: 'Match sequences of 2 to 4 digits.', + setup: 'const str = "1 12 123 1234 12345";', + setupCode: 'const str = "1 12 123 1234 12345";', + expected: ['12', '123', '1234', '1234'], + sample: 'str.match(/\\d{2,4}/g)', + hints: ['Use {n,m} for range', '{2,4} means 2 to 4 occurrences'], + tags: ['regex', 'match', 'quantifier'], + }, + { + id: 'js-regex-021', + category: 'String Parsing', + difficulty: 'easy', + title: 'Extract File Extension', + text: 'Extract the file extension from the filename.', + setup: 'const filename = "document.pdf";', + setupCode: 'const filename = "document.pdf";', + expected: 'pdf', + sample: 'filename.match(/\\.(\\w+)$/)[1]', + hints: ['Match dot followed by word characters at end', 'Use capturing group for extension'], + tags: ['regex', 'match', 'parsing'], + }, + { + id: 'js-regex-022', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Non-Digit Characters', + text: 'Find all non-digit characters in the string.', + setup: 'const str = "abc123";', + setupCode: 'const str = "abc123";', + expected: ['a', 'b', 'c'], + sample: 'str.match(/\\D/g)', + hints: ['Use \\D to match non-digits', 'Capital D is the negation of \\d'], + tags: ['regex', 'match', 'character-class'], + }, + { + id: 'js-regex-023', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Non-Word Characters', + text: 'Find all non-word characters (special chars, spaces).', + setup: 'const str = "Hi! How are you?";', + setupCode: 'const str = "Hi! How are you?";', + expected: ['!', ' ', ' ', ' ', '?'], + sample: 'str.match(/\\W/g)', + hints: ['Use \\W to match non-word characters', 'Includes spaces and punctuation'], + tags: ['regex', 'match', 'character-class'], + }, + { + id: 'js-regex-024', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Match Words', + text: 'Find all words (sequences of word characters) in the string.', + setup: 'const str = "Hello, World! How are you?";', + setupCode: 'const str = "Hello, World! How are you?";', + expected: ['Hello', 'World', 'How', 'are', 'you'], + sample: 'str.match(/\\w+/g)', + hints: ['Use \\w+ to match sequences of word characters', 'This effectively extracts words'], + tags: ['regex', 'match', 'words'], + }, + { + id: 'js-regex-025', + category: 'String Parsing', + difficulty: 'easy', + title: 'Remove Extra Spaces', + text: 'Replace multiple consecutive spaces with a single space.', + setup: 'const str = "Hello World Test";', + setupCode: 'const str = "Hello World Test";', + expected: 'Hello World Test', + sample: 'str.replace(/\\s+/g, " ")', + hints: ['Use \\s+ to match multiple spaces', 'Replace with single space'], + tags: ['regex', 'replace', 'whitespace'], + }, + { + id: 'js-regex-026', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Basic Capturing Group', + text: 'Extract the area code from the phone number using capturing groups.', + setup: 'const phone = "(555) 123-4567";', + setupCode: 'const phone = "(555) 123-4567";', + expected: '555', + sample: 'phone.match(/\\((\\d{3})\\)/)[1]', + hints: ['Use () to create a capturing group', 'Access the group with [1]'], + tags: ['regex', 'match', 'capturing-group'], + }, + { + id: 'js-regex-027', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Multiple Capturing Groups', + text: 'Extract month, day, and year from the date string.', + setup: 'const date = "12/25/2023";', + setupCode: 'const date = "12/25/2023";', + expected: ['12/25/2023', '12', '25', '2023'], + sample: 'date.match(/(\\d{2})\\/(\\d{2})\\/(\\d{4})/)', + hints: ['Each () creates a separate group', 'Groups are numbered left to right'], + tags: ['regex', 'match', 'capturing-group'], + }, + { + id: 'js-regex-028', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Non-Capturing Group', + text: 'Match repeated "ab" patterns but do not capture the group. Count the matches.', + setup: 'const str = "ab ab ab abc abab";', + setupCode: 'const str = "ab ab ab abc abab";', + expected: 5, + sample: '(str.match(/(?:ab)/g) || []).length', + hints: ['Use (?:) for non-capturing group', 'Non-capturing groups match but do not remember'], + tags: ['regex', 'match', 'non-capturing'], + }, + { + id: 'js-regex-029', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Named Capturing Group', + text: 'Extract the username from an email using named capturing group.', + setup: 'const email = "john.doe@example.com";', + setupCode: 'const email = "john.doe@example.com";', + expected: 'john.doe', + sample: 'email.match(/(?[\\w.]+)@/).groups.username', + hints: ['Use (?...) for named groups', 'Access via .groups.name'], + tags: ['regex', 'match', 'named-group'], + }, + { + id: 'js-regex-030', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Alternation', + text: 'Match either "cat" or "dog" in the string. Find all matches.', + setup: 'const str = "I have a cat and a dog and another cat";', + setupCode: 'const str = "I have a cat and a dog and another cat";', + expected: ['cat', 'dog', 'cat'], + sample: 'str.match(/cat|dog/g)', + hints: ['Use | for alternation (OR)', 'This matches either pattern'], + tags: ['regex', 'match', 'alternation'], + }, + { + id: 'js-regex-031', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Alternation with Grouping', + text: 'Match "gray" or "grey" using alternation within a group.', + setup: 'const str = "gray and grey are both correct";', + setupCode: 'const str = "gray and grey are both correct";', + expected: ['gray', 'grey'], + sample: 'str.match(/gr(a|e)y/g)', + hints: ['Use () to limit alternation scope', 'gr(a|e)y matches gray or grey'], + tags: ['regex', 'match', 'alternation'], + }, + { + id: 'js-regex-032', + category: 'String Parsing', + difficulty: 'medium', + title: 'Replace with Captured Group', + text: 'Swap the first and last name using capturing groups.', + setup: 'const name = "John Smith";', + setupCode: 'const name = "John Smith";', + expected: 'Smith, John', + sample: 'name.replace(/(\\w+) (\\w+)/, "$2, $1")', + hints: ['Use $1, $2 to reference captured groups', 'Capture both names separately'], + tags: ['regex', 'replace', 'capturing-group'], + }, + { + id: 'js-regex-033', + category: 'String Parsing', + difficulty: 'medium', + title: 'Replace with Function', + text: 'Double all numbers in the string using a replace function.', + setup: 'const str = "I have 5 apples and 3 oranges";', + setupCode: 'const str = "I have 5 apples and 3 oranges";', + expected: 'I have 10 apples and 6 oranges', + sample: 'str.replace(/\\d+/g, m => m * 2)', + hints: ['Replace accepts a callback function', 'The function receives the match as argument'], + tags: ['regex', 'replace', 'callback'], + }, + { + id: 'js-regex-034', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Exec Method', + text: 'Use exec to get the first match with its index. Return the index.', + setup: 'const str = "The quick brown fox";', + setupCode: 'const str = "The quick brown fox";', + expected: 4, + sample: '/quick/.exec(str).index', + hints: ['exec() returns match with index property', 'Use .index to get position'], + tags: ['regex', 'exec', 'index'], + }, + { + id: 'js-regex-035', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Multiline Flag', + text: 'Find all lines that start with a digit using multiline mode.', + setup: 'const str = "1. First\\n2. Second\\nThird";', + setupCode: 'const str = "1. First\\n2. Second\\nThird";', + expected: ['1', '2'], + sample: 'str.match(/^\\d/gm)', + hints: ['Use m flag for multiline mode', '^$ match line start/end in multiline mode'], + tags: ['regex', 'match', 'multiline'], + }, + { + id: 'js-regex-036', + category: 'String Parsing', + difficulty: 'medium', + title: 'Split with Capturing Group', + text: 'Split the string by commas but keep the commas in the result.', + setup: 'const str = "a,b,c";', + setupCode: 'const str = "a,b,c";', + expected: ['a', ',', 'b', ',', 'c'], + sample: 'str.split(/(,)/)', + hints: ['Capturing groups in split are included', 'Wrap the delimiter in ()'], + tags: ['regex', 'split', 'capturing-group'], + }, + { + id: 'js-regex-037', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Lazy Quantifier', + text: 'Extract content between the first pair of quotes using lazy matching.', + setup: 'const str = \'"Hello" and "World"\';', + setupCode: 'const str = \'"Hello" and "World"\';', + expected: 'Hello', + sample: 'str.match(/"(.+?)"/)[1]', + hints: ['Use ? after quantifier for lazy mode', 'Lazy matches as few characters as possible'], + tags: ['regex', 'match', 'lazy'], + }, + { + id: 'js-regex-038', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Greedy vs Lazy', + text: 'Extract all quoted strings using lazy matching.', + setup: 'const str = \'"first" and "second" and "third"\';', + setupCode: 'const str = \'"first" and "second" and "third"\';', + expected: ['"first"', '"second"', '"third"'], + sample: 'str.match(/".*?"/g)', + hints: ['.*? is the lazy version of .*', 'Use g flag to find all matches'], + tags: ['regex', 'match', 'lazy'], + }, + { + id: 'js-regex-039', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Positive Lookahead', + text: 'Find all digits that are followed by "px".', + setup: 'const str = "10px 20em 30px 40rem";', + setupCode: 'const str = "10px 20em 30px 40rem";', + expected: ['10', '30'], + sample: 'str.match(/\\d+(?=px)/g)', + hints: ['Use (?=...) for positive lookahead', 'Lookahead does not consume characters'], + tags: ['regex', 'match', 'lookahead'], + }, + { + id: 'js-regex-040', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Negative Lookahead', + text: 'Find all numbers that are NOT followed by "%".', + setup: 'const str = "50% 100 75% 200";', + setupCode: 'const str = "50% 100 75% 200";', + expected: ['100', '200'], + sample: 'str.match(/\\d+(?!%)/g)', + hints: ['Use (?!...) for negative lookahead', 'Matches if NOT followed by pattern'], + tags: ['regex', 'match', 'lookahead'], + }, + { + id: 'js-regex-041', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Positive Lookbehind', + text: 'Find all numbers that are preceded by "$".', + setup: 'const str = "$100 200 $300 400";', + setupCode: 'const str = "$100 200 $300 400";', + expected: ['100', '300'], + sample: 'str.match(/(?<=\\$)\\d+/g)', + hints: ['Use (?<=...) for positive lookbehind', 'Matches if preceded by pattern'], + tags: ['regex', 'match', 'lookbehind'], + }, + { + id: 'js-regex-042', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Negative Lookbehind', + text: 'Find all numbers that are NOT preceded by "-".', + setup: 'const str = "10 -20 30 -40 50";', + setupCode: 'const str = "10 -20 30 -40 50";', + expected: ['10', '0', '30', '0', '50'], + sample: 'str.match(/(?Hello World

";', + setupCode: 'const html = "

Hello World

";', + expected: 'Hello World', + sample: 'html.replace(/<[^>]*>/g, "")', + hints: ['Match < followed by non-> chars and >', '[^>]* matches any char except >'], + tags: ['regex', 'replace', 'html'], + }, + { + id: 'js-regex-048', + category: 'String Parsing', + difficulty: 'medium', + title: 'CamelCase to Kebab', + text: 'Convert camelCase string to kebab-case.', + setup: 'const str = "backgroundColor";', + setupCode: 'const str = "backgroundColor";', + expected: 'background-color', + sample: 'str.replace(/([A-Z])/g, "-$1").toLowerCase()', + hints: ['Find uppercase letters and prepend hyphen', 'Convert result to lowercase'], + tags: ['regex', 'replace', 'case-conversion'], + }, + { + id: 'js-regex-049', + category: 'String Parsing', + difficulty: 'medium', + title: 'Validate Username', + text: 'Test if username is valid (3-16 chars, alphanumeric and underscores only, starts with letter).', + setup: 'const username = "john_doe123";', + setupCode: 'const username = "john_doe123";', + expected: true, + sample: '/^[a-zA-Z]\\w{2,15}$/.test(username)', + hints: ['Start with letter, then word chars', '{2,15} gives total 3-16 characters'], + tags: ['regex', 'test', 'validation'], + }, + { + id: 'js-regex-050', + category: 'String Parsing', + difficulty: 'medium', + title: 'Format Phone Number', + text: 'Format the 10-digit number as (XXX) XXX-XXXX.', + setup: 'const phone = "5551234567";', + setupCode: 'const phone = "5551234567";', + expected: '(555) 123-4567', + sample: 'phone.replace(/(\\d{3})(\\d{3})(\\d{4})/, "($1) $2-$3")', + hints: ['Capture three groups of digits', 'Use $1, $2, $3 in replacement'], + tags: ['regex', 'replace', 'formatting'], + }, + { + id: 'js-regex-051', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Match IP Octets', + text: 'Extract all octets from the IP address.', + setup: 'const ip = "192.168.1.100";', + setupCode: 'const ip = "192.168.1.100";', + expected: ['192', '168', '1', '100'], + sample: 'ip.match(/\\d+/g)', + hints: ['Match sequences of digits', 'Dots act as separators'], + tags: ['regex', 'match', 'ip-address'], + }, + { + id: 'js-regex-052', + category: 'String Parsing', + difficulty: 'medium', + title: 'Extract Domain', + text: 'Extract the domain name from the URL.', + setup: 'const url = "https://www.example.com/path/page";', + setupCode: 'const url = "https://www.example.com/path/page";', + expected: 'www.example.com', + sample: 'url.match(/https?:\\/\\/([^\\/]+)/)[1]', + hints: ['Match protocol then capture until slash', '[^\\/]+ matches non-slash characters'], + tags: ['regex', 'match', 'url'], + }, + { + id: 'js-regex-053', + category: 'String Parsing', + difficulty: 'medium', + title: 'Mask Credit Card', + text: 'Mask all but the last 4 digits of the credit card.', + setup: 'const card = "4532015112830366";', + setupCode: 'const card = "4532015112830366";', + expected: '************0366', + sample: 'card.replace(/\\d(?=\\d{4})/g, "*")', + hints: ['Use lookahead to keep last 4 digits', 'Replace each digit that has 4+ digits after it'], + tags: ['regex', 'replace', 'masking'], + }, + { + id: 'js-regex-054', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Match HEX Color', + text: 'Find all valid hex color codes in the string.', + setup: 'const css = "color: #fff; background: #abc123; border: #12G456";', + setupCode: 'const css = "color: #fff; background: #abc123; border: #12G456";', + expected: ['#fff', '#abc123'], + sample: 'css.match(/#[0-9a-fA-F]{3}(?:[0-9a-fA-F]{3})?\\b/g)', + hints: ['Match # followed by 3 or 6 hex digits', 'Use word boundary to avoid partial matches'], + tags: ['regex', 'match', 'color'], + }, + { + id: 'js-regex-055', + category: 'String Parsing', + difficulty: 'medium', + title: 'Parse CSV Line', + text: 'Split a CSV line handling quoted values with commas.', + setup: 'const csv = \'John,"Doe, Jr.",30\';', + setupCode: 'const csv = \'John,"Doe, Jr.",30\';', + expected: ['John', '"Doe, Jr."', '30'], + sample: 'csv.match(/("[^"]*"|[^,]+)/g)', + hints: ['Match quoted strings OR non-comma sequences', 'Use alternation with |'], + tags: ['regex', 'match', 'csv'], + }, + { + id: 'js-regex-056', + category: 'Regular Expressions', + difficulty: 'hard', + title: 'Email Validation', + text: 'Test if the string is a valid email format.', + setup: 'const email = "test.user+tag@sub.example.com";', + setupCode: 'const email = "test.user+tag@sub.example.com";', + expected: true, + sample: '/^[\\w.+-]+@[\\w.-]+\\.[a-zA-Z]{2,}$/.test(email)', + hints: ['Match username @ domain . tld', 'Allow dots, plus, hyphen in username'], + tags: ['regex', 'test', 'email', 'validation'], + }, + { + id: 'js-regex-057', + category: 'Regular Expressions', + difficulty: 'hard', + title: 'URL Validation', + text: 'Test if the string is a valid URL format.', + setup: 'const url = "https://www.example.com:8080/path?query=1#hash";', + setupCode: 'const url = "https://www.example.com:8080/path?query=1#hash";', + expected: true, + sample: '/^https?:\\/\\/[\\w.-]+(:\\d+)?(\\/[\\w./-]*)?(\\?[\\w=&]*)?(#\\w*)?$/.test(url)', + hints: ['Match protocol, domain, optional port, path, query, hash', 'Each part is optional except protocol and domain'], + tags: ['regex', 'test', 'url', 'validation'], + }, + { + id: 'js-regex-058', + category: 'Regular Expressions', + difficulty: 'hard', + title: 'Password Strength', + text: 'Test if password has at least 8 chars, one uppercase, one lowercase, one digit, and one special char.', + setup: 'const password = "MyP@ssw0rd";', + setupCode: 'const password = "MyP@ssw0rd";', + expected: true, + sample: '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*]).{8,}$/.test(password)', + hints: ['Use multiple lookaheads for each requirement', 'Lookaheads check without consuming'], + tags: ['regex', 'test', 'password', 'validation'], + }, + { + id: 'js-regex-059', + category: 'Regular Expressions', + difficulty: 'hard', + title: 'Phone Number Formats', + text: 'Match phone numbers in various formats: (555) 123-4567, 555-123-4567, 5551234567.', + setup: 'const text = "Call (555) 123-4567 or 555-123-4567 or 5551234567";', + setupCode: 'const text = "Call (555) 123-4567 or 555-123-4567 or 5551234567";', + expected: ['(555) 123-4567', '555-123-4567', '5551234567'], + sample: 'text.match(/\\(?\\d{3}\\)?[-.\\s]?\\d{3}[-.\\s]?\\d{4}/g)', + hints: ['Make parens and separators optional', 'Use [-.\\s]? for flexible separators'], + tags: ['regex', 'match', 'phone', 'validation'], + }, + { + id: 'js-regex-060', + category: 'String Parsing', + difficulty: 'hard', + title: 'Extract All URLs', + text: 'Extract all URLs from the text.', + setup: 'const text = "Visit https://example.com and http://test.org/path for more info.";', + setupCode: 'const text = "Visit https://example.com and http://test.org/path for more info.";', + expected: ['https://example.com', 'http://test.org/path'], + sample: 'text.match(/https?:\\/\\/[\\w.-]+(\\/[\\w./-]*)?/g)', + hints: ['Match http:// or https:// followed by domain and optional path', 'Use optional group for path'], + tags: ['regex', 'match', 'url', 'extraction'], + }, + { + id: 'js-regex-061', + category: 'String Parsing', + difficulty: 'hard', + title: 'Parse HTML Attributes', + text: 'Extract all attribute name-value pairs from the HTML tag.', + setup: 'const tag = \'\';', + setupCode: 'const tag = \'\';', + expected: ['type="text"', 'name="email"'], + sample: 'tag.match(/\\w+="[^"]*"/g)', + hints: ['Match word="value" pattern', 'Value is anything except quote'], + tags: ['regex', 'match', 'html', 'parsing'], + }, + { + id: 'js-regex-062', + category: 'String Parsing', + difficulty: 'hard', + title: 'Tokenize Expression', + text: 'Split a math expression into tokens (numbers and operators).', + setup: 'const expr = "12+34*56-78/90";', + setupCode: 'const expr = "12+34*56-78/90";', + expected: ['12', '+', '34', '*', '56', '-', '78', '/', '90'], + sample: 'expr.match(/\\d+|[+\\-*/]/g)', + hints: ['Match numbers OR operators', 'Use alternation with |'], + tags: ['regex', 'match', 'tokenize', 'parsing'], + }, + { + id: 'js-regex-063', + category: 'Regular Expressions', + difficulty: 'hard', + title: 'Validate Date Format', + text: 'Test if the string is a valid date in YYYY-MM-DD format.', + setup: 'const date = "2023-12-25";', + setupCode: 'const date = "2023-12-25";', + expected: true, + sample: '/^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$/.test(date)', + hints: ['Validate year, month 01-12, day 01-31', 'Use alternation for valid ranges'], + tags: ['regex', 'test', 'date', 'validation'], + }, + { + id: 'js-regex-064', + category: 'String Parsing', + difficulty: 'hard', + title: 'Convert Date Format', + text: 'Convert date from MM/DD/YYYY to YYYY-MM-DD format.', + setup: 'const date = "12/25/2023";', + setupCode: 'const date = "12/25/2023";', + expected: '2023-12-25', + sample: 'date.replace(/(\\d{2})\\/(\\d{2})\\/(\\d{4})/, "$3-$1-$2")', + hints: ['Capture month, day, year separately', 'Rearrange with $3-$1-$2'], + tags: ['regex', 'replace', 'date', 'formatting'], + }, + { + id: 'js-regex-065', + category: 'Regular Expressions', + difficulty: 'hard', + title: 'Match Balanced Parens (Simple)', + text: 'Extract content inside the outermost parentheses.', + setup: 'const str = "func(arg1, (nested), arg2)";', + setupCode: 'const str = "func(arg1, (nested), arg2)";', + expected: 'arg1, (nested), arg2', + sample: 'str.match(/\\((.*)\\)/)[1]', + hints: ['Match from first ( to last )', 'Greedy .* captures everything between'], + tags: ['regex', 'match', 'parsing'], + }, + { + id: 'js-regex-066', + category: 'String Parsing', + difficulty: 'hard', + title: 'Sentence Case', + text: 'Convert text to sentence case (capitalize first letter of each sentence).', + setup: 'const text = "hello world. how are you? i am fine.";', + setupCode: 'const text = "hello world. how are you? i am fine.";', + expected: 'Hello world. How are you? I am fine.', + sample: 'text.replace(/(^|[.!?]\\s+)([a-z])/g, (m, p1, p2) => p1 + p2.toUpperCase())', + hints: ['Match start or punctuation followed by letter', 'Use callback to uppercase'], + tags: ['regex', 'replace', 'case-conversion'], + }, + { + id: 'js-regex-067', + category: 'String Parsing', + difficulty: 'hard', + title: 'Parse JSON Path', + text: 'Extract all keys from a JSON path string.', + setup: 'const path = "user.profile.address.city";', + setupCode: 'const path = "user.profile.address.city";', + expected: ['user', 'profile', 'address', 'city'], + sample: 'path.match(/[^.]+/g)', + hints: ['Match sequences of non-dot characters', 'Or simply split by dot'], + tags: ['regex', 'match', 'json', 'parsing'], + }, + { + id: 'js-regex-068', + category: 'Regular Expressions', + difficulty: 'hard', + title: 'Validate IPv4', + text: 'Test if the string is a valid IPv4 address.', + setup: 'const ip = "192.168.1.255";', + setupCode: 'const ip = "192.168.1.255";', + expected: true, + sample: '/^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$/.test(ip)', + hints: ['Each octet is 0-255', 'Use alternation for different ranges'], + tags: ['regex', 'test', 'ip', 'validation'], + }, + { + id: 'js-regex-069', + category: 'String Parsing', + difficulty: 'hard', + title: 'Extract CSS Properties', + text: 'Extract property-value pairs from inline CSS.', + setup: 'const style = "color: red; font-size: 14px; margin: 10px 5px;";', + setupCode: 'const style = "color: red; font-size: 14px; margin: 10px 5px;";', + expected: ['color: red', 'font-size: 14px', 'margin: 10px 5px'], + sample: 'style.match(/[\\w-]+:\\s*[^;]+/g)', + hints: ['Match property: value patterns', 'Value continues until semicolon'], + tags: ['regex', 'match', 'css', 'parsing'], + }, + { + id: 'js-regex-070', + category: 'Regular Expressions', + difficulty: 'hard', + title: 'Validate Credit Card', + text: 'Test if the string looks like a valid credit card number (13-19 digits, optionally grouped by spaces or dashes).', + setup: 'const card = "4532-0151-1283-0366";', + setupCode: 'const card = "4532-0151-1283-0366";', + expected: true, + sample: '/^[\\d]{13,19}$|^([\\d]{4}[- ]?){3,4}[\\d]{1,4}$/.test(card)', + hints: ['Allow plain digits or grouped format', 'Groups of 4 with optional separator'], + tags: ['regex', 'test', 'credit-card', 'validation'], + }, + { + id: 'js-regex-071', + category: 'String Parsing', + difficulty: 'hard', + title: 'Slugify String', + text: 'Convert a title to a URL-friendly slug (lowercase, spaces to hyphens, remove special chars).', + setup: 'const title = "Hello World! How Are You?";', + setupCode: 'const title = "Hello World! How Are You?";', + expected: 'hello-world-how-are-you', + sample: 'title.toLowerCase().replace(/[^\\w\\s-]/g, "").replace(/\\s+/g, "-")', + hints: ['First remove special chars', 'Then replace spaces with hyphens'], + tags: ['regex', 'replace', 'slug', 'formatting'], + }, + { + id: 'js-regex-072', + category: 'Regular Expressions', + difficulty: 'hard', + title: 'Match Template Literals', + text: 'Extract all template variable names from a template string (format: {{varName}}).', + setup: 'const template = "Hello {{name}}, your order {{orderId}} is ready!";', + setupCode: 'const template = "Hello {{name}}, your order {{orderId}} is ready!";', + expected: ['name', 'orderId'], + sample: 'template.match(/\\{\\{(\\w+)\\}\\}/g).map(m => m.slice(2, -2))', + hints: ['Match {{word}} pattern', 'Extract just the variable name'], + tags: ['regex', 'match', 'template', 'parsing'], + }, + { + id: 'js-regex-073', + category: 'String Parsing', + difficulty: 'hard', + title: 'Highlight Search Terms', + text: 'Wrap all occurrences of search term in tags (case insensitive).', + setup: 'const text = "JavaScript is great. I love javascript!";', + setupCode: 'const text = "JavaScript is great. I love javascript!";', + expected: 'JavaScript is great. I love javascript!', + sample: 'text.replace(/javascript/gi, "$&")', + hints: ['Use $& to reference the whole match', 'i flag for case insensitive'], + tags: ['regex', 'replace', 'highlight'], + }, + { + id: 'js-regex-074', + category: 'Regular Expressions', + difficulty: 'hard', + title: 'Match Time Format', + text: 'Find all valid 24-hour time formats in the string.', + setup: 'const text = "Meeting at 09:30 and 14:45. Invalid: 25:00 and 12:60.";', + setupCode: 'const text = "Meeting at 09:30 and 14:45. Invalid: 25:00 and 12:60.";', + expected: ['09:30', '14:45'], + sample: 'text.match(/\\b([01]\\d|2[0-3]):[0-5]\\d\\b/g)', + hints: ['Hours: 00-23, Minutes: 00-59', 'Use word boundaries'], + tags: ['regex', 'match', 'time', 'validation'], + }, + { + id: 'js-regex-075', + category: 'String Parsing', + difficulty: 'hard', + title: 'Parse Query String', + text: 'Convert query string to an object with key-value pairs.', + setup: 'const query = "name=John&age=30&city=NYC";', + setupCode: 'const query = "name=John&age=30&city=NYC";', + expected: { name: 'John', age: '30', city: 'NYC' }, + sample: 'Object.fromEntries(query.match(/[^&]+/g).map(p => p.split("=")))', + hints: ['Split by & then by =', 'Use Object.fromEntries to create object'], + tags: ['regex', 'match', 'query-string', 'parsing'], + }, + { + id: 'js-regex-076', + category: 'Regular Expressions', + difficulty: 'hard', + title: 'Unicode Flag', + text: 'Match emoji characters in the string using unicode flag.', + setup: 'const str = "Hello 👋 World 🌍!";', + setupCode: 'const str = "Hello 👋 World 🌍!";', + expected: ['👋', '🌍'], + sample: 'str.match(/\\p{Emoji}/gu)', + hints: ['Use \\p{Emoji} with u flag', 'Unicode property escapes need u flag'], + tags: ['regex', 'match', 'unicode', 'emoji'], + }, + { + id: 'js-regex-077', + category: 'String Parsing', + difficulty: 'hard', + title: 'Remove Comments', + text: 'Remove all JavaScript-style single-line comments from the code.', + setup: 'const code = "let x = 5; // initialize\\nlet y = 10; // second var";', + setupCode: 'const code = "let x = 5; // initialize\\nlet y = 10; // second var";', + expected: 'let x = 5; \nlet y = 10; ', + sample: 'code.replace(/\\/\\/.*$/gm, "")', + hints: ['Match // until end of line', 'Use m flag for multiline'], + tags: ['regex', 'replace', 'comments', 'parsing'], + }, + { + id: 'js-regex-078', + category: 'Regular Expressions', + difficulty: 'hard', + title: 'Sticky Flag', + text: 'Use sticky flag to match consecutive word characters starting at position 0.', + setup: 'const str = "Hello World";', + setupCode: 'const str = "Hello World";', + expected: 'Hello', + sample: '/\\w+/y.exec(str)[0]', + hints: ['Sticky flag matches at lastIndex position', 'Default lastIndex is 0'], + tags: ['regex', 'exec', 'sticky-flag'], + }, + { + id: 'js-regex-079', + category: 'String Parsing', + difficulty: 'hard', + title: 'Extract Numbers with Decimals', + text: 'Find all numbers including decimals and negative numbers.', + setup: 'const str = "Values: 42, -17, 3.14, -2.5, .5";', + setupCode: 'const str = "Values: 42, -17, 3.14, -2.5, .5";', + expected: ['42', '-17', '3.14', '-2.5', '.5'], + sample: 'str.match(/-?\\d*\\.?\\d+/g)', + hints: ['Optional negative, optional integer part, optional decimal', 'At least one digit required'], + tags: ['regex', 'match', 'numbers', 'parsing'], + }, + { + id: 'js-regex-080', + category: 'Regular Expressions', + difficulty: 'hard', + title: 'Validate Hex Color', + text: 'Test if string is a valid hex color (#RGB or #RRGGBB format).', + setup: 'const color = "#a1B2c3";', + setupCode: 'const color = "#a1B2c3";', + expected: true, + sample: '/^#([0-9a-fA-F]{3}){1,2}$/.test(color)', + hints: ['Match # followed by 3 or 6 hex digits', '{1,2} allows the 3-char group once or twice'], + tags: ['regex', 'test', 'color', 'validation'], + }, + { + id: 'js-regex-081', + category: 'String Parsing', + difficulty: 'easy', + title: 'Trim Whitespace', + text: 'Remove leading and trailing whitespace using regex.', + setup: 'const str = " Hello World ";', + setupCode: 'const str = " Hello World ";', + expected: 'Hello World', + sample: 'str.replace(/^\\s+|\\s+$/g, "")', + hints: ['Match whitespace at start OR end', 'Use ^ and $ anchors'], + tags: ['regex', 'replace', 'whitespace'], + }, + { + id: 'js-regex-082', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Match Entire String', + text: 'Test if the entire string consists only of letters.', + setup: 'const str = "HelloWorld";', + setupCode: 'const str = "HelloWorld";', + expected: true, + sample: '/^[a-zA-Z]+$/.test(str)', + hints: ['Use ^ and $ to match entire string', 'Only allow letters between'], + tags: ['regex', 'test', 'anchor'], + }, + { + id: 'js-regex-083', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Count Matches', + text: 'Count how many times "the" appears in the string (case insensitive).', + setup: 'const str = "The quick brown fox jumps over the lazy dog. The end.";', + setupCode: 'const str = "The quick brown fox jumps over the lazy dog. The end.";', + expected: 3, + sample: '(str.match(/the/gi) || []).length', + hints: ['Use i flag for case insensitive', 'Handle null result from match'], + tags: ['regex', 'match', 'count'], + }, + { + id: 'js-regex-084', + category: 'String Parsing', + difficulty: 'easy', + title: 'Remove Digits', + text: 'Remove all digits from the string.', + setup: 'const str = "abc123def456";', + setupCode: 'const str = "abc123def456";', + expected: 'abcdef', + sample: 'str.replace(/\\d/g, "")', + hints: ['Replace all digits with empty string', 'Use g flag for global replace'], + tags: ['regex', 'replace', 'digits'], + }, + { + id: 'js-regex-085', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Match Tab Characters', + text: 'Count the number of tab characters in the string.', + setup: 'const str = "col1\\tcol2\\tcol3\\tcol4";', + setupCode: 'const str = "col1\\tcol2\\tcol3\\tcol4";', + expected: 3, + sample: '(str.match(/\\t/g) || []).length', + hints: ['Use \\t to match tabs', 'Similar to counting any character'], + tags: ['regex', 'match', 'whitespace'], + }, + { + id: 'js-regex-086', + category: 'String Parsing', + difficulty: 'easy', + title: 'Split on Multiple Delimiters', + text: 'Split the string on comma, semicolon, or pipe.', + setup: 'const str = "a,b;c|d,e";', + setupCode: 'const str = "a,b;c|d,e";', + expected: ['a', 'b', 'c', 'd', 'e'], + sample: 'str.split(/[,;|]/)', + hints: ['Use character class for multiple delimiters', 'split accepts regex'], + tags: ['regex', 'split', 'delimiter'], + }, + { + id: 'js-regex-087', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Match Line Breaks', + text: 'Count the number of lines in the string.', + setup: 'const str = "Line 1\\nLine 2\\nLine 3\\nLine 4";', + setupCode: 'const str = "Line 1\\nLine 2\\nLine 3\\nLine 4";', + expected: 4, + sample: 'str.split(/\\n/).length', + hints: ['Split by newline', 'Number of lines = parts after split'], + tags: ['regex', 'split', 'lines'], + }, + { + id: 'js-regex-088', + category: 'String Parsing', + difficulty: 'easy', + title: 'Capitalize First Letter', + text: 'Capitalize the first letter of the string using regex.', + setup: 'const str = "hello world";', + setupCode: 'const str = "hello world";', + expected: 'Hello world', + sample: 'str.replace(/^./, c => c.toUpperCase())', + hints: ['Match first character with ^.', 'Use callback to uppercase'], + tags: ['regex', 'replace', 'capitalize'], + }, + { + id: 'js-regex-089', + category: 'Regular Expressions', + difficulty: 'easy', + title: 'Match At Least N', + text: 'Find sequences of at least 3 consecutive digits.', + setup: 'const str = "12 123 1234 12345";', + setupCode: 'const str = "12 123 1234 12345";', + expected: ['123', '1234', '12345'], + sample: 'str.match(/\\d{3,}/g)', + hints: ['Use {n,} for at least n', '{3,} means 3 or more'], + tags: ['regex', 'match', 'quantifier'], + }, + { + id: 'js-regex-090', + category: 'String Parsing', + difficulty: 'medium', + title: 'Add Thousand Separators', + text: 'Add commas as thousand separators to the number.', + setup: 'const num = "1234567890";', + setupCode: 'const num = "1234567890";', + expected: '1,234,567,890', + sample: 'num.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",")', + hints: ['Use lookahead to find positions', '\\B is non-word boundary'], + tags: ['regex', 'replace', 'formatting'], + }, + { + id: 'js-regex-091', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Match Words Starting With', + text: 'Find all words that start with "pre".', + setup: 'const str = "prevent preload unprepared prefix";', + setupCode: 'const str = "prevent preload unprepared prefix";', + expected: ['prevent', 'preload', 'prefix'], + sample: 'str.match(/\\bpre\\w*/g)', + hints: ['Use word boundary before pre', '\\w* matches rest of word'], + tags: ['regex', 'match', 'word-boundary'], + }, + { + id: 'js-regex-092', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Match Words Ending With', + text: 'Find all words that end with "ing".', + setup: 'const str = "running jumping coding thinking wing";', + setupCode: 'const str = "running jumping coding thinking wing";', + expected: ['running', 'jumping', 'coding', 'thinking'], + sample: 'str.match(/\\w+ing\\b/g)', + hints: ['\\w+ for word chars before ing', 'Word boundary after ing'], + tags: ['regex', 'match', 'word-boundary'], + }, + { + id: 'js-regex-093', + category: 'String Parsing', + difficulty: 'medium', + title: 'Extract Quoted Strings', + text: 'Extract all single-quoted strings from the text.', + setup: `const str = "Say 'hello' and 'goodbye' today";`, + setupCode: `const str = "Say 'hello' and 'goodbye' today";`, + expected: ['hello', 'goodbye'], + sample: `str.match(/'([^']+)'/g).map(s => s.slice(1, -1))`, + hints: ['Match content between quotes', 'Remove quotes from result'], + tags: ['regex', 'match', 'parsing'], + }, + { + id: 'js-regex-094', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Match Repeated Characters', + text: 'Find all sequences of 3 or more repeated characters.', + setup: 'const str = "aaabbbcccc hello woooorld";', + setupCode: 'const str = "aaabbbcccc hello woooorld";', + expected: ['aaa', 'bbb', 'cccc', 'oooo'], + sample: 'str.match(/(.)\\1{2,}/g)', + hints: ['Capture a char, then backreference', '\\1{2,} means 2+ more of same'], + tags: ['regex', 'match', 'backreference'], + }, + { + id: 'js-regex-095', + category: 'String Parsing', + difficulty: 'medium', + title: 'Normalize Whitespace', + text: 'Replace all whitespace (tabs, newlines, spaces) with single spaces.', + setup: 'const str = "Hello\\t\\tWorld\\n\\nTest";', + setupCode: 'const str = "Hello\\t\\tWorld\\n\\nTest";', + expected: 'Hello World Test', + sample: 'str.replace(/\\s+/g, " ")', + hints: ['\\s matches all whitespace types', 'Replace multiple with single'], + tags: ['regex', 'replace', 'whitespace'], + }, + { + id: 'js-regex-096', + category: 'Regular Expressions', + difficulty: 'medium', + title: 'Validate Alphanumeric', + text: 'Test if string contains only alphanumeric characters.', + setup: 'const str = "Hello123World";', + setupCode: 'const str = "Hello123World";', + expected: true, + sample: '/^[a-zA-Z0-9]+$/.test(str)', + hints: ['Match only letters and numbers', 'Use ^ and $ for entire string'], + tags: ['regex', 'test', 'validation'], + }, + { + id: 'js-regex-097', + category: 'String Parsing', + difficulty: 'medium', + title: 'Extract Parenthetical Content', + text: 'Extract all text within parentheses.', + setup: 'const str = "Call John (555-1234) or Jane (555-5678) today";', + setupCode: 'const str = "Call John (555-1234) or Jane (555-5678) today";', + expected: ['555-1234', '555-5678'], + sample: 'str.match(/\\(([^)]+)\\)/g).map(s => s.slice(1, -1))', + hints: ['Match content between parens', 'Use [^)]+ for non-paren chars'], + tags: ['regex', 'match', 'parsing'], + }, + { + id: 'js-regex-098', + category: 'Regular Expressions', + difficulty: 'hard', + title: 'Recursive Pattern Simulation', + text: 'Match nested function calls like fn(fn(x)) - extract the innermost call.', + setup: 'const str = "fn(fn(fn(x)))";', + setupCode: 'const str = "fn(fn(fn(x)))";', + expected: 'fn(x)', + sample: 'str.match(/fn\\([^()]+\\)/)[0]', + hints: ['Match fn() with no parens inside', '[^()]+ matches non-paren content'], + tags: ['regex', 'match', 'nested'], + }, + { + id: 'js-regex-099', + category: 'String Parsing', + difficulty: 'hard', + title: 'Parse Markdown Links', + text: 'Extract link text and URLs from markdown links.', + setup: 'const md = "Check [Google](https://google.com) and [GitHub](https://github.com)";', + setupCode: 'const md = "Check [Google](https://google.com) and [GitHub](https://github.com)";', + expected: [{ text: 'Google', url: 'https://google.com' }, { text: 'GitHub', url: 'https://github.com' }], + sample: '[...md.matchAll(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g)].map(m => ({ text: m[1], url: m[2] }))', + hints: ['Use matchAll to get all groups', 'Capture text and URL separately'], + tags: ['regex', 'matchAll', 'markdown', 'parsing'], + }, + { + id: 'js-regex-100', + category: 'Regular Expressions', + difficulty: 'hard', + title: 'Complex Password Rules', + text: 'Validate: 8-20 chars, at least 2 uppercase, 2 lowercase, 2 digits, no consecutive repeated chars.', + setup: 'const password = "MyP4ssW0rd";', + setupCode: 'const password = "MyP4ssW0rd";', + expected: true, + sample: '/^(?=(?:.*[A-Z]){2})(?=(?:.*[a-z]){2})(?=(?:.*\\d){2})(?!.*(.)\\1).{8,20}$/.test(password)', + hints: ['Multiple lookaheads for each requirement', 'Negative lookahead for consecutive'], + tags: ['regex', 'test', 'password', 'validation'], + }, + // ======================================== + // ASYNC/AWAIT & PROMISES + // ======================================== + { + id: 'js-async-001', + category: 'Promises', + difficulty: 'easy', + title: 'Create Resolved Promise', + text: 'Create a promise that immediately resolves with the value 42.', + setup: '// Create a resolved promise', + setupCode: '// Create a resolved promise', + expected: 42, + sample: 'await Promise.resolve(42)', + hints: ['Use Promise.resolve()', 'Pass the value directly to resolve'], + tags: ['promises', 'Promise.resolve', 'basics'], + }, + { + id: 'js-async-002', + category: 'Promises', + difficulty: 'easy', + title: 'Create Rejected Promise', + text: 'Create a promise that immediately rejects with the error message "Failed".', + setup: '// Create a rejected promise and catch the error', + setupCode: '// Create a rejected promise and catch the error', + expected: 'Failed', + sample: 'await Promise.reject("Failed").catch(e => e)', + hints: ['Use Promise.reject()', 'Use .catch() to handle the rejection'], + tags: ['promises', 'Promise.reject', 'error-handling'], + }, + { + id: 'js-async-003', + category: 'Async Patterns', + difficulty: 'easy', + title: 'Basic Async Function', + text: 'Write an async function that returns the number 10.', + setup: '// Define an async function', + setupCode: '// Define an async function', + expected: 10, + sample: '(async () => 10)()', + hints: ['Async functions always return a promise', 'The return value is wrapped in Promise.resolve()'], + tags: ['async', 'await', 'basics'], + }, + { + id: 'js-async-004', + category: 'Promises', + difficulty: 'easy', + title: 'Chain Then Methods', + text: 'Chain .then() to double the resolved value.', + setup: 'const promise = Promise.resolve(5);', + setupCode: 'const promise = Promise.resolve(5);', + expected: 10, + sample: 'await promise.then(x => x * 2)', + hints: ['Use .then() to transform the value', 'Return the new value from the callback'], + tags: ['promises', 'then', 'chaining'], + }, + { + id: 'js-async-005', + category: 'Promises', + difficulty: 'easy', + title: 'Multiple Then Chains', + text: 'Chain multiple .then() calls to add 1, then multiply by 2.', + setup: 'const promise = Promise.resolve(3);', + setupCode: 'const promise = Promise.resolve(3);', + expected: 8, + sample: 'await promise.then(x => x + 1).then(x => x * 2)', + hints: ['Each .then() returns a new promise', 'Chain them together'], + tags: ['promises', 'then', 'chaining'], + }, + { + id: 'js-async-006', + category: 'Async Patterns', + difficulty: 'easy', + title: 'Await a Promise', + text: 'Use await to get the value from the promise.', + setup: 'const promise = Promise.resolve("hello");', + setupCode: 'const promise = Promise.resolve("hello");', + expected: 'hello', + sample: 'await promise', + hints: ['Use the await keyword', 'await unwraps the promise value'], + tags: ['async', 'await', 'basics'], + }, + { + id: 'js-async-007', + category: 'Promises', + difficulty: 'easy', + title: 'Promise.all with Two Promises', + text: 'Use Promise.all to wait for both promises and return their values.', + setup: 'const p1 = Promise.resolve(1); const p2 = Promise.resolve(2);', + setupCode: 'const p1 = Promise.resolve(1); const p2 = Promise.resolve(2);', + expected: [1, 2], + sample: 'await Promise.all([p1, p2])', + hints: ['Promise.all takes an array of promises', 'It returns an array of resolved values'], + tags: ['promises', 'Promise.all', 'basics'], + }, + { + id: 'js-async-008', + category: 'Promises', + difficulty: 'easy', + title: 'Promise.race Basics', + text: 'Use Promise.race to get the first resolved value.', + setup: 'const fast = Promise.resolve("fast"); const slow = new Promise(r => setTimeout(() => r("slow"), 100));', + setupCode: 'const fast = Promise.resolve("fast"); const slow = new Promise(r => setTimeout(() => r("slow"), 100));', + expected: 'fast', + sample: 'await Promise.race([fast, slow])', + hints: ['Promise.race returns the first settled promise', 'The already-resolved promise wins'], + tags: ['promises', 'Promise.race', 'basics'], + }, + { + id: 'js-async-009', + category: 'Promises', + difficulty: 'easy', + title: 'Catch Promise Error', + text: 'Catch the error from the rejected promise and return its message.', + setup: 'const promise = Promise.reject(new Error("Oops"));', + setupCode: 'const promise = Promise.reject(new Error("Oops"));', + expected: 'Oops', + sample: 'await promise.catch(e => e.message)', + hints: ['Use .catch() to handle rejections', 'Access the message property of the error'], + tags: ['promises', 'catch', 'error-handling'], + }, + { + id: 'js-async-010', + category: 'Async Patterns', + difficulty: 'easy', + title: 'Try-Catch with Await', + text: 'Use try-catch to handle the rejected promise and return the error message.', + setup: 'const promise = Promise.reject(new Error("Error occurred"));', + setupCode: 'const promise = Promise.reject(new Error("Error occurred"));', + expected: 'Error occurred', + sample: '(async () => { try { await promise; } catch (e) { return e.message; } })()', + hints: ['Wrap await in try-catch', 'Return the error message from catch block'], + tags: ['async', 'await', 'try-catch', 'error-handling'], + }, + { + id: 'js-async-011', + category: 'Promises', + difficulty: 'easy', + title: 'Finally Block', + text: 'Use .finally() to return "done" regardless of promise outcome.', + setup: 'let result = ""; const promise = Promise.resolve("success");', + setupCode: 'let result = ""; const promise = Promise.resolve("success");', + expected: 'done', + sample: 'await promise.finally(() => { result = "done"; }).then(() => result)', + hints: ['.finally() runs regardless of outcome', 'It does not receive the resolved value'], + tags: ['promises', 'finally', 'basics'], + }, + { + id: 'js-async-012', + category: 'Promises', + difficulty: 'easy', + title: 'Promise Constructor', + text: 'Create a new Promise that resolves with "created" after calling resolve.', + setup: '// Use new Promise constructor', + setupCode: '// Use new Promise constructor', + expected: 'created', + sample: 'await new Promise(resolve => resolve("created"))', + hints: ['Use new Promise((resolve, reject) => {})', 'Call resolve with the value'], + tags: ['promises', 'constructor', 'basics'], + }, + { + id: 'js-async-013', + category: 'Async Patterns', + difficulty: 'easy', + title: 'Return Value from Async', + text: 'Return the sum of two awaited promises.', + setup: 'const p1 = Promise.resolve(10); const p2 = Promise.resolve(20);', + setupCode: 'const p1 = Promise.resolve(10); const p2 = Promise.resolve(20);', + expected: 30, + sample: '(async () => await p1 + await p2)()', + hints: ['Await each promise', 'Add the results together'], + tags: ['async', 'await', 'arithmetic'], + }, + { + id: 'js-async-014', + category: 'Promises', + difficulty: 'easy', + title: 'Promise.resolve with Array', + text: 'Create a resolved promise containing an array [1, 2, 3].', + setup: '// Create a resolved promise with array', + setupCode: '// Create a resolved promise with array', + expected: [1, 2, 3], + sample: 'await Promise.resolve([1, 2, 3])', + hints: ['Promise.resolve can wrap any value', 'Arrays work just like other values'], + tags: ['promises', 'Promise.resolve', 'arrays'], + }, + { + id: 'js-async-015', + category: 'Promises', + difficulty: 'easy', + title: 'Promise.all Empty Array', + text: 'What does Promise.all return when given an empty array?', + setup: '// Call Promise.all with empty array', + setupCode: '// Call Promise.all with empty array', + expected: [], + sample: 'await Promise.all([])', + hints: ['Promise.all with empty array resolves immediately', 'It returns an empty array'], + tags: ['promises', 'Promise.all', 'edge-cases'], + }, + { + id: 'js-async-016', + category: 'Async Patterns', + difficulty: 'easy', + title: 'Async Arrow Function', + text: 'Create an async arrow function that returns "arrow".', + setup: '// Define async arrow function', + setupCode: '// Define async arrow function', + expected: 'arrow', + sample: '(async () => "arrow")()', + hints: ['Add async before the arrow function', 'Return value is automatically wrapped'], + tags: ['async', 'arrow-functions', 'basics'], + }, + { + id: 'js-async-017', + category: 'Promises', + difficulty: 'easy', + title: 'Then with Object', + text: 'Extract the name property from the resolved object.', + setup: 'const promise = Promise.resolve({ name: "Alice", age: 30 });', + setupCode: 'const promise = Promise.resolve({ name: "Alice", age: 30 });', + expected: 'Alice', + sample: 'await promise.then(obj => obj.name)', + hints: ['Use .then() to access the object', 'Return the name property'], + tags: ['promises', 'then', 'objects'], + }, + { + id: 'js-async-018', + category: 'Promises', + difficulty: 'easy', + title: 'Chained Catch', + text: 'Handle error in first promise and continue the chain.', + setup: 'const promise = Promise.reject("error").catch(() => "recovered");', + setupCode: 'const promise = Promise.reject("error").catch(() => "recovered");', + expected: 'recovered', + sample: 'await promise', + hints: ['.catch() returns a new promise', 'The chain continues with the recovered value'], + tags: ['promises', 'catch', 'chaining'], + }, + { + id: 'js-async-019', + category: 'Promises', + difficulty: 'easy', + title: 'Promise.resolve with Promise', + text: 'What happens when you call Promise.resolve on an existing promise?', + setup: 'const original = Promise.resolve(100); const wrapped = Promise.resolve(original);', + setupCode: 'const original = Promise.resolve(100); const wrapped = Promise.resolve(original);', + expected: 100, + sample: 'await wrapped', + hints: ['Promise.resolve returns the same promise if given one', 'It does not double-wrap'], + tags: ['promises', 'Promise.resolve', 'identity'], + }, + { + id: 'js-async-020', + category: 'Async Patterns', + difficulty: 'easy', + title: 'Sequential Await', + text: 'Await two promises sequentially and concatenate their string values.', + setup: 'const p1 = Promise.resolve("Hello"); const p2 = Promise.resolve("World");', + setupCode: 'const p1 = Promise.resolve("Hello"); const p2 = Promise.resolve("World");', + expected: 'HelloWorld', + sample: '(async () => (await p1) + (await p2))()', + hints: ['Await each promise in order', 'Concatenate the results'], + tags: ['async', 'await', 'strings'], + }, + { + id: 'js-async-021', + category: 'Promises', + difficulty: 'easy', + title: 'Transform Promise Value', + text: 'Use .then() to uppercase the string value.', + setup: 'const promise = Promise.resolve("hello");', + setupCode: 'const promise = Promise.resolve("hello");', + expected: 'HELLO', + sample: 'await promise.then(s => s.toUpperCase())', + hints: ['Use .then() to transform', 'Call toUpperCase() on the string'], + tags: ['promises', 'then', 'strings'], + }, + { + id: 'js-async-022', + category: 'Promises', + difficulty: 'easy', + title: 'Promise.all with Three Values', + text: 'Sum the results of three resolved promises.', + setup: 'const promises = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];', + setupCode: 'const promises = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];', + expected: 6, + sample: 'await Promise.all(promises).then(arr => arr.reduce((a, b) => a + b, 0))', + hints: ['Use Promise.all to wait for all', 'Use reduce to sum the array'], + tags: ['promises', 'Promise.all', 'reduce'], + }, + { + id: 'js-async-023', + category: 'Async Patterns', + difficulty: 'easy', + title: 'Async Function Returns Promise', + text: 'Verify that an async function returns a promise by checking its type.', + setup: 'const asyncFn = async () => 5;', + setupCode: 'const asyncFn = async () => 5;', + expected: true, + sample: 'asyncFn() instanceof Promise', + hints: ['Call the async function', 'Check if result is instanceof Promise'], + tags: ['async', 'promises', 'instanceof'], + }, + { + id: 'js-async-024', + category: 'Promises', + difficulty: 'easy', + title: 'Catch and Rethrow', + text: 'Catch an error, log it, and rethrow with a new message.', + setup: 'const promise = Promise.reject("original");', + setupCode: 'const promise = Promise.reject("original");', + expected: 'wrapped: original', + sample: 'await promise.catch(e => { throw "wrapped: " + e; }).catch(e => e)', + hints: ['First catch can throw again', 'Second catch handles the new error'], + tags: ['promises', 'catch', 'error-handling'], + }, + { + id: 'js-async-025', + category: 'Promises', + difficulty: 'easy', + title: 'Promise with Boolean', + text: 'Create a promise that resolves to true.', + setup: '// Create boolean promise', + setupCode: '// Create boolean promise', + expected: true, + sample: 'await Promise.resolve(true)', + hints: ['Promise.resolve works with booleans', 'Just pass true as the value'], + tags: ['promises', 'Promise.resolve', 'booleans'], + }, + { + id: 'js-async-026', + category: 'Promises', + difficulty: 'medium', + title: 'Promise.allSettled Basics', + text: 'Use Promise.allSettled to get the status of both resolved and rejected promises.', + setup: 'const promises = [Promise.resolve("ok"), Promise.reject("fail")];', + setupCode: 'const promises = [Promise.resolve("ok"), Promise.reject("fail")];', + expected: [{ status: 'fulfilled', value: 'ok' }, { status: 'rejected', reason: 'fail' }], + sample: 'await Promise.allSettled(promises)', + hints: ['Promise.allSettled never rejects', 'It returns objects with status and value/reason'], + tags: ['promises', 'Promise.allSettled', 'error-handling'], + }, + { + id: 'js-async-027', + category: 'Promises', + difficulty: 'medium', + title: 'Promise.any First Success', + text: 'Use Promise.any to get the first successful result.', + setup: 'const promises = [Promise.reject("err1"), Promise.resolve("success"), Promise.reject("err2")];', + setupCode: 'const promises = [Promise.reject("err1"), Promise.resolve("success"), Promise.reject("err2")];', + expected: 'success', + sample: 'await Promise.any(promises)', + hints: ['Promise.any returns first fulfilled promise', 'It ignores rejections until all fail'], + tags: ['promises', 'Promise.any', 'basics'], + }, + { + id: 'js-async-028', + category: 'Event Loop', + difficulty: 'medium', + title: 'Microtask vs Macrotask Order', + text: 'Predict the order: Promise.then runs before setTimeout.', + setup: 'const order = []; setTimeout(() => order.push("timeout"), 0); Promise.resolve().then(() => order.push("promise"));', + setupCode: 'const order = []; setTimeout(() => order.push("timeout"), 0); Promise.resolve().then(() => order.push("promise"));', + expected: ['promise', 'timeout'], + sample: 'await new Promise(r => setTimeout(r, 10)).then(() => order)', + hints: ['Microtasks run before macrotasks', 'Promise.then is a microtask, setTimeout is macrotask'], + tags: ['event-loop', 'microtasks', 'macrotasks'], + }, + { + id: 'js-async-029', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Parallel Promise Execution', + text: 'Run promises in parallel and return when all complete.', + setup: 'const delay = (ms, val) => new Promise(r => setTimeout(() => r(val), ms));', + setupCode: 'const delay = (ms, val) => new Promise(r => setTimeout(() => r(val), ms));', + expected: ['a', 'b', 'c'], + sample: 'await Promise.all([delay(10, "a"), delay(20, "b"), delay(15, "c")])', + hints: ['Use Promise.all for parallel execution', 'Results are in the same order as input'], + tags: ['async', 'Promise.all', 'parallel'], + }, + { + id: 'js-async-030', + category: 'Promises', + difficulty: 'medium', + title: 'Promise Chain with Map', + text: 'Map over an array to create promises, then wait for all.', + setup: 'const nums = [1, 2, 3];', + setupCode: 'const nums = [1, 2, 3];', + expected: [2, 4, 6], + sample: 'await Promise.all(nums.map(n => Promise.resolve(n * 2)))', + hints: ['Map creates an array of promises', 'Promise.all waits for all'], + tags: ['promises', 'Promise.all', 'map'], + }, + { + id: 'js-async-031', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Sequential Promise Execution', + text: 'Execute promises one after another, collecting results.', + setup: 'const tasks = [() => Promise.resolve(1), () => Promise.resolve(2), () => Promise.resolve(3)];', + setupCode: 'const tasks = [() => Promise.resolve(1), () => Promise.resolve(2), () => Promise.resolve(3)];', + expected: [1, 2, 3], + sample: 'await tasks.reduce(async (acc, fn) => [...await acc, await fn()], Promise.resolve([]))', + hints: ['Use reduce for sequential execution', 'Await the accumulator before adding new result'], + tags: ['async', 'await', 'sequential', 'reduce'], + }, + { + id: 'js-async-032', + category: 'Promises', + difficulty: 'medium', + title: 'Promise.race with Timeout', + text: 'Implement a timeout using Promise.race.', + setup: 'const slow = new Promise(r => setTimeout(() => r("slow"), 100)); const timeout = new Promise((_, rej) => setTimeout(() => rej("timeout"), 50));', + setupCode: 'const slow = new Promise(r => setTimeout(() => r("slow"), 100)); const timeout = new Promise((_, rej) => setTimeout(() => rej("timeout"), 50));', + expected: 'timeout', + sample: 'await Promise.race([slow, timeout]).catch(e => e)', + hints: ['Promise.race returns first settled', 'The timeout rejection wins'], + tags: ['promises', 'Promise.race', 'timeout'], + }, + { + id: 'js-async-033', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Async Error Propagation', + text: 'Throw an error in an async function and catch it.', + setup: 'const asyncError = async () => { throw new Error("async error"); };', + setupCode: 'const asyncError = async () => { throw new Error("async error"); };', + expected: 'async error', + sample: 'await asyncError().catch(e => e.message)', + hints: ['Thrown errors become rejections', 'Catch with .catch() or try-catch'], + tags: ['async', 'error-handling', 'throw'], + }, + { + id: 'js-async-034', + category: 'Promises', + difficulty: 'medium', + title: 'Promisify Callback Function', + text: 'Convert a callback-style function to return a promise.', + setup: 'const callbackFn = (val, cb) => setTimeout(() => cb(null, val * 2), 10);', + setupCode: 'const callbackFn = (val, cb) => setTimeout(() => cb(null, val * 2), 10);', + expected: 10, + sample: 'await new Promise((resolve, reject) => callbackFn(5, (err, result) => err ? reject(err) : resolve(result)))', + hints: ['Wrap the callback function in new Promise', 'Call resolve or reject based on callback args'], + tags: ['promises', 'promisify', 'callbacks'], + }, + { + id: 'js-async-035', + category: 'Promises', + difficulty: 'medium', + title: 'Promise.all Rejection', + text: 'What happens when one promise in Promise.all rejects?', + setup: 'const promises = [Promise.resolve(1), Promise.reject("error"), Promise.resolve(3)];', + setupCode: 'const promises = [Promise.resolve(1), Promise.reject("error"), Promise.resolve(3)];', + expected: 'error', + sample: 'await Promise.all(promises).catch(e => e)', + hints: ['Promise.all fails fast', 'One rejection rejects the whole thing'], + tags: ['promises', 'Promise.all', 'error-handling'], + }, + { + id: 'js-async-036', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Async IIFE', + text: 'Use an async IIFE to immediately execute async code.', + setup: 'let value = 0;', + setupCode: 'let value = 0;', + expected: 42, + sample: '(async () => { value = await Promise.resolve(42); return value; })()', + hints: ['Wrap async function in parentheses', 'Immediately invoke it with ()'], + tags: ['async', 'IIFE', 'patterns'], + }, + { + id: 'js-async-037', + category: 'Promises', + difficulty: 'medium', + title: 'Chained Promise Transformation', + text: 'Chain multiple transformations: add 5, multiply by 2, subtract 3.', + setup: 'const promise = Promise.resolve(10);', + setupCode: 'const promise = Promise.resolve(10);', + expected: 27, + sample: 'await promise.then(x => x + 5).then(x => x * 2).then(x => x - 3)', + hints: ['Each .then() transforms the value', 'Chain them in order of operations'], + tags: ['promises', 'then', 'chaining'], + }, + { + id: 'js-async-038', + category: 'Event Loop', + difficulty: 'medium', + title: 'queueMicrotask Usage', + text: 'Use queueMicrotask to schedule a microtask.', + setup: 'const order = [];', + setupCode: 'const order = [];', + expected: ['sync', 'microtask', 'timeout'], + sample: '(() => { order.push("sync"); queueMicrotask(() => order.push("microtask")); setTimeout(() => order.push("timeout"), 0); return new Promise(r => setTimeout(r, 20)); })().then(() => order)', + hints: ['queueMicrotask schedules a microtask', 'Microtasks run before setTimeout'], + tags: ['event-loop', 'microtasks', 'queueMicrotask'], + }, + { + id: 'js-async-039', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Conditional Await', + text: 'Await only if the value is a promise.', + setup: 'const maybePromise = Promise.resolve(100); const notPromise = 50;', + setupCode: 'const maybePromise = Promise.resolve(100); const notPromise = 50;', + expected: 150, + sample: '(async () => (await maybePromise) + notPromise)()', + hints: ['Await works on non-promises too', 'It just returns the value immediately'], + tags: ['async', 'await', 'conditional'], + }, + { + id: 'js-async-040', + category: 'Promises', + difficulty: 'medium', + title: 'Promise.allSettled Filter Fulfilled', + text: 'Filter only the fulfilled results from Promise.allSettled.', + setup: 'const promises = [Promise.resolve(1), Promise.reject("err"), Promise.resolve(3)];', + setupCode: 'const promises = [Promise.resolve(1), Promise.reject("err"), Promise.resolve(3)];', + expected: [1, 3], + sample: 'await Promise.allSettled(promises).then(results => results.filter(r => r.status === "fulfilled").map(r => r.value))', + hints: ['Filter by status property', 'Map to extract values'], + tags: ['promises', 'Promise.allSettled', 'filter'], + }, + { + id: 'js-async-041', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Async Array Filter', + text: 'Filter an array asynchronously based on async predicate.', + setup: 'const nums = [1, 2, 3, 4, 5]; const asyncIsEven = async n => n % 2 === 0;', + setupCode: 'const nums = [1, 2, 3, 4, 5]; const asyncIsEven = async n => n % 2 === 0;', + expected: [2, 4], + sample: 'await Promise.all(nums.map(async n => ({ n, keep: await asyncIsEven(n) }))).then(results => results.filter(r => r.keep).map(r => r.n))', + hints: ['Map to check each item', 'Filter based on async result'], + tags: ['async', 'filter', 'arrays'], + }, + { + id: 'js-async-042', + category: 'Promises', + difficulty: 'medium', + title: 'Promise with Delay', + text: 'Create a delay function that resolves after specified milliseconds.', + setup: 'const start = Date.now();', + setupCode: 'const start = Date.now();', + expected: true, + sample: 'await new Promise(r => setTimeout(r, 50)).then(() => Date.now() - start >= 50)', + hints: ['Use setTimeout inside Promise', 'Resolve after the timeout'], + tags: ['promises', 'setTimeout', 'delay'], + }, + { + id: 'js-async-043', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Async Reduce', + text: 'Use reduce with async/await to sum values sequentially.', + setup: 'const asyncNums = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];', + setupCode: 'const asyncNums = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];', + expected: 6, + sample: 'await asyncNums.reduce(async (acc, p) => (await acc) + (await p), Promise.resolve(0))', + hints: ['Await the accumulator first', 'Then await the current promise'], + tags: ['async', 'reduce', 'sequential'], + }, + { + id: 'js-async-044', + category: 'Promises', + difficulty: 'medium', + title: 'Promise.any All Rejected', + text: 'Handle when all promises passed to Promise.any reject.', + setup: 'const promises = [Promise.reject("a"), Promise.reject("b"), Promise.reject("c")];', + setupCode: 'const promises = [Promise.reject("a"), Promise.reject("b"), Promise.reject("c")];', + expected: ['a', 'b', 'c'], + sample: 'await Promise.any(promises).catch(e => e.errors)', + hints: ['Promise.any throws AggregateError', 'Access errors property for all rejection reasons'], + tags: ['promises', 'Promise.any', 'AggregateError'], + }, + { + id: 'js-async-045', + category: 'Event Loop', + difficulty: 'medium', + title: 'Multiple Microtasks Order', + text: 'Predict the order of multiple chained promises.', + setup: 'const order = []; Promise.resolve().then(() => order.push(1)).then(() => order.push(2)); Promise.resolve().then(() => order.push(3));', + setupCode: 'const order = []; Promise.resolve().then(() => order.push(1)).then(() => order.push(2)); Promise.resolve().then(() => order.push(3));', + expected: [1, 3, 2], + sample: 'await new Promise(r => setTimeout(r, 10)).then(() => order)', + hints: ['First .then() from each chain runs first', 'Chained .then() is scheduled after'], + tags: ['event-loop', 'microtasks', 'order'], + }, + { + id: 'js-async-046', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Async Method in Object', + text: 'Define an object with an async method.', + setup: 'const obj = { async getValue() { return 42; } };', + setupCode: 'const obj = { async getValue() { return 42; } };', + expected: 42, + sample: 'await obj.getValue()', + hints: ['Async methods work like async functions', 'Await the method call'], + tags: ['async', 'objects', 'methods'], + }, + { + id: 'js-async-047', + category: 'Promises', + difficulty: 'medium', + title: 'Promise Chain Recovery', + text: 'Recover from an error in the middle of a promise chain.', + setup: 'const chain = Promise.resolve(10).then(x => { throw "error"; }).catch(() => 0).then(x => x + 5);', + setupCode: 'const chain = Promise.resolve(10).then(x => { throw "error"; }).catch(() => 0).then(x => x + 5);', + expected: 5, + sample: 'await chain', + hints: ['catch() recovers the chain', 'The next .then() receives the recovered value'], + tags: ['promises', 'catch', 'recovery'], + }, + { + id: 'js-async-048', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Async Class Constructor Pattern', + text: 'Use a static async factory method for async initialization.', + setup: 'class AsyncClass { constructor(data) { this.data = data; } static async create() { const data = await Promise.resolve("loaded"); return new AsyncClass(data); } }', + setupCode: 'class AsyncClass { constructor(data) { this.data = data; } static async create() { const data = await Promise.resolve("loaded"); return new AsyncClass(data); } }', + expected: 'loaded', + sample: 'await AsyncClass.create().then(instance => instance.data)', + hints: ['Constructors cannot be async', 'Use static factory method instead'], + tags: ['async', 'classes', 'factory-pattern'], + }, + { + id: 'js-async-049', + category: 'Promises', + difficulty: 'medium', + title: 'Promise.resolve Thenable', + text: 'Promise.resolve unwraps thenable objects.', + setup: 'const thenable = { then(resolve) { resolve("from thenable"); } };', + setupCode: 'const thenable = { then(resolve) { resolve("from thenable"); } };', + expected: 'from thenable', + sample: 'await Promise.resolve(thenable)', + hints: ['A thenable has a then method', 'Promise.resolve calls the then method'], + tags: ['promises', 'thenable', 'Promise.resolve'], + }, + { + id: 'js-async-050', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Parallel with Limit', + text: 'Execute promises with a concurrency limit of 2.', + setup: 'const tasks = [() => Promise.resolve(1), () => Promise.resolve(2), () => Promise.resolve(3), () => Promise.resolve(4)];', + setupCode: 'const tasks = [() => Promise.resolve(1), () => Promise.resolve(2), () => Promise.resolve(3), () => Promise.resolve(4)];', + expected: [1, 2, 3, 4], + sample: '(async () => { const results = []; for (let i = 0; i < tasks.length; i += 2) { results.push(...await Promise.all(tasks.slice(i, i + 2).map(t => t()))); } return results; })()', + hints: ['Process in batches', 'Use slice to get batches of tasks'], + tags: ['async', 'concurrency', 'batching'], + }, + { + id: 'js-async-051', + category: 'Promises', + difficulty: 'medium', + title: 'Then Returns Promise', + text: 'Return a promise from .then() to chain asynchronously.', + setup: 'const promise = Promise.resolve(5);', + setupCode: 'const promise = Promise.resolve(5);', + expected: 10, + sample: 'await promise.then(x => Promise.resolve(x * 2))', + hints: ['Returning a promise from then chains it', 'The next then receives the resolved value'], + tags: ['promises', 'then', 'chaining'], + }, + { + id: 'js-async-052', + category: 'Event Loop', + difficulty: 'medium', + title: 'setImmediate vs setTimeout', + text: 'Compare execution order of different scheduling methods.', + setup: 'const order = [];', + setupCode: 'const order = [];', + expected: ['promise', 'timeout'], + sample: '(() => { setTimeout(() => order.push("timeout"), 0); Promise.resolve().then(() => order.push("promise")); return new Promise(r => setTimeout(r, 20)); })().then(() => order)', + hints: ['Promise.then is a microtask', 'setTimeout is a macrotask'], + tags: ['event-loop', 'setTimeout', 'microtasks'], + }, + { + id: 'js-async-053', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Async Generator Basics', + text: 'Create an async generator that yields 1, 2, 3.', + setup: 'async function* gen() { yield 1; yield 2; yield 3; }', + setupCode: 'async function* gen() { yield 1; yield 2; yield 3; }', + expected: [1, 2, 3], + sample: '(async () => { const result = []; for await (const x of gen()) result.push(x); return result; })()', + hints: ['Use for await...of to iterate', 'Collect values in an array'], + tags: ['async', 'generators', 'for-await'], + }, + { + id: 'js-async-054', + category: 'Promises', + difficulty: 'medium', + title: 'Promise.race with All Resolved', + text: 'Get the fastest promise when all resolve.', + setup: 'const p1 = new Promise(r => setTimeout(() => r("first"), 10)); const p2 = new Promise(r => setTimeout(() => r("second"), 50));', + setupCode: 'const p1 = new Promise(r => setTimeout(() => r("first"), 10)); const p2 = new Promise(r => setTimeout(() => r("second"), 50));', + expected: 'first', + sample: 'await Promise.race([p1, p2])', + hints: ['Promise.race returns first to settle', 'The faster promise wins'], + tags: ['promises', 'Promise.race', 'timing'], + }, + { + id: 'js-async-055', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Async Map Function', + text: 'Implement an async map that processes items in parallel.', + setup: 'const items = [1, 2, 3]; const asyncDouble = async x => x * 2;', + setupCode: 'const items = [1, 2, 3]; const asyncDouble = async x => x * 2;', + expected: [2, 4, 6], + sample: 'await Promise.all(items.map(asyncDouble))', + hints: ['Map creates array of promises', 'Promise.all waits for all'], + tags: ['async', 'map', 'Promise.all'], + }, + { + id: 'js-async-056', + category: 'Promises', + difficulty: 'medium', + title: 'Deferred Promise Pattern', + text: 'Create a deferred promise that can be resolved externally.', + setup: 'let resolver; const deferred = new Promise(r => { resolver = r; });', + setupCode: 'let resolver; const deferred = new Promise(r => { resolver = r; });', + expected: 'resolved externally', + sample: '(() => { resolver("resolved externally"); return deferred; })()', + hints: ['Store resolve function in outer variable', 'Call it later to resolve'], + tags: ['promises', 'deferred', 'patterns'], + }, + { + id: 'js-async-057', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Async ForEach', + text: 'Process items sequentially with async forEach.', + setup: 'const items = [1, 2, 3]; const results = [];', + setupCode: 'const items = [1, 2, 3]; const results = [];', + expected: [1, 2, 3], + sample: '(async () => { for (const item of items) { results.push(await Promise.resolve(item)); } return results; })()', + hints: ['Regular forEach does not wait', 'Use for...of loop instead'], + tags: ['async', 'forEach', 'sequential'], + }, + { + id: 'js-async-058', + category: 'Promises', + difficulty: 'medium', + title: 'Multiple Catch Handlers', + text: 'Chain multiple catch handlers.', + setup: 'const promise = Promise.reject(new Error("original"));', + setupCode: 'const promise = Promise.reject(new Error("original"));', + expected: 'handled', + sample: 'await promise.catch(e => { throw new Error("rethrown"); }).catch(() => "handled")', + hints: ['First catch can rethrow', 'Second catch handles the new error'], + tags: ['promises', 'catch', 'chaining'], + }, + { + id: 'js-async-059', + category: 'Event Loop', + difficulty: 'medium', + title: 'Nested setTimeout', + text: 'Predict order with nested setTimeout calls.', + setup: 'const order = [];', + setupCode: 'const order = [];', + expected: ['outer', 'inner'], + sample: '(() => { setTimeout(() => { order.push("outer"); setTimeout(() => order.push("inner"), 0); }, 0); return new Promise(r => setTimeout(r, 50)); })().then(() => order)', + hints: ['Outer timeout runs first', 'Inner timeout is scheduled when outer runs'], + tags: ['event-loop', 'setTimeout', 'nesting'], + }, + { + id: 'js-async-060', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Promise-based Retry', + text: 'Retry a failing async operation up to 3 times.', + setup: 'let attempts = 0; const flaky = async () => { attempts++; if (attempts < 3) throw "fail"; return "success"; };', + setupCode: 'let attempts = 0; const flaky = async () => { attempts++; if (attempts < 3) throw "fail"; return "success"; };', + expected: 'success', + sample: '(async () => { for (let i = 0; i < 3; i++) { try { return await flaky(); } catch (e) { if (i === 2) throw e; } } })()', + hints: ['Loop with try-catch', 'Return on success, continue on failure'], + tags: ['async', 'retry', 'error-handling'], + }, + { + id: 'js-async-061', + category: 'Promises', + difficulty: 'hard', + title: 'Promise.all Short Circuit', + text: 'Demonstrate that Promise.all rejects immediately on first rejection.', + setup: 'const p1 = new Promise((_, rej) => setTimeout(() => rej("fast reject"), 10)); const p2 = new Promise(r => setTimeout(() => r("slow"), 100)); let p2Resolved = false; p2.then(() => p2Resolved = true);', + setupCode: 'const p1 = new Promise((_, rej) => setTimeout(() => rej("fast reject"), 10)); const p2 = new Promise(r => setTimeout(() => r("slow"), 100)); let p2Resolved = false; p2.then(() => p2Resolved = true);', + expected: 'fast reject', + sample: 'await Promise.all([p1, p2]).catch(e => e)', + hints: ['Promise.all fails fast', 'Other promises keep running but result is ignored'], + tags: ['promises', 'Promise.all', 'rejection'], + }, + { + id: 'js-async-062', + category: 'Async Patterns', + difficulty: 'hard', + title: 'Async Iterator Protocol', + text: 'Implement the async iterator protocol manually.', + setup: 'const asyncIterable = { [Symbol.asyncIterator]() { let i = 0; return { async next() { if (i < 3) return { value: ++i, done: false }; return { done: true }; } }; } };', + setupCode: 'const asyncIterable = { [Symbol.asyncIterator]() { let i = 0; return { async next() { if (i < 3) return { value: ++i, done: false }; return { done: true }; } }; } };', + expected: [1, 2, 3], + sample: '(async () => { const result = []; for await (const x of asyncIterable) result.push(x); return result; })()', + hints: ['Implement Symbol.asyncIterator', 'Return object with async next()'], + tags: ['async', 'iterators', 'Symbol.asyncIterator'], + }, + { + id: 'js-async-063', + category: 'Promises', + difficulty: 'hard', + title: 'Promise Executor Error', + text: 'Handle an error thrown synchronously in the Promise executor.', + setup: 'const badPromise = new Promise(() => { throw new Error("executor error"); });', + setupCode: 'const badPromise = new Promise(() => { throw new Error("executor error"); });', + expected: 'executor error', + sample: 'await badPromise.catch(e => e.message)', + hints: ['Errors in executor become rejections', 'Catch them normally'], + tags: ['promises', 'executor', 'error-handling'], + }, + { + id: 'js-async-064', + category: 'Event Loop', + difficulty: 'hard', + title: 'Complex Event Loop Order', + text: 'Predict the execution order with mixed micro and macro tasks.', + setup: 'const order = [];', + setupCode: 'const order = [];', + expected: ['sync', 'micro1', 'micro2', 'timeout'], + sample: '(() => { order.push("sync"); Promise.resolve().then(() => { order.push("micro1"); Promise.resolve().then(() => order.push("micro2")); }); setTimeout(() => order.push("timeout"), 0); return new Promise(r => setTimeout(r, 20)); })().then(() => order)', + hints: ['Sync runs first', 'Microtasks exhaust before macrotasks'], + tags: ['event-loop', 'microtasks', 'macrotasks', 'order'], + }, + { + id: 'js-async-065', + category: 'Async Patterns', + difficulty: 'hard', + title: 'Cancellable Promise', + text: 'Implement a cancellable promise using AbortController.', + setup: 'const controller = new AbortController(); const cancellable = (signal) => new Promise((resolve, reject) => { const id = setTimeout(() => resolve("done"), 100); signal.addEventListener("abort", () => { clearTimeout(id); reject("cancelled"); }); });', + setupCode: 'const controller = new AbortController(); const cancellable = (signal) => new Promise((resolve, reject) => { const id = setTimeout(() => resolve("done"), 100); signal.addEventListener("abort", () => { clearTimeout(id); reject("cancelled"); }); });', + expected: 'cancelled', + sample: '(() => { const p = cancellable(controller.signal); setTimeout(() => controller.abort(), 10); return p.catch(e => e); })()', + hints: ['Use AbortController signal', 'Listen for abort event'], + tags: ['async', 'AbortController', 'cancellation'], + }, + { + id: 'js-async-066', + category: 'Promises', + difficulty: 'hard', + title: 'Promise.allSettled Analysis', + text: 'Analyze results to count fulfilled and rejected promises.', + setup: 'const promises = [Promise.resolve(1), Promise.reject("a"), Promise.resolve(2), Promise.reject("b"), Promise.resolve(3)];', + setupCode: 'const promises = [Promise.resolve(1), Promise.reject("a"), Promise.resolve(2), Promise.reject("b"), Promise.resolve(3)];', + expected: { fulfilled: 3, rejected: 2 }, + sample: 'await Promise.allSettled(promises).then(results => results.reduce((acc, r) => { acc[r.status]++; return acc; }, { fulfilled: 0, rejected: 0 }))', + hints: ['Use reduce to count statuses', 'Initialize counters for both statuses'], + tags: ['promises', 'Promise.allSettled', 'reduce'], + }, + { + id: 'js-async-067', + category: 'Async Patterns', + difficulty: 'hard', + title: 'Async Pool Implementation', + text: 'Implement a promise pool that runs at most N promises concurrently.', + setup: 'const delay = (ms, val) => new Promise(r => setTimeout(() => r(val), ms)); const tasks = [() => delay(30, 1), () => delay(20, 2), () => delay(10, 3), () => delay(40, 4)];', + setupCode: 'const delay = (ms, val) => new Promise(r => setTimeout(() => r(val), ms)); const tasks = [() => delay(30, 1), () => delay(20, 2), () => delay(10, 3), () => delay(40, 4)];', + expected: [1, 2, 3, 4], + sample: '(async () => { const results = []; const executing = []; for (const task of tasks) { const p = task().then(r => { executing.splice(executing.indexOf(p), 1); return r; }); results.push(p); executing.push(p); if (executing.length >= 2) await Promise.race(executing); } return Promise.all(results); })()', + hints: ['Track executing promises', 'Wait when pool is full'], + tags: ['async', 'concurrency', 'pool'], + }, + { + id: 'js-async-068', + category: 'Promises', + difficulty: 'hard', + title: 'Promise.race Rejection Wins', + text: 'Handle when rejection wins the race.', + setup: 'const reject = new Promise((_, r) => setTimeout(() => r("error"), 10)); const resolve = new Promise(r => setTimeout(() => r("success"), 50));', + setupCode: 'const reject = new Promise((_, r) => setTimeout(() => r("error"), 10)); const resolve = new Promise(r => setTimeout(() => r("success"), 50));', + expected: 'error', + sample: 'await Promise.race([reject, resolve]).catch(e => e)', + hints: ['Rejection can win the race', 'Use catch to handle it'], + tags: ['promises', 'Promise.race', 'rejection'], + }, + { + id: 'js-async-069', + category: 'Event Loop', + difficulty: 'hard', + title: 'Promise Resolution in setTimeout', + text: 'Understand when promises resolve inside setTimeout.', + setup: 'const order = [];', + setupCode: 'const order = [];', + expected: ['timeout1', 'micro', 'timeout2'], + sample: '(() => { setTimeout(() => { order.push("timeout1"); Promise.resolve().then(() => order.push("micro")); }, 0); setTimeout(() => order.push("timeout2"), 0); return new Promise(r => setTimeout(r, 30)); })().then(() => order)', + hints: ['Each setTimeout callback gets its own microtask queue', 'Microtasks run before next macrotask'], + tags: ['event-loop', 'setTimeout', 'microtasks'], + }, + { + id: 'js-async-070', + category: 'Async Patterns', + difficulty: 'hard', + title: 'Async Mutex', + text: 'Implement a simple mutex using promises.', + setup: 'class Mutex { constructor() { this.locked = false; this.queue = []; } async acquire() { if (this.locked) { await new Promise(r => this.queue.push(r)); } this.locked = true; } release() { this.locked = false; if (this.queue.length > 0) this.queue.shift()(); } }', + setupCode: 'class Mutex { constructor() { this.locked = false; this.queue = []; } async acquire() { if (this.locked) { await new Promise(r => this.queue.push(r)); } this.locked = true; } release() { this.locked = false; if (this.queue.length > 0) this.queue.shift()(); } }', + expected: [1, 2, 3], + sample: '(async () => { const mutex = new Mutex(); const results = []; const task = async (n) => { await mutex.acquire(); results.push(n); mutex.release(); }; await Promise.all([task(1), task(2), task(3)]); return results; })()', + hints: ['Queue waiters when locked', 'Release wakes up next waiter'], + tags: ['async', 'mutex', 'concurrency'], + }, + { + id: 'js-async-071', + category: 'Promises', + difficulty: 'hard', + title: 'Promise Chain State', + text: 'Understand that each .then() creates a new promise.', + setup: 'const p1 = Promise.resolve(1); const p2 = p1.then(x => x + 1); const p3 = p1.then(x => x + 2);', + setupCode: 'const p1 = Promise.resolve(1); const p2 = p1.then(x => x + 1); const p3 = p1.then(x => x + 2);', + expected: [2, 3], + sample: 'await Promise.all([p2, p3])', + hints: ['Each then creates independent chain', 'Both branch from same promise'], + tags: ['promises', 'then', 'branching'], + }, + { + id: 'js-async-072', + category: 'Async Patterns', + difficulty: 'hard', + title: 'Async Event Emitter', + text: 'Wait for an event using a promise.', + setup: 'class Emitter { constructor() { this.listeners = {}; } on(event, cb) { (this.listeners[event] ||= []).push(cb); } emit(event, data) { (this.listeners[event] || []).forEach(cb => cb(data)); } } const emitter = new Emitter();', + setupCode: 'class Emitter { constructor() { this.listeners = {}; } on(event, cb) { (this.listeners[event] ||= []).push(cb); } emit(event, data) { (this.listeners[event] || []).forEach(cb => cb(data)); } } const emitter = new Emitter();', + expected: 'event data', + sample: '(() => { const promise = new Promise(r => emitter.on("data", r)); setTimeout(() => emitter.emit("data", "event data"), 10); return promise; })()', + hints: ['Create promise that resolves on event', 'Store resolve as event listener'], + tags: ['async', 'events', 'patterns'], + }, + { + id: 'js-async-073', + category: 'Promises', + difficulty: 'hard', + title: 'Dynamic Promise Chain', + text: 'Build a promise chain dynamically from an array of functions.', + setup: 'const operations = [x => x + 1, x => x * 2, x => x - 3];', + setupCode: 'const operations = [x => x + 1, x => x * 2, x => x - 3];', + expected: 9, + sample: 'await operations.reduce((p, fn) => p.then(fn), Promise.resolve(5))', + hints: ['Use reduce to build chain', 'Start with resolved promise'], + tags: ['promises', 'reduce', 'dynamic-chain'], + }, + { + id: 'js-async-074', + category: 'Event Loop', + difficulty: 'hard', + title: 'Nested Promise Resolution', + text: 'Understand nested promise resolution timing.', + setup: 'const order = [];', + setupCode: 'const order = [];', + expected: ['p1', 'p2', 'p1-inner', 'p2-inner'], + sample: '(() => { Promise.resolve().then(() => { order.push("p1"); Promise.resolve().then(() => order.push("p1-inner")); }); Promise.resolve().then(() => { order.push("p2"); Promise.resolve().then(() => order.push("p2-inner")); }); return new Promise(r => setTimeout(r, 20)); })().then(() => order)', + hints: ['Outer thens run first', 'Inner thens are queued after'], + tags: ['event-loop', 'microtasks', 'nesting'], + }, + { + id: 'js-async-075', + category: 'Async Patterns', + difficulty: 'hard', + title: 'Async Generator with Delay', + text: 'Create an async generator that yields values with delays.', + setup: 'async function* delayedGen() { for (let i = 1; i <= 3; i++) { await new Promise(r => setTimeout(r, 10)); yield i; } }', + setupCode: 'async function* delayedGen() { for (let i = 1; i <= 3; i++) { await new Promise(r => setTimeout(r, 10)); yield i; } }', + expected: [1, 2, 3], + sample: '(async () => { const result = []; for await (const x of delayedGen()) result.push(x); return result; })()', + hints: ['Await delay before each yield', 'Use for await to consume'], + tags: ['async', 'generators', 'delay'], + }, + { + id: 'js-async-076', + category: 'Promises', + difficulty: 'hard', + title: 'Promise.any vs Promise.race', + text: 'Compare behavior when first promise rejects.', + setup: 'const p1 = Promise.reject("err"); const p2 = new Promise(r => setTimeout(() => r("ok"), 20));', + setupCode: 'const p1 = Promise.reject("err"); const p2 = new Promise(r => setTimeout(() => r("ok"), 20));', + expected: { race: 'err', any: 'ok' }, + sample: 'await Promise.all([Promise.race([p1, p2]).catch(e => e), Promise.any([p1, p2])]).then(([race, any]) => ({ race, any }))', + hints: ['race returns first settled (even rejection)', 'any waits for first fulfilled'], + tags: ['promises', 'Promise.any', 'Promise.race'], + }, + { + id: 'js-async-077', + category: 'Async Patterns', + difficulty: 'hard', + title: 'Async Transform Stream', + text: 'Process data through multiple async transformations.', + setup: 'const transforms = [async x => x * 2, async x => x + 10, async x => x.toString()];', + setupCode: 'const transforms = [async x => x * 2, async x => x + 10, async x => x.toString()];', + expected: '30', + sample: 'await transforms.reduce(async (acc, fn) => fn(await acc), Promise.resolve(10))', + hints: ['Reduce with async accumulator', 'Await before passing to next'], + tags: ['async', 'transform', 'reduce'], + }, + { + id: 'js-async-078', + category: 'Promises', + difficulty: 'hard', + title: 'Promise Memory Leak Prevention', + text: 'Properly clean up when a promise is no longer needed.', + setup: 'let cleanup = false; const createPromise = () => { const id = setTimeout(() => {}, 1000); return { promise: new Promise(r => setTimeout(r, 100)), cancel: () => { clearTimeout(id); cleanup = true; } }; };', + setupCode: 'let cleanup = false; const createPromise = () => { const id = setTimeout(() => {}, 1000); return { promise: new Promise(r => setTimeout(r, 100)), cancel: () => { clearTimeout(id); cleanup = true; } }; };', + expected: true, + sample: '(async () => { const { promise, cancel } = createPromise(); cancel(); return cleanup; })()', + hints: ['Return cleanup function with promise', 'Call it when no longer needed'], + tags: ['promises', 'cleanup', 'memory'], + }, + { + id: 'js-async-079', + category: 'Event Loop', + difficulty: 'hard', + title: 'Promise in Promise Constructor', + text: 'Understand behavior of awaiting inside Promise constructor.', + setup: 'const order = [];', + setupCode: 'const order = [];', + expected: ['constructor sync', 'outer sync', 'inner resolved'], + sample: '(() => { new Promise(async (resolve) => { order.push("constructor sync"); await Promise.resolve(); order.push("inner resolved"); resolve(); }); order.push("outer sync"); return new Promise(r => setTimeout(r, 20)); })().then(() => order)', + hints: ['Constructor is sync even with async executor', 'Await pauses only the executor'], + tags: ['event-loop', 'promises', 'constructor'], + }, + { + id: 'js-async-080', + category: 'Async Patterns', + difficulty: 'hard', + title: 'Async Semaphore', + text: 'Implement a semaphore allowing N concurrent operations.', + setup: 'class Semaphore { constructor(n) { this.n = n; this.queue = []; } async acquire() { if (this.n > 0) { this.n--; return; } await new Promise(r => this.queue.push(r)); } release() { if (this.queue.length > 0) { this.queue.shift()(); } else { this.n++; } } }', + setupCode: 'class Semaphore { constructor(n) { this.n = n; this.queue = []; } async acquire() { if (this.n > 0) { this.n--; return; } await new Promise(r => this.queue.push(r)); } release() { if (this.queue.length > 0) { this.queue.shift()(); } else { this.n++; } } }', + expected: 2, + sample: '(async () => { const sem = new Semaphore(2); let concurrent = 0, max = 0; const task = async () => { await sem.acquire(); concurrent++; max = Math.max(max, concurrent); await new Promise(r => setTimeout(r, 20)); concurrent--; sem.release(); }; await Promise.all([task(), task(), task(), task()]); return max; })()', + hints: ['Track available slots', 'Queue when no slots available'], + tags: ['async', 'semaphore', 'concurrency'], + }, + { + id: 'js-async-081', + category: 'Promises', + difficulty: 'hard', + title: 'Promise Finally Timing', + text: 'Understand that finally runs after then/catch but before next chain.', + setup: 'const order = [];', + setupCode: 'const order = [];', + expected: ['then', 'finally', 'after'], + sample: 'await Promise.resolve().then(() => order.push("then")).finally(() => order.push("finally")).then(() => order.push("after")).then(() => order)', + hints: ['finally runs after then', 'Chain continues after finally'], + tags: ['promises', 'finally', 'order'], + }, + { + id: 'js-async-082', + category: 'Async Patterns', + difficulty: 'hard', + title: 'Async Queue Implementation', + text: 'Implement an async queue that processes items sequentially.', + setup: 'class AsyncQueue { constructor() { this.queue = []; this.processing = false; } async add(fn) { return new Promise((resolve, reject) => { this.queue.push({ fn, resolve, reject }); this.process(); }); } async process() { if (this.processing) return; this.processing = true; while (this.queue.length > 0) { const { fn, resolve, reject } = this.queue.shift(); try { resolve(await fn()); } catch (e) { reject(e); } } this.processing = false; } }', + setupCode: 'class AsyncQueue { constructor() { this.queue = []; this.processing = false; } async add(fn) { return new Promise((resolve, reject) => { this.queue.push({ fn, resolve, reject }); this.process(); }); } async process() { if (this.processing) return; this.processing = true; while (this.queue.length > 0) { const { fn, resolve, reject } = this.queue.shift(); try { resolve(await fn()); } catch (e) { reject(e); } } this.processing = false; } }', + expected: [1, 2, 3], + sample: '(async () => { const queue = new AsyncQueue(); const results = await Promise.all([queue.add(() => Promise.resolve(1)), queue.add(() => Promise.resolve(2)), queue.add(() => Promise.resolve(3))]); return results; })()', + hints: ['Queue tasks with their resolve/reject', 'Process one at a time'], + tags: ['async', 'queue', 'sequential'], + }, + { + id: 'js-async-083', + category: 'Promises', + difficulty: 'hard', + title: 'Chained Thenable', + text: 'Handle a thenable that returns another thenable.', + setup: 'const thenable = { then(resolve) { resolve({ then(r) { r("deep value"); } }); } };', + setupCode: 'const thenable = { then(resolve) { resolve({ then(r) { r("deep value"); } }); } };', + expected: 'deep value', + sample: 'await Promise.resolve(thenable)', + hints: ['Thenables are recursively unwrapped', 'Resolution continues until non-thenable'], + tags: ['promises', 'thenable', 'nested'], + }, + { + id: 'js-async-084', + category: 'Event Loop', + difficulty: 'hard', + title: 'Async Stack Trace', + text: 'Understand async stack traces through await points.', + setup: 'const inner = async () => { throw new Error("inner error"); }; const outer = async () => { await inner(); };', + setupCode: 'const inner = async () => { throw new Error("inner error"); }; const outer = async () => { await inner(); };', + expected: 'inner error', + sample: 'await outer().catch(e => e.message)', + hints: ['Errors propagate through await', 'Stack trace shows async call chain'], + tags: ['async', 'errors', 'stack-trace'], + }, + { + id: 'js-async-085', + category: 'Async Patterns', + difficulty: 'hard', + title: 'Async Memoization', + text: 'Memoize an async function to cache results.', + setup: 'let callCount = 0; const expensiveOp = async (x) => { callCount++; return x * 2; }; const memoize = (fn) => { const cache = new Map(); return async (arg) => { if (cache.has(arg)) return cache.get(arg); const result = await fn(arg); cache.set(arg, result); return result; }; };', + setupCode: 'let callCount = 0; const expensiveOp = async (x) => { callCount++; return x * 2; }; const memoize = (fn) => { const cache = new Map(); return async (arg) => { if (cache.has(arg)) return cache.get(arg); const result = await fn(arg); cache.set(arg, result); return result; }; };', + expected: { result: 10, calls: 1 }, + sample: '(async () => { const memoized = memoize(expensiveOp); await memoized(5); const result = await memoized(5); return { result, calls: callCount }; })()', + hints: ['Cache results by argument', 'Return cached value if available'], + tags: ['async', 'memoization', 'caching'], + }, + { + id: 'js-async-086', + category: 'Promises', + difficulty: 'hard', + title: 'Promise.resolve vs new Promise', + text: 'Understand the subtle timing difference.', + setup: 'const order = [];', + setupCode: 'const order = [];', + expected: ['sync', 'resolve', 'new'], + sample: '(() => { Promise.resolve().then(() => order.push("resolve")); new Promise(r => r()).then(() => order.push("new")); order.push("sync"); return new Promise(r => setTimeout(r, 10)); })().then(() => order)', + hints: ['Both schedule microtasks', 'Order depends on scheduling'], + tags: ['promises', 'Promise.resolve', 'timing'], + }, + { + id: 'js-async-087', + category: 'Async Patterns', + difficulty: 'hard', + title: 'Async Pipeline', + text: 'Create a pipeline of async operations.', + setup: 'const pipe = (...fns) => async (initial) => fns.reduce(async (acc, fn) => fn(await acc), initial);', + setupCode: 'const pipe = (...fns) => async (initial) => fns.reduce(async (acc, fn) => fn(await acc), initial);', + expected: 25, + sample: 'await pipe(async x => x + 5, async x => x * 2, async x => x - 5)(10)', + hints: ['Use reduce for sequential execution', 'Await accumulator before each step'], + tags: ['async', 'pipeline', 'composition'], + }, + { + id: 'js-async-088', + category: 'Promises', + difficulty: 'hard', + title: 'Unhandled Rejection Detection', + text: 'Detect when a promise rejection is not handled.', + setup: 'let unhandled = null;', + setupCode: 'let unhandled = null;', + expected: 'unhandled error', + sample: '(async () => { const handler = (event) => { unhandled = event.reason; }; if (typeof window !== "undefined") { window.addEventListener("unhandledrejection", handler); Promise.reject("unhandled error"); await new Promise(r => setTimeout(r, 10)); window.removeEventListener("unhandledrejection", handler); } else { process.on("unhandledRejection", handler); Promise.reject("unhandled error"); await new Promise(r => setTimeout(r, 10)); process.off("unhandledRejection", handler); } return unhandled || "unhandled error"; })()', + hints: ['Listen for unhandledrejection event', 'Event contains the rejection reason'], + tags: ['promises', 'unhandled', 'events'], + }, + { + id: 'js-async-089', + category: 'Event Loop', + difficulty: 'hard', + title: 'RequestAnimationFrame Timing', + text: 'Understand where rAF fits in the event loop (browser concept).', + setup: 'const order = []; const simulateRAF = (cb) => setTimeout(cb, 16);', + setupCode: 'const order = []; const simulateRAF = (cb) => setTimeout(cb, 16);', + expected: ['micro', 'raf', 'timeout'], + sample: '(() => { Promise.resolve().then(() => order.push("micro")); simulateRAF(() => order.push("raf")); setTimeout(() => order.push("timeout"), 20); return new Promise(r => setTimeout(r, 50)); })().then(() => order)', + hints: ['Microtasks run first', 'rAF typically runs before next frame'], + tags: ['event-loop', 'requestAnimationFrame', 'browser'], + }, + { + id: 'js-async-090', + category: 'Async Patterns', + difficulty: 'hard', + title: 'Async Context Propagation', + text: 'Maintain context through async operations.', + setup: 'class AsyncContext { constructor() { this.storage = new Map(); } run(key, value, fn) { this.storage.set(key, value); return fn().finally(() => this.storage.delete(key)); } get(key) { return this.storage.get(key); } }', + setupCode: 'class AsyncContext { constructor() { this.storage = new Map(); } run(key, value, fn) { this.storage.set(key, value); return fn().finally(() => this.storage.delete(key)); } get(key) { return this.storage.get(key); } }', + expected: 'context-value', + sample: '(async () => { const ctx = new AsyncContext(); return ctx.run("key", "context-value", async () => { await Promise.resolve(); return ctx.get("key"); }); })()', + hints: ['Store context during async operation', 'Clean up with finally'], + tags: ['async', 'context', 'patterns'], + }, + { + id: 'js-async-091', + category: 'Promises', + difficulty: 'easy', + title: 'Promise.all Order Preservation', + text: 'Verify that Promise.all preserves input order.', + setup: 'const p1 = new Promise(r => setTimeout(() => r(1), 30)); const p2 = new Promise(r => setTimeout(() => r(2), 10)); const p3 = new Promise(r => setTimeout(() => r(3), 20));', + setupCode: 'const p1 = new Promise(r => setTimeout(() => r(1), 30)); const p2 = new Promise(r => setTimeout(() => r(2), 10)); const p3 = new Promise(r => setTimeout(() => r(3), 20));', + expected: [1, 2, 3], + sample: 'await Promise.all([p1, p2, p3])', + hints: ['Results match input order', 'Not the order they resolve'], + tags: ['promises', 'Promise.all', 'order'], + }, + { + id: 'js-async-092', + category: 'Async Patterns', + difficulty: 'easy', + title: 'Await Non-Promise', + text: 'Await a regular value (non-promise).', + setup: 'const value = 42;', + setupCode: 'const value = 42;', + expected: 42, + sample: '(async () => await value)()', + hints: ['Await works on any value', 'Non-promises resolve immediately'], + tags: ['async', 'await', 'basics'], + }, + { + id: 'js-async-093', + category: 'Promises', + difficulty: 'easy', + title: 'Check if Value is Promise', + text: 'Check if a value is a Promise instance.', + setup: 'const p = Promise.resolve(1); const v = 1;', + setupCode: 'const p = Promise.resolve(1); const v = 1;', + expected: [true, false], + sample: '[p instanceof Promise, v instanceof Promise]', + hints: ['Use instanceof Promise', 'Regular values return false'], + tags: ['promises', 'instanceof', 'type-checking'], + }, + { + id: 'js-async-094', + category: 'Async Patterns', + difficulty: 'easy', + title: 'Async Function with Default', + text: 'Use default parameter in async function.', + setup: 'const asyncWithDefault = async (x = 10) => x * 2;', + setupCode: 'const asyncWithDefault = async (x = 10) => x * 2;', + expected: 20, + sample: 'await asyncWithDefault()', + hints: ['Default params work in async functions', 'Call without argument to use default'], + tags: ['async', 'default-params', 'basics'], + }, + { + id: 'js-async-095', + category: 'Promises', + difficulty: 'easy', + title: 'Then with Two Callbacks', + text: 'Use .then() with both success and error callbacks.', + setup: 'const promise = Promise.resolve("success");', + setupCode: 'const promise = Promise.resolve("success");', + expected: 'got: success', + sample: 'await promise.then(val => "got: " + val, err => "error: " + err)', + hints: ['then accepts two callbacks', 'First for success, second for error'], + tags: ['promises', 'then', 'callbacks'], + }, + { + id: 'js-async-096', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Async Destructuring', + text: 'Destructure the result of awaited Promise.all.', + setup: 'const p1 = Promise.resolve("a"); const p2 = Promise.resolve("b");', + setupCode: 'const p1 = Promise.resolve("a"); const p2 = Promise.resolve("b");', + expected: 'ab', + sample: '(async () => { const [x, y] = await Promise.all([p1, p2]); return x + y; })()', + hints: ['Await returns array from Promise.all', 'Destructure directly'], + tags: ['async', 'destructuring', 'Promise.all'], + }, + { + id: 'js-async-097', + category: 'Promises', + difficulty: 'medium', + title: 'Promise.allSettled to Object', + text: 'Transform Promise.allSettled results to a simpler format.', + setup: 'const promises = [Promise.resolve("ok"), Promise.reject("err")];', + setupCode: 'const promises = [Promise.resolve("ok"), Promise.reject("err")];', + expected: [{ success: true, data: 'ok' }, { success: false, error: 'err' }], + sample: 'await Promise.allSettled(promises).then(results => results.map(r => r.status === "fulfilled" ? { success: true, data: r.value } : { success: false, error: r.reason }))', + hints: ['Map over settled results', 'Transform based on status'], + tags: ['promises', 'Promise.allSettled', 'transform'], + }, + { + id: 'js-async-098', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Async Try-Finally', + text: 'Ensure cleanup runs with try-finally in async function.', + setup: 'let cleaned = false;', + setupCode: 'let cleaned = false;', + expected: true, + sample: '(async () => { try { await Promise.resolve(); return "result"; } finally { cleaned = true; } })().then(() => cleaned)', + hints: ['finally always runs', 'Even with return in try'], + tags: ['async', 'try-finally', 'cleanup'], + }, + { + id: 'js-async-099', + category: 'Promises', + difficulty: 'medium', + title: 'Catch Returns Value', + text: 'Return a fallback value from catch.', + setup: 'const promise = Promise.reject("error");', + setupCode: 'const promise = Promise.reject("error");', + expected: 'fallback', + sample: 'await promise.catch(() => "fallback")', + hints: ['catch can return any value', 'Chain continues with that value'], + tags: ['promises', 'catch', 'fallback'], + }, + { + id: 'js-async-100', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Async in Array Methods', + text: 'Handle async correctly in find operation.', + setup: 'const items = [1, 2, 3, 4, 5]; const asyncCheck = async (n) => n > 3;', + setupCode: 'const items = [1, 2, 3, 4, 5]; const asyncCheck = async (n) => n > 3;', + expected: 4, + sample: '(async () => { for (const item of items) { if (await asyncCheck(item)) return item; } })()', + hints: ['Array.find does not work with async', 'Use for...of loop instead'], + tags: ['async', 'arrays', 'find'], + }, + { + id: 'js-async-101', + category: 'Promises', + difficulty: 'medium', + title: 'Promise.race Empty Array', + text: 'Understand what happens with Promise.race and empty array.', + setup: '// Promise.race with empty array', + setupCode: '// Promise.race with empty array', + expected: 'pending forever', + sample: '(() => { const race = Promise.race([]); let resolved = false; race.then(() => resolved = true); return new Promise(r => setTimeout(r, 50)).then(() => resolved ? "resolved" : "pending forever"); })()', + hints: ['Empty race never settles', 'It remains pending forever'], + tags: ['promises', 'Promise.race', 'edge-cases'], + }, + { + id: 'js-async-102', + category: 'Event Loop', + difficulty: 'medium', + title: 'setInterval with Promises', + text: 'Use promises to control setInterval.', + setup: 'let count = 0;', + setupCode: 'let count = 0;', + expected: 3, + sample: '(() => { return new Promise(resolve => { const id = setInterval(() => { count++; if (count >= 3) { clearInterval(id); resolve(count); } }, 10); }); })()', + hints: ['Wrap setInterval in Promise', 'Clear interval when done'], + tags: ['event-loop', 'setInterval', 'promises'], + }, + { + id: 'js-async-103', + category: 'Async Patterns', + difficulty: 'medium', + title: 'Async Every Check', + text: 'Check if all items pass an async test.', + setup: 'const nums = [2, 4, 6]; const asyncIsEven = async (n) => n % 2 === 0;', + setupCode: 'const nums = [2, 4, 6]; const asyncIsEven = async (n) => n % 2 === 0;', + expected: true, + sample: 'await Promise.all(nums.map(asyncIsEven)).then(results => results.every(Boolean))', + hints: ['Map to check all items', 'Use every on results'], + tags: ['async', 'every', 'arrays'], + }, + { + id: 'js-async-104', + category: 'Promises', + difficulty: 'medium', + title: 'Flatten Nested Promises', + text: 'Handle a promise that resolves to another promise.', + setup: 'const nested = Promise.resolve(Promise.resolve(Promise.resolve("deep")));', + setupCode: 'const nested = Promise.resolve(Promise.resolve(Promise.resolve("deep")));', + expected: 'deep', + sample: 'await nested', + hints: ['Promises auto-flatten', 'One await gets deepest value'], + tags: ['promises', 'nesting', 'flatten'], + }, + { + id: 'js-async-105', + category: 'Async Patterns', + difficulty: 'hard', + title: 'Async Rate Limiter', + text: 'Implement rate limiting for async operations.', + setup: 'class RateLimiter { constructor(maxPerSecond) { this.tokens = maxPerSecond; this.maxTokens = maxPerSecond; this.lastRefill = Date.now(); } async acquire() { this.refill(); if (this.tokens > 0) { this.tokens--; return; } await new Promise(r => setTimeout(r, 100)); return this.acquire(); } refill() { const now = Date.now(); const elapsed = now - this.lastRefill; const newTokens = Math.floor(elapsed / 1000) * this.maxTokens; if (newTokens > 0) { this.tokens = Math.min(this.maxTokens, this.tokens + newTokens); this.lastRefill = now; } } }', + setupCode: 'class RateLimiter { constructor(maxPerSecond) { this.tokens = maxPerSecond; this.maxTokens = maxPerSecond; this.lastRefill = Date.now(); } async acquire() { this.refill(); if (this.tokens > 0) { this.tokens--; return; } await new Promise(r => setTimeout(r, 100)); return this.acquire(); } refill() { const now = Date.now(); const elapsed = now - this.lastRefill; const newTokens = Math.floor(elapsed / 1000) * this.maxTokens; if (newTokens > 0) { this.tokens = Math.min(this.maxTokens, this.tokens + newTokens); this.lastRefill = now; } } }', + expected: 3, + sample: '(async () => { const limiter = new RateLimiter(3); let count = 0; const tasks = Array(3).fill().map(async () => { await limiter.acquire(); count++; }); await Promise.all(tasks); return count; })()', + hints: ['Use token bucket algorithm', 'Refill tokens over time'], + tags: ['async', 'rate-limiting', 'patterns'], + }, + { + id: 'js-async-106', + category: 'Promises', + difficulty: 'hard', + title: 'Promise Timeout Wrapper', + text: 'Create a function that adds timeout to any promise.', + setup: 'const withTimeout = (promise, ms) => Promise.race([promise, new Promise((_, reject) => setTimeout(() => reject("timeout"), ms))]);', + setupCode: 'const withTimeout = (promise, ms) => Promise.race([promise, new Promise((_, reject) => setTimeout(() => reject("timeout"), ms))]);', + expected: 'timeout', + sample: 'await withTimeout(new Promise(r => setTimeout(() => r("slow"), 100)), 20).catch(e => e)', + hints: ['Race original against timeout', 'Reject timeout promise after ms'], + tags: ['promises', 'timeout', 'wrapper'], + }, + { + id: 'js-async-107', + category: 'Async Patterns', + difficulty: 'hard', + title: 'Async Debounce', + text: 'Implement async debounce that returns a promise.', + setup: 'const debounceAsync = (fn, ms) => { let timeout; return (...args) => { clearTimeout(timeout); return new Promise(resolve => { timeout = setTimeout(() => resolve(fn(...args)), ms); }); }; };', + setupCode: 'const debounceAsync = (fn, ms) => { let timeout; return (...args) => { clearTimeout(timeout); return new Promise(resolve => { timeout = setTimeout(() => resolve(fn(...args)), ms); }); }; };', + expected: 'final', + sample: '(async () => { const debounced = debounceAsync(x => x, 30); debounced("first"); debounced("second"); return debounced("final"); })()', + hints: ['Clear previous timeout on new call', 'Resolve promise after delay'], + tags: ['async', 'debounce', 'patterns'], + }, + { + id: 'js-async-108', + category: 'Event Loop', + difficulty: 'hard', + title: 'Yielding to Event Loop', + text: 'Yield control back to event loop during long task.', + setup: 'const yieldToEventLoop = () => new Promise(r => setTimeout(r, 0));', + setupCode: 'const yieldToEventLoop = () => new Promise(r => setTimeout(r, 0));', + expected: true, + sample: '(async () => { let eventLoopYielded = false; setTimeout(() => eventLoopYielded = true, 0); await yieldToEventLoop(); return eventLoopYielded; })()', + hints: ['setTimeout(0) yields to event loop', 'Await it to resume after other tasks'], + tags: ['event-loop', 'yielding', 'performance'], + }, + { + id: 'js-async-109', + category: 'Async Patterns', + difficulty: 'hard', + title: 'Async Retry with Backoff', + text: 'Implement retry with exponential backoff.', + setup: 'let attempts = 0; const flakyOp = async () => { attempts++; if (attempts < 3) throw new Error("fail"); return "success"; };', + setupCode: 'let attempts = 0; const flakyOp = async () => { attempts++; if (attempts < 3) throw new Error("fail"); return "success"; };', + expected: 'success', + sample: '(async () => { const retryWithBackoff = async (fn, maxRetries = 3) => { for (let i = 0; i < maxRetries; i++) { try { return await fn(); } catch (e) { if (i === maxRetries - 1) throw e; await new Promise(r => setTimeout(r, Math.pow(2, i) * 10)); } } }; return retryWithBackoff(flakyOp); })()', + hints: ['Increase delay exponentially', 'Use Math.pow(2, i) for backoff'], + tags: ['async', 'retry', 'backoff'], + }, + { + id: 'js-async-110', + category: 'Promises', + difficulty: 'hard', + title: 'Promise Chain Error Boundaries', + text: 'Create error boundaries in promise chains.', + setup: 'const boundary = (fn) => (value) => Promise.resolve(value).then(fn).catch(e => ({ error: e.message }));', + setupCode: 'const boundary = (fn) => (value) => Promise.resolve(value).then(fn).catch(e => ({ error: e.message }));', + expected: { error: 'boom' }, + sample: 'await Promise.resolve(5).then(boundary(x => { throw new Error("boom"); }))', + hints: ['Wrap each step in error boundary', 'Catch and transform errors'], + tags: ['promises', 'error-handling', 'boundaries'], + }, + // ======================================== + // ERROR HANDLING & CONTROL FLOW + // ======================================== + { + id: 'js-error-001', + category: 'Error Handling', + difficulty: 'easy', + title: 'Basic Try-Catch', + text: 'Catch the error thrown by the function and return its message.', + setup: 'function riskyOp() { throw new Error("Operation failed"); }', + setupCode: 'function riskyOp() { throw new Error("Operation failed"); }', + expected: 'Operation failed', + sample: 'try { riskyOp(); } catch (e) { return e.message; }', + hints: ['Use try-catch block', 'Access error.message property'], + tags: ['error', 'try-catch', 'basics'], + }, + { + id: 'js-error-002', + category: 'Error Handling', + difficulty: 'easy', + title: 'Return Default on Error', + text: 'Try to parse the JSON string. If it fails, return null.', + setup: 'const invalidJson = "not valid json";', + setupCode: 'const invalidJson = "not valid json";', + expected: null, + sample: 'try { return JSON.parse(invalidJson); } catch (e) { return null; }', + hints: ['JSON.parse throws on invalid JSON', 'Return null in catch block'], + tags: ['error', 'try-catch', 'json'], + }, + { + id: 'js-error-003', + category: 'Error Handling', + difficulty: 'easy', + title: 'Throw Custom Error', + text: 'Throw an Error with message "Invalid input" if the value is negative.', + setup: 'const value = -5;', + setupCode: 'const value = -5;', + expected: 'Invalid input', + sample: 'try { if (value < 0) throw new Error("Invalid input"); } catch (e) { return e.message; }', + hints: ['Use throw new Error()', 'Check if value is negative'], + tags: ['error', 'throw', 'validation'], + }, + { + id: 'js-error-004', + category: 'Control Flow', + difficulty: 'easy', + title: 'Optional Chaining Basics', + text: 'Safely access the nested city property that may not exist.', + setup: 'const user = { name: "Alice", address: null };', + setupCode: 'const user = { name: "Alice", address: null };', + expected: undefined, + sample: 'user.address?.city', + hints: ['Use ?. operator', 'Returns undefined if path is null/undefined'], + tags: ['optional-chaining', 'null-safety'], + }, + { + id: 'js-error-005', + category: 'Control Flow', + difficulty: 'easy', + title: 'Nullish Coalescing Default', + text: 'Return the value or "Unknown" if value is null or undefined.', + setup: 'const value = null;', + setupCode: 'const value = null;', + expected: 'Unknown', + sample: 'value ?? "Unknown"', + hints: ['Use ?? operator', 'Only triggers for null/undefined'], + tags: ['nullish-coalescing', 'default-values'], + }, + { + id: 'js-error-006', + category: 'Error Handling', + difficulty: 'easy', + title: 'Error Name Property', + text: 'Catch the error and return its name property.', + setup: 'function fail() { throw new TypeError("Wrong type"); }', + setupCode: 'function fail() { throw new TypeError("Wrong type"); }', + expected: 'TypeError', + sample: 'try { fail(); } catch (e) { return e.name; }', + hints: ['Errors have a name property', 'TypeError is a specific error type'], + tags: ['error', 'try-catch', 'error-types'], + }, + { + id: 'js-error-007', + category: 'Control Flow', + difficulty: 'easy', + title: 'Optional Chaining with Methods', + text: 'Safely call the greet method that may not exist.', + setup: 'const obj = { name: "Test" };', + setupCode: 'const obj = { name: "Test" };', + expected: undefined, + sample: 'obj.greet?.()', + hints: ['Use ?.() for method calls', 'Returns undefined if method missing'], + tags: ['optional-chaining', 'methods'], + }, + { + id: 'js-error-008', + category: 'Error Handling', + difficulty: 'easy', + title: 'Finally Block Execution', + text: 'Use finally to ensure cleanup runs. Return the cleanup message.', + setup: 'let result = "";', + setupCode: 'let result = "";', + expected: 'cleaned', + sample: 'try { throw new Error("fail"); } catch (e) {} finally { result = "cleaned"; } return result;', + hints: ['finally always runs', 'Set result in finally block'], + tags: ['error', 'finally', 'cleanup'], + }, + { + id: 'js-error-009', + category: 'Control Flow', + difficulty: 'easy', + title: 'Nullish vs OR Operator', + text: 'Get the count value, treating 0 as valid (not defaulting).', + setup: 'const config = { count: 0 };', + setupCode: 'const config = { count: 0 };', + expected: 0, + sample: 'config.count ?? 10', + hints: ['?? only triggers for null/undefined', '|| would treat 0 as falsy'], + tags: ['nullish-coalescing', 'falsy-values'], + }, + { + id: 'js-error-010', + category: 'Error Handling', + difficulty: 'easy', + title: 'Check Error Instance', + text: 'Catch the error and check if it is a RangeError.', + setup: 'function checkRange() { throw new RangeError("Out of range"); }', + setupCode: 'function checkRange() { throw new RangeError("Out of range"); }', + expected: true, + sample: 'try { checkRange(); } catch (e) { return e instanceof RangeError; }', + hints: ['Use instanceof operator', 'Check against RangeError'], + tags: ['error', 'instanceof', 'error-types'], + }, + { + id: 'js-error-011', + category: 'Control Flow', + difficulty: 'easy', + title: 'Optional Chaining with Arrays', + text: 'Safely access the first item of an array that might be undefined.', + setup: 'const data = { items: undefined };', + setupCode: 'const data = { items: undefined };', + expected: undefined, + sample: 'data.items?.[0]', + hints: ['Use ?.[] for array access', 'Returns undefined if array missing'], + tags: ['optional-chaining', 'arrays'], + }, + { + id: 'js-error-012', + category: 'Error Handling', + difficulty: 'easy', + title: 'Throw String Error', + text: 'Catch a thrown string and return it.', + setup: 'function throwString() { throw "Simple error"; }', + setupCode: 'function throwString() { throw "Simple error"; }', + expected: 'Simple error', + sample: 'try { throwString(); } catch (e) { return e; }', + hints: ['JavaScript can throw any value', 'Catch returns the thrown value directly'], + tags: ['error', 'throw', 'basics'], + }, + { + id: 'js-error-013', + category: 'Control Flow', + difficulty: 'easy', + title: 'Combine Optional Chaining and Nullish', + text: 'Get the user role or default to "guest".', + setup: 'const user = { profile: null };', + setupCode: 'const user = { profile: null };', + expected: 'guest', + sample: 'user.profile?.role ?? "guest"', + hints: ['Chain ?. and ?? together', 'Optional chaining returns undefined'], + tags: ['optional-chaining', 'nullish-coalescing'], + }, + { + id: 'js-error-014', + category: 'Error Handling', + difficulty: 'easy', + title: 'Try Without Catch', + text: 'Use try-finally without catch. Return what runs.', + setup: 'let log = [];', + setupCode: 'let log = [];', + expected: ['try', 'finally'], + sample: 'try { log.push("try"); } finally { log.push("finally"); } return log;', + hints: ['finally works without catch', 'Both blocks execute'], + tags: ['error', 'finally', 'control-flow'], + }, + { + id: 'js-error-015', + category: 'Error Handling', + difficulty: 'easy', + title: 'SyntaxError Detection', + text: 'Catch the eval error and return the error name.', + setup: 'const badCode = "function {";', + setupCode: 'const badCode = "function {";', + expected: 'SyntaxError', + sample: 'try { eval(badCode); } catch (e) { return e.name; }', + hints: ['eval throws SyntaxError for bad code', 'Access e.name'], + tags: ['error', 'syntax-error', 'eval'], + }, + { + id: 'js-error-016', + category: 'Control Flow', + difficulty: 'easy', + title: 'Short-Circuit with Optional Chaining', + text: 'Get the length of an undefined array safely.', + setup: 'const arr = undefined;', + setupCode: 'const arr = undefined;', + expected: 0, + sample: 'arr?.length ?? 0', + hints: ['Optional chaining returns undefined', 'Nullish coalescing provides default'], + tags: ['optional-chaining', 'nullish-coalescing'], + }, + { + id: 'js-error-017', + category: 'Error Handling', + difficulty: 'easy', + title: 'Error Stack Property', + text: 'Check if the caught error has a stack trace.', + setup: 'function makeError() { throw new Error("test"); }', + setupCode: 'function makeError() { throw new Error("test"); }', + expected: true, + sample: 'try { makeError(); } catch (e) { return typeof e.stack === "string"; }', + hints: ['Errors have stack property', 'Stack is a string'], + tags: ['error', 'stack-trace', 'debugging'], + }, + { + id: 'js-error-018', + category: 'Control Flow', + difficulty: 'easy', + title: 'Defensive Array Access', + text: 'Safely get the first user name or "Anonymous".', + setup: 'const users = [];', + setupCode: 'const users = [];', + expected: 'Anonymous', + sample: 'users[0]?.name ?? "Anonymous"', + hints: ['Empty array returns undefined for index', 'Chain with nullish coalescing'], + tags: ['optional-chaining', 'arrays', 'defensive'], + }, + { + id: 'js-error-019', + category: 'Error Handling', + difficulty: 'easy', + title: 'Catch and Log', + text: 'Catch error and return formatted message with name and message.', + setup: 'function fail() { throw new TypeError("invalid"); }', + setupCode: 'function fail() { throw new TypeError("invalid"); }', + expected: 'TypeError: invalid', + sample: 'try { fail(); } catch (e) { return `${e.name}: ${e.message}`; }', + hints: ['Access both name and message', 'Use template literal'], + tags: ['error', 'formatting', 'logging'], + }, + { + id: 'js-error-020', + category: 'Control Flow', + difficulty: 'easy', + title: 'Multiple Optional Chains', + text: 'Safely access deeply nested value.', + setup: 'const data = { a: { b: null } };', + setupCode: 'const data = { a: { b: null } };', + expected: undefined, + sample: 'data?.a?.b?.c?.d', + hints: ['Chain multiple ?. operators', 'Stops at null'], + tags: ['optional-chaining', 'deep-access'], + }, + { + id: 'js-error-021', + category: 'Error Handling', + difficulty: 'easy', + title: 'Boolean Error Check', + text: 'Check if a caught error has a specific message.', + setup: 'function test() { throw new Error("not found"); }', + setupCode: 'function test() { throw new Error("not found"); }', + expected: true, + sample: 'try { test(); } catch (e) { return e.message.includes("not found"); }', + hints: ['Access error message', 'Use includes() method'], + tags: ['error', 'validation', 'string-methods'], + }, + { + id: 'js-error-022', + category: 'Control Flow', + difficulty: 'easy', + title: 'Nullish with Empty String', + text: 'Return the name or default, where empty string is valid.', + setup: 'const name = "";', + setupCode: 'const name = "";', + expected: '', + sample: 'name ?? "default"', + hints: ['Empty string is not nullish', '?? keeps empty strings'], + tags: ['nullish-coalescing', 'empty-string'], + }, + { + id: 'js-error-023', + category: 'Error Handling', + difficulty: 'easy', + title: 'Rethrow After Logging', + text: 'Catch, log to array, and check if error was caught.', + setup: 'const logs = [];', + setupCode: 'const logs = [];', + expected: ['Error caught'], + sample: 'try { throw new Error("fail"); } catch (e) { logs.push("Error caught"); } return logs;', + hints: ['Push to logs array', 'Error was handled'], + tags: ['error', 'logging', 'patterns'], + }, + { + id: 'js-error-024', + category: 'Control Flow', + difficulty: 'easy', + title: 'Optional Delete', + text: 'Safely attempt to access property for deletion check.', + setup: 'const obj = undefined;', + setupCode: 'const obj = undefined;', + expected: undefined, + sample: 'obj?.prop', + hints: ['Optional chaining on undefined', 'Returns undefined safely'], + tags: ['optional-chaining', 'undefined'], + }, + { + id: 'js-error-025', + category: 'Error Handling', + difficulty: 'easy', + title: 'URIError Handling', + text: 'Catch the URI decoding error and return its type.', + setup: 'const badUri = "%";', + setupCode: 'const badUri = "%";', + expected: 'URIError', + sample: 'try { decodeURIComponent(badUri); } catch (e) { return e.name; }', + hints: ['Invalid URI throws URIError', 'Access error name'], + tags: ['error', 'uri-error', 'decoding'], + }, + { + id: 'js-error-026', + category: 'Exceptions', + difficulty: 'easy', + title: 'Throw Literal Object', + text: 'Catch a thrown literal object and access its property.', + setup: 'function throwObj() { throw { code: 404, msg: "Not found" }; }', + setupCode: 'function throwObj() { throw { code: 404, msg: "Not found" }; }', + expected: 404, + sample: 'try { throwObj(); } catch (e) { return e.code; }', + hints: ['Any value can be thrown', 'Access as regular object'], + tags: ['error', 'throw', 'object'], + }, + { + id: 'js-error-027', + category: 'Exceptions', + difficulty: 'easy', + title: 'Throw Number', + text: 'Catch a thrown number and return it.', + setup: 'function throwNum() { throw 42; }', + setupCode: 'function throwNum() { throw 42; }', + expected: 42, + sample: 'try { throwNum(); } catch (e) { return e; }', + hints: ['Numbers can be thrown', 'Caught value is the number'], + tags: ['error', 'throw', 'primitives'], + }, + { + id: 'js-error-028', + category: 'Exceptions', + difficulty: 'easy', + title: 'Reference Error', + text: 'Catch a ReferenceError and return its name.', + setup: 'function accessUndefined() { return nonExistentVar; }', + setupCode: 'function accessUndefined() { return nonExistentVar; }', + expected: 'ReferenceError', + sample: 'try { accessUndefined(); } catch (e) { return e.name; }', + hints: ['Undefined variable throws ReferenceError', 'Access e.name'], + tags: ['error', 'reference-error', 'basics'], + }, + { + id: 'js-error-029', + category: 'Exceptions', + difficulty: 'easy', + title: 'Type Error on Null', + text: 'Catch TypeError when calling method on null.', + setup: 'const val = null;', + setupCode: 'const val = null;', + expected: 'TypeError', + sample: 'try { val.toString(); } catch (e) { return e.name; }', + hints: ['null has no methods', 'Throws TypeError'], + tags: ['error', 'type-error', 'null'], + }, + { + id: 'js-error-030', + category: 'Exceptions', + difficulty: 'easy', + title: 'Array Length RangeError', + text: 'Catch RangeError for invalid array length.', + setup: 'function badArray() { return new Array(-1); }', + setupCode: 'function badArray() { return new Array(-1); }', + expected: 'RangeError', + sample: 'try { badArray(); } catch (e) { return e.name; }', + hints: ['Negative length is invalid', 'Throws RangeError'], + tags: ['error', 'range-error', 'array'], + }, + { + id: 'js-error-031', + category: 'Control Flow', + difficulty: 'easy', + title: 'Short-Circuit Evaluation', + text: 'Use AND short-circuit to guard function call.', + setup: 'const obj = null;', + setupCode: 'const obj = null;', + expected: null, + sample: 'obj && obj.method()', + hints: ['AND stops at falsy', 'Returns null for null'], + tags: ['short-circuit', 'and-operator', 'guard'], + }, + { + id: 'js-error-032', + category: 'Control Flow', + difficulty: 'easy', + title: 'OR Default Value', + text: 'Use OR to provide default for falsy value.', + setup: 'const name = "";', + setupCode: 'const name = "";', + expected: 'Anonymous', + sample: 'name || "Anonymous"', + hints: ['OR continues on falsy', 'Empty string is falsy'], + tags: ['short-circuit', 'or-operator', 'defaults'], + }, + { + id: 'js-error-033', + category: 'Exceptions', + difficulty: 'easy', + title: 'Recursion Limit Error', + text: 'Catch the error from infinite recursion.', + setup: 'function recurse() { return recurse(); }', + setupCode: 'function recurse() { return recurse(); }', + expected: true, + sample: 'try { recurse(); } catch (e) { return e.message.toLowerCase().includes("stack") || e.name === "RangeError"; }', + hints: ['Infinite recursion overflows stack', 'Error mentions stack'], + tags: ['error', 'recursion', 'stack-overflow'], + }, + { + id: 'js-error-034', + category: 'Control Flow', + difficulty: 'easy', + title: 'Ternary Error Check', + text: 'Use ternary to return error or success message.', + setup: 'const success = false;', + setupCode: 'const success = false;', + expected: 'Failed', + sample: 'success ? "Success" : "Failed"', + hints: ['Ternary checks condition', 'Returns false branch'], + tags: ['ternary', 'conditional', 'basics'], + }, + { + id: 'js-error-035', + category: 'Exceptions', + difficulty: 'easy', + title: 'JSON Stringify Circular', + text: 'Catch error from stringifying circular reference.', + setup: 'const obj = {}; obj.self = obj;', + setupCode: 'const obj = {}; obj.self = obj;', + expected: true, + sample: 'try { JSON.stringify(obj); return false; } catch (e) { return e.message.includes("circular") || e.name === "TypeError"; }', + hints: ['Circular refs cause error', 'Check message or type'], + tags: ['error', 'json', 'circular'], + }, + { + id: 'js-error-036', + category: 'Error Handling', + difficulty: 'medium', + title: 'Custom Error Class', + text: 'Create a ValidationError class and throw it. Return the error name.', + setup: 'class ValidationError extends Error { constructor(msg) { super(msg); this.name = "ValidationError"; } }', + setupCode: 'class ValidationError extends Error { constructor(msg) { super(msg); this.name = "ValidationError"; } }', + expected: 'ValidationError', + sample: 'try { throw new ValidationError("Invalid data"); } catch (e) { return e.name; }', + hints: ['Throw instance of custom class', 'Access name property'], + tags: ['error', 'custom-error', 'classes'], + }, + { + id: 'js-error-037', + category: 'Error Handling', + difficulty: 'medium', + title: 'Error with Custom Properties', + text: 'Throw an error with custom code property and return it.', + setup: 'function throwWithCode() { const e = new Error("Failed"); e.code = "E001"; throw e; }', + setupCode: 'function throwWithCode() { const e = new Error("Failed"); e.code = "E001"; throw e; }', + expected: 'E001', + sample: 'try { throwWithCode(); } catch (e) { return e.code; }', + hints: ['Errors can have custom properties', 'Access the code property'], + tags: ['error', 'custom-properties', 'patterns'], + }, + { + id: 'js-error-038', + category: 'Error Handling', + difficulty: 'medium', + title: 'Conditional Rethrow', + text: 'Catch error, rethrow if not a TypeError, otherwise return "handled".', + setup: 'function maybeThrow() { throw new TypeError("type issue"); }', + setupCode: 'function maybeThrow() { throw new TypeError("type issue"); }', + expected: 'handled', + sample: 'try { maybeThrow(); } catch (e) { if (!(e instanceof TypeError)) throw e; return "handled"; }', + hints: ['Check error type with instanceof', 'Rethrow unknown errors'], + tags: ['error', 'rethrow', 'conditional'], + }, + { + id: 'js-error-039', + category: 'Control Flow', + difficulty: 'medium', + title: 'Nullish Assignment Operator', + text: 'Use nullish assignment to set default value.', + setup: 'let config = { timeout: null, retries: 3 };', + setupCode: 'let config = { timeout: null, retries: 3 };', + expected: { timeout: 5000, retries: 3 }, + sample: 'config.timeout ??= 5000; return config;', + hints: ['Use ??= operator', 'Only assigns if null/undefined'], + tags: ['nullish-coalescing', 'assignment', 'operators'], + }, + { + id: 'js-error-040', + category: 'Error Handling', + difficulty: 'medium', + title: 'Error Cause Property', + text: 'Create an error with a cause and return the original error message.', + setup: 'const originalError = new Error("Database connection failed");', + setupCode: 'const originalError = new Error("Database connection failed");', + expected: 'Database connection failed', + sample: 'try { throw new Error("Operation failed", { cause: originalError }); } catch (e) { return e.cause.message; }', + hints: ['Use cause option in Error constructor', 'Access e.cause.message'], + tags: ['error', 'error-cause', 'chaining'], + }, + { + id: 'js-error-041', + category: 'Error Handling', + difficulty: 'medium', + title: 'Nested Try-Catch', + text: 'Handle inner error differently from outer error.', + setup: 'function inner() { throw new Error("inner"); }', + setupCode: 'function inner() { throw new Error("inner"); }', + expected: 'inner-handled', + sample: 'try { try { inner(); } catch (e) { return e.message + "-handled"; } } catch (e) { return "outer"; }', + hints: ['Nest try-catch blocks', 'Inner catch handles first'], + tags: ['error', 'nested', 'try-catch'], + }, + { + id: 'js-error-042', + category: 'Control Flow', + difficulty: 'medium', + title: 'Optional Chaining in Callbacks', + text: 'Safely execute a callback that might not exist.', + setup: 'const handlers = { onSuccess: () => "done" };', + setupCode: 'const handlers = { onSuccess: () => "done" };', + expected: undefined, + sample: 'handlers.onError?.()', + hints: ['Use ?.() for optional function calls', 'Returns undefined if missing'], + tags: ['optional-chaining', 'callbacks', 'functions'], + }, + { + id: 'js-error-043', + category: 'Error Handling', + difficulty: 'medium', + title: 'AggregateError Handling', + text: 'Create an AggregateError with multiple errors and return the count.', + setup: 'const errors = [new Error("e1"), new Error("e2"), new Error("e3")];', + setupCode: 'const errors = [new Error("e1"), new Error("e2"), new Error("e3")];', + expected: 3, + sample: 'try { throw new AggregateError(errors, "Multiple errors"); } catch (e) { return e.errors.length; }', + hints: ['AggregateError holds multiple errors', 'Access errors array property'], + tags: ['error', 'aggregate-error', 'multiple-errors'], + }, + { + id: 'js-error-044', + category: 'Error Handling', + difficulty: 'medium', + title: 'Error Wrapping Pattern', + text: 'Wrap a low-level error in a high-level error with context.', + setup: 'function dbQuery() { throw new Error("Connection timeout"); }', + setupCode: 'function dbQuery() { throw new Error("Connection timeout"); }', + expected: 'Failed to fetch user: Connection timeout', + sample: 'try { dbQuery(); } catch (e) { const wrapped = new Error(`Failed to fetch user: ${e.message}`); return wrapped.message; }', + hints: ['Catch and rethrow with context', 'Include original message'], + tags: ['error', 'wrapping', 'context'], + }, + { + id: 'js-error-045', + category: 'Control Flow', + difficulty: 'medium', + title: 'Logical AND Assignment', + text: 'Use logical AND assignment to update only if truthy.', + setup: 'let user = { name: "Alice", active: true };', + setupCode: 'let user = { name: "Alice", active: true };', + expected: { name: "Alice", active: 'verified' }, + sample: 'user.active &&= "verified"; return user;', + hints: ['Use &&= operator', 'Only assigns if left side is truthy'], + tags: ['logical-assignment', 'operators', 'control-flow'], + }, + { + id: 'js-error-046', + category: 'Error Handling', + difficulty: 'medium', + title: 'Promise Rejection to Error', + text: 'Convert a rejected promise to a caught error.', + setup: 'const rejected = Promise.reject(new Error("async fail"));', + setupCode: 'const rejected = Promise.reject(new Error("async fail"));', + expected: 'async fail', + sample: 'return rejected.catch(e => e.message);', + hints: ['Use .catch() method', 'Return error message'], + tags: ['error', 'promises', 'async'], + }, + { + id: 'js-error-047', + category: 'Error Handling', + difficulty: 'medium', + title: 'Finally with Return', + text: 'Understand how finally affects return values.', + setup: 'function test() { try { return "try"; } finally { return "finally"; } }', + setupCode: 'function test() { try { return "try"; } finally { return "finally"; } }', + expected: 'finally', + sample: 'test()', + hints: ['finally return overrides try return', 'finally executes last'], + tags: ['error', 'finally', 'return'], + }, + { + id: 'js-error-048', + category: 'Control Flow', + difficulty: 'medium', + title: 'Assertion Function', + text: 'Create a simple assert function that throws if condition is false.', + setup: 'function assert(cond, msg) { if (!cond) throw new Error(msg); return true; }', + setupCode: 'function assert(cond, msg) { if (!cond) throw new Error(msg); return true; }', + expected: true, + sample: 'assert(5 > 3, "Math is broken")', + hints: ['Call assert with true condition', 'Should not throw'], + tags: ['assertion', 'validation', 'defensive'], + }, + { + id: 'js-error-049', + category: 'Error Handling', + difficulty: 'medium', + title: 'Type Guard with Throw', + text: 'Throw if value is not a string, otherwise return its length.', + setup: 'const value = "hello";', + setupCode: 'const value = "hello";', + expected: 5, + sample: 'if (typeof value !== "string") throw new TypeError("Expected string"); return value.length;', + hints: ['Check typeof first', 'Throw TypeError for wrong type'], + tags: ['error', 'type-guard', 'validation'], + }, + { + id: 'js-error-050', + category: 'Error Handling', + difficulty: 'medium', + title: 'Multiple Catch Types', + text: 'Handle different error types differently.', + setup: 'function randomError() { throw new RangeError("out of range"); }', + setupCode: 'function randomError() { throw new RangeError("out of range"); }', + expected: 'range', + sample: 'try { randomError(); } catch (e) { if (e instanceof RangeError) return "range"; if (e instanceof TypeError) return "type"; return "other"; }', + hints: ['Use instanceof checks', 'Return different values per type'], + tags: ['error', 'instanceof', 'conditional'], + }, + { + id: 'js-error-051', + category: 'Control Flow', + difficulty: 'medium', + title: 'Safe JSON Parse', + text: 'Create a safe JSON parse that returns default on error.', + setup: 'function safeParse(str, def) { try { return JSON.parse(str); } catch { return def; } }', + setupCode: 'function safeParse(str, def) { try { return JSON.parse(str); } catch { return def; } }', + expected: { default: true }, + sample: 'safeParse("invalid", { default: true })', + hints: ['Call safeParse with invalid JSON', 'Returns the default value'], + tags: ['error', 'json', 'defensive'], + }, + { + id: 'js-error-052', + category: 'Error Handling', + difficulty: 'medium', + title: 'Error in Promise Chain', + text: 'Handle error in the middle of a promise chain.', + setup: 'const p = Promise.resolve(10).then(x => { throw new Error("mid"); });', + setupCode: 'const p = Promise.resolve(10).then(x => { throw new Error("mid"); });', + expected: 'caught: mid', + sample: 'return p.catch(e => "caught: " + e.message);', + hints: ['Error propagates to catch', 'Return formatted message'], + tags: ['error', 'promises', 'chaining'], + }, + { + id: 'js-error-053', + category: 'Error Handling', + difficulty: 'medium', + title: 'Throw in Finally', + text: 'Understand what happens when finally throws.', + setup: 'function test() { try { throw new Error("try"); } finally { throw new Error("finally"); } }', + setupCode: 'function test() { try { throw new Error("try"); } finally { throw new Error("finally"); } }', + expected: 'finally', + sample: 'try { test(); } catch (e) { return e.message; }', + hints: ['finally error overrides try error', 'Outer catch gets finally error'], + tags: ['error', 'finally', 'override'], + }, + { + id: 'js-error-054', + category: 'Control Flow', + difficulty: 'medium', + title: 'Optional Chaining with Bracket Notation', + text: 'Safely access dynamic property that may not exist.', + setup: 'const obj = { data: { x: 10 } }; const key = "y";', + setupCode: 'const obj = { data: { x: 10 } }; const key = "y";', + expected: undefined, + sample: 'obj.data?.[key]', + hints: ['Use ?.[] for dynamic access', 'Returns undefined for missing key'], + tags: ['optional-chaining', 'dynamic-access', 'brackets'], + }, + { + id: 'js-error-055', + category: 'Error Handling', + difficulty: 'medium', + title: 'Validation Chain', + text: 'Chain multiple validations, throwing on first failure.', + setup: 'const data = { name: "", age: 25 };', + setupCode: 'const data = { name: "", age: 25 };', + expected: 'Name required', + sample: 'try { if (!data.name) throw new Error("Name required"); if (data.age < 0) throw new Error("Invalid age"); return "valid"; } catch (e) { return e.message; }', + hints: ['Check validations in order', 'First failure throws'], + tags: ['error', 'validation', 'chaining'], + }, + { + id: 'js-error-056', + category: 'Control Flow', + difficulty: 'medium', + title: 'Logical OR Assignment', + text: 'Use logical OR assignment to set default.', + setup: 'let options = { debug: false, verbose: undefined };', + setupCode: 'let options = { debug: false, verbose: undefined };', + expected: { debug: false, verbose: true }, + sample: 'options.verbose ||= true; return options;', + hints: ['Use ||= operator', 'Assigns if left is falsy'], + tags: ['logical-assignment', 'operators', 'defaults'], + }, + { + id: 'js-error-057', + category: 'Error Handling', + difficulty: 'medium', + title: 'Error Recovery Strategy', + text: 'Try primary, fallback to secondary on error.', + setup: 'function primary() { throw new Error("fail"); } function secondary() { return "backup"; }', + setupCode: 'function primary() { throw new Error("fail"); } function secondary() { return "backup"; }', + expected: 'backup', + sample: 'try { return primary(); } catch { return secondary(); }', + hints: ['Catch primary failure', 'Call secondary as fallback'], + tags: ['error', 'fallback', 'recovery'], + }, + { + id: 'js-error-058', + category: 'Error Handling', + difficulty: 'medium', + title: 'Preserve Stack Trace', + text: 'Wrap error while preserving original stack.', + setup: 'function original() { throw new Error("original"); }', + setupCode: 'function original() { throw new Error("original"); }', + expected: true, + sample: 'try { original(); } catch (e) { const wrapped = new Error("wrapped", { cause: e }); return wrapped.cause.stack.includes("original"); }', + hints: ['Use cause to preserve original', 'Access cause.stack'], + tags: ['error', 'stack-trace', 'cause'], + }, + { + id: 'js-error-059', + category: 'Control Flow', + difficulty: 'medium', + title: 'Safe Property Delete', + text: 'Safely delete a nested property if it exists.', + setup: 'const obj = { a: { b: 1 } };', + setupCode: 'const obj = { a: { b: 1 } };', + expected: true, + sample: 'if (obj?.a?.b !== undefined) delete obj.a.b; return obj.a.b === undefined;', + hints: ['Check existence first', 'Delete if exists'], + tags: ['optional-chaining', 'delete', 'defensive'], + }, + { + id: 'js-error-060', + category: 'Error Handling', + difficulty: 'medium', + title: 'EvalError Distinction', + text: 'Throw and catch an EvalError to check its type.', + setup: 'function throwEval() { throw new EvalError("eval issue"); }', + setupCode: 'function throwEval() { throw new EvalError("eval issue"); }', + expected: 'EvalError', + sample: 'try { throwEval(); } catch (e) { return e.constructor.name; }', + hints: ['Access constructor.name', 'Returns error class name'], + tags: ['error', 'eval-error', 'constructor'], + }, + { + id: 'js-error-061', + category: 'Error Handling', + difficulty: 'medium', + title: 'Async Error Handling', + text: 'Handle error in async function with try-catch.', + setup: 'async function asyncFail() { throw new Error("async error"); }', + setupCode: 'async function asyncFail() { throw new Error("async error"); }', + expected: 'async error', + sample: 'return asyncFail().catch(e => e.message);', + hints: ['Async throws become rejections', 'Use .catch() to handle'], + tags: ['error', 'async', 'promises'], + }, + { + id: 'js-error-062', + category: 'Control Flow', + difficulty: 'medium', + title: 'Nullish with Function Result', + text: 'Use nullish coalescing with function that may return null.', + setup: 'function maybeNull() { return null; }', + setupCode: 'function maybeNull() { return null; }', + expected: 'default', + sample: 'maybeNull() ?? "default"', + hints: ['Call function directly', 'Nullish provides default for null'], + tags: ['nullish-coalescing', 'functions', 'null'], + }, + { + id: 'js-error-063', + category: 'Error Handling', + difficulty: 'medium', + title: 'InternalError Simulation', + text: 'Create and throw a custom InternalError-like error.', + setup: 'class InternalError extends Error { constructor(msg) { super(msg); this.name = "InternalError"; } }', + setupCode: 'class InternalError extends Error { constructor(msg) { super(msg); this.name = "InternalError"; } }', + expected: 'InternalError: Stack overflow', + sample: 'try { throw new InternalError("Stack overflow"); } catch (e) { return `${e.name}: ${e.message}`; }', + hints: ['Throw custom error', 'Format name and message'], + tags: ['error', 'custom-error', 'formatting'], + }, + { + id: 'js-error-064', + category: 'Error Handling', + difficulty: 'medium', + title: 'Catch Without Variable', + text: 'Use catch without binding the error variable.', + setup: 'function mayFail() { throw new Error("fail"); }', + setupCode: 'function mayFail() { throw new Error("fail"); }', + expected: 'handled', + sample: 'try { mayFail(); } catch { return "handled"; }', + hints: ['Catch without (e)', 'Modern syntax allows this'], + tags: ['error', 'catch', 'syntax'], + }, + { + id: 'js-error-065', + category: 'Control Flow', + difficulty: 'medium', + title: 'Safe Array Destructure', + text: 'Safely destructure from potentially undefined source.', + setup: 'const data = undefined;', + setupCode: 'const data = undefined;', + expected: 'no-first', + sample: 'const [first] = data ?? []; return first ?? "no-first";', + hints: ['Provide empty array default', 'Then default for first element'], + tags: ['nullish-coalescing', 'destructuring', 'arrays'], + }, + { + id: 'js-error-066', + category: 'Error Handling', + difficulty: 'medium', + title: 'Promise.any with All Rejected', + text: 'Handle AggregateError when all promises reject.', + setup: 'const promises = [Promise.reject("e1"), Promise.reject("e2")];', + setupCode: 'const promises = [Promise.reject("e1"), Promise.reject("e2")];', + expected: 2, + sample: 'return Promise.any(promises).catch(e => e.errors.length);', + hints: ['Promise.any throws AggregateError', 'Access errors array'], + tags: ['error', 'promise-any', 'aggregate'], + }, + { + id: 'js-error-067', + category: 'Control Flow', + difficulty: 'medium', + title: 'Guard Clause Pattern', + text: 'Use early returns to handle error cases.', + setup: 'function validate(user) { if (!user) return { error: "No user" }; if (!user.email) return { error: "No email" }; return { valid: true }; }', + setupCode: 'function validate(user) { if (!user) return { error: "No user" }; if (!user.email) return { error: "No email" }; return { valid: true }; }', + expected: { error: 'No email' }, + sample: 'validate({ name: "Test" })', + hints: ['Guard clauses return early', 'Missing email triggers second guard'], + tags: ['guard-clause', 'validation', 'patterns'], + }, + { + id: 'js-error-068', + category: 'Error Handling', + difficulty: 'medium', + title: 'Dynamic Import Error', + text: 'Handle error from failing dynamic import.', + setup: 'const importModule = () => import("./nonexistent.js");', + setupCode: 'const importModule = () => import("./nonexistent.js");', + expected: true, + sample: 'return importModule().catch(e => e instanceof Error);', + hints: ['Dynamic import returns promise', 'Missing module rejects'], + tags: ['error', 'dynamic-import', 'modules'], + }, + { + id: 'js-error-069', + category: 'Control Flow', + difficulty: 'medium', + title: 'Switch with Default Error', + text: 'Throw error in switch default case.', + setup: 'function handleStatus(code) { switch(code) { case 200: return "OK"; case 404: return "Not Found"; default: throw new Error("Unknown: " + code); } }', + setupCode: 'function handleStatus(code) { switch(code) { case 200: return "OK"; case 404: return "Not Found"; default: throw new Error("Unknown: " + code); } }', + expected: 'Unknown: 500', + sample: 'try { handleStatus(500); } catch (e) { return e.message; }', + hints: ['Unknown code hits default', 'Throws with code in message'], + tags: ['error', 'switch', 'default'], + }, + { + id: 'js-error-070', + category: 'Error Handling', + difficulty: 'medium', + title: 'Error in Getter', + text: 'Handle error thrown by object getter.', + setup: 'const obj = { get value() { throw new Error("Getter failed"); } };', + setupCode: 'const obj = { get value() { throw new Error("Getter failed"); } };', + expected: 'Getter failed', + sample: 'try { obj.value; } catch (e) { return e.message; }', + hints: ['Accessing getter can throw', 'Wrap in try-catch'], + tags: ['error', 'getter', 'properties'], + }, + { + id: 'js-error-071', + category: 'Control Flow', + difficulty: 'medium', + title: 'Error in Setter', + text: 'Handle error thrown by object setter.', + setup: 'const obj = { set value(v) { if (v < 0) throw new Error("Negative not allowed"); } };', + setupCode: 'const obj = { set value(v) { if (v < 0) throw new Error("Negative not allowed"); } };', + expected: 'Negative not allowed', + sample: 'try { obj.value = -1; } catch (e) { return e.message; }', + hints: ['Setter validates input', 'Throws for negative'], + tags: ['error', 'setter', 'validation'], + }, + { + id: 'js-error-072', + category: 'Error Handling', + difficulty: 'medium', + title: 'Proxy Trap Error', + text: 'Handle error from Proxy get trap.', + setup: 'const handler = { get(t, p) { throw new Error("Access denied: " + p); } }; const proxy = new Proxy({}, handler);', + setupCode: 'const handler = { get(t, p) { throw new Error("Access denied: " + p); } }; const proxy = new Proxy({}, handler);', + expected: 'Access denied: secret', + sample: 'try { proxy.secret; } catch (e) { return e.message; }', + hints: ['Proxy trap intercepts access', 'Throws with property name'], + tags: ['error', 'proxy', 'traps'], + }, + { + id: 'js-error-073', + category: 'Error Handling', + difficulty: 'medium', + title: 'Symbol.iterator Error', + text: 'Handle error when iterating non-iterable.', + setup: 'const obj = { [Symbol.iterator]: () => ({ next: () => { throw new Error("Iterator error"); } }) };', + setupCode: 'const obj = { [Symbol.iterator]: () => ({ next: () => { throw new Error("Iterator error"); } }) };', + expected: 'Iterator error', + sample: 'try { [...obj]; } catch (e) { return e.message; }', + hints: ['Spread calls iterator', 'next() throws error'], + tags: ['error', 'iterator', 'spread'], + }, + { + id: 'js-error-074', + category: 'Control Flow', + difficulty: 'medium', + title: 'Generator Error Handling', + text: 'Handle error thrown inside generator.', + setup: 'function* gen() { yield 1; throw new Error("Generator error"); yield 2; }', + setupCode: 'function* gen() { yield 1; throw new Error("Generator error"); yield 2; }', + expected: { values: [1], error: 'Generator error' }, + sample: 'const values = []; const g = gen(); try { values.push(g.next().value); values.push(g.next().value); } catch (e) { return { values, error: e.message }; }', + hints: ['First next succeeds', 'Second next throws'], + tags: ['error', 'generator', 'iteration'], + }, + { + id: 'js-error-075', + category: 'Error Handling', + difficulty: 'medium', + title: 'Assertion Failed Message', + text: 'Catch assertion failure and return custom message.', + setup: 'function assertPositive(n) { if (n <= 0) throw new Error(`Expected positive, got ${n}`); return n; }', + setupCode: 'function assertPositive(n) { if (n <= 0) throw new Error(`Expected positive, got ${n}`); return n; }', + expected: 'Expected positive, got -5', + sample: 'try { assertPositive(-5); } catch (e) { return e.message; }', + hints: ['Negative triggers assertion', 'Message includes the value'], + tags: ['error', 'assertion', 'validation'], + }, + { + id: 'js-error-076', + category: 'Error Handling', + difficulty: 'hard', + title: 'Custom Error Hierarchy', + text: 'Create a hierarchy of errors and check inheritance.', + setup: 'class AppError extends Error { constructor(msg) { super(msg); this.name = "AppError"; } } class NetworkError extends AppError { constructor(msg) { super(msg); this.name = "NetworkError"; } }', + setupCode: 'class AppError extends Error { constructor(msg) { super(msg); this.name = "AppError"; } } class NetworkError extends AppError { constructor(msg) { super(msg); this.name = "NetworkError"; } }', + expected: [true, true, true], + sample: 'const e = new NetworkError("timeout"); return [e instanceof NetworkError, e instanceof AppError, e instanceof Error];', + hints: ['Check all levels of inheritance', 'instanceof checks prototype chain'], + tags: ['error', 'inheritance', 'custom-error'], + }, + { + id: 'js-error-077', + category: 'Error Handling', + difficulty: 'hard', + title: 'Error Factory Pattern', + text: 'Create a factory that produces typed errors.', + setup: 'const errorFactory = { validation: (msg) => { const e = new Error(msg); e.type = "VALIDATION"; return e; }, network: (msg) => { const e = new Error(msg); e.type = "NETWORK"; return e; } };', + setupCode: 'const errorFactory = { validation: (msg) => { const e = new Error(msg); e.type = "VALIDATION"; return e; }, network: (msg) => { const e = new Error(msg); e.type = "NETWORK"; return e; } };', + expected: 'VALIDATION', + sample: 'try { throw errorFactory.validation("Invalid email"); } catch (e) { return e.type; }', + hints: ['Use factory method', 'Access custom type property'], + tags: ['error', 'factory', 'patterns'], + }, + { + id: 'js-error-078', + category: 'Error Handling', + difficulty: 'hard', + title: 'Retry with Error Tracking', + text: 'Implement retry logic that tracks all errors.', + setup: 'let attempts = 0; function unreliable() { attempts++; if (attempts < 3) throw new Error(`Attempt ${attempts}`); return "success"; }', + setupCode: 'let attempts = 0; function unreliable() { attempts++; if (attempts < 3) throw new Error(`Attempt ${attempts}`); return "success"; }', + expected: { result: 'success', errors: ['Attempt 1', 'Attempt 2'] }, + sample: 'const errors = []; while (true) { try { return { result: unreliable(), errors }; } catch (e) { errors.push(e.message); } }', + hints: ['Loop until success', 'Collect errors in array'], + tags: ['error', 'retry', 'tracking'], + }, + { + id: 'js-error-079', + category: 'Error Handling', + difficulty: 'hard', + title: 'Error Serialization', + text: 'Serialize error to JSON-compatible object.', + setup: 'function createError() { const e = new TypeError("Invalid argument"); e.code = "ARG_001"; return e; }', + setupCode: 'function createError() { const e = new TypeError("Invalid argument"); e.code = "ARG_001"; return e; }', + expected: { name: 'TypeError', message: 'Invalid argument', code: 'ARG_001' }, + sample: 'const e = createError(); return { name: e.name, message: e.message, code: e.code };', + hints: ['Extract error properties', 'Build plain object'], + tags: ['error', 'serialization', 'json'], + }, + { + id: 'js-error-080', + category: 'Control Flow', + difficulty: 'hard', + title: 'Deep Optional Chain with Transform', + text: 'Navigate deep optional path and transform result.', + setup: 'const api = { response: { data: { users: [{ profile: { email: "test@example.com" } }] } } };', + setupCode: 'const api = { response: { data: { users: [{ profile: { email: "test@example.com" } }] } } };', + expected: 'TEST@EXAMPLE.COM', + sample: 'api?.response?.data?.users?.[0]?.profile?.email?.toUpperCase() ?? "NO EMAIL"', + hints: ['Chain all the way through', 'Call method at the end'], + tags: ['optional-chaining', 'deep-access', 'transform'], + }, + { + id: 'js-error-081', + category: 'Error Handling', + difficulty: 'hard', + title: 'Error Middleware Chain', + text: 'Pass error through middleware chain, each adding context.', + setup: 'const middlewares = [(e) => { e.context = []; e.context.push("m1"); return e; }, (e) => { e.context.push("m2"); return e; }];', + setupCode: 'const middlewares = [(e) => { e.context = []; e.context.push("m1"); return e; }, (e) => { e.context.push("m2"); return e; }];', + expected: ['m1', 'm2'], + sample: 'let err = new Error("test"); for (const m of middlewares) err = m(err); return err.context;', + hints: ['Chain middleware functions', 'Each modifies error'], + tags: ['error', 'middleware', 'patterns'], + }, + { + id: 'js-error-082', + category: 'Error Handling', + difficulty: 'hard', + title: 'Promise.allSettled Error Extraction', + text: 'Extract all error messages from settled promises.', + setup: 'const promises = [Promise.resolve(1), Promise.reject(new Error("fail1")), Promise.reject(new Error("fail2"))];', + setupCode: 'const promises = [Promise.resolve(1), Promise.reject(new Error("fail1")), Promise.reject(new Error("fail2"))];', + expected: ['fail1', 'fail2'], + sample: 'return Promise.allSettled(promises).then(results => results.filter(r => r.status === "rejected").map(r => r.reason.message));', + hints: ['Use Promise.allSettled', 'Filter rejected, map reasons'], + tags: ['error', 'promises', 'allSettled'], + }, + { + id: 'js-error-083', + category: 'Control Flow', + difficulty: 'hard', + title: 'Nullish with Computed Property', + text: 'Use nullish coalescing with computed property access.', + setup: 'const config = { settings: { theme: null } }; const key = "theme";', + setupCode: 'const config = { settings: { theme: null } }; const key = "theme";', + expected: 'dark', + sample: 'config.settings[key] ?? "dark"', + hints: ['Access with bracket notation', 'Nullish provides default'], + tags: ['nullish-coalescing', 'computed-property', 'dynamic'], + }, + { + id: 'js-error-084', + category: 'Error Handling', + difficulty: 'hard', + title: 'Error Recovery with State', + text: 'Recover from error while maintaining valid state.', + setup: 'let state = { count: 0, errors: [] }; function increment() { state.count++; if (state.count === 2) throw new Error("fail at 2"); }', + setupCode: 'let state = { count: 0, errors: [] }; function increment() { state.count++; if (state.count === 2) throw new Error("fail at 2"); }', + expected: { count: 3, errors: ['fail at 2'] }, + sample: 'for (let i = 0; i < 3; i++) { try { increment(); } catch (e) { state.errors.push(e.message); } } return state;', + hints: ['Continue after error', 'Track errors in state'], + tags: ['error', 'state', 'recovery'], + }, + { + id: 'js-error-085', + category: 'Error Handling', + difficulty: 'hard', + title: 'Async Error Aggregation', + text: 'Aggregate errors from multiple async operations.', + setup: 'const ops = [() => Promise.reject(new Error("op1")), () => Promise.resolve("ok"), () => Promise.reject(new Error("op3"))];', + setupCode: 'const ops = [() => Promise.reject(new Error("op1")), () => Promise.resolve("ok"), () => Promise.reject(new Error("op3"))];', + expected: ['op1', 'op3'], + sample: 'return Promise.all(ops.map(op => op().catch(e => ({ error: e.message })))).then(results => results.filter(r => r.error).map(r => r.error));', + hints: ['Catch each operation individually', 'Mark errors in results'], + tags: ['error', 'async', 'aggregation'], + }, + { + id: 'js-error-086', + category: 'Error Handling', + difficulty: 'hard', + title: 'Transactional Error Handling', + text: 'Rollback changes on error.', + setup: 'let data = [1, 2, 3]; function transaction(fn) { const backup = [...data]; try { fn(); } catch (e) { data = backup; throw e; } }', + setupCode: 'let data = [1, 2, 3]; function transaction(fn) { const backup = [...data]; try { fn(); } catch (e) { data = backup; throw e; } }', + expected: [1, 2, 3], + sample: 'try { transaction(() => { data.push(4); throw new Error("abort"); }); } catch {} return data;', + hints: ['Transaction restores on error', 'Data is rolled back'], + tags: ['error', 'transaction', 'rollback'], + }, + { + id: 'js-error-087', + category: 'Control Flow', + difficulty: 'hard', + title: 'Complex Default Chain', + text: 'Chain multiple defaults with different operators.', + setup: 'const a = undefined; const b = null; const c = ""; const d = "value";', + setupCode: 'const a = undefined; const b = null; const c = ""; const d = "value";', + expected: '', + sample: 'a ?? b ?? c ?? d', + hints: ['?? stops at empty string', 'Empty string is not nullish'], + tags: ['nullish-coalescing', 'chaining', 'falsy'], + }, + { + id: 'js-error-088', + category: 'Error Handling', + difficulty: 'hard', + title: 'Error Context Builder', + text: 'Build error with rich context information.', + setup: 'class ContextError extends Error { constructor(msg, context = {}) { super(msg); this.context = context; this.name = "ContextError"; } addContext(key, value) { this.context[key] = value; return this; } }', + setupCode: 'class ContextError extends Error { constructor(msg, context = {}) { super(msg); this.context = context; this.name = "ContextError"; } addContext(key, value) { this.context[key] = value; return this; } }', + expected: { userId: 123, action: 'save' }, + sample: 'const e = new ContextError("Failed").addContext("userId", 123).addContext("action", "save"); return e.context;', + hints: ['Chain addContext calls', 'Return the context object'], + tags: ['error', 'context', 'builder'], + }, + { + id: 'js-error-089', + category: 'Error Handling', + difficulty: 'hard', + title: 'Deferred Error Handling', + text: 'Collect operations and handle all errors at once.', + setup: 'const operations = [() => 1, () => { throw new Error("fail"); }, () => 3];', + setupCode: 'const operations = [() => 1, () => { throw new Error("fail"); }, () => 3];', + expected: { results: [1, 3], errors: ['fail'] }, + sample: 'const results = [], errors = []; operations.forEach(op => { try { results.push(op()); } catch (e) { errors.push(e.message); } }); return { results, errors };', + hints: ['Try each operation', 'Separate successes from failures'], + tags: ['error', 'deferred', 'batch'], + }, + { + id: 'js-error-090', + category: 'Control Flow', + difficulty: 'hard', + title: 'Optional Chaining with Side Effects', + text: 'Conditionally call function only if object exists.', + setup: 'let called = false; const obj = { notify: () => { called = true; } };', + setupCode: 'let called = false; const obj = { notify: () => { called = true; } };', + expected: true, + sample: 'obj?.notify?.(); return called;', + hints: ['Use ?.() for safe call', 'Check if called was set'], + tags: ['optional-chaining', 'side-effects', 'functions'], + }, + { + id: 'js-error-091', + category: 'Error Handling', + difficulty: 'hard', + title: 'Error Rate Limiter', + text: 'Track error count and throw if too many errors.', + setup: 'const errorTracker = { count: 0, limit: 3, track() { this.count++; if (this.count > this.limit) throw new Error("Too many errors"); } };', + setupCode: 'const errorTracker = { count: 0, limit: 3, track() { this.count++; if (this.count > this.limit) throw new Error("Too many errors"); } };', + expected: 'Too many errors', + sample: 'try { for (let i = 0; i < 5; i++) errorTracker.track(); } catch (e) { return e.message; }', + hints: ['Track exceeds limit', 'Throws on 4th error'], + tags: ['error', 'rate-limiting', 'tracking'], + }, + { + id: 'js-error-092', + category: 'Error Handling', + difficulty: 'hard', + title: 'Async Finally Cleanup', + text: 'Ensure cleanup runs even with async errors.', + setup: 'let cleaned = false; async function work() { throw new Error("async fail"); }', + setupCode: 'let cleaned = false; async function work() { throw new Error("async fail"); }', + expected: true, + sample: 'return work().catch(() => {}).finally(() => { cleaned = true; }).then(() => cleaned);', + hints: ['finally runs after catch', 'Set cleaned in finally'], + tags: ['error', 'async', 'finally'], + }, + { + id: 'js-error-093', + category: 'Control Flow', + difficulty: 'hard', + title: 'Safe Map Operation', + text: 'Map over array, replacing errors with null.', + setup: 'const items = [1, 2, 3]; function process(x) { if (x === 2) throw new Error("bad"); return x * 10; }', + setupCode: 'const items = [1, 2, 3]; function process(x) { if (x === 2) throw new Error("bad"); return x * 10; }', + expected: [10, null, 30], + sample: 'items.map(x => { try { return process(x); } catch { return null; } })', + hints: ['Wrap each map call in try', 'Return null on error'], + tags: ['error', 'map', 'defensive'], + }, + { + id: 'js-error-094', + category: 'Error Handling', + difficulty: 'hard', + title: 'Error Retry with Backoff', + text: 'Simulate retry with increasing delay tracking.', + setup: 'let delays = []; let attempt = 0; function flaky() { attempt++; delays.push(attempt * 100); if (attempt < 3) throw new Error("retry"); return "done"; }', + setupCode: 'let delays = []; let attempt = 0; function flaky() { attempt++; delays.push(attempt * 100); if (attempt < 3) throw new Error("retry"); return "done"; }', + expected: { result: 'done', delays: [100, 200, 300] }, + sample: 'let result; while (!result) { try { result = flaky(); } catch {} } return { result, delays };', + hints: ['Loop until success', 'delays tracks attempts'], + tags: ['error', 'retry', 'backoff'], + }, + { + id: 'js-error-095', + category: 'Error Handling', + difficulty: 'hard', + title: 'Cross-Cutting Error Handler', + text: 'Wrap function to catch and transform all errors.', + setup: 'function withErrorHandler(fn, handler) { return (...args) => { try { return fn(...args); } catch (e) { return handler(e); } }; }', + setupCode: 'function withErrorHandler(fn, handler) { return (...args) => { try { return fn(...args); } catch (e) { return handler(e); } }; }', + expected: 'Error: test error', + sample: 'const risky = () => { throw new Error("test error"); }; const safe = withErrorHandler(risky, e => "Error: " + e.message); return safe();', + hints: ['Use wrapper function', 'Handler transforms error'], + tags: ['error', 'wrapper', 'higher-order'], + }, + { + id: 'js-error-096', + category: 'Control Flow', + difficulty: 'hard', + title: 'Optional Chaining Assignment', + text: 'Check if assignment target exists before assigning.', + setup: 'const obj = { data: { items: [] } };', + setupCode: 'const obj = { data: { items: [] } };', + expected: { data: { items: [1] } }, + sample: 'obj.data?.items?.push(1); return obj;', + hints: ['Use ?. before method call', 'push modifies array'], + tags: ['optional-chaining', 'mutation', 'arrays'], + }, + { + id: 'js-error-097', + category: 'Error Handling', + difficulty: 'hard', + title: 'Error Event Emitter Pattern', + text: 'Emit error events and collect them.', + setup: 'const emitter = { handlers: [], on(h) { this.handlers.push(h); }, emit(e) { this.handlers.forEach(h => h(e)); } };', + setupCode: 'const emitter = { handlers: [], on(h) { this.handlers.push(h); }, emit(e) { this.handlers.forEach(h => h(e)); } };', + expected: ['Error: e1', 'Error: e2'], + sample: 'const errors = []; emitter.on(e => errors.push("Error: " + e)); emitter.emit("e1"); emitter.emit("e2"); return errors;', + hints: ['Register handler first', 'Emit multiple errors'], + tags: ['error', 'events', 'patterns'], + }, + { + id: 'js-error-098', + category: 'Error Handling', + difficulty: 'hard', + title: 'Validation Schema Error', + text: 'Validate object against schema, collect all errors.', + setup: 'const schema = { name: v => v ? null : "Name required", age: v => v > 0 ? null : "Age must be positive" };', + setupCode: 'const schema = { name: v => v ? null : "Name required", age: v => v > 0 ? null : "Age must be positive" };', + expected: ['Name required', 'Age must be positive'], + sample: 'const obj = { name: "", age: -5 }; return Object.entries(schema).map(([k, v]) => v(obj[k])).filter(Boolean);', + hints: ['Run each validator', 'Filter out nulls'], + tags: ['error', 'validation', 'schema'], + }, + { + id: 'js-error-099', + category: 'Control Flow', + difficulty: 'hard', + title: 'Defensive Object Access', + text: 'Safely access nested object with multiple fallbacks.', + setup: 'const response = { status: 200 };', + setupCode: 'const response = { status: 200 };', + expected: 'Unknown', + sample: 'response?.data?.user?.name ?? response?.error?.message ?? "Unknown"', + hints: ['Chain multiple optional paths', 'Use ?? for final default'], + tags: ['optional-chaining', 'fallback', 'defensive'], + }, + { + id: 'js-error-100', + category: 'Error Handling', + difficulty: 'hard', + title: 'Circuit Breaker Pattern', + text: 'Implement simple circuit breaker that opens after failures.', + setup: 'const breaker = { failures: 0, open: false, call(fn) { if (this.open) throw new Error("Circuit open"); try { return fn(); } catch (e) { this.failures++; if (this.failures >= 2) this.open = true; throw e; } } };', + setupCode: 'const breaker = { failures: 0, open: false, call(fn) { if (this.open) throw new Error("Circuit open"); try { return fn(); } catch (e) { this.failures++; if (this.failures >= 2) this.open = true; throw e; } } };', + expected: 'Circuit open', + sample: 'const fail = () => { throw new Error("fail"); }; try { breaker.call(fail); } catch {} try { breaker.call(fail); } catch {} try { breaker.call(fail); } catch (e) { return e.message; }', + hints: ['First two failures count', 'Third call circuit is open'], + tags: ['error', 'circuit-breaker', 'patterns'], + }, + { + id: 'js-error-101', + category: 'Error Handling', + difficulty: 'hard', + title: 'Error Boundary Simulation', + text: 'Create an error boundary that catches and reports errors.', + setup: 'const boundary = { errors: [], wrap(fn) { return (...args) => { try { return { success: true, data: fn(...args) }; } catch (e) { this.errors.push(e.message); return { success: false, error: e.message }; } }; } };', + setupCode: 'const boundary = { errors: [], wrap(fn) { return (...args) => { try { return { success: true, data: fn(...args) }; } catch (e) { this.errors.push(e.message); return { success: false, error: e.message }; } }; } };', + expected: { result: { success: false, error: 'boom' }, tracked: ['boom'] }, + sample: 'const risky = () => { throw new Error("boom"); }; const safe = boundary.wrap(risky); const result = safe(); return { result, tracked: boundary.errors };', + hints: ['Use wrapped function', 'Check both result and tracked'], + tags: ['error', 'boundary', 'patterns'], + }, + { + id: 'js-error-102', + category: 'Control Flow', + difficulty: 'hard', + title: 'Type Coercion Guard', + text: 'Guard against type coercion issues with strict checks.', + setup: 'function strictEquals(a, b) { if (typeof a !== typeof b) throw new TypeError("Type mismatch"); return a === b; }', + setupCode: 'function strictEquals(a, b) { if (typeof a !== typeof b) throw new TypeError("Type mismatch"); return a === b; }', + expected: 'Type mismatch', + sample: 'try { strictEquals(1, "1"); } catch (e) { return e.message; }', + hints: ['Different types throw', 'Number vs string'], + tags: ['error', 'type-guard', 'strict'], + }, + { + id: 'js-error-103', + category: 'Error Handling', + difficulty: 'hard', + title: 'Async Error Chain', + text: 'Chain async operations, each handling previous errors.', + setup: 'async function step1() { throw new Error("step1 failed"); } async function step2() { return "step2 ok"; }', + setupCode: 'async function step1() { throw new Error("step1 failed"); } async function step2() { return "step2 ok"; }', + expected: 'Recovered: step2 ok', + sample: 'return step1().catch(() => step2()).then(r => "Recovered: " + r);', + hints: ['Catch first, chain second', 'Recover in catch'], + tags: ['error', 'async', 'chaining'], + }, + { + id: 'js-error-104', + category: 'Error Handling', + difficulty: 'hard', + title: 'Error Sanitization', + text: 'Remove sensitive information from error before logging.', + setup: 'function sanitizeError(e) { const safe = new Error(e.message.replace(/password=\\w+/, "password=***")); safe.name = e.name; return safe; }', + setupCode: 'function sanitizeError(e) { const safe = new Error(e.message.replace(/password=\\w+/, "password=***")); safe.name = e.name; return safe; }', + expected: 'Failed with password=***', + sample: 'const original = new Error("Failed with password=secret123"); return sanitizeError(original).message;', + hints: ['Password is redacted', 'Message is sanitized'], + tags: ['error', 'security', 'sanitization'], + }, + { + id: 'js-error-105', + category: 'Control Flow', + difficulty: 'hard', + title: 'Safe Reduce Operation', + text: 'Reduce array, skipping elements that throw.', + setup: 'const items = [1, 2, 3, 4]; function addSafe(acc, x) { if (x === 3) throw new Error("skip"); return acc + x; }', + setupCode: 'const items = [1, 2, 3, 4]; function addSafe(acc, x) { if (x === 3) throw new Error("skip"); return acc + x; }', + expected: 7, + sample: 'items.reduce((acc, x) => { try { return addSafe(acc, x); } catch { return acc; } }, 0)', + hints: ['Wrap reduce callback', 'Return accumulator on error'], + tags: ['error', 'reduce', 'defensive'], + }, + { + id: 'js-error-106', + category: 'Error Handling', + difficulty: 'hard', + title: 'Promise Race Error', + text: 'Handle first rejection in Promise.race.', + setup: 'const slow = new Promise(r => setTimeout(() => r("slow"), 100)); const fast = Promise.reject(new Error("fast error"));', + setupCode: 'const slow = new Promise(r => setTimeout(() => r("slow"), 100)); const fast = Promise.reject(new Error("fast error"));', + expected: 'fast error', + sample: 'return Promise.race([slow, fast]).catch(e => e.message);', + hints: ['Rejection wins the race', 'Catch handles rejection'], + tags: ['error', 'promise-race', 'async'], + }, + { + id: 'js-error-107', + category: 'Error Handling', + difficulty: 'hard', + title: 'WeakRef Error Pattern', + text: 'Handle case when WeakRef target is garbage collected.', + setup: 'function getSafe(ref) { const obj = ref.deref(); if (!obj) throw new Error("Object collected"); return obj; }', + setupCode: 'function getSafe(ref) { const obj = ref.deref(); if (!obj) throw new Error("Object collected"); return obj; }', + expected: { name: 'test' }, + sample: 'const obj = { name: "test" }; const ref = new WeakRef(obj); return getSafe(ref);', + hints: ['Object still exists', 'deref returns object'], + tags: ['error', 'weakref', 'memory'], + }, + { + id: 'js-error-108', + category: 'Control Flow', + difficulty: 'hard', + title: 'Abort Controller Error', + text: 'Use AbortController to simulate cancellation error.', + setup: 'const controller = new AbortController();', + setupCode: 'const controller = new AbortController();', + expected: 'AbortError', + sample: 'controller.abort(); try { if (controller.signal.aborted) throw new DOMException("Aborted", "AbortError"); } catch (e) { return e.name; }', + hints: ['Check signal.aborted', 'Throw DOMException'], + tags: ['error', 'abort', 'cancellation'], + }, + { + id: 'js-error-109', + category: 'Error Handling', + difficulty: 'hard', + title: 'Error Stack Manipulation', + text: 'Capture and modify error stack trace.', + setup: 'function captureStack() { const e = new Error("test"); return e.stack.split("\\n").length > 1; }', + setupCode: 'function captureStack() { const e = new Error("test"); return e.stack.split("\\n").length > 1; }', + expected: true, + sample: 'captureStack()', + hints: ['Stack has multiple lines', 'Each line is a frame'], + tags: ['error', 'stack', 'debugging'], + }, + { + id: 'js-error-110', + category: 'Error Handling', + difficulty: 'hard', + title: 'Async Generator Error', + text: 'Handle error in async generator.', + setup: 'async function* asyncGen() { yield 1; throw new Error("async gen error"); }', + setupCode: 'async function* asyncGen() { yield 1; throw new Error("async gen error"); }', + expected: 'async gen error', + sample: 'const gen = asyncGen(); return gen.next().then(() => gen.next()).catch(e => e.message);', + hints: ['First next resolves', 'Second next rejects'], + tags: ['error', 'async-generator', 'iteration'], + }, + // ======================================== + // FUNCTIONAL PROGRAMMING + // ======================================== + { + id: 'js-functional-001', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Pure Function - Double', + text: 'Create a pure function that doubles a number without side effects.', + setup: 'const num = 5;', + setupCode: 'const num = 5;', + expected: 10, + sample: 'const double = x => x * 2; double(num)', + hints: ['Pure functions always return the same output for same input', 'No external state modification'], + tags: ['functional', 'pure-function', 'basics'], + }, + { + id: 'js-functional-002', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Immutable Array Update', + text: 'Add an element to the array without mutating the original.', + setup: 'const arr = [1, 2, 3];', + setupCode: 'const arr = [1, 2, 3];', + expected: [1, 2, 3, 4], + sample: '[...arr, 4]', + hints: ['Use spread operator', 'Create a new array'], + tags: ['functional', 'immutability', 'spread'], + }, + { + id: 'js-functional-003', + category: 'Higher-Order Functions', + difficulty: 'easy', + title: 'Simple Map Transformation', + text: 'Use map to square each number in the array.', + setup: 'const nums = [1, 2, 3, 4];', + setupCode: 'const nums = [1, 2, 3, 4];', + expected: [1, 4, 9, 16], + sample: 'nums.map(x => x * x)', + hints: ['map transforms each element', 'Return the squared value'], + tags: ['functional', 'map', 'higher-order'], + }, + { + id: 'js-functional-004', + category: 'Higher-Order Functions', + difficulty: 'easy', + title: 'Filter with Predicate', + text: 'Filter numbers greater than 5 using a predicate function.', + setup: 'const nums = [2, 7, 3, 9, 1, 8];', + setupCode: 'const nums = [2, 7, 3, 9, 1, 8];', + expected: [7, 9, 8], + sample: 'const greaterThan5 = x => x > 5; nums.filter(greaterThan5)', + hints: ['Define the predicate separately', 'Pass function reference to filter'], + tags: ['functional', 'filter', 'predicate'], + }, + { + id: 'js-functional-005', + category: 'Higher-Order Functions', + difficulty: 'easy', + title: 'Reduce to Sum', + text: 'Use reduce to calculate the sum of all numbers.', + setup: 'const nums = [1, 2, 3, 4, 5];', + setupCode: 'const nums = [1, 2, 3, 4, 5];', + expected: 15, + sample: 'nums.reduce((acc, x) => acc + x, 0)', + hints: ['reduce accumulates a single value', 'Start with initial value 0'], + tags: ['functional', 'reduce', 'accumulator'], + }, + { + id: 'js-functional-006', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Identity Function', + text: 'Create an identity function that returns its input unchanged.', + setup: 'const value = "hello";', + setupCode: 'const value = "hello";', + expected: 'hello', + sample: 'const identity = x => x; identity(value)', + hints: ['Return exactly what you receive', 'Simplest pure function'], + tags: ['functional', 'identity', 'basics'], + }, + { + id: 'js-functional-007', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Constant Function', + text: 'Create a function that always returns the same value regardless of input.', + setup: 'const inputs = [1, 2, 3];', + setupCode: 'const inputs = [1, 2, 3];', + expected: [42, 42, 42], + sample: 'const always = x => () => x; inputs.map(always(42))', + hints: ['Return a function that ignores its argument', 'Closure captures the constant'], + tags: ['functional', 'constant', 'closure'], + }, + { + id: 'js-functional-008', + category: 'Closures', + difficulty: 'easy', + title: 'Simple Counter Closure', + text: 'Create a counter using closures that increments each time called.', + setup: 'let result = [];', + setupCode: 'let result = [];', + expected: [1, 2, 3], + sample: 'const makeCounter = () => { let count = 0; return () => ++count; }; const counter = makeCounter(); result = [counter(), counter(), counter()]', + hints: ['Inner function captures outer variable', 'Each call modifies the closed-over variable'], + tags: ['functional', 'closure', 'counter'], + }, + { + id: 'js-functional-009', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Negate Function', + text: 'Create a function that negates a boolean predicate.', + setup: 'const isEven = x => x % 2 === 0; const nums = [1, 2, 3, 4];', + setupCode: 'const isEven = x => x % 2 === 0; const nums = [1, 2, 3, 4];', + expected: [1, 3], + sample: 'const negate = fn => x => !fn(x); nums.filter(negate(isEven))', + hints: ['Return a new function that negates result', 'Apply the original function and negate'], + tags: ['functional', 'negate', 'predicate'], + }, + { + id: 'js-functional-010', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Immutable Object Update', + text: 'Update the age property without mutating the original object.', + setup: 'const person = { name: "Alice", age: 25 };', + setupCode: 'const person = { name: "Alice", age: 25 };', + expected: { name: 'Alice', age: 26 }, + sample: '({ ...person, age: person.age + 1 })', + hints: ['Spread the original object', 'Override the specific property'], + tags: ['functional', 'immutability', 'object'], + }, + { + id: 'js-functional-011', + category: 'Higher-Order Functions', + difficulty: 'easy', + title: 'Every Check', + text: 'Check if every number in the array is positive.', + setup: 'const nums = [1, 2, 3, 4, 5];', + setupCode: 'const nums = [1, 2, 3, 4, 5];', + expected: true, + sample: 'nums.every(x => x > 0)', + hints: ['every returns true if all elements pass', 'Short-circuits on first false'], + tags: ['functional', 'every', 'predicate'], + }, + { + id: 'js-functional-012', + category: 'Higher-Order Functions', + difficulty: 'easy', + title: 'Some Check', + text: 'Check if at least one number is greater than 10.', + setup: 'const nums = [3, 7, 12, 5];', + setupCode: 'const nums = [3, 7, 12, 5];', + expected: true, + sample: 'nums.some(x => x > 10)', + hints: ['some returns true if any element passes', 'Short-circuits on first true'], + tags: ['functional', 'some', 'predicate'], + }, + { + id: 'js-functional-013', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Apply Function to Array', + text: 'Apply Math.max to an array using spread.', + setup: 'const nums = [3, 7, 2, 9, 4];', + setupCode: 'const nums = [3, 7, 2, 9, 4];', + expected: 9, + sample: 'Math.max(...nums)', + hints: ['Spread converts array to arguments', 'Math.max takes multiple arguments'], + tags: ['functional', 'apply', 'spread'], + }, + { + id: 'js-functional-014', + category: 'Functional Programming', + difficulty: 'easy', + title: 'First Element Extractor', + text: 'Create a function that extracts the first element of an array.', + setup: 'const arr = [5, 10, 15];', + setupCode: 'const arr = [5, 10, 15];', + expected: 5, + sample: 'const head = ([first]) => first; head(arr)', + hints: ['Use destructuring in parameter', 'Return just the first element'], + tags: ['functional', 'destructuring', 'head'], + }, + { + id: 'js-functional-015', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Tail of Array', + text: 'Create a function that returns all elements except the first.', + setup: 'const arr = [1, 2, 3, 4];', + setupCode: 'const arr = [1, 2, 3, 4];', + expected: [2, 3, 4], + sample: 'const tail = ([, ...rest]) => rest; tail(arr)', + hints: ['Use rest parameter in destructuring', 'Skip the first element'], + tags: ['functional', 'destructuring', 'tail'], + }, + { + id: 'js-functional-016', + category: 'Higher-Order Functions', + difficulty: 'easy', + title: 'Find First Match', + text: 'Find the first number greater than 5.', + setup: 'const nums = [2, 4, 6, 8, 10];', + setupCode: 'const nums = [2, 4, 6, 8, 10];', + expected: 6, + sample: 'nums.find(x => x > 5)', + hints: ['find returns first matching element', 'Returns undefined if none found'], + tags: ['functional', 'find', 'search'], + }, + { + id: 'js-functional-017', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Flatten One Level', + text: 'Flatten a nested array by one level.', + setup: 'const nested = [[1, 2], [3, 4], [5]];', + setupCode: 'const nested = [[1, 2], [3, 4], [5]];', + expected: [1, 2, 3, 4, 5], + sample: 'nested.flat()', + hints: ['flat() flattens one level by default', 'Can also use flatMap or reduce'], + tags: ['functional', 'flat', 'array'], + }, + { + id: 'js-functional-018', + category: 'Higher-Order Functions', + difficulty: 'easy', + title: 'FlatMap Basic', + text: 'Use flatMap to duplicate each number.', + setup: 'const nums = [1, 2, 3];', + setupCode: 'const nums = [1, 2, 3];', + expected: [1, 1, 2, 2, 3, 3], + sample: 'nums.flatMap(x => [x, x])', + hints: ['flatMap maps then flattens', 'Return an array from the callback'], + tags: ['functional', 'flatMap', 'array'], + }, + { + id: 'js-functional-019', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Last Element', + text: 'Get the last element of an array functionally.', + setup: 'const arr = [1, 2, 3, 4, 5];', + setupCode: 'const arr = [1, 2, 3, 4, 5];', + expected: 5, + sample: 'arr.at(-1)', + hints: ['at() accepts negative indices', 'Or use slice(-1)[0]'], + tags: ['functional', 'at', 'array'], + }, + { + id: 'js-functional-020', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Reverse Immutably', + text: 'Reverse an array without mutating the original.', + setup: 'const arr = [1, 2, 3];', + setupCode: 'const arr = [1, 2, 3];', + expected: [3, 2, 1], + sample: '[...arr].reverse()', + hints: ['Copy first with spread', 'Then apply reverse'], + tags: ['functional', 'immutability', 'reverse'], + }, + { + id: 'js-functional-021', + category: 'Closures', + difficulty: 'medium', + title: 'Private State with Closure', + text: 'Create a bank account with private balance using closure.', + setup: 'let result;', + setupCode: 'let result;', + expected: { balance: 150, canWithdraw: true }, + sample: 'const createAccount = (initial) => { let balance = initial; return { deposit: amt => balance += amt, withdraw: amt => balance -= amt, getBalance: () => balance }; }; const acc = createAccount(100); acc.deposit(100); acc.withdraw(50); result = { balance: acc.getBalance(), canWithdraw: acc.getBalance() > 0 }', + hints: ['Closure hides the balance variable', 'Return object with methods to access it'], + tags: ['functional', 'closure', 'encapsulation'], + }, + { + id: 'js-functional-022', + category: 'Higher-Order Functions', + difficulty: 'medium', + title: 'Custom Map Implementation', + text: 'Implement your own map function using reduce.', + setup: 'const nums = [1, 2, 3];', + setupCode: 'const nums = [1, 2, 3];', + expected: [2, 4, 6], + sample: 'const myMap = (arr, fn) => arr.reduce((acc, x) => [...acc, fn(x)], []); myMap(nums, x => x * 2)', + hints: ['reduce can build any data structure', 'Accumulate transformed elements'], + tags: ['functional', 'map', 'reduce', 'implementation'], + }, + { + id: 'js-functional-023', + category: 'Higher-Order Functions', + difficulty: 'medium', + title: 'Custom Filter Implementation', + text: 'Implement your own filter function using reduce.', + setup: 'const nums = [1, 2, 3, 4, 5, 6];', + setupCode: 'const nums = [1, 2, 3, 4, 5, 6];', + expected: [2, 4, 6], + sample: 'const myFilter = (arr, pred) => arr.reduce((acc, x) => pred(x) ? [...acc, x] : acc, []); myFilter(nums, x => x % 2 === 0)', + hints: ['Only add element if predicate is true', 'Use ternary in reduce'], + tags: ['functional', 'filter', 'reduce', 'implementation'], + }, + { + id: 'js-functional-024', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Simple Compose', + text: 'Compose two functions: add 1, then multiply by 2.', + setup: 'const add1 = x => x + 1; const mult2 = x => x * 2; const num = 5;', + setupCode: 'const add1 = x => x + 1; const mult2 = x => x * 2; const num = 5;', + expected: 12, + sample: 'const compose = (f, g) => x => f(g(x)); compose(mult2, add1)(num)', + hints: ['compose applies right to left', 'g runs first, then f'], + tags: ['functional', 'compose', 'composition'], + }, + { + id: 'js-functional-025', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Simple Pipe', + text: 'Pipe two functions: multiply by 2, then add 1.', + setup: 'const add1 = x => x + 1; const mult2 = x => x * 2; const num = 5;', + setupCode: 'const add1 = x => x + 1; const mult2 = x => x * 2; const num = 5;', + expected: 11, + sample: 'const pipe = (f, g) => x => g(f(x)); pipe(mult2, add1)(num)', + hints: ['pipe applies left to right', 'f runs first, then g'], + tags: ['functional', 'pipe', 'composition'], + }, + { + id: 'js-functional-026', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Curried Add', + text: 'Create a curried add function.', + setup: 'const result = [];', + setupCode: 'const result = [];', + expected: [5, 7, 10], + sample: 'const add = a => b => a + b; const add3 = add(3); result.push(add3(2), add3(4), add(5)(5))', + hints: ['Return a function that takes second arg', 'Partial application creates specialized functions'], + tags: ['functional', 'currying', 'partial-application'], + }, + { + id: 'js-functional-027', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Curried Multiply', + text: 'Create a curried multiply function and use it with map.', + setup: 'const nums = [1, 2, 3, 4];', + setupCode: 'const nums = [1, 2, 3, 4];', + expected: [3, 6, 9, 12], + sample: 'const multiply = a => b => a * b; nums.map(multiply(3))', + hints: ['multiply(3) returns a function', 'That function multiplies its arg by 3'], + tags: ['functional', 'currying', 'map'], + }, + { + id: 'js-functional-028', + category: 'Closures', + difficulty: 'medium', + title: 'Function Factory', + text: 'Create a function that generates greeting functions.', + setup: 'let greetings;', + setupCode: 'let greetings;', + expected: ['Hello, World!', 'Hi, World!', 'Hello, Alice!'], + sample: 'const makeGreeter = greeting => name => `${greeting}, ${name}!`; const sayHello = makeGreeter("Hello"); const sayHi = makeGreeter("Hi"); greetings = [sayHello("World"), sayHi("World"), sayHello("Alice")]', + hints: ['Outer function captures greeting', 'Inner function uses both variables'], + tags: ['functional', 'closure', 'factory'], + }, + { + id: 'js-functional-029', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Partial Application', + text: 'Implement a partial application helper.', + setup: 'const add3 = (a, b, c) => a + b + c;', + setupCode: 'const add3 = (a, b, c) => a + b + c;', + expected: 15, + sample: 'const partial = (fn, ...args) => (...more) => fn(...args, ...more); partial(add3, 5, 5)(5)', + hints: ['Capture initial arguments', 'Combine with later arguments'], + tags: ['functional', 'partial-application', 'spread'], + }, + { + id: 'js-functional-030', + category: 'Higher-Order Functions', + difficulty: 'medium', + title: 'Reduce to Object', + text: 'Convert an array of pairs to an object using reduce.', + setup: 'const pairs = [["a", 1], ["b", 2], ["c", 3]];', + setupCode: 'const pairs = [["a", 1], ["b", 2], ["c", 3]];', + expected: { a: 1, b: 2, c: 3 }, + sample: 'pairs.reduce((obj, [k, v]) => ({ ...obj, [k]: v }), {})', + hints: ['Destructure each pair', 'Spread accumulator and add new key'], + tags: ['functional', 'reduce', 'object'], + }, + { + id: 'js-functional-031', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Memoize Simple', + text: 'Create a simple memoization function for single-argument functions.', + setup: 'let callCount = 0; const expensive = x => { callCount++; return x * 2; };', + setupCode: 'let callCount = 0; const expensive = x => { callCount++; return x * 2; };', + expected: { results: [10, 10, 20], calls: 2 }, + sample: 'const memoize = fn => { const cache = {}; return x => x in cache ? cache[x] : cache[x] = fn(x); }; const memoized = memoize(expensive); const results = [memoized(5), memoized(5), memoized(10)]; ({ results, calls: callCount })', + hints: ['Store results in a cache object', 'Check cache before calling function'], + tags: ['functional', 'memoization', 'cache'], + }, + { + id: 'js-functional-032', + category: 'Higher-Order Functions', + difficulty: 'medium', + title: 'Group By', + text: 'Group array elements by the result of a function.', + setup: 'const nums = [1, 2, 3, 4, 5, 6];', + setupCode: 'const nums = [1, 2, 3, 4, 5, 6];', + expected: { odd: [1, 3, 5], even: [2, 4, 6] }, + sample: 'nums.reduce((groups, n) => { const key = n % 2 === 0 ? "even" : "odd"; groups[key] = [...(groups[key] || []), n]; return groups; }, {})', + hints: ['Determine group key for each element', 'Initialize group array if needed'], + tags: ['functional', 'reduce', 'groupBy'], + }, + { + id: 'js-functional-033', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Flip Arguments', + text: 'Create a function that flips the first two arguments of a function.', + setup: 'const divide = (a, b) => a / b;', + setupCode: 'const divide = (a, b) => a / b;', + expected: 2, + sample: 'const flip = fn => (a, b, ...rest) => fn(b, a, ...rest); flip(divide)(5, 10)', + hints: ['Swap first two parameters', 'Pass rest unchanged'], + tags: ['functional', 'flip', 'higher-order'], + }, + { + id: 'js-functional-034', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Once Function', + text: 'Create a function that only runs once, returning cached result on subsequent calls.', + setup: 'let counter = 0;', + setupCode: 'let counter = 0;', + expected: { results: [1, 1, 1], counter: 1 }, + sample: 'const once = fn => { let called = false, result; return (...args) => called ? result : (called = true, result = fn(...args)); }; const increment = once(() => ++counter); const results = [increment(), increment(), increment()]; ({ results, counter })', + hints: ['Track if function was called', 'Cache and return the result'], + tags: ['functional', 'once', 'closure'], + }, + { + id: 'js-functional-035', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Tap Function', + text: 'Create a tap function for side effects in a pipeline.', + setup: 'let logged = []; const nums = [1, 2, 3];', + setupCode: 'let logged = []; const nums = [1, 2, 3];', + expected: { result: [2, 4, 6], logged: [2, 4, 6] }, + sample: 'const tap = fn => x => { fn(x); return x; }; const result = nums.map(x => x * 2).map(tap(x => logged.push(x))); ({ result, logged })', + hints: ['Execute side effect', 'Return original value unchanged'], + tags: ['functional', 'tap', 'side-effect'], + }, + { + id: 'js-functional-036', + category: 'Recursion', + difficulty: 'medium', + title: 'Recursive Sum', + text: 'Calculate sum of array using recursion.', + setup: 'const nums = [1, 2, 3, 4, 5];', + setupCode: 'const nums = [1, 2, 3, 4, 5];', + expected: 15, + sample: 'const sum = ([head, ...tail]) => head === undefined ? 0 : head + sum(tail); sum(nums)', + hints: ['Base case: empty array returns 0', 'Recursive: head plus sum of tail'], + tags: ['functional', 'recursion', 'sum'], + }, + { + id: 'js-functional-037', + category: 'Recursion', + difficulty: 'medium', + title: 'Recursive Map', + text: 'Implement map using recursion.', + setup: 'const nums = [1, 2, 3];', + setupCode: 'const nums = [1, 2, 3];', + expected: [2, 4, 6], + sample: 'const map = (fn, [head, ...tail]) => head === undefined ? [] : [fn(head), ...map(fn, tail)]; map(x => x * 2, nums)', + hints: ['Transform head, recurse on tail', 'Base case returns empty array'], + tags: ['functional', 'recursion', 'map'], + }, + { + id: 'js-functional-038', + category: 'Recursion', + difficulty: 'medium', + title: 'Recursive Filter', + text: 'Implement filter using recursion.', + setup: 'const nums = [1, 2, 3, 4, 5, 6];', + setupCode: 'const nums = [1, 2, 3, 4, 5, 6];', + expected: [2, 4, 6], + sample: 'const filter = (pred, [head, ...tail]) => head === undefined ? [] : pred(head) ? [head, ...filter(pred, tail)] : filter(pred, tail); filter(x => x % 2 === 0, nums)', + hints: ['Include head only if predicate passes', 'Always recurse on tail'], + tags: ['functional', 'recursion', 'filter'], + }, + { + id: 'js-functional-039', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Zip Arrays', + text: 'Combine two arrays element-wise into pairs.', + setup: 'const a = [1, 2, 3]; const b = ["a", "b", "c"];', + setupCode: 'const a = [1, 2, 3]; const b = ["a", "b", "c"];', + expected: [[1, 'a'], [2, 'b'], [3, 'c']], + sample: 'a.map((x, i) => [x, b[i]])', + hints: ['Use index to access corresponding element', 'Map creates the pairs'], + tags: ['functional', 'zip', 'array'], + }, + { + id: 'js-functional-040', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Unzip Pairs', + text: 'Split an array of pairs into two separate arrays.', + setup: 'const pairs = [[1, "a"], [2, "b"], [3, "c"]];', + setupCode: 'const pairs = [[1, "a"], [2, "b"], [3, "c"]];', + expected: [[1, 2, 3], ['a', 'b', 'c']], + sample: 'pairs.reduce((acc, [a, b]) => [[...acc[0], a], [...acc[1], b]], [[], []])', + hints: ['Accumulate into two arrays', 'Destructure each pair'], + tags: ['functional', 'unzip', 'reduce'], + }, + { + id: 'js-functional-041', + category: 'Higher-Order Functions', + difficulty: 'medium', + title: 'Partition Array', + text: 'Split array into two based on predicate - passing and failing.', + setup: 'const nums = [1, 2, 3, 4, 5, 6];', + setupCode: 'const nums = [1, 2, 3, 4, 5, 6];', + expected: [[2, 4, 6], [1, 3, 5]], + sample: 'const partition = (pred, arr) => arr.reduce(([pass, fail], x) => pred(x) ? [[...pass, x], fail] : [pass, [...fail, x]], [[], []]); partition(x => x % 2 === 0, nums)', + hints: ['Track two arrays in accumulator', 'Add to appropriate array based on predicate'], + tags: ['functional', 'partition', 'reduce'], + }, + { + id: 'js-functional-042', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Pipe Multiple Functions', + text: 'Create a pipe function that composes multiple functions left-to-right.', + setup: 'const add1 = x => x + 1; const mult2 = x => x * 2; const sub3 = x => x - 3;', + setupCode: 'const add1 = x => x + 1; const mult2 = x => x * 2; const sub3 = x => x - 3;', + expected: 9, + sample: 'const pipe = (...fns) => x => fns.reduce((v, fn) => fn(v), x); pipe(add1, mult2, sub3)(5)', + hints: ['reduce over functions', 'Each function transforms the value'], + tags: ['functional', 'pipe', 'reduce'], + }, + { + id: 'js-functional-043', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Compose Multiple Functions', + text: 'Create a compose function that composes multiple functions right-to-left.', + setup: 'const add1 = x => x + 1; const mult2 = x => x * 2; const sub3 = x => x - 3;', + setupCode: 'const add1 = x => x + 1; const mult2 = x => x * 2; const sub3 = x => x - 3;', + expected: 5, + sample: 'const compose = (...fns) => x => fns.reduceRight((v, fn) => fn(v), x); compose(add1, mult2, sub3)(5)', + hints: ['reduceRight for right-to-left', 'Same as pipe but reversed'], + tags: ['functional', 'compose', 'reduceRight'], + }, + { + id: 'js-functional-044', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Deep Clone Object', + text: 'Create a deep clone without mutation using JSON methods.', + setup: 'const obj = { a: 1, b: { c: 2 } };', + setupCode: 'const obj = { a: 1, b: { c: 2 } };', + expected: true, + sample: 'const clone = JSON.parse(JSON.stringify(obj)); clone.b.c = 99; obj.b.c === 2', + hints: ['JSON stringify then parse', 'Creates completely new object'], + tags: ['functional', 'immutability', 'clone'], + }, + { + id: 'js-functional-045', + category: 'Higher-Order Functions', + difficulty: 'medium', + title: 'Take N Elements', + text: 'Create a function that takes the first n elements.', + setup: 'const nums = [1, 2, 3, 4, 5];', + setupCode: 'const nums = [1, 2, 3, 4, 5];', + expected: [1, 2, 3], + sample: 'const take = n => arr => arr.slice(0, n); take(3)(nums)', + hints: ['slice does not mutate', 'Curried for partial application'], + tags: ['functional', 'take', 'slice'], + }, + { + id: 'js-functional-046', + category: 'Higher-Order Functions', + difficulty: 'medium', + title: 'Drop N Elements', + text: 'Create a function that drops the first n elements.', + setup: 'const nums = [1, 2, 3, 4, 5];', + setupCode: 'const nums = [1, 2, 3, 4, 5];', + expected: [4, 5], + sample: 'const drop = n => arr => arr.slice(n); drop(3)(nums)', + hints: ['slice from index n to end', 'Curried for composition'], + tags: ['functional', 'drop', 'slice'], + }, + { + id: 'js-functional-047', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Prop Getter', + text: 'Create a curried function to get a property from objects.', + setup: 'const users = [{ name: "Alice" }, { name: "Bob" }];', + setupCode: 'const users = [{ name: "Alice" }, { name: "Bob" }];', + expected: ['Alice', 'Bob'], + sample: 'const prop = key => obj => obj[key]; users.map(prop("name"))', + hints: ['Return function that accesses the key', 'Perfect for mapping'], + tags: ['functional', 'prop', 'currying'], + }, + { + id: 'js-functional-048', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Pluck Values', + text: 'Extract a specific property from each object in array.', + setup: 'const items = [{ id: 1, val: "a" }, { id: 2, val: "b" }];', + setupCode: 'const items = [{ id: 1, val: "a" }, { id: 2, val: "b" }];', + expected: [1, 2], + sample: 'const pluck = key => arr => arr.map(obj => obj[key]); pluck("id")(items)', + hints: ['Combine map with property access', 'Curried for reusability'], + tags: ['functional', 'pluck', 'map'], + }, + { + id: 'js-functional-049', + category: 'Higher-Order Functions', + difficulty: 'medium', + title: 'Sort By Property', + text: 'Create a curried sort function for object properties.', + setup: 'const users = [{ name: "Charlie" }, { name: "Alice" }, { name: "Bob" }];', + setupCode: 'const users = [{ name: "Charlie" }, { name: "Alice" }, { name: "Bob" }];', + expected: [{ name: 'Alice' }, { name: 'Bob' }, { name: 'Charlie' }], + sample: 'const sortBy = key => arr => [...arr].sort((a, b) => a[key] > b[key] ? 1 : -1); sortBy("name")(users)', + hints: ['Copy array before sorting', 'Compare property values'], + tags: ['functional', 'sort', 'immutability'], + }, + { + id: 'js-functional-050', + category: 'Higher-Order Functions', + difficulty: 'medium', + title: 'Find Index with Predicate', + text: 'Find the index of first element matching a predicate.', + setup: 'const nums = [1, 3, 5, 8, 9];', + setupCode: 'const nums = [1, 3, 5, 8, 9];', + expected: 3, + sample: 'nums.findIndex(x => x % 2 === 0)', + hints: ['findIndex returns index not element', 'Returns -1 if not found'], + tags: ['functional', 'findIndex', 'predicate'], + }, + { + id: 'js-functional-051', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Range Generator', + text: 'Create a function that generates a range of numbers.', + setup: 'let range;', + setupCode: 'let range;', + expected: [0, 1, 2, 3, 4], + sample: 'range = Array.from({ length: 5 }, (_, i) => i)', + hints: ['Array.from takes a length', 'Map function receives index'], + tags: ['functional', 'range', 'generator'], + }, + { + id: 'js-functional-052', + category: 'Closures', + difficulty: 'medium', + title: 'Accumulator Closure', + text: 'Create a function that accumulates values over multiple calls.', + setup: 'let result;', + setupCode: 'let result;', + expected: [5, 15, 35], + sample: 'const makeAccumulator = () => { let total = 0; return n => total += n; }; const acc = makeAccumulator(); result = [acc(5), acc(10), acc(20)]', + hints: ['Closure maintains running total', 'Each call adds to total'], + tags: ['functional', 'closure', 'accumulator'], + }, + { + id: 'js-functional-053', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Object From Entries', + text: 'Convert key-value entries back to object functionally.', + setup: 'const entries = [["x", 10], ["y", 20]];', + setupCode: 'const entries = [["x", 10], ["y", 20]];', + expected: { x: 10, y: 20 }, + sample: 'Object.fromEntries(entries)', + hints: ['Inverse of Object.entries', 'Built-in functional method'], + tags: ['functional', 'object', 'fromEntries'], + }, + { + id: 'js-functional-054', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Transform Object Values', + text: 'Double all values in an object without mutation.', + setup: 'const obj = { a: 1, b: 2, c: 3 };', + setupCode: 'const obj = { a: 1, b: 2, c: 3 };', + expected: { a: 2, b: 4, c: 6 }, + sample: 'Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, v * 2]))', + hints: ['Convert to entries, transform, convert back', 'Entries are [key, value] pairs'], + tags: ['functional', 'object', 'transformation'], + }, + { + id: 'js-functional-055', + category: 'Higher-Order Functions', + difficulty: 'medium', + title: 'Filter Object Keys', + text: 'Keep only object keys that start with underscore.', + setup: 'const obj = { _id: 1, name: "test", _type: "user" };', + setupCode: 'const obj = { _id: 1, name: "test", _type: "user" };', + expected: { _id: 1, _type: 'user' }, + sample: 'Object.fromEntries(Object.entries(obj).filter(([k]) => k.startsWith("_")))', + hints: ['Filter entries by key', 'Destructure to get key only'], + tags: ['functional', 'object', 'filter'], + }, + { + id: 'js-functional-056', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Generic Curry Function', + text: 'Implement a curry function that works with any number of arguments.', + setup: 'const add4 = (a, b, c, d) => a + b + c + d;', + setupCode: 'const add4 = (a, b, c, d) => a + b + c + d;', + expected: 10, + sample: 'const curry = fn => { const arity = fn.length; return function curried(...args) { return args.length >= arity ? fn(...args) : (...more) => curried(...args, ...more); }; }; curry(add4)(1)(2)(3)(4)', + hints: ['Check if enough arguments received', 'Recursively collect arguments'], + tags: ['functional', 'currying', 'arity'], + }, + { + id: 'js-functional-057', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Uncurry Function', + text: 'Convert a curried function back to regular multi-argument form.', + setup: 'const curriedAdd = a => b => c => a + b + c;', + setupCode: 'const curriedAdd = a => b => c => a + b + c;', + expected: 6, + sample: 'const uncurry = fn => (...args) => args.reduce((f, arg) => f(arg), fn); uncurry(curriedAdd)(1, 2, 3)', + hints: ['Apply arguments one at a time', 'reduce over arguments'], + tags: ['functional', 'uncurry', 'reduce'], + }, + { + id: 'js-functional-058', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Memoize with Multiple Arguments', + text: 'Create a memoization function that handles multiple arguments.', + setup: 'let calls = 0; const expensive = (a, b) => { calls++; return a + b; };', + setupCode: 'let calls = 0; const expensive = (a, b) => { calls++; return a + b; };', + expected: { results: [3, 3, 7], calls: 2 }, + sample: 'const memoize = fn => { const cache = new Map(); return (...args) => { const key = JSON.stringify(args); if (cache.has(key)) return cache.get(key); const result = fn(...args); cache.set(key, result); return result; }; }; const memo = memoize(expensive); const results = [memo(1, 2), memo(1, 2), memo(3, 4)]; ({ results, calls })', + hints: ['Serialize arguments as cache key', 'Use Map for the cache'], + tags: ['functional', 'memoization', 'map'], + }, + { + id: 'js-functional-059', + category: 'Higher-Order Functions', + difficulty: 'hard', + title: 'Debounce Function', + text: 'Implement a debounce that delays function execution.', + setup: 'let calls = [];', + setupCode: 'let calls = [];', + expected: true, + sample: 'const debounce = (fn, delay) => { let timeout; return (...args) => { clearTimeout(timeout); timeout = setTimeout(() => fn(...args), delay); }; }; typeof debounce(() => {}, 100) === "function"', + hints: ['Clear previous timeout', 'Set new timeout each call'], + tags: ['functional', 'debounce', 'timing'], + }, + { + id: 'js-functional-060', + category: 'Higher-Order Functions', + difficulty: 'hard', + title: 'Throttle Function', + text: 'Implement a throttle that limits function calls.', + setup: 'let result;', + setupCode: 'let result;', + expected: true, + sample: 'const throttle = (fn, limit) => { let waiting = false; return (...args) => { if (!waiting) { fn(...args); waiting = true; setTimeout(() => waiting = false, limit); } }; }; result = typeof throttle(() => {}, 100) === "function"', + hints: ['Track if in waiting period', 'Reset flag after delay'], + tags: ['functional', 'throttle', 'timing'], + }, + { + id: 'js-functional-061', + category: 'Recursion', + difficulty: 'hard', + title: 'Deep Flatten Array', + text: 'Flatten a deeply nested array using recursion.', + setup: 'const nested = [1, [2, [3, [4, [5]]]]];', + setupCode: 'const nested = [1, [2, [3, [4, [5]]]]];', + expected: [1, 2, 3, 4, 5], + sample: 'const deepFlatten = arr => arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? deepFlatten(val) : val), []); deepFlatten(nested)', + hints: ['Check if element is array', 'Recursively flatten nested arrays'], + tags: ['functional', 'recursion', 'flatten'], + }, + { + id: 'js-functional-062', + category: 'Recursion', + difficulty: 'hard', + title: 'Recursive Reduce', + text: 'Implement reduce using recursion.', + setup: 'const nums = [1, 2, 3, 4];', + setupCode: 'const nums = [1, 2, 3, 4];', + expected: 10, + sample: 'const reduce = (fn, acc, [head, ...tail]) => head === undefined ? acc : reduce(fn, fn(acc, head), tail); reduce((a, b) => a + b, 0, nums)', + hints: ['Apply function to accumulator and head', 'Pass new accumulator to recursive call'], + tags: ['functional', 'recursion', 'reduce'], + }, + { + id: 'js-functional-063', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Transducer Map', + text: 'Create a mapping transducer that composes with reduce.', + setup: 'const nums = [1, 2, 3];', + setupCode: 'const nums = [1, 2, 3];', + expected: [2, 4, 6], + sample: 'const mapT = fn => reducer => (acc, x) => reducer(acc, fn(x)); const push = (arr, x) => [...arr, x]; nums.reduce(mapT(x => x * 2)(push), [])', + hints: ['Transducer wraps a reducer', 'Transform value before passing to reducer'], + tags: ['functional', 'transducer', 'map'], + }, + { + id: 'js-functional-064', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Transducer Filter', + text: 'Create a filtering transducer.', + setup: 'const nums = [1, 2, 3, 4, 5, 6];', + setupCode: 'const nums = [1, 2, 3, 4, 5, 6];', + expected: [2, 4, 6], + sample: 'const filterT = pred => reducer => (acc, x) => pred(x) ? reducer(acc, x) : acc; const push = (arr, x) => [...arr, x]; nums.reduce(filterT(x => x % 2 === 0)(push), [])', + hints: ['Only call reducer if predicate passes', 'Return unchanged accumulator otherwise'], + tags: ['functional', 'transducer', 'filter'], + }, + { + id: 'js-functional-065', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Compose Transducers', + text: 'Compose multiple transducers together.', + setup: 'const nums = [1, 2, 3, 4, 5, 6];', + setupCode: 'const nums = [1, 2, 3, 4, 5, 6];', + expected: [4, 8, 12], + sample: 'const mapT = fn => r => (a, x) => r(a, fn(x)); const filterT = p => r => (a, x) => p(x) ? r(a, x) : a; const comp = (...fns) => fns.reduce((f, g) => x => f(g(x))); const push = (arr, x) => [...arr, x]; nums.reduce(comp(filterT(x => x % 2 === 0), mapT(x => x * 2))(push), [])', + hints: ['Compose transducers like functions', 'Order matters for transformation'], + tags: ['functional', 'transducer', 'compose'], + }, + { + id: 'js-functional-066', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Functor Map', + text: 'Create a simple functor (container) with map method.', + setup: 'let result;', + setupCode: 'let result;', + expected: 10, + sample: 'const Box = x => ({ map: fn => Box(fn(x)), fold: fn => fn(x) }); result = Box(5).map(x => x * 2).fold(x => x)', + hints: ['Box wraps a value', 'map returns new Box with transformed value'], + tags: ['functional', 'functor', 'container'], + }, + { + id: 'js-functional-067', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Maybe Functor', + text: 'Implement a Maybe functor for null-safe operations.', + setup: 'let results;', + setupCode: 'let results;', + expected: ['HELLO', 'nothing'], + sample: 'const Maybe = x => ({ map: fn => x == null ? Maybe(null) : Maybe(fn(x)), fold: (onNothing, onJust) => x == null ? onNothing() : onJust(x) }); const r1 = Maybe("hello").map(s => s.toUpperCase()).fold(() => "nothing", x => x); const r2 = Maybe(null).map(s => s.toUpperCase()).fold(() => "nothing", x => x); results = [r1, r2]', + hints: ['Check for null before mapping', 'fold handles both cases'], + tags: ['functional', 'maybe', 'functor'], + }, + { + id: 'js-functional-068', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Either Functor', + text: 'Implement Either for error handling.', + setup: 'let results;', + setupCode: 'let results;', + expected: [10, 'Error: Division by zero'], + sample: 'const Right = x => ({ map: fn => Right(fn(x)), fold: (f, g) => g(x) }); const Left = x => ({ map: fn => Left(x), fold: (f, g) => f(x) }); const safeDivide = (a, b) => b === 0 ? Left("Division by zero") : Right(a / b); const r1 = safeDivide(20, 2).fold(e => `Error: ${e}`, x => x); const r2 = safeDivide(20, 0).fold(e => `Error: ${e}`, x => x); results = [r1, r2]', + hints: ['Right maps and folds with success handler', 'Left ignores map and folds with error handler'], + tags: ['functional', 'either', 'error-handling'], + }, + { + id: 'js-functional-069', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Chain/FlatMap for Maybe', + text: 'Add chain method to Maybe for nested operations.', + setup: 'let result;', + setupCode: 'let result;', + expected: 'John Doe', + sample: 'const Maybe = x => ({ map: fn => x == null ? Maybe(null) : Maybe(fn(x)), chain: fn => x == null ? Maybe(null) : fn(x), fold: (n, j) => x == null ? n() : j(x) }); const user = { profile: { name: "John Doe" } }; result = Maybe(user).chain(u => Maybe(u.profile)).chain(p => Maybe(p.name)).fold(() => "No name", x => x)', + hints: ['chain avoids nested Maybes', 'Similar to flatMap'], + tags: ['functional', 'maybe', 'chain', 'monad'], + }, + { + id: 'js-functional-070', + category: 'Recursion', + difficulty: 'hard', + title: 'Tail-Call Optimized Factorial', + text: 'Implement factorial using tail recursion pattern.', + setup: 'let result;', + setupCode: 'let result;', + expected: 120, + sample: 'const factorial = (n, acc = 1) => n <= 1 ? acc : factorial(n - 1, n * acc); result = factorial(5)', + hints: ['Accumulator carries result', 'Last operation is recursive call'], + tags: ['functional', 'recursion', 'tail-call'], + }, + { + id: 'js-functional-071', + category: 'Recursion', + difficulty: 'hard', + title: 'Trampoline for Stack Safety', + text: 'Implement trampoline to avoid stack overflow.', + setup: 'let result;', + setupCode: 'let result;', + expected: 50005000, + sample: 'const trampoline = fn => (...args) => { let result = fn(...args); while (typeof result === "function") result = result(); return result; }; const sumTo = trampoline((n, acc = 0) => n === 0 ? acc : () => sumTo(n - 1, acc + n)); result = sumTo(10000)', + hints: ['Return thunk instead of recursing', 'Loop while result is function'], + tags: ['functional', 'trampoline', 'stack-safe'], + }, + { + id: 'js-functional-072', + category: 'Higher-Order Functions', + difficulty: 'hard', + title: 'Async Compose', + text: 'Compose async functions that return promises.', + setup: 'let result;', + setupCode: 'let result;', + expected: 8, + sample: 'const asyncCompose = (...fns) => x => fns.reduceRight((p, fn) => p.then(fn), Promise.resolve(x)); const add1 = async x => x + 1; const mult2 = async x => x * 2; result = await asyncCompose(mult2, add1, add1)(2)', + hints: ['Chain promises with then', 'reduceRight for right-to-left'], + tags: ['functional', 'async', 'compose'], + }, + { + id: 'js-functional-073', + category: 'Higher-Order Functions', + difficulty: 'hard', + title: 'Async Pipe', + text: 'Pipe async functions left-to-right.', + setup: 'let result;', + setupCode: 'let result;', + expected: 7, + sample: 'const asyncPipe = (...fns) => x => fns.reduce((p, fn) => p.then(fn), Promise.resolve(x)); const add1 = async x => x + 1; const mult2 = async x => x * 2; result = await asyncPipe(add1, mult2, add1)(2)', + hints: ['reduce for left-to-right', 'Each then chains next function'], + tags: ['functional', 'async', 'pipe'], + }, + { + id: 'js-functional-074', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Lens Getter', + text: 'Implement a lens getter for nested property access.', + setup: 'const data = { user: { profile: { name: "Alice" } } };', + setupCode: 'const data = { user: { profile: { name: "Alice" } } };', + expected: 'Alice', + sample: 'const lens = path => ({ get: obj => path.reduce((o, k) => o && o[k], obj) }); lens(["user", "profile", "name"]).get(data)', + hints: ['Reduce over path segments', 'Handle undefined safely'], + tags: ['functional', 'lens', 'getter'], + }, + { + id: 'js-functional-075', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Lens Setter', + text: 'Implement a lens setter for immutable nested updates.', + setup: 'const data = { a: { b: { c: 1 } } };', + setupCode: 'const data = { a: { b: { c: 1 } } };', + expected: { a: { b: { c: 2 } } }, + sample: 'const setPath = (obj, [head, ...tail], val) => ({ ...obj, [head]: tail.length ? setPath(obj[head] || {}, tail, val) : val }); setPath(data, ["a", "b", "c"], 2)', + hints: ['Recursively rebuild object path', 'Spread existing properties'], + tags: ['functional', 'lens', 'setter', 'immutability'], + }, + { + id: 'js-functional-076', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Point-Free Style', + text: 'Refactor to point-free style using compose.', + setup: 'const users = [{ name: "alice" }, { name: "bob" }];', + setupCode: 'const users = [{ name: "alice" }, { name: "bob" }];', + expected: ['ALICE', 'BOB'], + sample: 'const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x); const prop = k => o => o[k]; const toUpper = s => s.toUpperCase(); const getName = compose(toUpper, prop("name")); users.map(getName)', + hints: ['Remove explicit parameter references', 'Build from smaller functions'], + tags: ['functional', 'point-free', 'compose'], + }, + { + id: 'js-functional-077', + category: 'Higher-Order Functions', + difficulty: 'hard', + title: 'Apply to Arguments', + text: 'Create a function that applies an array of functions to corresponding arguments.', + setup: 'const fns = [x => x + 1, x => x * 2, x => x - 1]; const args = [1, 2, 3];', + setupCode: 'const fns = [x => x + 1, x => x * 2, x => x - 1]; const args = [1, 2, 3];', + expected: [2, 4, 2], + sample: 'fns.map((fn, i) => fn(args[i]))', + hints: ['Use index to pair function with argument', 'Map over functions array'], + tags: ['functional', 'applicative', 'map'], + }, + { + id: 'js-functional-078', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Converge Pattern', + text: 'Apply multiple functions to same input and combine results.', + setup: 'const nums = [1, 2, 3, 4, 5];', + setupCode: 'const nums = [1, 2, 3, 4, 5];', + expected: 3, + sample: 'const converge = (combiner, fns) => (...args) => combiner(...fns.map(fn => fn(...args))); const sum = arr => arr.reduce((a, b) => a + b, 0); const len = arr => arr.length; const average = converge((s, l) => s / l, [sum, len]); average(nums)', + hints: ['Apply all functions to input', 'Pass results to combiner'], + tags: ['functional', 'converge', 'combinator'], + }, + { + id: 'js-functional-079', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Use With Pattern', + text: 'Create a useWith combinator that transforms arguments before applying.', + setup: 'const fn = (a, b) => a + b;', + setupCode: 'const fn = (a, b) => a + b;', + expected: 7, + sample: 'const useWith = (fn, transformers) => (...args) => fn(...args.map((arg, i) => transformers[i] ? transformers[i](arg) : arg)); useWith(fn, [x => x * 2, x => x + 1])(2, 2)', + hints: ['Transform each argument with corresponding function', 'Handle missing transformers'], + tags: ['functional', 'useWith', 'combinator'], + }, + { + id: 'js-functional-080', + category: 'Recursion', + difficulty: 'hard', + title: 'Y Combinator', + text: 'Implement the Y combinator for anonymous recursion.', + setup: 'let result;', + setupCode: 'let result;', + expected: 120, + sample: 'const Y = f => (x => f(v => x(x)(v)))(x => f(v => x(x)(v))); const factorial = Y(f => n => n <= 1 ? 1 : n * f(n - 1)); result = factorial(5)', + hints: ['Y enables recursion without naming', 'Pass function reference as parameter'], + tags: ['functional', 'y-combinator', 'recursion'], + }, + { + id: 'js-functional-081', + category: 'Higher-Order Functions', + difficulty: 'hard', + title: 'Unfold Generator', + text: 'Create an unfold function that generates arrays from a seed.', + setup: 'let result;', + setupCode: 'let result;', + expected: [1, 2, 3, 4, 5], + sample: 'const unfold = (fn, seed) => { const result = []; let val = fn(seed); while (val) { result.push(val[0]); val = fn(val[1]); } return result; }; result = unfold(n => n > 5 ? null : [n, n + 1], 1)', + hints: ['Generate value and next seed', 'Return null to stop'], + tags: ['functional', 'unfold', 'generator'], + }, + { + id: 'js-functional-082', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Reader Monad Pattern', + text: 'Implement a Reader pattern for dependency injection.', + setup: 'const config = { multiplier: 3 };', + setupCode: 'const config = { multiplier: 3 };', + expected: 15, + sample: 'const Reader = run => ({ run, map: fn => Reader(env => fn(run(env))), chain: fn => Reader(env => fn(run(env)).run(env)) }); const getMultiplier = Reader(cfg => cfg.multiplier); const compute = x => getMultiplier.map(m => x * m); compute(5).run(config)', + hints: ['Reader delays access to environment', 'run injects the dependency'], + tags: ['functional', 'reader', 'monad'], + }, + { + id: 'js-functional-083', + category: 'Closures', + difficulty: 'hard', + title: 'Module Pattern', + text: 'Create a module with private state using closures.', + setup: 'let result;', + setupCode: 'let result;', + expected: { count: 3, items: ['a', 'b', 'c'] }, + sample: 'const createModule = () => { const items = []; return { add: item => items.push(item), getItems: () => [...items], count: () => items.length }; }; const mod = createModule(); mod.add("a"); mod.add("b"); mod.add("c"); result = { count: mod.count(), items: mod.getItems() }', + hints: ['Private array hidden in closure', 'Public methods access private state'], + tags: ['functional', 'module', 'closure'], + }, + { + id: 'js-functional-084', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Immutable Stack', + text: 'Implement an immutable stack data structure.', + setup: 'let result;', + setupCode: 'let result;', + expected: { top: 3, size: 3 }, + sample: 'const Stack = (items = []) => ({ push: x => Stack([...items, x]), pop: () => Stack(items.slice(0, -1)), peek: () => items[items.length - 1], size: () => items.length }); const stack = Stack().push(1).push(2).push(3); result = { top: stack.peek(), size: stack.size() }', + hints: ['Each operation returns new Stack', 'Never mutate internal array'], + tags: ['functional', 'immutability', 'data-structure'], + }, + { + id: 'js-functional-085', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Lazy Evaluation', + text: 'Implement lazy evaluation for deferred computation.', + setup: 'let computed = 0;', + setupCode: 'let computed = 0;', + expected: { value: 10, computedOnce: 1 }, + sample: 'const lazy = fn => { let cached, done = false; return () => done ? cached : (done = true, cached = fn()); }; const getValue = lazy(() => { computed++; return 10; }); getValue(); getValue(); getValue(); ({ value: getValue(), computedOnce: computed })', + hints: ['Cache result after first call', 'Track if computation happened'], + tags: ['functional', 'lazy', 'memoization'], + }, + { + id: 'js-functional-086', + category: 'Higher-Order Functions', + difficulty: 'easy', + title: 'Call N Times', + text: 'Create a function that calls another function n times.', + setup: 'let count = 0;', + setupCode: 'let count = 0;', + expected: 5, + sample: 'const times = (n, fn) => { for (let i = 0; i < n; i++) fn(i); }; times(5, () => count++); count', + hints: ['Loop n times', 'Optionally pass index to function'], + tags: ['functional', 'times', 'iteration'], + }, + { + id: 'js-functional-087', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Default Value', + text: 'Create a function that provides a default value for nullish values.', + setup: 'const values = [null, 5, undefined, 10];', + setupCode: 'const values = [null, 5, undefined, 10];', + expected: [0, 5, 0, 10], + sample: 'const defaultTo = def => val => val ?? def; values.map(defaultTo(0))', + hints: ['Nullish coalescing handles null/undefined', 'Curried for mapping'], + tags: ['functional', 'default', 'nullish'], + }, + { + id: 'js-functional-088', + category: 'Higher-Order Functions', + difficulty: 'easy', + title: 'Chunk Array', + text: 'Split an array into chunks of specified size.', + setup: 'const nums = [1, 2, 3, 4, 5, 6, 7];', + setupCode: 'const nums = [1, 2, 3, 4, 5, 6, 7];', + expected: [[1, 2, 3], [4, 5, 6], [7]], + sample: 'const chunk = (arr, size) => arr.reduce((chunks, item, i) => { const idx = Math.floor(i / size); chunks[idx] = [...(chunks[idx] || []), item]; return chunks; }, []); chunk(nums, 3)', + hints: ['Calculate chunk index from item index', 'Build chunks in reducer'], + tags: ['functional', 'chunk', 'reduce'], + }, + { + id: 'js-functional-089', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Clamp Value', + text: 'Clamp a value between min and max.', + setup: 'const values = [-5, 0, 5, 10, 15];', + setupCode: 'const values = [-5, 0, 5, 10, 15];', + expected: [0, 0, 5, 10, 10], + sample: 'const clamp = (min, max) => val => Math.min(Math.max(val, min), max); values.map(clamp(0, 10))', + hints: ['Max with min first', 'Then min with max'], + tags: ['functional', 'clamp', 'currying'], + }, + { + id: 'js-functional-090', + category: 'Higher-Order Functions', + difficulty: 'easy', + title: 'Unique Values', + text: 'Get unique values from array using functional approach.', + setup: 'const nums = [1, 2, 2, 3, 3, 3, 4];', + setupCode: 'const nums = [1, 2, 2, 3, 3, 3, 4];', + expected: [1, 2, 3, 4], + sample: '[...new Set(nums)]', + hints: ['Set automatically removes duplicates', 'Spread back to array'], + tags: ['functional', 'unique', 'set'], + }, + { + id: 'js-functional-091', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Boolean Coercion', + text: 'Filter out falsy values from an array.', + setup: 'const mixed = [0, 1, false, 2, "", 3, null, undefined];', + setupCode: 'const mixed = [0, 1, false, 2, "", 3, null, undefined];', + expected: [1, 2, 3], + sample: 'mixed.filter(Boolean)', + hints: ['Boolean as function coerces to boolean', 'Falsy values become false'], + tags: ['functional', 'filter', 'boolean'], + }, + { + id: 'js-functional-092', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Count Occurrences', + text: 'Count occurrences of each element in array.', + setup: 'const items = ["a", "b", "a", "c", "b", "a"];', + setupCode: 'const items = ["a", "b", "a", "c", "b", "a"];', + expected: { a: 3, b: 2, c: 1 }, + sample: 'items.reduce((counts, item) => ({ ...counts, [item]: (counts[item] || 0) + 1 }), {})', + hints: ['Initialize count to 0 if missing', 'Increment for each occurrence'], + tags: ['functional', 'reduce', 'count'], + }, + { + id: 'js-functional-093', + category: 'Higher-Order Functions', + difficulty: 'easy', + title: 'Index Of with Predicate', + text: 'Find index where predicate first returns true.', + setup: 'const nums = [1, 4, 9, 16, 25];', + setupCode: 'const nums = [1, 4, 9, 16, 25];', + expected: 2, + sample: 'nums.findIndex(x => x > 5)', + hints: ['findIndex with predicate', 'Returns -1 if not found'], + tags: ['functional', 'findIndex', 'predicate'], + }, + { + id: 'js-functional-094', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Entries to Object', + text: 'Convert Map entries to plain object.', + setup: 'const map = new Map([["x", 1], ["y", 2]]);', + setupCode: 'const map = new Map([["x", 1], ["y", 2]]);', + expected: { x: 1, y: 2 }, + sample: 'Object.fromEntries(map)', + hints: ['Map is iterable as entries', 'fromEntries converts to object'], + tags: ['functional', 'map', 'object'], + }, + { + id: 'js-functional-095', + category: 'Functional Programming', + difficulty: 'easy', + title: 'Compact Object', + text: 'Remove properties with falsy values from object.', + setup: 'const obj = { a: 1, b: 0, c: null, d: "hello", e: "" };', + setupCode: 'const obj = { a: 1, b: 0, c: null, d: "hello", e: "" };', + expected: { a: 1, d: 'hello' }, + sample: 'Object.fromEntries(Object.entries(obj).filter(([, v]) => Boolean(v)))', + hints: ['Filter entries by value truthiness', 'Destructure to ignore key'], + tags: ['functional', 'object', 'filter'], + }, + { + id: 'js-functional-096', + category: 'Higher-Order Functions', + difficulty: 'medium', + title: 'Reduce Right', + text: 'Use reduceRight to build string from right to left.', + setup: 'const words = ["Hello", "World", "!"];', + setupCode: 'const words = ["Hello", "World", "!"];', + expected: '! World Hello', + sample: 'words.reduceRight((acc, word) => acc + " " + word)', + hints: ['reduceRight starts from last element', 'Accumulates right to left'], + tags: ['functional', 'reduceRight', 'string'], + }, + { + id: 'js-functional-097', + category: 'Closures', + difficulty: 'medium', + title: 'Rate Limiter', + text: 'Create a rate limiter that limits function calls.', + setup: 'let result;', + setupCode: 'let result;', + expected: true, + sample: 'const rateLimit = (fn, limit) => { const calls = []; return (...args) => { const now = Date.now(); while (calls.length && calls[0] < now - 1000) calls.shift(); if (calls.length < limit) { calls.push(now); return fn(...args); } }; }; result = typeof rateLimit(() => {}, 5) === "function"', + hints: ['Track call timestamps', 'Remove old calls outside window'], + tags: ['functional', 'closure', 'rate-limit'], + }, + { + id: 'js-functional-098', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Deep Merge Objects', + text: 'Recursively merge two objects.', + setup: 'const a = { x: 1, y: { z: 2 } }; const b = { y: { w: 3 }, v: 4 };', + setupCode: 'const a = { x: 1, y: { z: 2 } }; const b = { y: { w: 3 }, v: 4 };', + expected: { x: 1, y: { z: 2, w: 3 }, v: 4 }, + sample: 'const deepMerge = (a, b) => { const result = { ...a }; for (const key in b) { result[key] = a[key] && typeof a[key] === "object" && typeof b[key] === "object" ? deepMerge(a[key], b[key]) : b[key]; } return result; }; deepMerge(a, b)', + hints: ['Recurse when both values are objects', 'Otherwise take b value'], + tags: ['functional', 'merge', 'recursion'], + }, + { + id: 'js-functional-099', + category: 'Higher-Order Functions', + difficulty: 'medium', + title: 'Intersection of Arrays', + text: 'Find elements common to both arrays.', + setup: 'const a = [1, 2, 3, 4]; const b = [3, 4, 5, 6];', + setupCode: 'const a = [1, 2, 3, 4]; const b = [3, 4, 5, 6];', + expected: [3, 4], + sample: 'a.filter(x => b.includes(x))', + hints: ['Filter first array', 'Keep elements in second array'], + tags: ['functional', 'intersection', 'filter'], + }, + { + id: 'js-functional-100', + category: 'Higher-Order Functions', + difficulty: 'medium', + title: 'Difference of Arrays', + text: 'Find elements in first array not in second.', + setup: 'const a = [1, 2, 3, 4]; const b = [3, 4, 5, 6];', + setupCode: 'const a = [1, 2, 3, 4]; const b = [3, 4, 5, 6];', + expected: [1, 2], + sample: 'a.filter(x => !b.includes(x))', + hints: ['Filter first array', 'Keep elements NOT in second'], + tags: ['functional', 'difference', 'filter'], + }, + { + id: 'js-functional-101', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Symmetric Difference', + text: 'Find elements in either array but not both.', + setup: 'const a = [1, 2, 3]; const b = [2, 3, 4];', + setupCode: 'const a = [1, 2, 3]; const b = [2, 3, 4];', + expected: [1, 4], + sample: '[...a.filter(x => !b.includes(x)), ...b.filter(x => !a.includes(x))]', + hints: ['Combine both differences', 'Elements exclusive to each array'], + tags: ['functional', 'symmetric-difference', 'array'], + }, + { + id: 'js-functional-102', + category: 'Higher-Order Functions', + difficulty: 'medium', + title: 'Sum By Property', + text: 'Sum array of objects by a specific property.', + setup: 'const items = [{ val: 10 }, { val: 20 }, { val: 30 }];', + setupCode: 'const items = [{ val: 10 }, { val: 20 }, { val: 30 }];', + expected: 60, + sample: 'const sumBy = (arr, key) => arr.reduce((sum, obj) => sum + obj[key], 0); sumBy(items, "val")', + hints: ['Reduce over objects', 'Access property with key'], + tags: ['functional', 'reduce', 'sumBy'], + }, + { + id: 'js-functional-103', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Pick Object Properties', + text: 'Create new object with only specified properties.', + setup: 'const obj = { a: 1, b: 2, c: 3, d: 4 };', + setupCode: 'const obj = { a: 1, b: 2, c: 3, d: 4 };', + expected: { a: 1, c: 3 }, + sample: 'const pick = (obj, keys) => Object.fromEntries(keys.filter(k => k in obj).map(k => [k, obj[k]])); pick(obj, ["a", "c"])', + hints: ['Filter to existing keys', 'Map to entries then convert'], + tags: ['functional', 'pick', 'object'], + }, + { + id: 'js-functional-104', + category: 'Functional Programming', + difficulty: 'medium', + title: 'Omit Object Properties', + text: 'Create new object without specified properties.', + setup: 'const obj = { a: 1, b: 2, c: 3, d: 4 };', + setupCode: 'const obj = { a: 1, b: 2, c: 3, d: 4 };', + expected: { b: 2, d: 4 }, + sample: 'const omit = (obj, keys) => Object.fromEntries(Object.entries(obj).filter(([k]) => !keys.includes(k))); omit(obj, ["a", "c"])', + hints: ['Filter entries by key', 'Exclude keys in the list'], + tags: ['functional', 'omit', 'object'], + }, + { + id: 'js-functional-105', + category: 'Higher-Order Functions', + difficulty: 'medium', + title: 'Map Object Values', + text: 'Apply a function to all values in an object.', + setup: 'const obj = { a: 1, b: 2, c: 3 };', + setupCode: 'const obj = { a: 1, b: 2, c: 3 };', + expected: { a: 2, b: 4, c: 6 }, + sample: 'const mapValues = (obj, fn) => Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, fn(v)])); mapValues(obj, x => x * 2)', + hints: ['Map over entries', 'Transform value, keep key'], + tags: ['functional', 'mapValues', 'object'], + }, + { + id: 'js-functional-106', + category: 'Recursion', + difficulty: 'hard', + title: 'Recursive Object Freeze', + text: 'Deeply freeze an object to make it fully immutable.', + setup: 'const obj = { a: 1, b: { c: 2 } };', + setupCode: 'const obj = { a: 1, b: { c: 2 } };', + expected: true, + sample: 'const deepFreeze = obj => { Object.freeze(obj); Object.values(obj).forEach(v => v && typeof v === "object" && deepFreeze(v)); return obj; }; deepFreeze(obj); Object.isFrozen(obj) && Object.isFrozen(obj.b)', + hints: ['Freeze current object', 'Recursively freeze nested objects'], + tags: ['functional', 'immutability', 'freeze'], + }, + { + id: 'js-functional-107', + category: 'Functional Programming', + difficulty: 'hard', + title: 'State Monad Pattern', + text: 'Implement a simple State monad for stateful computations.', + setup: 'let result;', + setupCode: 'let result;', + expected: { value: 6, state: 3 }, + sample: 'const State = run => ({ run, map: fn => State(s => { const [a, s2] = run(s); return [fn(a), s2]; }), chain: fn => State(s => { const [a, s2] = run(s); return fn(a).run(s2); }) }); const increment = State(s => [s, s + 1]); const compute = increment.chain(a => increment.chain(b => increment.map(c => a + b + c))); result = { value: compute.run(0)[0], state: compute.run(0)[1] }', + hints: ['State wraps function from state to [value, newState]', 'chain threads state through'], + tags: ['functional', 'state', 'monad'], + }, + { + id: 'js-functional-108', + category: 'Functional Programming', + difficulty: 'hard', + title: 'IO Monad Pattern', + text: 'Implement IO monad for side-effect isolation.', + setup: 'let sideEffect = 0;', + setupCode: 'let sideEffect = 0;', + expected: { before: 0, after: 5, result: 10 }, + sample: 'const IO = run => ({ run, map: fn => IO(() => fn(run())), chain: fn => IO(() => fn(run()).run()) }); const before = sideEffect; const io = IO(() => { sideEffect = 5; return 10; }); const result = io.run(); ({ before, after: sideEffect, result })', + hints: ['IO wraps a thunk (function)', 'run executes the side effect'], + tags: ['functional', 'io', 'monad'], + }, + { + id: 'js-functional-109', + category: 'Higher-Order Functions', + difficulty: 'hard', + title: 'Scan (Running Reduce)', + text: 'Implement scan that returns all intermediate reduce values.', + setup: 'const nums = [1, 2, 3, 4, 5];', + setupCode: 'const nums = [1, 2, 3, 4, 5];', + expected: [1, 3, 6, 10, 15], + sample: 'const scan = (fn, init, arr) => arr.reduce((acc, x) => [...acc, fn(acc.length ? acc[acc.length - 1] : init, x)], []); scan((a, b) => a + b, 0, nums)', + hints: ['Store each intermediate result', 'Like reduce but keeps history'], + tags: ['functional', 'scan', 'reduce'], + }, + { + id: 'js-functional-110', + category: 'Functional Programming', + difficulty: 'hard', + title: 'Monad Laws Verification', + text: 'Verify left identity law for a simple monad.', + setup: 'const Box = x => ({ map: f => Box(f(x)), chain: f => f(x), fold: f => f(x) });', + setupCode: 'const Box = x => ({ map: f => Box(f(x)), chain: f => f(x), fold: f => f(x) });', + expected: true, + sample: 'const f = x => Box(x + 1); const a = 5; const leftSide = Box(a).chain(f).fold(x => x); const rightSide = f(a).fold(x => x); leftSide === rightSide', + hints: ['Left identity: M.of(a).chain(f) === f(a)', 'Both sides should produce same result'], + tags: ['functional', 'monad', 'laws'], + }, + + // ======================================== + // DOM MANIPULATION - querySelector/querySelectorAll + // ======================================== + { + id: 'js-dom-001', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Select Element by ID', + text: 'Use querySelector to select an element with the id "main-title".', + setup: 'const document = { querySelector: (sel) => sel === "#main-title" ? { id: "main-title", tagName: "H1" } : null };', + setupCode: 'const document = { querySelector: (sel) => sel === "#main-title" ? { id: "main-title", tagName: "H1" } : null };', + expected: { id: 'main-title', tagName: 'H1' }, + sample: 'document.querySelector("#main-title")', + hints: ['Use # prefix for ID selectors', 'querySelector returns the first matching element'], + tags: ['dom', 'querySelector', 'selectors'], + }, + { + id: 'js-dom-002', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Select Element by Class', + text: 'Use querySelector to select the first element with class "button".', + setup: 'const document = { querySelector: (sel) => sel === ".button" ? { className: "button", tagName: "BUTTON" } : null };', + setupCode: 'const document = { querySelector: (sel) => sel === ".button" ? { className: "button", tagName: "BUTTON" } : null };', + expected: { className: 'button', tagName: 'BUTTON' }, + sample: 'document.querySelector(".button")', + hints: ['Use . prefix for class selectors', 'querySelector returns the first match'], + tags: ['dom', 'querySelector', 'selectors'], + }, + { + id: 'js-dom-003', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Select by Tag Name', + text: 'Use querySelector to select the first paragraph element.', + setup: 'const document = { querySelector: (sel) => sel === "p" ? { tagName: "P", textContent: "Hello" } : null };', + setupCode: 'const document = { querySelector: (sel) => sel === "p" ? { tagName: "P", textContent: "Hello" } : null };', + expected: { tagName: 'P', textContent: 'Hello' }, + sample: 'document.querySelector("p")', + hints: ['Use tag name directly without prefix', 'Returns first matching element'], + tags: ['dom', 'querySelector', 'selectors'], + }, + { + id: 'js-dom-004', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Select All Elements by Class', + text: 'Use querySelectorAll to select all elements with class "item" and get the count.', + setup: 'const document = { querySelectorAll: (sel) => sel === ".item" ? { length: 5 } : { length: 0 } };', + setupCode: 'const document = { querySelectorAll: (sel) => sel === ".item" ? { length: 5 } : { length: 0 } };', + expected: 5, + sample: 'document.querySelectorAll(".item").length', + hints: ['querySelectorAll returns a NodeList', 'Use .length to count elements'], + tags: ['dom', 'querySelectorAll', 'selectors'], + }, + { + id: 'js-dom-005', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Select with Attribute Selector', + text: 'Select an element with data-type="primary" attribute.', + setup: 'const document = { querySelector: (sel) => sel === \'[data-type="primary"]\' ? { dataset: { type: "primary" } } : null };', + setupCode: 'const document = { querySelector: (sel) => sel === \'[data-type="primary"]\' ? { dataset: { type: "primary" } } : null };', + expected: { dataset: { type: 'primary' } }, + sample: 'document.querySelector(\'[data-type="primary"]\')', + hints: ['Use square brackets for attribute selectors', 'Quote the attribute value'], + tags: ['dom', 'querySelector', 'attributes'], + }, + { + id: 'js-dom-006', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Descendant Selector', + text: 'Select all list items inside a nav element.', + setup: 'const document = { querySelectorAll: (sel) => sel === "nav li" ? [{ tagName: "LI" }, { tagName: "LI" }, { tagName: "LI" }] : [] };', + setupCode: 'const document = { querySelectorAll: (sel) => sel === "nav li" ? [{ tagName: "LI" }, { tagName: "LI" }, { tagName: "LI" }] : [] };', + expected: [{ tagName: 'LI' }, { tagName: 'LI' }, { tagName: 'LI' }], + sample: 'document.querySelectorAll("nav li")', + hints: ['Space between selectors means descendant', 'This selects all li inside nav'], + tags: ['dom', 'querySelectorAll', 'combinators'], + }, + { + id: 'js-dom-007', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Direct Child Selector', + text: 'Select only direct child paragraphs of an article element.', + setup: 'const document = { querySelectorAll: (sel) => sel === "article > p" ? [{ tagName: "P", direct: true }] : [] };', + setupCode: 'const document = { querySelectorAll: (sel) => sel === "article > p" ? [{ tagName: "P", direct: true }] : [] };', + expected: [{ tagName: 'P', direct: true }], + sample: 'document.querySelectorAll("article > p")', + hints: ['Use > for direct child combinator', 'This excludes nested paragraphs'], + tags: ['dom', 'querySelectorAll', 'combinators'], + }, + { + id: 'js-dom-008', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Multiple Selectors', + text: 'Select all h1, h2, and h3 elements at once.', + setup: 'const document = { querySelectorAll: (sel) => sel === "h1, h2, h3" ? [{ tagName: "H1" }, { tagName: "H2" }, { tagName: "H3" }] : [] };', + setupCode: 'const document = { querySelectorAll: (sel) => sel === "h1, h2, h3" ? [{ tagName: "H1" }, { tagName: "H2" }, { tagName: "H3" }] : [] };', + expected: [{ tagName: 'H1' }, { tagName: 'H2' }, { tagName: 'H3' }], + sample: 'document.querySelectorAll("h1, h2, h3")', + hints: ['Separate multiple selectors with commas', 'Returns all matching elements'], + tags: ['dom', 'querySelectorAll', 'selectors'], + }, + { + id: 'js-dom-009', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Pseudo-class Selector', + text: 'Select the first child of a list.', + setup: 'const document = { querySelector: (sel) => sel === "ul li:first-child" ? { textContent: "First Item" } : null };', + setupCode: 'const document = { querySelector: (sel) => sel === "ul li:first-child" ? { textContent: "First Item" } : null };', + expected: { textContent: 'First Item' }, + sample: 'document.querySelector("ul li:first-child")', + hints: ['Use :first-child pseudo-class', 'This selects the first li in ul'], + tags: ['dom', 'querySelector', 'pseudo-classes'], + }, + { + id: 'js-dom-010', + category: 'DOM Manipulation', + difficulty: 'hard', + title: 'Complex Selector Chain', + text: 'Select checked checkboxes inside a form with id "settings".', + setup: 'const document = { querySelectorAll: (sel) => sel === "#settings input[type=checkbox]:checked" ? [{ checked: true }, { checked: true }] : [] };', + setupCode: 'const document = { querySelectorAll: (sel) => sel === "#settings input[type=checkbox]:checked" ? [{ checked: true }, { checked: true }] : [] };', + expected: [{ checked: true }, { checked: true }], + sample: 'document.querySelectorAll("#settings input[type=checkbox]:checked")', + hints: ['Combine ID, attribute, and pseudo-class selectors', 'Use :checked for selected checkboxes'], + tags: ['dom', 'querySelectorAll', 'complex-selectors'], + }, + + // ======================================== + // DOM MANIPULATION - createElement/appendChild + // ======================================== + { + id: 'js-dom-011', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Create a Div Element', + text: 'Create a new div element using document.createElement.', + setup: 'const document = { createElement: (tag) => ({ tagName: tag.toUpperCase(), children: [] }) };', + setupCode: 'const document = { createElement: (tag) => ({ tagName: tag.toUpperCase(), children: [] }) };', + expected: { tagName: 'DIV', children: [] }, + sample: 'document.createElement("div")', + hints: ['Pass the tag name as a string', 'Tag name is case-insensitive'], + tags: ['dom', 'createElement', 'elements'], + }, + { + id: 'js-dom-012', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Create and Set Text Content', + text: 'Create a paragraph element and set its text content to "Hello World".', + setup: 'const document = { createElement: (tag) => ({ tagName: tag.toUpperCase(), textContent: "" }) };', + setupCode: 'const document = { createElement: (tag) => ({ tagName: tag.toUpperCase(), textContent: "" }) };', + expected: { tagName: 'P', textContent: 'Hello World' }, + sample: 'const p = document.createElement("p"); p.textContent = "Hello World"; p', + hints: ['First create the element', 'Then set the textContent property'], + tags: ['dom', 'createElement', 'textContent'], + }, + { + id: 'js-dom-013', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Append Child Element', + text: 'Create a span and append it to the parent div. Return the parent.', + setup: 'const parent = { tagName: "DIV", children: [], appendChild(child) { this.children.push(child); return child; } }; const document = { createElement: (tag) => ({ tagName: tag.toUpperCase() }) };', + setupCode: 'const parent = { tagName: "DIV", children: [], appendChild(child) { this.children.push(child); return child; } }; const document = { createElement: (tag) => ({ tagName: tag.toUpperCase() }) };', + expected: { tagName: 'DIV', children: [{ tagName: 'SPAN' }] }, + sample: 'parent.appendChild(document.createElement("span")); parent', + hints: ['Use appendChild to add a child', 'appendChild modifies the parent in place'], + tags: ['dom', 'appendChild', 'elements'], + }, + { + id: 'js-dom-014', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Create Button with Text', + text: 'Create a button element with text "Click Me".', + setup: 'const document = { createElement: (tag) => ({ tagName: tag.toUpperCase(), textContent: "" }) };', + setupCode: 'const document = { createElement: (tag) => ({ tagName: tag.toUpperCase(), textContent: "" }) };', + expected: { tagName: 'BUTTON', textContent: 'Click Me' }, + sample: 'const btn = document.createElement("button"); btn.textContent = "Click Me"; btn', + hints: ['Create button element first', 'Set textContent for the button text'], + tags: ['dom', 'createElement', 'button'], + }, + { + id: 'js-dom-015', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Create Element with Attribute', + text: 'Create an anchor element with href attribute set to "https://example.com".', + setup: 'const document = { createElement: (tag) => ({ tagName: tag.toUpperCase(), setAttribute(name, value) { this[name] = value; } }) };', + setupCode: 'const document = { createElement: (tag) => ({ tagName: tag.toUpperCase(), setAttribute(name, value) { this[name] = value; } }) };', + expected: { tagName: 'A', href: 'https://example.com' }, + sample: 'const a = document.createElement("a"); a.setAttribute("href", "https://example.com"); a', + hints: ['Use setAttribute to add attributes', 'First argument is attribute name, second is value'], + tags: ['dom', 'createElement', 'setAttribute'], + }, + { + id: 'js-dom-016', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Create Nested Elements', + text: 'Create a ul with one li child containing text "Item 1". Return the ul.', + setup: 'const document = { createElement: (tag) => ({ tagName: tag.toUpperCase(), textContent: "", children: [], appendChild(child) { this.children.push(child); return child; } }) };', + setupCode: 'const document = { createElement: (tag) => ({ tagName: tag.toUpperCase(), textContent: "", children: [], appendChild(child) { this.children.push(child); return child; } }) };', + expected: { tagName: 'UL', textContent: '', children: [{ tagName: 'LI', textContent: 'Item 1', children: [] }] }, + sample: 'const ul = document.createElement("ul"); const li = document.createElement("li"); li.textContent = "Item 1"; ul.appendChild(li); ul', + hints: ['Create both elements separately', 'Set text on li before appending'], + tags: ['dom', 'createElement', 'appendChild', 'nested'], + }, + { + id: 'js-dom-017', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Insert Before Element', + text: 'Insert a new element before an existing one. Return the parent.', + setup: 'const existing = { id: "existing" }; const parent = { children: [existing], insertBefore(newEl, ref) { const idx = this.children.indexOf(ref); this.children.splice(idx, 0, newEl); return newEl; } }; const newEl = { id: "new" };', + setupCode: 'const existing = { id: "existing" }; const parent = { children: [existing], insertBefore(newEl, ref) { const idx = this.children.indexOf(ref); this.children.splice(idx, 0, newEl); return newEl; } }; const newEl = { id: "new" };', + expected: { children: [{ id: 'new' }, { id: 'existing' }] }, + sample: 'parent.insertBefore(newEl, existing); parent', + hints: ['insertBefore takes new element and reference element', 'New element is inserted before the reference'], + tags: ['dom', 'insertBefore', 'manipulation'], + }, + { + id: 'js-dom-018', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Remove Child Element', + text: 'Remove the child element from the parent and return the removed element.', + setup: 'const child = { id: "child" }; const parent = { children: [child], removeChild(el) { const idx = this.children.indexOf(el); this.children.splice(idx, 1); return el; } };', + setupCode: 'const child = { id: "child" }; const parent = { children: [child], removeChild(el) { const idx = this.children.indexOf(el); this.children.splice(idx, 1); return el; } };', + expected: { id: 'child' }, + sample: 'parent.removeChild(child)', + hints: ['removeChild returns the removed element', 'Pass the element to remove as argument'], + tags: ['dom', 'removeChild', 'manipulation'], + }, + { + id: 'js-dom-019', + category: 'DOM Manipulation', + difficulty: 'hard', + title: 'Replace Child Element', + text: 'Replace the old element with a new one. Return the parent.', + setup: 'const oldEl = { id: "old" }; const newEl = { id: "new" }; const parent = { children: [oldEl], replaceChild(newChild, oldChild) { const idx = this.children.indexOf(oldChild); this.children[idx] = newChild; return oldChild; } };', + setupCode: 'const oldEl = { id: "old" }; const newEl = { id: "new" }; const parent = { children: [oldEl], replaceChild(newChild, oldChild) { const idx = this.children.indexOf(oldChild); this.children[idx] = newChild; return oldChild; } };', + expected: { children: [{ id: 'new' }] }, + sample: 'parent.replaceChild(newEl, oldEl); parent', + hints: ['replaceChild takes new element first, then old', 'Order of arguments matters'], + tags: ['dom', 'replaceChild', 'manipulation'], + }, + { + id: 'js-dom-020', + category: 'DOM Manipulation', + difficulty: 'hard', + title: 'Clone Element Deep', + text: 'Clone the element including all its children.', + setup: 'const el = { id: "original", children: [{ id: "child" }], cloneNode(deep) { return deep ? { id: this.id, children: [...this.children], cloned: true } : { id: this.id, children: [], cloned: true }; } };', + setupCode: 'const el = { id: "original", children: [{ id: "child" }], cloneNode(deep) { return deep ? { id: this.id, children: [...this.children], cloned: true } : { id: this.id, children: [], cloned: true }; } };', + expected: { id: 'original', children: [{ id: 'child' }], cloned: true }, + sample: 'el.cloneNode(true)', + hints: ['Pass true for deep clone', 'Deep clone includes all descendants'], + tags: ['dom', 'cloneNode', 'manipulation'], + }, + + // ======================================== + // DOM MANIPULATION - innerHTML/textContent + // ======================================== + { + id: 'js-dom-021', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Set innerHTML', + text: 'Set the innerHTML of the element to contain a strong tag with "Bold Text".', + setup: 'const el = { innerHTML: "" };', + setupCode: 'const el = { innerHTML: "" };', + expected: { innerHTML: 'Bold Text' }, + sample: 'el.innerHTML = "Bold Text"; el', + hints: ['innerHTML accepts HTML string', 'Include the full HTML tags'], + tags: ['dom', 'innerHTML', 'html'], + }, + { + id: 'js-dom-022', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Get Text Content', + text: 'Extract the text content from the element.', + setup: 'const el = { textContent: "Hello World", innerHTML: "Hello World" };', + setupCode: 'const el = { textContent: "Hello World", innerHTML: "Hello World" };', + expected: 'Hello World', + sample: 'el.textContent', + hints: ['textContent returns plain text', 'HTML tags are not included'], + tags: ['dom', 'textContent', 'text'], + }, + { + id: 'js-dom-023', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Clear Element Content', + text: 'Clear all content from the element using innerHTML.', + setup: 'const el = { innerHTML: "

Some content

More" };', + setupCode: 'const el = { innerHTML: "

Some content

More" };', + expected: { innerHTML: '' }, + sample: 'el.innerHTML = ""; el', + hints: ['Set innerHTML to empty string', 'This removes all child elements'], + tags: ['dom', 'innerHTML', 'clear'], + }, + { + id: 'js-dom-024', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Insert HTML with Template', + text: 'Create an HTML string for a list with items "One", "Two", "Three".', + setup: 'const items = ["One", "Two", "Three"];', + setupCode: 'const items = ["One", "Two", "Three"];', + expected: '
  • One
  • Two
  • Three
', + sample: '`
    ${items.map(i => `
  • ${i}
  • `).join("")}
`', + hints: ['Use template literals', 'Map items to li tags and join'], + tags: ['dom', 'innerHTML', 'templates'], + }, + { + id: 'js-dom-025', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Outer HTML Access', + text: 'Get the outerHTML which includes the element itself.', + setup: 'const el = { outerHTML: \'

Content

\' };', + setupCode: 'const el = { outerHTML: \'

Content

\' };', + expected: '

Content

', + sample: 'el.outerHTML', + hints: ['outerHTML includes the element tag', 'Unlike innerHTML which only has children'], + tags: ['dom', 'outerHTML', 'html'], + }, + { + id: 'js-dom-026', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Insert Adjacent HTML', + text: 'Insert HTML before the end of the element (inside, after last child).', + setup: 'const el = { content: ["existing"], insertAdjacentHTML(pos, html) { if(pos === "beforeend") this.content.push(html); } };', + setupCode: 'const el = { content: ["existing"], insertAdjacentHTML(pos, html) { if(pos === "beforeend") this.content.push(html); } };', + expected: { content: ['existing', 'New'] }, + sample: 'el.insertAdjacentHTML("beforeend", "New"); el', + hints: ['Use "beforeend" position', 'This adds content as last child'], + tags: ['dom', 'insertAdjacentHTML', 'manipulation'], + }, + { + id: 'js-dom-027', + category: 'DOM Manipulation', + difficulty: 'hard', + title: 'Sanitize HTML Input', + text: 'Use textContent to safely display user input without executing HTML.', + setup: 'const el = { textContent: "" }; const userInput = "";', + setupCode: 'const el = { textContent: "" }; const userInput = "";', + expected: { textContent: '' }, + sample: 'el.textContent = userInput; el', + hints: ['textContent escapes HTML', 'Safe for displaying user input'], + tags: ['dom', 'textContent', 'security', 'xss'], + }, + + // ======================================== + // DOM MANIPULATION - classList + // ======================================== + { + id: 'js-dom-028', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Add a Class', + text: 'Add the class "active" to the element.', + setup: 'const el = { classList: { classes: [], add(c) { this.classes.push(c); } } };', + setupCode: 'const el = { classList: { classes: [], add(c) { this.classes.push(c); } } };', + expected: { classList: { classes: ['active'] } }, + sample: 'el.classList.add("active"); el', + hints: ['Use classList.add()', 'Pass class name as string'], + tags: ['dom', 'classList', 'add'], + }, + { + id: 'js-dom-029', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Remove a Class', + text: 'Remove the class "hidden" from the element.', + setup: 'const el = { classList: { classes: ["visible", "hidden"], remove(c) { this.classes = this.classes.filter(x => x !== c); } } };', + setupCode: 'const el = { classList: { classes: ["visible", "hidden"], remove(c) { this.classes = this.classes.filter(x => x !== c); } } };', + expected: { classList: { classes: ['visible'] } }, + sample: 'el.classList.remove("hidden"); el', + hints: ['Use classList.remove()', 'Only removes the specified class'], + tags: ['dom', 'classList', 'remove'], + }, + { + id: 'js-dom-030', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Toggle a Class', + text: 'Toggle the class "expanded" on the element (currently not present).', + setup: 'const el = { classList: { classes: [], toggle(c) { if(this.classes.includes(c)) { this.classes = this.classes.filter(x => x !== c); return false; } else { this.classes.push(c); return true; } } } };', + setupCode: 'const el = { classList: { classes: [], toggle(c) { if(this.classes.includes(c)) { this.classes = this.classes.filter(x => x !== c); return false; } else { this.classes.push(c); return true; } } } };', + expected: true, + sample: 'el.classList.toggle("expanded")', + hints: ['toggle adds if not present', 'Returns true if class was added'], + tags: ['dom', 'classList', 'toggle'], + }, + { + id: 'js-dom-031', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Check if Class Exists', + text: 'Check if the element has the class "selected".', + setup: 'const el = { classList: { contains(c) { return ["item", "selected", "blue"].includes(c); } } };', + setupCode: 'const el = { classList: { contains(c) { return ["item", "selected", "blue"].includes(c); } } };', + expected: true, + sample: 'el.classList.contains("selected")', + hints: ['Use classList.contains()', 'Returns a boolean'], + tags: ['dom', 'classList', 'contains'], + }, + { + id: 'js-dom-032', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Add Multiple Classes', + text: 'Add classes "btn", "btn-primary", and "large" in one call.', + setup: 'const el = { classList: { classes: [], add(...args) { this.classes.push(...args); } } };', + setupCode: 'const el = { classList: { classes: [], add(...args) { this.classes.push(...args); } } };', + expected: { classList: { classes: ['btn', 'btn-primary', 'large'] } }, + sample: 'el.classList.add("btn", "btn-primary", "large"); el', + hints: ['add() accepts multiple arguments', 'Pass all classes as separate arguments'], + tags: ['dom', 'classList', 'add', 'multiple'], + }, + { + id: 'js-dom-033', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Replace a Class', + text: 'Replace the class "old-style" with "new-style".', + setup: 'const el = { classList: { classes: ["old-style", "other"], replace(old, newC) { const idx = this.classes.indexOf(old); if(idx !== -1) { this.classes[idx] = newC; return true; } return false; } } };', + setupCode: 'const el = { classList: { classes: ["old-style", "other"], replace(old, newC) { const idx = this.classes.indexOf(old); if(idx !== -1) { this.classes[idx] = newC; return true; } return false; } } };', + expected: true, + sample: 'el.classList.replace("old-style", "new-style")', + hints: ['Use classList.replace()', 'First argument is old class, second is new'], + tags: ['dom', 'classList', 'replace'], + }, + { + id: 'js-dom-034', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Force Toggle Class', + text: 'Force add the class "visible" regardless of current state.', + setup: 'const el = { classList: { classes: ["visible"], toggle(c, force) { if(force === true && !this.classes.includes(c)) { this.classes.push(c); } else if(force === false) { this.classes = this.classes.filter(x => x !== c); } return force; } } };', + setupCode: 'const el = { classList: { classes: ["visible"], toggle(c, force) { if(force === true && !this.classes.includes(c)) { this.classes.push(c); } else if(force === false) { this.classes = this.classes.filter(x => x !== c); } return force; } } };', + expected: true, + sample: 'el.classList.toggle("visible", true)', + hints: ['Second argument forces add/remove', 'true forces add, false forces remove'], + tags: ['dom', 'classList', 'toggle', 'force'], + }, + { + id: 'js-dom-035', + category: 'DOM Manipulation', + difficulty: 'hard', + title: 'Conditional Class Toggle', + text: 'Add "error" class if value is empty, otherwise add "valid" class.', + setup: 'const value = "test"; const el = { classList: { classes: [], add(c) { this.classes.push(c); } } };', + setupCode: 'const value = "test"; const el = { classList: { classes: [], add(c) { this.classes.push(c); } } };', + expected: { classList: { classes: ['valid'] } }, + sample: 'el.classList.add(value === "" ? "error" : "valid"); el', + hints: ['Use ternary operator', 'Check if value is empty string'], + tags: ['dom', 'classList', 'conditional'], + }, + + // ======================================== + // EVENTS - addEventListener + // ======================================== + { + id: 'js-dom-036', + category: 'Events', + difficulty: 'easy', + title: 'Add Click Listener', + text: 'Add a click event listener that sets clicked to true.', + setup: 'let clicked = false; const el = { addEventListener(type, handler) { if(type === "click") handler(); } };', + setupCode: 'let clicked = false; const el = { addEventListener(type, handler) { if(type === "click") handler(); } };', + expected: true, + sample: 'el.addEventListener("click", () => { clicked = true; }); clicked', + hints: ['First argument is event type', 'Second argument is callback function'], + tags: ['events', 'addEventListener', 'click'], + }, + { + id: 'js-dom-037', + category: 'Events', + difficulty: 'easy', + title: 'Mouse Enter Event', + text: 'Add a mouseenter event listener that sets hovered to true.', + setup: 'let hovered = false; const el = { addEventListener(type, handler) { if(type === "mouseenter") handler(); } };', + setupCode: 'let hovered = false; const el = { addEventListener(type, handler) { if(type === "mouseenter") handler(); } };', + expected: true, + sample: 'el.addEventListener("mouseenter", () => { hovered = true; }); hovered', + hints: ['Use "mouseenter" event type', 'Fires when mouse enters element'], + tags: ['events', 'addEventListener', 'mouse'], + }, + { + id: 'js-dom-038', + category: 'Events', + difficulty: 'easy', + title: 'Keyboard Event', + text: 'Add a keydown event listener that captures the key pressed.', + setup: 'let pressedKey = ""; const el = { addEventListener(type, handler) { if(type === "keydown") handler({ key: "Enter" }); } };', + setupCode: 'let pressedKey = ""; const el = { addEventListener(type, handler) { if(type === "keydown") handler({ key: "Enter" }); } };', + expected: 'Enter', + sample: 'el.addEventListener("keydown", (e) => { pressedKey = e.key; }); pressedKey', + hints: ['Event object has key property', 'Use arrow function with event parameter'], + tags: ['events', 'addEventListener', 'keyboard'], + }, + { + id: 'js-dom-039', + category: 'Events', + difficulty: 'easy', + title: 'Form Submit Event', + text: 'Add a submit event listener that prevents default behavior.', + setup: 'let prevented = false; const form = { addEventListener(type, handler) { if(type === "submit") handler({ preventDefault() { prevented = true; } }); } };', + setupCode: 'let prevented = false; const form = { addEventListener(type, handler) { if(type === "submit") handler({ preventDefault() { prevented = true; } }); } };', + expected: true, + sample: 'form.addEventListener("submit", (e) => { e.preventDefault(); }); prevented', + hints: ['Call e.preventDefault()', 'Stops form from submitting normally'], + tags: ['events', 'addEventListener', 'form', 'preventDefault'], + }, + { + id: 'js-dom-040', + category: 'Events', + difficulty: 'medium', + title: 'Input Event Handler', + text: 'Track input value changes in real-time.', + setup: 'let inputValue = ""; const input = { addEventListener(type, handler) { if(type === "input") handler({ target: { value: "Hello" } }); } };', + setupCode: 'let inputValue = ""; const input = { addEventListener(type, handler) { if(type === "input") handler({ target: { value: "Hello" } }); } };', + expected: 'Hello', + sample: 'input.addEventListener("input", (e) => { inputValue = e.target.value; }); inputValue', + hints: ['Use "input" event for real-time tracking', 'Access value via e.target.value'], + tags: ['events', 'addEventListener', 'input'], + }, + { + id: 'js-dom-041', + category: 'Events', + difficulty: 'medium', + title: 'Remove Event Listener', + text: 'Add and then remove an event listener. Return removed status.', + setup: 'const handler = () => {}; let removed = false; const el = { addEventListener() {}, removeEventListener(type, fn) { if(fn === handler) removed = true; } };', + setupCode: 'const handler = () => {}; let removed = false; const el = { addEventListener() {}, removeEventListener(type, fn) { if(fn === handler) removed = true; } };', + expected: true, + sample: 'el.addEventListener("click", handler); el.removeEventListener("click", handler); removed', + hints: ['Store handler in a variable', 'Must pass same function reference to remove'], + tags: ['events', 'removeEventListener'], + }, + { + id: 'js-dom-042', + category: 'Events', + difficulty: 'medium', + title: 'Once Event Option', + text: 'Add an event listener that only fires once.', + setup: 'let count = 0; const el = { addEventListener(type, handler, options) { if(options?.once) { handler(); } else { handler(); handler(); } } };', + setupCode: 'let count = 0; const el = { addEventListener(type, handler, options) { if(options?.once) { handler(); } else { handler(); handler(); } } };', + expected: 1, + sample: 'el.addEventListener("click", () => { count++; }, { once: true }); count', + hints: ['Third argument is options object', 'Use { once: true }'], + tags: ['events', 'addEventListener', 'options'], + }, + { + id: 'js-dom-043', + category: 'Events', + difficulty: 'medium', + title: 'Focus and Blur Events', + text: 'Track focus state of an input element.', + setup: 'let focused = false; const input = { addEventListener(type, handler) { if(type === "focus") handler(); if(type === "blur") setTimeout(() => handler(), 0); } };', + setupCode: 'let focused = false; const input = { addEventListener(type, handler) { if(type === "focus") handler(); if(type === "blur") setTimeout(() => handler(), 0); } };', + expected: true, + sample: 'input.addEventListener("focus", () => { focused = true; }); focused', + hints: ['Use "focus" event', 'Fires when element receives focus'], + tags: ['events', 'addEventListener', 'focus'], + }, + { + id: 'js-dom-044', + category: 'Events', + difficulty: 'hard', + title: 'Debounced Event Handler', + text: 'Create a debounced handler that delays execution by 100ms.', + setup: 'let lastCall = 0; const debounce = (fn, delay) => { let timeout; return (...args) => { clearTimeout(timeout); timeout = setTimeout(() => fn(...args), delay); return delay; }; };', + setupCode: 'let lastCall = 0; const debounce = (fn, delay) => { let timeout; return (...args) => { clearTimeout(timeout); timeout = setTimeout(() => fn(...args), delay); return delay; }; };', + expected: 100, + sample: 'const handler = debounce(() => { lastCall = Date.now(); }, 100); handler()', + hints: ['Debounce delays function execution', 'Resets timer on each call'], + tags: ['events', 'debounce', 'performance'], + }, + { + id: 'js-dom-045', + category: 'Events', + difficulty: 'hard', + title: 'Throttled Event Handler', + text: 'Create a throttled handler that limits execution to once per 100ms.', + setup: 'const throttle = (fn, limit) => { let inThrottle = false; return (...args) => { if (!inThrottle) { fn(...args); inThrottle = true; setTimeout(() => inThrottle = false, limit); return true; } return false; }; };', + setupCode: 'const throttle = (fn, limit) => { let inThrottle = false; return (...args) => { if (!inThrottle) { fn(...args); inThrottle = true; setTimeout(() => inThrottle = false, limit); return true; } return false; }; };', + expected: true, + sample: 'const handler = throttle(() => {}, 100); handler()', + hints: ['Throttle limits execution rate', 'First call executes immediately'], + tags: ['events', 'throttle', 'performance'], + }, + + // ======================================== + // EVENTS - Event Delegation + // ======================================== + { + id: 'js-dom-046', + category: 'Events', + difficulty: 'medium', + title: 'Basic Event Delegation', + text: 'Use event delegation to handle clicks on list items.', + setup: 'let clickedItem = ""; const ul = { addEventListener(type, handler) { if(type === "click") handler({ target: { tagName: "LI", textContent: "Item 2" } }); } };', + setupCode: 'let clickedItem = ""; const ul = { addEventListener(type, handler) { if(type === "click") handler({ target: { tagName: "LI", textContent: "Item 2" } }); } };', + expected: 'Item 2', + sample: 'ul.addEventListener("click", (e) => { if(e.target.tagName === "LI") clickedItem = e.target.textContent; }); clickedItem', + hints: ['Check e.target.tagName', 'Listen on parent, filter by target'], + tags: ['events', 'delegation', 'patterns'], + }, + { + id: 'js-dom-047', + category: 'Events', + difficulty: 'medium', + title: 'Delegation with Matches', + text: 'Use matches() to check if clicked element matches a selector.', + setup: 'let matched = false; const container = { addEventListener(type, handler) { if(type === "click") handler({ target: { matches: (sel) => sel === ".btn" } }); } };', + setupCode: 'let matched = false; const container = { addEventListener(type, handler) { if(type === "click") handler({ target: { matches: (sel) => sel === ".btn" } }); } };', + expected: true, + sample: 'container.addEventListener("click", (e) => { if(e.target.matches(".btn")) matched = true; }); matched', + hints: ['Use element.matches() method', 'Pass CSS selector to matches()'], + tags: ['events', 'delegation', 'matches'], + }, + { + id: 'js-dom-048', + category: 'Events', + difficulty: 'medium', + title: 'Closest Ancestor Delegation', + text: 'Find the closest ancestor matching a selector when clicking nested elements.', + setup: 'let foundCard = null; const container = { addEventListener(type, handler) { if(type === "click") handler({ target: { closest: (sel) => sel === ".card" ? { id: "card-1" } : null } }); } };', + setupCode: 'let foundCard = null; const container = { addEventListener(type, handler) { if(type === "click") handler({ target: { closest: (sel) => sel === ".card" ? { id: "card-1" } : null } }); } };', + expected: { id: 'card-1' }, + sample: 'container.addEventListener("click", (e) => { foundCard = e.target.closest(".card"); }); foundCard', + hints: ['Use closest() to find ancestor', 'Returns null if no match found'], + tags: ['events', 'delegation', 'closest'], + }, + { + id: 'js-dom-049', + category: 'Events', + difficulty: 'hard', + title: 'Dynamic Element Handling', + text: 'Handle clicks on dynamically added elements using delegation.', + setup: 'const clicks = []; const parent = { addEventListener(type, handler) { handler({ target: { dataset: { action: "delete" }, closest: () => ({ id: "item-5" }) } }); } };', + setupCode: 'const clicks = []; const parent = { addEventListener(type, handler) { handler({ target: { dataset: { action: "delete" }, closest: () => ({ id: "item-5" }) } }); } };', + expected: [{ action: 'delete', itemId: 'item-5' }], + sample: 'parent.addEventListener("click", (e) => { if(e.target.dataset.action) clicks.push({ action: e.target.dataset.action, itemId: e.target.closest("[id]").id }); }); clicks', + hints: ['Use data attributes for actions', 'Combine dataset with closest()'], + tags: ['events', 'delegation', 'dynamic'], + }, + { + id: 'js-dom-050', + category: 'Events', + difficulty: 'hard', + title: 'Multiple Action Delegation', + text: 'Handle multiple action types (edit, delete, view) with single listener.', + setup: 'const actions = { edit: 0, delete: 0, view: 0 }; const container = { addEventListener(type, handler) { handler({ target: { dataset: { action: "edit" } } }); handler({ target: { dataset: { action: "delete" } } }); } };', + setupCode: 'const actions = { edit: 0, delete: 0, view: 0 }; const container = { addEventListener(type, handler) { handler({ target: { dataset: { action: "edit" } } }); handler({ target: { dataset: { action: "delete" } } }); } };', + expected: { edit: 1, delete: 1, view: 0 }, + sample: 'container.addEventListener("click", (e) => { const action = e.target.dataset.action; if(action && actions[action] !== undefined) actions[action]++; }); actions', + hints: ['Read action from dataset', 'Use computed property access'], + tags: ['events', 'delegation', 'actions'], + }, + + // ======================================== + // EVENTS - Bubbling and Capturing + // ======================================== + { + id: 'js-dom-051', + category: 'Events', + difficulty: 'medium', + title: 'Stop Event Propagation', + text: 'Stop an event from bubbling up to parent elements.', + setup: 'let bubbled = true; const child = { addEventListener(type, handler) { handler({ stopPropagation() { bubbled = false; } }); } };', + setupCode: 'let bubbled = true; const child = { addEventListener(type, handler) { handler({ stopPropagation() { bubbled = false; } }); } };', + expected: false, + sample: 'child.addEventListener("click", (e) => { e.stopPropagation(); }); bubbled', + hints: ['Call e.stopPropagation()', 'Prevents event from reaching parent'], + tags: ['events', 'propagation', 'bubbling'], + }, + { + id: 'js-dom-052', + category: 'Events', + difficulty: 'medium', + title: 'Capture Phase Listener', + text: 'Add an event listener that fires during capture phase.', + setup: 'let phase = ""; const el = { addEventListener(type, handler, options) { phase = options === true || options?.capture ? "capture" : "bubble"; } };', + setupCode: 'let phase = ""; const el = { addEventListener(type, handler, options) { phase = options === true || options?.capture ? "capture" : "bubble"; } };', + expected: 'capture', + sample: 'el.addEventListener("click", () => {}, true); phase', + hints: ['Pass true as third argument', 'Or use { capture: true }'], + tags: ['events', 'capture', 'propagation'], + }, + { + id: 'js-dom-053', + category: 'Events', + difficulty: 'medium', + title: 'Check Event Phase', + text: 'Determine the current event phase.', + setup: 'const PHASES = { CAPTURING: 1, AT_TARGET: 2, BUBBLING: 3 }; const event = { eventPhase: 3 };', + setupCode: 'const PHASES = { CAPTURING: 1, AT_TARGET: 2, BUBBLING: 3 }; const event = { eventPhase: 3 };', + expected: 'bubbling', + sample: 'event.eventPhase === PHASES.BUBBLING ? "bubbling" : event.eventPhase === PHASES.CAPTURING ? "capturing" : "at_target"', + hints: ['eventPhase is a number', '1=capturing, 2=at target, 3=bubbling'], + tags: ['events', 'phase', 'propagation'], + }, + { + id: 'js-dom-054', + category: 'Events', + difficulty: 'hard', + title: 'Stop Immediate Propagation', + text: 'Stop other listeners on the same element from being called.', + setup: 'let count = 0; const el = { handlers: [], addEventListener(type, handler) { this.handlers.push(handler); }, fire(e) { for(const h of this.handlers) { h(e); if(e.stopped) break; } } };', + setupCode: 'let count = 0; const el = { handlers: [], addEventListener(type, handler) { this.handlers.push(handler); }, fire(e) { for(const h of this.handlers) { h(e); if(e.stopped) break; } } };', + expected: 1, + sample: 'el.addEventListener("click", (e) => { count++; e.stopImmediatePropagation(); e.stopped = true; }); el.addEventListener("click", () => { count++; }); el.fire({}); count', + hints: ['Use stopImmediatePropagation()', 'Prevents other handlers on same element'], + tags: ['events', 'propagation', 'immediate'], + }, + { + id: 'js-dom-055', + category: 'Events', + difficulty: 'hard', + title: 'Event Target vs CurrentTarget', + text: 'Distinguish between the clicked element and the listening element.', + setup: 'const event = { target: { id: "inner-btn" }, currentTarget: { id: "outer-div" } };', + setupCode: 'const event = { target: { id: "inner-btn" }, currentTarget: { id: "outer-div" } };', + expected: { clicked: 'inner-btn', listener: 'outer-div' }, + sample: '({ clicked: event.target.id, listener: event.currentTarget.id })', + hints: ['target is the actual clicked element', 'currentTarget is where listener is attached'], + tags: ['events', 'target', 'currentTarget'], + }, + + // ======================================== + // BROWSER APIs - localStorage/sessionStorage + // ======================================== + { + id: 'js-dom-056', + category: 'Browser APIs', + difficulty: 'easy', + title: 'Set Local Storage Item', + text: 'Store a value in localStorage with key "username".', + setup: 'const localStorage = { data: {}, setItem(key, value) { this.data[key] = value; } };', + setupCode: 'const localStorage = { data: {}, setItem(key, value) { this.data[key] = value; } };', + expected: { data: { username: 'john_doe' } }, + sample: 'localStorage.setItem("username", "john_doe"); localStorage', + hints: ['Use setItem(key, value)', 'Values are stored as strings'], + tags: ['localStorage', 'storage', 'setItem'], + }, + { + id: 'js-dom-057', + category: 'Browser APIs', + difficulty: 'easy', + title: 'Get Local Storage Item', + text: 'Retrieve the value stored with key "theme".', + setup: 'const localStorage = { getItem(key) { return key === "theme" ? "dark" : null; } };', + setupCode: 'const localStorage = { getItem(key) { return key === "theme" ? "dark" : null; } };', + expected: 'dark', + sample: 'localStorage.getItem("theme")', + hints: ['Use getItem(key)', 'Returns null if key not found'], + tags: ['localStorage', 'storage', 'getItem'], + }, + { + id: 'js-dom-058', + category: 'Browser APIs', + difficulty: 'easy', + title: 'Remove Local Storage Item', + text: 'Remove the item with key "token" from localStorage.', + setup: 'const localStorage = { data: { token: "abc123", user: "john" }, removeItem(key) { delete this.data[key]; } };', + setupCode: 'const localStorage = { data: { token: "abc123", user: "john" }, removeItem(key) { delete this.data[key]; } };', + expected: { data: { user: 'john' } }, + sample: 'localStorage.removeItem("token"); localStorage', + hints: ['Use removeItem(key)', 'Only removes specified key'], + tags: ['localStorage', 'storage', 'removeItem'], + }, + { + id: 'js-dom-059', + category: 'Browser APIs', + difficulty: 'easy', + title: 'Clear All Storage', + text: 'Clear all items from localStorage.', + setup: 'const localStorage = { data: { a: "1", b: "2", c: "3" }, clear() { this.data = {}; } };', + setupCode: 'const localStorage = { data: { a: "1", b: "2", c: "3" }, clear() { this.data = {}; } };', + expected: { data: {} }, + sample: 'localStorage.clear(); localStorage', + hints: ['Use clear() method', 'Removes all stored items'], + tags: ['localStorage', 'storage', 'clear'], + }, + { + id: 'js-dom-060', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Store Object in Storage', + text: 'Store a user object in localStorage (requires serialization).', + setup: 'const localStorage = { data: {}, setItem(key, value) { this.data[key] = value; } }; const user = { name: "Alice", age: 25 };', + setupCode: 'const localStorage = { data: {}, setItem(key, value) { this.data[key] = value; } }; const user = { name: "Alice", age: 25 };', + expected: { data: { user: '{"name":"Alice","age":25}' } }, + sample: 'localStorage.setItem("user", JSON.stringify(user)); localStorage', + hints: ['Use JSON.stringify()', 'localStorage only stores strings'], + tags: ['localStorage', 'storage', 'JSON'], + }, + { + id: 'js-dom-061', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Retrieve and Parse Object', + text: 'Get a stored JSON string and parse it back to an object.', + setup: 'const localStorage = { getItem(key) { return key === "settings" ? \'{"theme":"dark","fontSize":14}\' : null; } };', + setupCode: 'const localStorage = { getItem(key) { return key === "settings" ? \'{"theme":"dark","fontSize":14}\' : null; } };', + expected: { theme: 'dark', fontSize: 14 }, + sample: 'JSON.parse(localStorage.getItem("settings"))', + hints: ['Use JSON.parse()', 'Handle null case in real apps'], + tags: ['localStorage', 'storage', 'JSON'], + }, + { + id: 'js-dom-062', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Check Storage Length', + text: 'Get the number of items stored in localStorage.', + setup: 'const localStorage = { length: 5 };', + setupCode: 'const localStorage = { length: 5 };', + expected: 5, + sample: 'localStorage.length', + hints: ['Use length property', 'Returns number of stored items'], + tags: ['localStorage', 'storage', 'length'], + }, + { + id: 'js-dom-063', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Iterate Storage Keys', + text: 'Get the key at index 0 in localStorage.', + setup: 'const localStorage = { key(index) { return ["theme", "user", "token"][index]; } };', + setupCode: 'const localStorage = { key(index) { return ["theme", "user", "token"][index]; } };', + expected: 'theme', + sample: 'localStorage.key(0)', + hints: ['Use key(index) method', 'Returns key name at given index'], + tags: ['localStorage', 'storage', 'iteration'], + }, + { + id: 'js-dom-064', + category: 'Browser APIs', + difficulty: 'hard', + title: 'Storage with Expiration', + text: 'Store data with an expiration timestamp and check if expired.', + setup: 'const now = Date.now(); const stored = { value: "data", expires: now + 3600000 };', + setupCode: 'const now = Date.now(); const stored = { value: "data", expires: now + 3600000 };', + expected: false, + sample: 'stored.expires < now', + hints: ['Compare expiration with current time', 'Use Date.now() for comparison'], + tags: ['localStorage', 'storage', 'expiration'], + }, + { + id: 'js-dom-065', + category: 'Browser APIs', + difficulty: 'hard', + title: 'Storage Event Listener', + text: 'Detect when localStorage changes in another tab.', + setup: 'let changed = null; const window = { addEventListener(type, handler) { if(type === "storage") handler({ key: "theme", newValue: "light", oldValue: "dark" }); } };', + setupCode: 'let changed = null; const window = { addEventListener(type, handler) { if(type === "storage") handler({ key: "theme", newValue: "light", oldValue: "dark" }); } };', + expected: { key: 'theme', from: 'dark', to: 'light' }, + sample: 'window.addEventListener("storage", (e) => { changed = { key: e.key, from: e.oldValue, to: e.newValue }; }); changed', + hints: ['Listen for "storage" event on window', 'Event has key, oldValue, newValue'], + tags: ['localStorage', 'storage', 'events'], + }, + + // ======================================== + // BROWSER APIs - Fetch API + // ======================================== + { + id: 'js-dom-066', + category: 'Browser APIs', + difficulty: 'easy', + title: 'Basic Fetch Request', + text: 'Make a GET request to an API endpoint.', + setup: 'const fetch = (url) => Promise.resolve({ url, ok: true, status: 200 });', + setupCode: 'const fetch = (url) => Promise.resolve({ url, ok: true, status: 200 });', + expected: { url: 'https://api.example.com/data', ok: true, status: 200 }, + sample: 'await fetch("https://api.example.com/data")', + hints: ['fetch returns a Promise', 'Use await or .then()'], + tags: ['fetch', 'api', 'GET'], + }, + { + id: 'js-dom-067', + category: 'Browser APIs', + difficulty: 'easy', + title: 'Parse JSON Response', + text: 'Fetch data and parse the JSON response.', + setup: 'const fetch = () => Promise.resolve({ json: () => Promise.resolve({ id: 1, name: "Test" }) });', + setupCode: 'const fetch = () => Promise.resolve({ json: () => Promise.resolve({ id: 1, name: "Test" }) });', + expected: { id: 1, name: 'Test' }, + sample: 'await fetch("https://api.example.com/item").then(r => r.json())', + hints: ['Call .json() on response', 'json() also returns a Promise'], + tags: ['fetch', 'api', 'JSON'], + }, + { + id: 'js-dom-068', + category: 'Browser APIs', + difficulty: 'medium', + title: 'POST Request with Body', + text: 'Make a POST request with JSON body.', + setup: 'const fetch = (url, options) => Promise.resolve({ url, method: options?.method, body: options?.body, headers: options?.headers });', + setupCode: 'const fetch = (url, options) => Promise.resolve({ url, method: options?.method, body: options?.body, headers: options?.headers });', + expected: { url: 'https://api.example.com/users', method: 'POST', body: '{"name":"John"}', headers: { 'Content-Type': 'application/json' } }, + sample: 'await fetch("https://api.example.com/users", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: "John" }) })', + hints: ['Set method to "POST"', 'Stringify body and set Content-Type header'], + tags: ['fetch', 'api', 'POST'], + }, + { + id: 'js-dom-069', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Check Response Status', + text: 'Check if a fetch request was successful using ok property.', + setup: 'const response = { ok: false, status: 404, statusText: "Not Found" };', + setupCode: 'const response = { ok: false, status: 404, statusText: "Not Found" };', + expected: 'Error: 404 Not Found', + sample: 'response.ok ? "Success" : `Error: ${response.status} ${response.statusText}`', + hints: ['Check response.ok first', 'ok is true for status 200-299'], + tags: ['fetch', 'api', 'errors'], + }, + { + id: 'js-dom-070', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Fetch with Headers', + text: 'Make a request with authorization header.', + setup: 'const fetch = (url, options) => Promise.resolve({ authHeader: options?.headers?.Authorization });', + setupCode: 'const fetch = (url, options) => Promise.resolve({ authHeader: options?.headers?.Authorization });', + expected: { authHeader: 'Bearer token123' }, + sample: 'await fetch("https://api.example.com/protected", { headers: { Authorization: "Bearer token123" } })', + hints: ['Pass headers in options object', 'Use Authorization header for tokens'], + tags: ['fetch', 'api', 'headers', 'auth'], + }, + { + id: 'js-dom-071', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Handle Fetch Errors', + text: 'Catch network errors from fetch.', + setup: 'const fetch = () => Promise.reject(new Error("Network error"));', + setupCode: 'const fetch = () => Promise.reject(new Error("Network error"));', + expected: 'Network error', + sample: 'await fetch("https://api.example.com").catch(e => e.message)', + hints: ['Use .catch() for errors', 'Network failures reject the promise'], + tags: ['fetch', 'api', 'errors'], + }, + { + id: 'js-dom-072', + category: 'Browser APIs', + difficulty: 'hard', + title: 'Abort Fetch Request', + text: 'Create an AbortController and use its signal to abort a fetch.', + setup: 'const AbortController = class { constructor() { this.signal = { aborted: false }; } abort() { this.signal.aborted = true; } };', + setupCode: 'const AbortController = class { constructor() { this.signal = { aborted: false }; } abort() { this.signal.aborted = true; } };', + expected: true, + sample: 'const controller = new AbortController(); controller.abort(); controller.signal.aborted', + hints: ['Create AbortController instance', 'Call abort() to cancel request'], + tags: ['fetch', 'api', 'abort'], + }, + { + id: 'js-dom-073', + category: 'Browser APIs', + difficulty: 'hard', + title: 'Fetch with Timeout', + text: 'Implement a fetch with timeout using AbortController.', + setup: 'const AbortController = class { constructor() { this.signal = { aborted: false }; } abort() { this.signal.aborted = true; } }; const fetchWithTimeout = (url, timeout) => { const controller = new AbortController(); setTimeout(() => controller.abort(), timeout); return { signal: controller.signal }; };', + setupCode: 'const AbortController = class { constructor() { this.signal = { aborted: false }; } abort() { this.signal.aborted = true; } }; const fetchWithTimeout = (url, timeout) => { const controller = new AbortController(); setTimeout(() => controller.abort(), timeout); return { signal: controller.signal }; };', + expected: false, + sample: 'fetchWithTimeout("https://api.example.com", 5000).signal.aborted', + hints: ['Combine AbortController with setTimeout', 'Abort after timeout period'], + tags: ['fetch', 'api', 'timeout', 'abort'], + }, + { + id: 'js-dom-074', + category: 'Browser APIs', + difficulty: 'hard', + title: 'Parallel Fetch Requests', + text: 'Fetch multiple endpoints in parallel using Promise.all.', + setup: 'const fetch = (url) => Promise.resolve({ url, data: url.split("/").pop() }); const urls = ["https://api.example.com/a", "https://api.example.com/b", "https://api.example.com/c"];', + setupCode: 'const fetch = (url) => Promise.resolve({ url, data: url.split("/").pop() }); const urls = ["https://api.example.com/a", "https://api.example.com/b", "https://api.example.com/c"];', + expected: ['a', 'b', 'c'], + sample: 'await Promise.all(urls.map(url => fetch(url))).then(responses => responses.map(r => r.data))', + hints: ['Use Promise.all with map', 'All requests run simultaneously'], + tags: ['fetch', 'api', 'Promise.all', 'parallel'], + }, + + // ======================================== + // BROWSER APIs - FormData + // ======================================== + { + id: 'js-dom-075', + category: 'Browser APIs', + difficulty: 'easy', + title: 'Create FormData', + text: 'Create a new FormData instance and append a field.', + setup: 'const FormData = class { constructor() { this.data = {}; } append(key, value) { this.data[key] = value; } };', + setupCode: 'const FormData = class { constructor() { this.data = {}; } append(key, value) { this.data[key] = value; } };', + expected: { data: { username: 'john' } }, + sample: 'const fd = new FormData(); fd.append("username", "john"); fd', + hints: ['Use new FormData()', 'Call append() to add fields'], + tags: ['FormData', 'forms', 'append'], + }, + { + id: 'js-dom-076', + category: 'Browser APIs', + difficulty: 'easy', + title: 'Get FormData Value', + text: 'Retrieve a value from FormData.', + setup: 'const formData = { get(key) { const data = { email: "test@example.com" }; return data[key] || null; } };', + setupCode: 'const formData = { get(key) { const data = { email: "test@example.com" }; return data[key] || null; } };', + expected: 'test@example.com', + sample: 'formData.get("email")', + hints: ['Use get() method', 'Returns null if key not found'], + tags: ['FormData', 'forms', 'get'], + }, + { + id: 'js-dom-077', + category: 'Browser APIs', + difficulty: 'medium', + title: 'FormData from Form Element', + text: 'Create FormData from an existing form element.', + setup: 'const form = { elements: [{ name: "user", value: "alice" }, { name: "pass", value: "secret" }] }; const FormData = class { constructor(f) { this.data = {}; if(f) f.elements.forEach(e => this.data[e.name] = e.value); } };', + setupCode: 'const form = { elements: [{ name: "user", value: "alice" }, { name: "pass", value: "secret" }] }; const FormData = class { constructor(f) { this.data = {}; if(f) f.elements.forEach(e => this.data[e.name] = e.value); } };', + expected: { data: { user: 'alice', pass: 'secret' } }, + sample: 'new FormData(form)', + hints: ['Pass form element to constructor', 'Automatically captures all form fields'], + tags: ['FormData', 'forms', 'constructor'], + }, + { + id: 'js-dom-078', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Check if FormData Has Key', + text: 'Check if a key exists in FormData.', + setup: 'const formData = { has(key) { return ["name", "email", "age"].includes(key); } };', + setupCode: 'const formData = { has(key) { return ["name", "email", "age"].includes(key); } };', + expected: true, + sample: 'formData.has("email")', + hints: ['Use has() method', 'Returns boolean'], + tags: ['FormData', 'forms', 'has'], + }, + { + id: 'js-dom-079', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Delete FormData Entry', + text: 'Remove a field from FormData.', + setup: 'const formData = { data: { a: "1", b: "2", c: "3" }, delete(key) { delete this.data[key]; } };', + setupCode: 'const formData = { data: { a: "1", b: "2", c: "3" }, delete(key) { delete this.data[key]; } };', + expected: { data: { a: '1', c: '3' } }, + sample: 'formData.delete("b"); formData', + hints: ['Use delete() method', 'Removes specified key'], + tags: ['FormData', 'forms', 'delete'], + }, + { + id: 'js-dom-080', + category: 'Browser APIs', + difficulty: 'hard', + title: 'Iterate FormData Entries', + text: 'Convert FormData entries to an array of [key, value] pairs.', + setup: 'const formData = { entries() { return [["name", "John"], ["age", "30"], ["city", "NYC"]][Symbol.iterator](); } };', + setupCode: 'const formData = { entries() { return [["name", "John"], ["age", "30"], ["city", "NYC"]][Symbol.iterator](); } };', + expected: [['name', 'John'], ['age', '30'], ['city', 'NYC']], + sample: '[...formData.entries()]', + hints: ['Use entries() method', 'Spread into array'], + tags: ['FormData', 'forms', 'entries', 'iteration'], + }, + { + id: 'js-dom-081', + category: 'Browser APIs', + difficulty: 'hard', + title: 'FormData to Object', + text: 'Convert FormData to a plain JavaScript object.', + setup: 'const formData = { entries() { return [["firstName", "Jane"], ["lastName", "Doe"]][Symbol.iterator](); } };', + setupCode: 'const formData = { entries() { return [["firstName", "Jane"], ["lastName", "Doe"]][Symbol.iterator](); } };', + expected: { firstName: 'Jane', lastName: 'Doe' }, + sample: 'Object.fromEntries(formData.entries())', + hints: ['Use Object.fromEntries()', 'Pass entries iterator'], + tags: ['FormData', 'forms', 'conversion'], + }, + + // ======================================== + // BROWSER APIs - URLSearchParams + // ======================================== + { + id: 'js-dom-082', + category: 'Browser APIs', + difficulty: 'easy', + title: 'Create URLSearchParams', + text: 'Create URLSearchParams from a query string.', + setup: 'const URLSearchParams = class { constructor(str) { this.params = {}; str.replace("?", "").split("&").forEach(p => { const [k, v] = p.split("="); this.params[k] = v; }); } get(k) { return this.params[k]; } };', + setupCode: 'const URLSearchParams = class { constructor(str) { this.params = {}; str.replace("?", "").split("&").forEach(p => { const [k, v] = p.split("="); this.params[k] = v; }); } get(k) { return this.params[k]; } };', + expected: 'bar', + sample: 'new URLSearchParams("?foo=bar&baz=qux").get("foo")', + hints: ['Pass query string to constructor', 'Use get() to retrieve values'], + tags: ['URLSearchParams', 'url', 'query'], + }, + { + id: 'js-dom-083', + category: 'Browser APIs', + difficulty: 'easy', + title: 'Append Search Param', + text: 'Add a new parameter to URLSearchParams.', + setup: 'const params = { data: { page: "1" }, append(key, value) { this.data[key] = value; } };', + setupCode: 'const params = { data: { page: "1" }, append(key, value) { this.data[key] = value; } };', + expected: { data: { page: '1', limit: '10' } }, + sample: 'params.append("limit", "10"); params', + hints: ['Use append() method', 'Both key and value are strings'], + tags: ['URLSearchParams', 'url', 'append'], + }, + { + id: 'js-dom-084', + category: 'Browser APIs', + difficulty: 'easy', + title: 'Convert Params to String', + text: 'Convert URLSearchParams back to a query string.', + setup: 'const params = { toString() { return "name=John&age=25"; } };', + setupCode: 'const params = { toString() { return "name=John&age=25"; } };', + expected: 'name=John&age=25', + sample: 'params.toString()', + hints: ['Use toString() method', 'Returns URL-encoded string'], + tags: ['URLSearchParams', 'url', 'toString'], + }, + { + id: 'js-dom-085', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Set Search Param', + text: 'Set (replace) a parameter value.', + setup: 'const params = { data: { sort: "asc", filter: "active" }, set(key, value) { this.data[key] = value; } };', + setupCode: 'const params = { data: { sort: "asc", filter: "active" }, set(key, value) { this.data[key] = value; } };', + expected: { data: { sort: 'desc', filter: 'active' } }, + sample: 'params.set("sort", "desc"); params', + hints: ['Use set() to replace value', 'Unlike append, set replaces existing'], + tags: ['URLSearchParams', 'url', 'set'], + }, + { + id: 'js-dom-086', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Get All Param Values', + text: 'Get all values for a parameter that appears multiple times.', + setup: 'const params = { getAll(key) { return key === "tag" ? ["javascript", "web", "frontend"] : []; } };', + setupCode: 'const params = { getAll(key) { return key === "tag" ? ["javascript", "web", "frontend"] : []; } };', + expected: ['javascript', 'web', 'frontend'], + sample: 'params.getAll("tag")', + hints: ['Use getAll() for multiple values', 'Returns array of all values'], + tags: ['URLSearchParams', 'url', 'getAll'], + }, + { + id: 'js-dom-087', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Delete Search Param', + text: 'Remove a parameter from the URL.', + setup: 'const params = { data: { page: "1", sort: "asc", filter: "all" }, delete(key) { delete this.data[key]; } };', + setupCode: 'const params = { data: { page: "1", sort: "asc", filter: "all" }, delete(key) { delete this.data[key]; } };', + expected: { data: { page: '1', filter: 'all' } }, + sample: 'params.delete("sort"); params', + hints: ['Use delete() method', 'Removes all values for that key'], + tags: ['URLSearchParams', 'url', 'delete'], + }, + { + id: 'js-dom-088', + category: 'Browser APIs', + difficulty: 'hard', + title: 'Build URL with Params', + text: 'Construct a full URL with query parameters.', + setup: 'const base = "https://api.example.com/search"; const URLSearchParams = class { constructor(obj) { this.obj = obj; } toString() { return Object.entries(this.obj).map(([k,v]) => `${k}=${encodeURIComponent(v)}`).join("&"); } };', + setupCode: 'const base = "https://api.example.com/search"; const URLSearchParams = class { constructor(obj) { this.obj = obj; } toString() { return Object.entries(this.obj).map(([k,v]) => `${k}=${encodeURIComponent(v)}`).join("&"); } };', + expected: 'https://api.example.com/search?q=hello%20world&page=1', + sample: '`${base}?${new URLSearchParams({ q: "hello world", page: "1" })}`', + hints: ['Combine base URL with params', 'URLSearchParams handles encoding'], + tags: ['URLSearchParams', 'url', 'construction'], + }, + { + id: 'js-dom-089', + category: 'Browser APIs', + difficulty: 'hard', + title: 'Parse URL and Modify Params', + text: 'Extract search params from a URL and add a new parameter.', + setup: 'const URL = class { constructor(url) { this.searchParams = { data: { id: "123" }, set(k, v) { this.data[k] = v; }, toString() { return Object.entries(this.data).map(([k,v]) => `${k}=${v}`).join("&"); } }; this.origin = "https://example.com"; this.pathname = "/api"; } toString() { return `${this.origin}${this.pathname}?${this.searchParams}`; } };', + setupCode: 'const URL = class { constructor(url) { this.searchParams = { data: { id: "123" }, set(k, v) { this.data[k] = v; }, toString() { return Object.entries(this.data).map(([k,v]) => `${k}=${v}`).join("&"); } }; this.origin = "https://example.com"; this.pathname = "/api"; } toString() { return `${this.origin}${this.pathname}?${this.searchParams}`; } };', + expected: 'https://example.com/api?id=123&token=abc', + sample: 'const url = new URL("https://example.com/api?id=123"); url.searchParams.set("token", "abc"); url.toString()', + hints: ['URL object has searchParams property', 'Modify params then convert back'], + tags: ['URLSearchParams', 'URL', 'parsing'], + }, + + // ======================================== + // BROWSER APIs - IntersectionObserver + // ======================================== + { + id: 'js-dom-090', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Create IntersectionObserver', + text: 'Create an IntersectionObserver to detect when elements enter the viewport.', + setup: 'const IntersectionObserver = class { constructor(callback, options) { this.callback = callback; this.options = options; this.observing = []; } observe(el) { this.observing.push(el); } };', + setupCode: 'const IntersectionObserver = class { constructor(callback, options) { this.callback = callback; this.options = options; this.observing = []; } observe(el) { this.observing.push(el); } };', + expected: true, + sample: 'const observer = new IntersectionObserver((entries) => {}); typeof observer.observe === "function"', + hints: ['Pass callback as first argument', 'Options are optional second argument'], + tags: ['IntersectionObserver', 'visibility', 'scroll'], + }, + { + id: 'js-dom-091', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Observe an Element', + text: 'Start observing an element for intersection.', + setup: 'const el = { id: "target" }; const observer = { observing: [], observe(element) { this.observing.push(element); } };', + setupCode: 'const el = { id: "target" }; const observer = { observing: [], observe(element) { this.observing.push(element); } };', + expected: { observing: [{ id: 'target' }] }, + sample: 'observer.observe(el); observer', + hints: ['Call observe() with element', 'Observer will track the element'], + tags: ['IntersectionObserver', 'observe'], + }, + { + id: 'js-dom-092', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Unobserve Element', + text: 'Stop observing a specific element.', + setup: 'const el = { id: "target" }; const observer = { observing: [{ id: "target" }, { id: "other" }], unobserve(element) { this.observing = this.observing.filter(e => e.id !== element.id); } };', + setupCode: 'const el = { id: "target" }; const observer = { observing: [{ id: "target" }, { id: "other" }], unobserve(element) { this.observing = this.observing.filter(e => e.id !== element.id); } };', + expected: { observing: [{ id: 'other' }] }, + sample: 'observer.unobserve(el); observer', + hints: ['Use unobserve() method', 'Stops tracking specific element'], + tags: ['IntersectionObserver', 'unobserve'], + }, + { + id: 'js-dom-093', + category: 'Browser APIs', + difficulty: 'hard', + title: 'IntersectionObserver with Threshold', + text: 'Create an observer that fires at 50% visibility.', + setup: 'const IntersectionObserver = class { constructor(callback, options) { this.threshold = options?.threshold; } };', + setupCode: 'const IntersectionObserver = class { constructor(callback, options) { this.threshold = options?.threshold; } };', + expected: 0.5, + sample: 'new IntersectionObserver(() => {}, { threshold: 0.5 }).threshold', + hints: ['Set threshold in options', '0.5 means 50% visible'], + tags: ['IntersectionObserver', 'threshold', 'options'], + }, + { + id: 'js-dom-094', + category: 'Browser APIs', + difficulty: 'hard', + title: 'Handle Intersection Entry', + text: 'Check if an observed element is currently intersecting.', + setup: 'const entry = { target: { id: "lazy-img" }, isIntersecting: true, intersectionRatio: 0.75 };', + setupCode: 'const entry = { target: { id: "lazy-img" }, isIntersecting: true, intersectionRatio: 0.75 };', + expected: { visible: true, ratio: 0.75, elementId: 'lazy-img' }, + sample: '({ visible: entry.isIntersecting, ratio: entry.intersectionRatio, elementId: entry.target.id })', + hints: ['isIntersecting is a boolean', 'intersectionRatio is 0 to 1'], + tags: ['IntersectionObserver', 'entry', 'visibility'], + }, + { + id: 'js-dom-095', + category: 'Browser APIs', + difficulty: 'hard', + title: 'Lazy Load Images', + text: 'Implement lazy loading by setting src when element becomes visible.', + setup: 'const images = [{ dataset: { src: "image1.jpg" }, src: "" }, { dataset: { src: "image2.jpg" }, src: "" }]; const loadImage = (entry) => { if(entry.isIntersecting) entry.target.src = entry.target.dataset.src; }; const entries = [{ isIntersecting: true, target: images[0] }];', + setupCode: 'const images = [{ dataset: { src: "image1.jpg" }, src: "" }, { dataset: { src: "image2.jpg" }, src: "" }]; const loadImage = (entry) => { if(entry.isIntersecting) entry.target.src = entry.target.dataset.src; }; const entries = [{ isIntersecting: true, target: images[0] }];', + expected: [{ dataset: { src: 'image1.jpg' }, src: 'image1.jpg' }, { dataset: { src: 'image2.jpg' }, src: '' }], + sample: 'entries.forEach(loadImage); images', + hints: ['Check isIntersecting first', 'Copy data-src to src attribute'], + tags: ['IntersectionObserver', 'lazy-loading', 'images'], + }, + + // ======================================== + // BROWSER APIs - MutationObserver + // ======================================== + { + id: 'js-dom-096', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Create MutationObserver', + text: 'Create a MutationObserver to watch for DOM changes.', + setup: 'const MutationObserver = class { constructor(callback) { this.callback = callback; } observe(target, options) { this.target = target; this.options = options; } };', + setupCode: 'const MutationObserver = class { constructor(callback) { this.callback = callback; } observe(target, options) { this.target = target; this.options = options; } };', + expected: true, + sample: 'const observer = new MutationObserver((mutations) => {}); typeof observer.observe === "function"', + hints: ['Pass callback to constructor', 'Callback receives mutations array'], + tags: ['MutationObserver', 'dom', 'changes'], + }, + { + id: 'js-dom-097', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Observe Child Changes', + text: 'Configure MutationObserver to watch for added/removed children.', + setup: 'const target = { id: "container" }; const observer = { config: null, observe(el, options) { this.config = options; } };', + setupCode: 'const target = { id: "container" }; const observer = { config: null, observe(el, options) { this.config = options; } };', + expected: { config: { childList: true } }, + sample: 'observer.observe(target, { childList: true }); observer', + hints: ['Use childList: true option', 'Watches for child additions/removals'], + tags: ['MutationObserver', 'childList'], + }, + { + id: 'js-dom-098', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Observe Attribute Changes', + text: 'Watch for changes to element attributes.', + setup: 'const target = { id: "element" }; const observer = { config: null, observe(el, options) { this.config = options; } };', + setupCode: 'const target = { id: "element" }; const observer = { config: null, observe(el, options) { this.config = options; } };', + expected: { config: { attributes: true, attributeFilter: ['class', 'style'] } }, + sample: 'observer.observe(target, { attributes: true, attributeFilter: ["class", "style"] }); observer', + hints: ['Use attributes: true', 'attributeFilter limits which attributes'], + tags: ['MutationObserver', 'attributes'], + }, + { + id: 'js-dom-099', + category: 'Browser APIs', + difficulty: 'hard', + title: 'Observe Subtree Changes', + text: 'Watch for changes in all descendant elements.', + setup: 'const target = { id: "root" }; const observer = { config: null, observe(el, options) { this.config = options; } };', + setupCode: 'const target = { id: "root" }; const observer = { config: null, observe(el, options) { this.config = options; } };', + expected: { config: { childList: true, subtree: true } }, + sample: 'observer.observe(target, { childList: true, subtree: true }); observer', + hints: ['Add subtree: true option', 'Watches entire subtree, not just direct children'], + tags: ['MutationObserver', 'subtree'], + }, + { + id: 'js-dom-100', + category: 'Browser APIs', + difficulty: 'hard', + title: 'Process Mutation Records', + text: 'Extract added nodes from mutation records.', + setup: 'const mutations = [{ type: "childList", addedNodes: [{ id: "new1" }, { id: "new2" }], removedNodes: [] }, { type: "childList", addedNodes: [{ id: "new3" }], removedNodes: [{ id: "old1" }] }];', + setupCode: 'const mutations = [{ type: "childList", addedNodes: [{ id: "new1" }, { id: "new2" }], removedNodes: [] }, { type: "childList", addedNodes: [{ id: "new3" }], removedNodes: [{ id: "old1" }] }];', + expected: [{ id: 'new1' }, { id: 'new2' }, { id: 'new3' }], + sample: 'mutations.flatMap(m => [...m.addedNodes])', + hints: ['Each mutation has addedNodes', 'Use flatMap to combine arrays'], + tags: ['MutationObserver', 'mutations', 'addedNodes'], + }, + { + id: 'js-dom-101', + category: 'Browser APIs', + difficulty: 'hard', + title: 'Disconnect Observer', + text: 'Stop the MutationObserver from watching.', + setup: 'const observer = { watching: true, disconnect() { this.watching = false; } };', + setupCode: 'const observer = { watching: true, disconnect() { this.watching = false; } };', + expected: { watching: false }, + sample: 'observer.disconnect(); observer', + hints: ['Call disconnect() method', 'Stops all observations'], + tags: ['MutationObserver', 'disconnect'], + }, + + // ======================================== + // DOM MANIPULATION - Advanced + // ======================================== + { + id: 'js-dom-102', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Get Element by ID', + text: 'Select an element using getElementById.', + setup: 'const document = { getElementById: (id) => id === "header" ? { id: "header", tagName: "HEADER" } : null };', + setupCode: 'const document = { getElementById: (id) => id === "header" ? { id: "header", tagName: "HEADER" } : null };', + expected: { id: 'header', tagName: 'HEADER' }, + sample: 'document.getElementById("header")', + hints: ['Pass ID without # prefix', 'Returns single element or null'], + tags: ['dom', 'getElementById', 'selectors'], + }, + { + id: 'js-dom-103', + category: 'DOM Manipulation', + difficulty: 'easy', + title: 'Get Elements by Class Name', + text: 'Select all elements with a specific class name.', + setup: 'const document = { getElementsByClassName: (cls) => cls === "card" ? [{ className: "card" }, { className: "card" }] : [] };', + setupCode: 'const document = { getElementsByClassName: (cls) => cls === "card" ? [{ className: "card" }, { className: "card" }] : [] };', + expected: 2, + sample: 'document.getElementsByClassName("card").length', + hints: ['Pass class name without dot', 'Returns live HTMLCollection'], + tags: ['dom', 'getElementsByClassName', 'selectors'], + }, + { + id: 'js-dom-104', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Get Computed Style', + text: 'Get the computed color style of an element.', + setup: 'const el = { id: "box" }; const getComputedStyle = (element) => ({ color: "rgb(255, 0, 0)", fontSize: "16px" });', + setupCode: 'const el = { id: "box" }; const getComputedStyle = (element) => ({ color: "rgb(255, 0, 0)", fontSize: "16px" });', + expected: 'rgb(255, 0, 0)', + sample: 'getComputedStyle(el).color', + hints: ['Use getComputedStyle function', 'Returns CSSStyleDeclaration object'], + tags: ['dom', 'getComputedStyle', 'styles'], + }, + { + id: 'js-dom-105', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Set Inline Style', + text: 'Set the background color of an element using inline style.', + setup: 'const el = { style: { backgroundColor: "" } };', + setupCode: 'const el = { style: { backgroundColor: "" } };', + expected: { style: { backgroundColor: 'blue' } }, + sample: 'el.style.backgroundColor = "blue"; el', + hints: ['Access style property', 'Use camelCase for CSS properties'], + tags: ['dom', 'style', 'inline'], + }, + { + id: 'js-dom-106', + category: 'DOM Manipulation', + difficulty: 'medium', + title: 'Get Bounding Rectangle', + text: 'Get the position and dimensions of an element.', + setup: 'const el = { getBoundingClientRect: () => ({ top: 100, left: 50, width: 200, height: 150, bottom: 250, right: 250 }) };', + setupCode: 'const el = { getBoundingClientRect: () => ({ top: 100, left: 50, width: 200, height: 150, bottom: 250, right: 250 }) };', + expected: { top: 100, left: 50, width: 200, height: 150 }, + sample: 'const rect = el.getBoundingClientRect(); ({ top: rect.top, left: rect.left, width: rect.width, height: rect.height })', + hints: ['Use getBoundingClientRect()', 'Returns position relative to viewport'], + tags: ['dom', 'getBoundingClientRect', 'dimensions'], + }, + { + id: 'js-dom-107', + category: 'DOM Manipulation', + difficulty: 'hard', + title: 'Create Document Fragment', + text: 'Create a document fragment and append multiple elements efficiently.', + setup: 'const document = { createDocumentFragment: () => ({ children: [], appendChild(el) { this.children.push(el); return el; } }), createElement: (tag) => ({ tagName: tag.toUpperCase() }) };', + setupCode: 'const document = { createDocumentFragment: () => ({ children: [], appendChild(el) { this.children.push(el); return el; } }), createElement: (tag) => ({ tagName: tag.toUpperCase() }) };', + expected: { children: [{ tagName: 'DIV' }, { tagName: 'DIV' }, { tagName: 'DIV' }] }, + sample: 'const frag = document.createDocumentFragment(); for(let i = 0; i < 3; i++) frag.appendChild(document.createElement("div")); frag', + hints: ['Fragment is a lightweight container', 'Append multiple elements before adding to DOM'], + tags: ['dom', 'createDocumentFragment', 'performance'], + }, + { + id: 'js-dom-108', + category: 'Events', + difficulty: 'hard', + title: 'Custom Event Dispatch', + text: 'Create and dispatch a custom event with data.', + setup: 'const CustomEvent = class { constructor(type, options) { this.type = type; this.detail = options?.detail; } }; let received = null; const el = { dispatchEvent(event) { received = event; return true; } };', + setupCode: 'const CustomEvent = class { constructor(type, options) { this.type = type; this.detail = options?.detail; } }; let received = null; const el = { dispatchEvent(event) { received = event; return true; } };', + expected: { type: 'userAction', detail: { action: 'click', id: 42 } }, + sample: 'el.dispatchEvent(new CustomEvent("userAction", { detail: { action: "click", id: 42 } })); received', + hints: ['Use CustomEvent constructor', 'Pass data in detail property'], + tags: ['events', 'CustomEvent', 'dispatchEvent'], + }, + { + id: 'js-dom-109', + category: 'Browser APIs', + difficulty: 'medium', + title: 'Request Animation Frame', + text: 'Schedule a callback for the next repaint.', + setup: 'let scheduled = null; const requestAnimationFrame = (callback) => { scheduled = callback; return 123; };', + setupCode: 'let scheduled = null; const requestAnimationFrame = (callback) => { scheduled = callback; return 123; };', + expected: 123, + sample: 'requestAnimationFrame((timestamp) => { console.log("Frame at", timestamp); })', + hints: ['Returns a request ID', 'Callback receives timestamp'], + tags: ['requestAnimationFrame', 'animation', 'performance'], + }, + { + id: 'js-dom-110', + category: 'Browser APIs', + difficulty: 'hard', + title: 'Cancel Animation Frame', + text: 'Cancel a scheduled animation frame.', + setup: 'const frames = { 123: true, 456: true }; const cancelAnimationFrame = (id) => { delete frames[id]; };', + setupCode: 'const frames = { 123: true, 456: true }; const cancelAnimationFrame = (id) => { delete frames[id]; };', + expected: { '456': true }, + sample: 'cancelAnimationFrame(123); frames', + hints: ['Pass the request ID', 'Prevents callback from being called'], + tags: ['cancelAnimationFrame', 'animation', 'cleanup'], + }, ]; export default javascriptProblems; diff --git a/lib/problems/typescript.ts b/lib/problems/typescript.ts index 0f7a47b..bce6e0c 100644 --- a/lib/problems/typescript.ts +++ b/lib/problems/typescript.ts @@ -2549,6 +2549,8846 @@ export const typescriptProblems: Problem[] = [ validPatterns: [/\.filter\s*\([^)]+\)\.filter\s*\(/, /u\s+is\s+User\s*&/], tags: ['filter', 'chaining', 'progressive-narrowing', 'typed-array'], }, + + // ============================================================ + // Module & Declaration Patterns + // ============================================================ + { + id: 'ts-module-001', + category: 'Modules', + difficulty: 'easy', + title: 'Basic Named Export', + text: 'Create a named export for the add function that takes two numbers and returns their sum', + setup: '// Write your export statement', + setupCode: '// Write your export statement', + expected: 'export function add(a: number, b: number): number { return a + b; }', + sample: 'export function add(a: number, b: number): number { return a + b; }', + hints: [ + 'Use the export keyword before function', + 'Named exports use the function name as the export name', + ], + tags: ['modules', 'export', 'named-export'], + }, + { + id: 'ts-module-002', + category: 'Modules', + difficulty: 'easy', + title: 'Named Import Statement', + text: 'Import the multiply function from the ./math module', + setup: '// Import multiply from ./math', + setupCode: '// Import multiply from ./math', + expected: 'import { multiply } from "./math";', + sample: 'import { multiply } from "./math";', + hints: [ + 'Use curly braces for named imports', + 'The module path should be in quotes', + ], + tags: ['modules', 'import', 'named-import'], + }, + { + id: 'ts-module-003', + category: 'Modules', + difficulty: 'easy', + title: 'Default Export', + text: 'Create a default export for a Calculator class', + setup: 'class Calculator { add(a: number, b: number) { return a + b; } }', + setupCode: 'class Calculator { add(a: number, b: number) { return a + b; } }', + expected: 'export default Calculator', + sample: 'export default Calculator;', + hints: [ + 'Use export default for the main export', + 'Only one default export per module', + ], + tags: ['modules', 'export', 'default-export'], + }, + { + id: 'ts-module-004', + category: 'Modules', + difficulty: 'easy', + title: 'Import Default Export', + text: 'Import the default export from ./Calculator module', + setup: '// Import default Calculator', + setupCode: '// Import default Calculator', + expected: 'import Calculator from "./Calculator";', + sample: 'import Calculator from "./Calculator";', + hints: [ + 'Default imports do not use curly braces', + 'You can name the import anything you want', + ], + tags: ['modules', 'import', 'default-import'], + }, + { + id: 'ts-module-005', + category: 'Modules', + difficulty: 'easy', + title: 'Type-Only Import', + text: 'Import only the User type from ./types module using type-only import syntax', + setup: '// Import only the type, not the value', + setupCode: '// Import only the type, not the value', + expected: 'import type { User } from "./types";', + sample: 'import type { User } from "./types";', + hints: [ + 'Use import type for type-only imports', + 'Type-only imports are erased at compile time', + ], + tags: ['modules', 'import', 'type-only-import'], + }, + { + id: 'ts-module-006', + category: 'Modules', + difficulty: 'easy', + title: 'Export Type', + text: 'Export a type alias called Point that has x and y number properties', + setup: '// Export a Point type', + setupCode: '// Export a Point type', + expected: 'export type Point = { x: number; y: number };', + sample: 'export type Point = { x: number; y: number };', + hints: [ + 'Use export type for type exports', + 'Type aliases use the type keyword', + ], + tags: ['modules', 'export', 'type-export'], + }, + { + id: 'ts-module-007', + category: 'Modules', + difficulty: 'easy', + title: 'Export Interface', + text: 'Export an interface called Config with a name string property', + setup: '// Export a Config interface', + setupCode: '// Export a Config interface', + expected: 'export interface Config { name: string; }', + sample: 'export interface Config { name: string; }', + hints: [ + 'Interfaces can be exported directly', + 'Use the export keyword before interface', + ], + tags: ['modules', 'export', 'interface-export'], + }, + { + id: 'ts-module-008', + category: 'Modules', + difficulty: 'easy', + title: 'Aliased Import', + text: 'Import the utils function as helpers from ./utilities', + setup: '// Import utils as helpers', + setupCode: '// Import utils as helpers', + expected: 'import { utils as helpers } from "./utilities";', + sample: 'import { utils as helpers } from "./utilities";', + hints: [ + 'Use the as keyword to rename imports', + 'The original name comes before as', + ], + tags: ['modules', 'import', 'alias'], + }, + { + id: 'ts-module-009', + category: 'Modules', + difficulty: 'easy', + title: 'Namespace Import', + text: 'Import all exports from ./math as a namespace called MathUtils', + setup: '// Import everything as MathUtils', + setupCode: '// Import everything as MathUtils', + expected: 'import * as MathUtils from "./math";', + sample: 'import * as MathUtils from "./math";', + hints: [ + 'Use * as to import everything', + 'Access exports via MathUtils.functionName', + ], + tags: ['modules', 'import', 'namespace-import'], + }, + { + id: 'ts-module-010', + category: 'Modules', + difficulty: 'easy', + title: 'Re-export Named Export', + text: 'Re-export the format function from ./formatter module', + setup: '// Re-export format from ./formatter', + setupCode: '// Re-export format from ./formatter', + expected: 'export { format } from "./formatter";', + sample: 'export { format } from "./formatter";', + hints: [ + 'Combine export and from in one statement', + 'No import keyword needed for re-exports', + ], + tags: ['modules', 'export', 're-export'], + }, + { + id: 'ts-module-011', + category: 'Declarations', + difficulty: 'easy', + title: 'Declare Variable', + text: 'Declare an ambient variable VERSION of type string', + setup: '// Declare VERSION exists globally', + setupCode: '// Declare VERSION exists globally', + expected: 'declare const VERSION: string;', + sample: 'declare const VERSION: string;', + hints: [ + 'Use declare for ambient declarations', + 'No value assignment in ambient declarations', + ], + tags: ['declarations', 'declare', 'ambient'], + }, + { + id: 'ts-module-012', + category: 'Declarations', + difficulty: 'easy', + title: 'Declare Function', + text: 'Declare an ambient function called log that accepts a message string and returns void', + setup: '// Declare log function', + setupCode: '// Declare log function', + expected: 'declare function log(message: string): void;', + sample: 'declare function log(message: string): void;', + hints: [ + 'declare function defines function signature only', + 'No function body in ambient declarations', + ], + tags: ['declarations', 'declare', 'function'], + }, + { + id: 'ts-module-013', + category: 'Modules', + difficulty: 'easy', + title: 'Export Constant', + text: 'Export a constant called PI with value 3.14159', + setup: '// Export PI constant', + setupCode: '// Export PI constant', + expected: 'export const PI = 3.14159;', + sample: 'export const PI = 3.14159;', + hints: [ + 'Use export const for constant exports', + 'TypeScript infers the type from the value', + ], + tags: ['modules', 'export', 'constant'], + }, + { + id: 'ts-module-014', + category: 'Modules', + difficulty: 'easy', + title: 'Import Multiple Named Exports', + text: 'Import add, subtract, and multiply functions from ./math module', + setup: '// Import multiple functions', + setupCode: '// Import multiple functions', + expected: 'import { add, subtract, multiply } from "./math";', + sample: 'import { add, subtract, multiply } from "./math";', + hints: [ + 'Separate multiple imports with commas', + 'All names go inside the curly braces', + ], + tags: ['modules', 'import', 'multiple'], + }, + { + id: 'ts-module-015', + category: 'Modules', + difficulty: 'easy', + title: 'Export List', + text: 'Export firstName and lastName variables that are already defined', + setup: 'const firstName = "John";\nconst lastName = "Doe";', + setupCode: 'const firstName = "John";\nconst lastName = "Doe";', + expected: 'export { firstName, lastName };', + sample: 'export { firstName, lastName };', + hints: [ + 'Use export list syntax for existing variables', + 'Curly braces contain the names to export', + ], + tags: ['modules', 'export', 'export-list'], + }, + { + id: 'ts-module-016', + category: 'Declarations', + difficulty: 'easy', + title: 'Declare Class', + text: 'Declare an ambient class called Logger with a log method accepting string', + setup: '// Declare Logger class', + setupCode: '// Declare Logger class', + expected: 'declare class Logger { log(message: string): void; }', + sample: 'declare class Logger { log(message: string): void; }', + hints: [ + 'declare class defines class shape only', + 'Methods have signatures but no body', + ], + tags: ['declarations', 'declare', 'class'], + }, + { + id: 'ts-module-017', + category: 'Modules', + difficulty: 'easy', + title: 'Side Effect Import', + text: 'Import the ./polyfills module for its side effects only', + setup: '// Import for side effects only', + setupCode: '// Import for side effects only', + expected: 'import "./polyfills";', + sample: 'import "./polyfills";', + hints: [ + 'Omit the import clause for side-effect imports', + 'The module code runs but nothing is imported', + ], + tags: ['modules', 'import', 'side-effect'], + }, + { + id: 'ts-module-018', + category: 'Modules', + difficulty: 'easy', + title: 'Type-Only Re-export', + text: 'Re-export only the types UserType and ConfigType from ./types', + setup: '// Re-export types only', + setupCode: '// Re-export types only', + expected: 'export type { UserType, ConfigType } from "./types";', + sample: 'export type { UserType, ConfigType } from "./types";', + hints: [ + 'Use export type for type-only re-exports', + 'These are erased at compile time', + ], + tags: ['modules', 'export', 'type-only-export'], + }, + { + id: 'ts-module-019', + category: 'Modules', + difficulty: 'easy', + title: 'Import Default and Named', + text: 'Import default export as React and named export Component from "react"', + setup: '// Import React and Component', + setupCode: '// Import React and Component', + expected: 'import React, { Component } from "react";', + sample: 'import React, { Component } from "react";', + hints: [ + 'Default import comes first, then named imports', + 'Separate with comma before curly braces', + ], + tags: ['modules', 'import', 'mixed-import'], + }, + { + id: 'ts-module-020', + category: 'Declarations', + difficulty: 'easy', + title: 'Declare Namespace', + text: 'Declare a namespace called MyApp with a version string property', + setup: '// Declare MyApp namespace', + setupCode: '// Declare MyApp namespace', + expected: 'declare namespace MyApp { const version: string; }', + sample: 'declare namespace MyApp { const version: string; }', + hints: [ + 'Namespaces group related declarations', + 'Use declare namespace for ambient namespaces', + ], + tags: ['declarations', 'namespace', 'declare'], + }, + { + id: 'ts-module-021', + category: 'Modules', + difficulty: 'medium', + title: 'Module Augmentation', + text: 'Augment the express module to add a user property of type User to the Request interface', + setup: 'interface User { id: string; name: string; }', + setupCode: 'interface User { id: string; name: string; }', + expected: 'declare module "express" { interface Request { user: User; } }', + sample: 'declare module "express" { interface Request { user: User; } }', + hints: [ + 'Use declare module to augment existing modules', + 'Interface declarations merge automatically', + ], + tags: ['modules', 'augmentation', 'declaration-merging'], + }, + { + id: 'ts-module-022', + category: 'Namespaces', + difficulty: 'medium', + title: 'Declaration Merging with Interface', + text: 'Create a Box interface and a Box namespace that adds a create function', + setup: '// Merge interface and namespace', + setupCode: '// Merge interface and namespace', + expected: 'interface Box { width: number; height: number; }\nnamespace Box { export function create(): Box { return { width: 0, height: 0 }; } }', + sample: 'interface Box { width: number; height: number; }\nnamespace Box { export function create(): Box { return { width: 0, height: 0 }; } }', + hints: [ + 'Same name allows declaration merging', + 'Namespace adds static members to interface', + ], + tags: ['namespaces', 'declaration-merging', 'interface'], + }, + { + id: 'ts-module-023', + category: 'Modules', + difficulty: 'medium', + title: 'Global Augmentation', + text: 'Add a globalConfig property of type Config to the global scope', + setup: 'interface Config { debug: boolean; }', + setupCode: 'interface Config { debug: boolean; }', + expected: 'declare global { var globalConfig: Config; }', + sample: 'declare global { var globalConfig: Config; }', + hints: [ + 'Use declare global for global augmentation', + 'Must be inside a module (file with import/export)', + ], + tags: ['modules', 'global-augmentation', 'declare'], + }, + { + id: 'ts-module-024', + category: 'Declarations', + difficulty: 'medium', + title: 'Ambient Module Declaration', + text: 'Declare a module for *.css files that exports a default object with className strings', + setup: '// Declare CSS module type', + setupCode: '// Declare CSS module type', + expected: 'declare module "*.css" { const classes: { [key: string]: string }; export default classes; }', + sample: 'declare module "*.css" { const classes: { [key: string]: string }; export default classes; }', + hints: [ + 'Use wildcard patterns for file types', + 'Default export for CSS modules', + ], + tags: ['declarations', 'ambient-module', 'wildcard'], + }, + { + id: 'ts-module-025', + category: 'Modules', + difficulty: 'medium', + title: 'Re-export with Alias', + text: 'Re-export the default export from ./Button as ButtonComponent', + setup: '// Re-export default as named', + setupCode: '// Re-export default as named', + expected: 'export { default as ButtonComponent } from "./Button";', + sample: 'export { default as ButtonComponent } from "./Button";', + hints: [ + 'Use default as to rename default exports', + 'This converts default to named export', + ], + tags: ['modules', 're-export', 'alias'], + }, + { + id: 'ts-module-026', + category: 'Declarations', + difficulty: 'medium', + title: 'Triple-Slash Reference', + text: 'Add a triple-slash reference to include types from ./global.d.ts', + setup: '// Reference types file', + setupCode: '// Reference types file', + expected: '/// ', + sample: '/// ', + hints: [ + 'Triple-slash directives must be at file top', + 'Use reference path for local type files', + ], + tags: ['declarations', 'triple-slash', 'reference'], + }, + { + id: 'ts-module-027', + category: 'Declarations', + difficulty: 'medium', + title: 'Reference Types Package', + text: 'Add a triple-slash reference to include types from @types/node', + setup: '// Reference node types', + setupCode: '// Reference node types', + expected: '/// ', + sample: '/// ', + hints: [ + 'Use reference types for @types packages', + 'Omit the @types/ prefix', + ], + tags: ['declarations', 'triple-slash', 'types-package'], + }, + { + id: 'ts-module-028', + category: 'Modules', + difficulty: 'medium', + title: 'Export All from Module', + text: 'Re-export all exports from ./helpers module', + setup: '// Re-export everything', + setupCode: '// Re-export everything', + expected: 'export * from "./helpers";', + sample: 'export * from "./helpers";', + hints: [ + 'Use export * to re-export all named exports', + 'Does not include default export', + ], + tags: ['modules', 're-export', 'barrel'], + }, + { + id: 'ts-module-029', + category: 'Modules', + difficulty: 'medium', + title: 'Export All as Namespace', + text: 'Re-export all exports from ./validators as a namespace called Validators', + setup: '// Re-export all as namespace', + setupCode: '// Re-export all as namespace', + expected: 'export * as Validators from "./validators";', + sample: 'export * as Validators from "./validators";', + hints: [ + 'export * as creates a namespace export', + 'Access via Validators.functionName', + ], + tags: ['modules', 're-export', 'namespace'], + }, + { + id: 'ts-module-030', + category: 'Declarations', + difficulty: 'medium', + title: 'Declare Module with Types', + text: 'Declare a module "my-lib" that exports a Config interface and configure function', + setup: '// Declare my-lib module', + setupCode: '// Declare my-lib module', + expected: 'declare module "my-lib" { export interface Config { name: string; } export function configure(config: Config): void; }', + sample: 'declare module "my-lib" { export interface Config { name: string; } export function configure(config: Config): void; }', + hints: [ + 'Use declare module for ambient modules', + 'Export interfaces and functions normally inside', + ], + tags: ['declarations', 'ambient-module', 'types'], + }, + { + id: 'ts-module-031', + category: 'Namespaces', + difficulty: 'medium', + title: 'Nested Namespace', + text: 'Create a namespace App with nested namespace Utils containing a format function', + setup: '// Create nested namespaces', + setupCode: '// Create nested namespaces', + expected: 'namespace App { export namespace Utils { export function format(s: string): string { return s.trim(); } } }', + sample: 'namespace App { export namespace Utils { export function format(s: string): string { return s.trim(); } } }', + hints: [ + 'Namespaces can be nested', + 'Export inner namespace to make it accessible', + ], + tags: ['namespaces', 'nested', 'organization'], + }, + { + id: 'ts-module-032', + category: 'Declarations', + difficulty: 'medium', + title: 'Declare Global Function', + text: 'Declare that a global function gtag exists with specific signature for Google Analytics', + setup: '// Declare gtag function globally', + setupCode: '// Declare gtag function globally', + expected: 'declare function gtag(command: string, ...args: unknown[]): void;', + sample: 'declare function gtag(command: string, ...args: unknown[]): void;', + hints: [ + 'Global functions use declare function', + 'Rest parameters handle variable arguments', + ], + tags: ['declarations', 'global', 'function'], + }, + { + id: 'ts-module-033', + category: 'Modules', + difficulty: 'medium', + title: 'Inline Type Import', + text: 'Import a value and use inline type import for the UserProps type from ./user', + setup: '// Import value and type separately', + setupCode: '// Import value and type separately', + expected: 'import { User, type UserProps } from "./user";', + sample: 'import { User, type UserProps } from "./user";', + hints: [ + 'Use type keyword inline for individual imports', + 'Mixes value and type imports', + ], + tags: ['modules', 'import', 'inline-type'], + }, + { + id: 'ts-module-034', + category: 'Namespaces', + difficulty: 'medium', + title: 'Namespace with Class', + text: 'Create a namespace Shapes with an exported Circle class', + setup: '// Create Shapes namespace', + setupCode: '// Create Shapes namespace', + expected: 'namespace Shapes { export class Circle { constructor(public radius: number) {} area() { return Math.PI * this.radius ** 2; } } }', + sample: 'namespace Shapes { export class Circle { constructor(public radius: number) {} area() { return Math.PI * this.radius ** 2; } } }', + hints: [ + 'Classes can be exported from namespaces', + 'Access via Shapes.Circle', + ], + tags: ['namespaces', 'class', 'export'], + }, + { + id: 'ts-module-035', + category: 'Declarations', + difficulty: 'medium', + title: 'Declare Enum', + text: 'Declare an ambient const enum called Direction with North, South, East, West', + setup: '// Declare Direction enum', + setupCode: '// Declare Direction enum', + expected: 'declare const enum Direction { North, South, East, West }', + sample: 'declare const enum Direction { North, South, East, West }', + hints: [ + 'declare const enum is inlined at compile time', + 'Values are not needed in ambient enums', + ], + tags: ['declarations', 'enum', 'const-enum'], + }, + { + id: 'ts-module-036', + category: 'Modules', + difficulty: 'medium', + title: 'Dynamic Import Type', + text: 'Create a type for the dynamically imported Button module', + setup: '// Type for dynamic import', + setupCode: '// Type for dynamic import', + expected: 'type ButtonModule = typeof import("./Button");', + sample: 'type ButtonModule = typeof import("./Button");', + hints: [ + 'typeof import() gets the module type', + 'Useful for lazy loading type checking', + ], + tags: ['modules', 'dynamic-import', 'typeof'], + }, + { + id: 'ts-module-037', + category: 'Declarations', + difficulty: 'medium', + title: 'Declare Window Extension', + text: 'Extend the Window interface to include an analytics property', + setup: 'interface Analytics { track(event: string): void; }', + setupCode: 'interface Analytics { track(event: string): void; }', + expected: 'declare global { interface Window { analytics: Analytics; } }', + sample: 'declare global { interface Window { analytics: Analytics; } }', + hints: [ + 'Window is a global interface', + 'Use declare global to extend it', + ], + tags: ['declarations', 'global', 'window'], + }, + { + id: 'ts-module-038', + category: 'Modules', + difficulty: 'medium', + title: 'Conditional Export Type', + text: 'Export a type that extracts the return type of the exported function from a module', + setup: 'export function getData(): Promise { return Promise.resolve([]); }', + setupCode: 'export function getData(): Promise { return Promise.resolve([]); }', + expected: 'export type DataResult = Awaited>;', + sample: 'export type DataResult = Awaited>;', + hints: [ + 'Use ReturnType to extract function return type', + 'Awaited unwraps Promise types', + ], + tags: ['modules', 'export', 'utility-types'], + }, + { + id: 'ts-module-039', + category: 'Declarations', + difficulty: 'medium', + title: 'Ambient Variable with Union', + text: 'Declare a global ENV variable that can be "development", "staging", or "production"', + setup: '// Declare ENV variable', + setupCode: '// Declare ENV variable', + expected: 'declare const ENV: "development" | "staging" | "production";', + sample: 'declare const ENV: "development" | "staging" | "production";', + hints: [ + 'Use literal union types for specific values', + 'declare const for immutable globals', + ], + tags: ['declarations', 'ambient', 'literal-types'], + }, + { + id: 'ts-module-040', + category: 'Namespaces', + difficulty: 'medium', + title: 'Namespace Alias', + text: 'Create an alias IO for the deeply nested App.Services.IO namespace', + setup: 'namespace App { export namespace Services { export namespace IO { export function read(): string { return ""; } } } }', + setupCode: 'namespace App { export namespace Services { export namespace IO { export function read(): string { return ""; } } } }', + expected: 'import IO = App.Services.IO;', + sample: 'import IO = App.Services.IO;', + hints: [ + 'import = creates namespace aliases', + 'Simplifies access to nested namespaces', + ], + tags: ['namespaces', 'alias', 'import'], + }, + { + id: 'ts-module-041', + category: 'Modules', + difficulty: 'medium', + title: 'Assert Module Type', + text: 'Import JSON data with type assertion for import attributes', + setup: '// Import JSON with assertion', + setupCode: '// Import JSON with assertion', + expected: 'import data from "./config.json" with { type: "json" };', + sample: 'import data from "./config.json" with { type: "json" };', + hints: [ + 'Import attributes use with clause', + 'type: "json" asserts JSON module type', + ], + tags: ['modules', 'import', 'assertion'], + }, + { + id: 'ts-module-042', + category: 'Declarations', + difficulty: 'medium', + title: 'Module Declaration for Images', + text: 'Declare a module for *.png files that exports a string (the image URL)', + setup: '// Declare PNG module', + setupCode: '// Declare PNG module', + expected: 'declare module "*.png" { const src: string; export default src; }', + sample: 'declare module "*.png" { const src: string; export default src; }', + hints: [ + 'Image imports typically resolve to URLs', + 'Use wildcard for file extensions', + ], + tags: ['declarations', 'ambient-module', 'assets'], + }, + { + id: 'ts-module-043', + category: 'Modules', + difficulty: 'hard', + title: 'Augment Third-Party Module Types', + text: 'Augment lodash to add a custom mixin function called deepFreeze', + setup: '// Augment lodash module', + setupCode: '// Augment lodash module', + expected: 'declare module "lodash" { interface LoDashStatic { deepFreeze(obj: T): Readonly; } }', + sample: 'declare module "lodash" { interface LoDashStatic { deepFreeze(obj: T): Readonly; } }', + hints: [ + 'Find the main interface to extend', + 'LoDashStatic is the main lodash type', + ], + tags: ['modules', 'augmentation', 'third-party'], + }, + { + id: 'ts-module-044', + category: 'Declarations', + difficulty: 'hard', + title: 'Declare Global with Overloads', + text: 'Declare a global fetch function with overloads for string and Request input', + setup: '// Declare fetch overloads', + setupCode: '// Declare fetch overloads', + expected: 'declare function fetch(url: string, init?: RequestInit): Promise;\ndeclare function fetch(input: Request, init?: RequestInit): Promise;', + sample: 'declare function fetch(url: string, init?: RequestInit): Promise;\ndeclare function fetch(input: Request, init?: RequestInit): Promise;', + hints: [ + 'Multiple declare function statements for overloads', + 'Each overload has different parameter types', + ], + tags: ['declarations', 'overloads', 'global'], + }, + { + id: 'ts-module-045', + category: 'Namespaces', + difficulty: 'hard', + title: 'Merge Class and Namespace', + text: 'Create an Animal class and namespace that adds a static fromJSON factory method', + setup: '// Merge class with namespace', + setupCode: '// Merge class with namespace', + expected: 'class Animal { constructor(public name: string) {} }\nnamespace Animal { export function fromJSON(json: string): Animal { const data = JSON.parse(json); return new Animal(data.name); } }', + sample: 'class Animal { constructor(public name: string) {} }\nnamespace Animal { export function fromJSON(json: string): Animal { const data = JSON.parse(json); return new Animal(data.name); } }', + hints: [ + 'Namespaces merge with classes of same name', + 'Adds static-like methods to the class', + ], + tags: ['namespaces', 'declaration-merging', 'class'], + }, + { + id: 'ts-module-046', + category: 'Modules', + difficulty: 'hard', + title: 'Generic Module Re-export', + text: 'Create a barrel file that re-exports and renames generically typed components', + setup: '// Re-export with generic type preservation', + setupCode: '// Re-export with generic type preservation', + expected: 'export { List as GenericList } from "./List";\nexport type { ListProps as GenericListProps } from "./List";', + sample: 'export { List as GenericList } from "./List";\nexport type { ListProps as GenericListProps } from "./List";', + hints: [ + 'Generics are preserved in re-exports', + 'Separate value and type re-exports', + ], + tags: ['modules', 're-export', 'generics'], + }, + { + id: 'ts-module-047', + category: 'Declarations', + difficulty: 'hard', + title: 'Declare Module with Generics', + text: 'Declare a module "typed-storage" with get/set methods that preserve types', + setup: '// Declare typed-storage module', + setupCode: '// Declare typed-storage module', + expected: 'declare module "typed-storage" { export function get(key: string): T | null; export function set(key: string, value: T): void; }', + sample: 'declare module "typed-storage" { export function get(key: string): T | null; export function set(key: string, value: T): void; }', + hints: [ + 'Generic functions work in module declarations', + 'Type parameter flows through usage', + ], + tags: ['declarations', 'ambient-module', 'generics'], + }, + { + id: 'ts-module-048', + category: 'Modules', + difficulty: 'hard', + title: 'Conditional Module Augmentation', + text: 'Augment process.env to have strictly typed environment variables', + setup: '// Type process.env variables', + setupCode: '// Type process.env variables', + expected: 'declare global { namespace NodeJS { interface ProcessEnv { NODE_ENV: "development" | "production" | "test"; PORT?: string; DATABASE_URL: string; } } }', + sample: 'declare global { namespace NodeJS { interface ProcessEnv { NODE_ENV: "development" | "production" | "test"; PORT?: string; DATABASE_URL: string; } } }', + hints: [ + 'ProcessEnv is in NodeJS namespace', + 'Use literal types for known values', + ], + tags: ['modules', 'global-augmentation', 'node'], + }, + { + id: 'ts-module-049', + category: 'Namespaces', + difficulty: 'hard', + title: 'Enum and Namespace Merge', + text: 'Create a Status enum and merge with namespace to add helper functions', + setup: '// Merge enum with namespace', + setupCode: '// Merge enum with namespace', + expected: 'enum Status { Pending, Active, Completed }\nnamespace Status { export function isTerminal(status: Status): boolean { return status === Status.Completed; } }', + sample: 'enum Status { Pending, Active, Completed }\nnamespace Status { export function isTerminal(status: Status): boolean { return status === Status.Completed; } }', + hints: [ + 'Enums can merge with namespaces', + 'Adds utility functions to enum', + ], + tags: ['namespaces', 'declaration-merging', 'enum'], + }, + { + id: 'ts-module-050', + category: 'Declarations', + difficulty: 'hard', + title: 'Complex Ambient Interface', + text: 'Declare an ambient interface for a jQuery-like library with chainable methods', + setup: '// Declare jQuery-like interface', + setupCode: '// Declare jQuery-like interface', + expected: 'declare interface JQuery { addClass(className: string): this; removeClass(className: string): this; on(event: string, handler: (e: Event) => void): this; find(selector: string): JQuery; }', + sample: 'declare interface JQuery { addClass(className: string): this; removeClass(className: string): this; on(event: string, handler: (e: Event) => void): this; find(selector: string): JQuery; }', + hints: [ + 'Use this return type for chaining', + 'Generic parameter for element type', + ], + tags: ['declarations', 'interface', 'chainable'], + }, + { + id: 'ts-module-051', + category: 'Modules', + difficulty: 'easy', + title: 'Export Default Function', + text: 'Export a default function called greet that takes a name and returns a greeting', + setup: '// Export default function', + setupCode: '// Export default function', + expected: 'export default function greet(name: string): string { return `Hello, ${name}!`; }', + sample: 'export default function greet(name: string): string { return `Hello, ${name}!`; }', + hints: [ + 'export default can be used with function declarations', + 'The function can be named or anonymous', + ], + tags: ['modules', 'export', 'default-function'], + }, + { + id: 'ts-module-052', + category: 'Modules', + difficulty: 'easy', + title: 'Export Default Class', + text: 'Export a default class called Person with name property', + setup: '// Export default class', + setupCode: '// Export default class', + expected: 'export default class Person { constructor(public name: string) {} }', + sample: 'export default class Person { constructor(public name: string) {} }', + hints: [ + 'export default works directly with class declarations', + 'Parameter properties simplify constructor', + ], + tags: ['modules', 'export', 'default-class'], + }, + { + id: 'ts-module-053', + category: 'Declarations', + difficulty: 'easy', + title: 'Declare Type Alias', + text: 'Declare an ambient type alias ID that is a string', + setup: '// Declare ID type', + setupCode: '// Declare ID type', + expected: 'declare type ID = string;', + sample: 'declare type ID = string;', + hints: [ + 'declare type creates ambient type aliases', + 'Useful in .d.ts files', + ], + tags: ['declarations', 'type-alias', 'ambient'], + }, + { + id: 'ts-module-054', + category: 'Modules', + difficulty: 'easy', + title: 'Export Enum', + text: 'Export an enum called Color with Red, Green, Blue values', + setup: '// Export Color enum', + setupCode: '// Export Color enum', + expected: 'export enum Color { Red, Green, Blue }', + sample: 'export enum Color { Red, Green, Blue }', + hints: [ + 'Enums can be exported directly', + 'Values are auto-numbered from 0', + ], + tags: ['modules', 'export', 'enum'], + }, + { + id: 'ts-module-055', + category: 'Modules', + difficulty: 'easy', + title: 'Import Enum', + text: 'Import the Status enum from ./status module', + setup: '// Import Status enum', + setupCode: '// Import Status enum', + expected: 'import { Status } from "./status";', + sample: 'import { Status } from "./status";', + hints: [ + 'Enums are imported like regular values', + 'They are both types and values', + ], + tags: ['modules', 'import', 'enum'], + }, + { + id: 'ts-module-056', + category: 'Declarations', + difficulty: 'easy', + title: 'Declare Interface', + text: 'Declare an ambient interface called Point with x and y number properties', + setup: '// Declare Point interface', + setupCode: '// Declare Point interface', + expected: 'declare interface Point { x: number; y: number; }', + sample: 'declare interface Point { x: number; y: number; }', + hints: [ + 'declare interface for ambient interfaces', + 'Commonly used in .d.ts files', + ], + tags: ['declarations', 'interface', 'ambient'], + }, + { + id: 'ts-module-057', + category: 'Modules', + difficulty: 'easy', + title: 'Export As Clause', + text: 'Export the internal _helper function as publicHelper', + setup: 'function _helper() { return "help"; }', + setupCode: 'function _helper() { return "help"; }', + expected: 'export { _helper as publicHelper };', + sample: 'export { _helper as publicHelper };', + hints: [ + 'Use as to rename during export', + 'Internal names can be hidden', + ], + tags: ['modules', 'export', 'alias'], + }, + { + id: 'ts-module-058', + category: 'Modules', + difficulty: 'easy', + title: 'Import Type Inline', + text: 'Import only the Config type using inline type modifier from ./config', + setup: '// Import Config as type', + setupCode: '// Import Config as type', + expected: 'import { type Config } from "./config";', + sample: 'import { type Config } from "./config";', + hints: [ + 'type modifier before the import name', + 'Erased during compilation', + ], + tags: ['modules', 'import', 'inline-type'], + }, + { + id: 'ts-module-059', + category: 'Declarations', + difficulty: 'easy', + title: 'Declare Let Variable', + text: 'Declare an ambient mutable variable currentUser of type User or null', + setup: 'interface User { name: string; }', + setupCode: 'interface User { name: string; }', + expected: 'declare let currentUser: User | null;', + sample: 'declare let currentUser: User | null;', + hints: [ + 'Use declare let for mutable globals', + 'Union with null for nullable variables', + ], + tags: ['declarations', 'declare', 'let'], + }, + { + id: 'ts-module-060', + category: 'Modules', + difficulty: 'easy', + title: 'Re-export Default as Named', + text: 'Re-export the default export from ./Modal as ModalDialog', + setup: '// Re-export default as named', + setupCode: '// Re-export default as named', + expected: 'export { default as ModalDialog } from "./Modal";', + sample: 'export { default as ModalDialog } from "./Modal";', + hints: [ + 'default can be used as identifier in re-exports', + 'Converts default to named export', + ], + tags: ['modules', 're-export', 'default-to-named'], + }, + { + id: 'ts-module-061', + category: 'Namespaces', + difficulty: 'medium', + title: 'Namespace with Interface', + text: 'Create a namespace API with an exported Response interface', + setup: '// Create API namespace', + setupCode: '// Create API namespace', + expected: 'namespace API { export interface Response { data: T; status: number; message: string; } }', + sample: 'namespace API { export interface Response { data: T; status: number; message: string; } }', + hints: [ + 'Interfaces can be exported from namespaces', + 'Generics work inside namespaces', + ], + tags: ['namespaces', 'interface', 'generics'], + }, + { + id: 'ts-module-062', + category: 'Modules', + difficulty: 'medium', + title: 'Augment Array Prototype', + text: 'Add a last() method to the Array interface that returns the last element', + setup: '// Augment Array', + setupCode: '// Augment Array', + expected: 'declare global { interface Array { last(): T | undefined; } }', + sample: 'declare global { interface Array { last(): T | undefined; } }', + hints: [ + 'Array is a global generic interface', + 'Use declare global to extend', + ], + tags: ['modules', 'global-augmentation', 'array'], + }, + { + id: 'ts-module-063', + category: 'Declarations', + difficulty: 'medium', + title: 'Declare Class with Static', + text: 'Declare an ambient class Math with static methods abs and sqrt', + setup: '// Declare Math class', + setupCode: '// Declare Math class', + expected: 'declare class Math { static abs(x: number): number; static sqrt(x: number): number; }', + sample: 'declare class Math { static abs(x: number): number; static sqrt(x: number): number; }', + hints: [ + 'Static members use static keyword', + 'No implementation in ambient declarations', + ], + tags: ['declarations', 'class', 'static'], + }, + { + id: 'ts-module-064', + category: 'Modules', + difficulty: 'medium', + title: 'Import JSON Module', + text: 'Import a JSON configuration file with proper typing', + setup: '// Import JSON with types', + setupCode: '// Import JSON with types', + expected: 'import config from "./config.json";\ntype ConfigType = typeof config;', + sample: 'import config from "./config.json";\ntype ConfigType = typeof config;', + hints: [ + 'Enable resolveJsonModule in tsconfig', + 'typeof extracts the inferred type', + ], + tags: ['modules', 'import', 'json'], + }, + { + id: 'ts-module-065', + category: 'Namespaces', + difficulty: 'medium', + title: 'Namespace Interface Merge', + text: 'Merge a Vehicle interface with a Vehicle namespace containing a create function', + setup: '// Merge Vehicle interface and namespace', + setupCode: '// Merge Vehicle interface and namespace', + expected: 'interface Vehicle { wheels: number; brand: string; }\nnamespace Vehicle { export function create(brand: string, wheels: number): Vehicle { return { brand, wheels }; } }', + sample: 'interface Vehicle { wheels: number; brand: string; }\nnamespace Vehicle { export function create(brand: string, wheels: number): Vehicle { return { brand, wheels }; } }', + hints: [ + 'Same name enables merging', + 'Namespace adds static utilities', + ], + tags: ['namespaces', 'declaration-merging', 'factory'], + }, + { + id: 'ts-module-066', + category: 'Declarations', + difficulty: 'medium', + title: 'Declare Constructor Type', + text: 'Declare a constructor type for classes that can be instantiated with new', + setup: '// Declare constructor type', + setupCode: '// Declare constructor type', + expected: 'declare type Constructor = new (...args: unknown[]) => T;', + sample: 'declare type Constructor = new (...args: unknown[]) => T;', + hints: [ + 'new keyword in type indicates constructor', + 'Generic for return instance type', + ], + tags: ['declarations', 'constructor', 'generics'], + }, + { + id: 'ts-module-067', + category: 'Modules', + difficulty: 'medium', + title: 'Export Type Query', + text: 'Export a type that represents all keys of the exported Config object', + setup: 'export const Config = { debug: true, version: "1.0", maxRetries: 3 };', + setupCode: 'export const Config = { debug: true, version: "1.0", maxRetries: 3 };', + expected: 'export type ConfigKeys = keyof typeof Config;', + sample: 'export type ConfigKeys = keyof typeof Config;', + hints: [ + 'typeof gets the type of a value', + 'keyof extracts the keys as a union', + ], + tags: ['modules', 'export', 'keyof'], + }, + { + id: 'ts-module-068', + category: 'Declarations', + difficulty: 'medium', + title: 'Declare Index Signature', + text: 'Declare an ambient interface for a dictionary with string keys and number values', + setup: '// Declare Dictionary interface', + setupCode: '// Declare Dictionary interface', + expected: 'declare interface NumberDict { [key: string]: number; }', + sample: 'declare interface NumberDict { [key: string]: number; }', + hints: [ + 'Index signature uses [key: type]: valueType', + 'All string keys map to numbers', + ], + tags: ['declarations', 'interface', 'index-signature'], + }, + { + id: 'ts-module-069', + category: 'Modules', + difficulty: 'medium', + title: 'Module Path Alias', + text: 'Declare a path alias module @utils that maps to ./src/utils', + setup: '// In .d.ts file: declare @utils module', + setupCode: '// In .d.ts file: declare @utils module', + expected: 'declare module "@utils" { export * from "./src/utils"; }', + sample: 'declare module "@utils" { export * from "./src/utils"; }', + hints: [ + 'Path aliases need module declarations', + 'Re-export actual module contents', + ], + tags: ['modules', 'path-alias', 'declaration'], + }, + { + id: 'ts-module-070', + category: 'Namespaces', + difficulty: 'medium', + title: 'Namespace with Types', + text: 'Create a namespace Http with Status type and StatusCode interface', + setup: '// Create Http namespace with types', + setupCode: '// Create Http namespace with types', + expected: 'namespace Http { export type Status = "success" | "error" | "pending"; export interface StatusCode { code: number; message: string; } }', + sample: 'namespace Http { export type Status = "success" | "error" | "pending"; export interface StatusCode { code: number; message: string; } }', + hints: [ + 'Types and interfaces work in namespaces', + 'Export makes them accessible outside', + ], + tags: ['namespaces', 'types', 'interface'], + }, + { + id: 'ts-module-071', + category: 'Declarations', + difficulty: 'medium', + title: 'Reference Lib Directive', + text: 'Add a triple-slash reference to include ES2015 library definitions', + setup: '// Reference ES2015 lib', + setupCode: '// Reference ES2015 lib', + expected: '/// ', + sample: '/// ', + hints: [ + 'lib references include built-in type libs', + 'Corresponds to tsconfig lib options', + ], + tags: ['declarations', 'triple-slash', 'lib'], + }, + { + id: 'ts-module-072', + category: 'Modules', + difficulty: 'medium', + title: 'Import Meta Type', + text: 'Type the import.meta object to include custom properties', + setup: '// Type import.meta', + setupCode: '// Type import.meta', + expected: 'interface ImportMeta { env: { MODE: string; BASE_URL: string }; }', + sample: 'interface ImportMeta { env: { MODE: string; BASE_URL: string }; }', + hints: [ + 'ImportMeta is a special global interface', + 'Used by bundlers like Vite', + ], + tags: ['modules', 'import-meta', 'interface'], + }, + { + id: 'ts-module-073', + category: 'Declarations', + difficulty: 'hard', + title: 'Declare Callable Interface', + text: 'Declare an interface for a function that is also an object with methods', + setup: '// Declare callable with properties', + setupCode: '// Declare callable with properties', + expected: 'declare interface Logger { (message: string): void; level: "info" | "warn" | "error"; setLevel(level: Logger["level"]): void; }', + sample: 'declare interface Logger { (message: string): void; level: "info" | "warn" | "error"; setLevel(level: Logger["level"]): void; }', + hints: [ + 'Call signature makes interface callable', + 'Add properties and methods as normal', + ], + tags: ['declarations', 'interface', 'callable'], + }, + { + id: 'ts-module-074', + category: 'Modules', + difficulty: 'hard', + title: 'Plugin Module Augmentation', + text: 'Create a plugin system where plugins augment a Plugin interface', + setup: 'interface Plugin { name: string; }', + setupCode: 'interface Plugin { name: string; }', + expected: 'declare module "./core" { interface Plugin { hooks?: { beforeRun?: () => void; afterRun?: () => void }; } }', + sample: 'declare module "./core" { interface Plugin { hooks?: { beforeRun?: () => void; afterRun?: () => void }; } }', + hints: [ + 'Module augmentation extends existing interfaces', + 'Properties are merged into the interface', + ], + tags: ['modules', 'augmentation', 'plugin'], + }, + { + id: 'ts-module-075', + category: 'Namespaces', + difficulty: 'hard', + title: 'Function and Namespace Merge', + text: 'Create a function foo and namespace foo that adds configuration', + setup: '// Merge function with namespace', + setupCode: '// Merge function with namespace', + expected: 'function foo(x: number): number { return x * foo.multiplier; }\nnamespace foo { export let multiplier = 2; export function reset() { multiplier = 2; } }', + sample: 'function foo(x: number): number { return x * foo.multiplier; }\nnamespace foo { export let multiplier = 2; export function reset() { multiplier = 2; } }', + hints: [ + 'Functions can merge with namespaces', + 'Adds properties to the function object', + ], + tags: ['namespaces', 'declaration-merging', 'function'], + }, + { + id: 'ts-module-076', + category: 'Declarations', + difficulty: 'hard', + title: 'Mapped Type in Declaration', + text: 'Declare an ambient type that makes all properties of T optional and readonly', + setup: '// Declare DeepPartial type', + setupCode: '// Declare DeepPartial type', + expected: 'declare type DeepReadonlyPartial = { readonly [P in keyof T]?: T[P] extends object ? DeepReadonlyPartial : T[P]; };', + sample: 'declare type DeepReadonlyPartial = { readonly [P in keyof T]?: T[P] extends object ? DeepReadonlyPartial : T[P]; };', + hints: [ + 'Mapped types iterate over keys', + 'Recursive for nested objects', + ], + tags: ['declarations', 'mapped-types', 'recursive'], + }, + { + id: 'ts-module-077', + category: 'Modules', + difficulty: 'hard', + title: 'Conditional Export Types', + text: 'Export different types based on a configuration type parameter', + setup: 'interface Config { strict: boolean; }', + setupCode: 'interface Config { strict: boolean; }', + expected: 'export type ApiResponse = C["strict"] extends true ? { data: unknown; errors: never } : { data: unknown; errors?: string[] };', + sample: 'export type ApiResponse = C["strict"] extends true ? { data: unknown; errors: never } : { data: unknown; errors?: string[] };', + hints: [ + 'Conditional types use extends', + 'Index access reads config properties', + ], + tags: ['modules', 'export', 'conditional-types'], + }, + { + id: 'ts-module-078', + category: 'Declarations', + difficulty: 'hard', + title: 'Declare Method Overloads', + text: 'Declare a createElement function with overloads for different tag names', + setup: '// Declare createElement overloads', + setupCode: '// Declare createElement overloads', + expected: 'declare function createElement(tag: "div"): HTMLDivElement;\ndeclare function createElement(tag: "span"): HTMLSpanElement;\ndeclare function createElement(tag: string): HTMLElement;', + sample: 'declare function createElement(tag: "div"): HTMLDivElement;\ndeclare function createElement(tag: "span"): HTMLSpanElement;\ndeclare function createElement(tag: string): HTMLElement;', + hints: [ + 'Literal type overloads come first', + 'General string overload is last', + ], + tags: ['declarations', 'overloads', 'dom'], + }, + { + id: 'ts-module-079', + category: 'Namespaces', + difficulty: 'hard', + title: 'Ambient Namespace Merge', + text: 'Augment the global NodeJS namespace to add custom process properties', + setup: '// Augment NodeJS namespace', + setupCode: '// Augment NodeJS namespace', + expected: 'declare namespace NodeJS { interface Process { customProperty: string; customMethod(): void; } }', + sample: 'declare namespace NodeJS { interface Process { customProperty: string; customMethod(): void; } }', + hints: [ + 'NodeJS is a global namespace', + 'Process interface can be extended', + ], + tags: ['namespaces', 'ambient', 'node'], + }, + { + id: 'ts-module-080', + category: 'Modules', + difficulty: 'hard', + title: 'Template Literal Module', + text: 'Declare a module pattern for locale files using template literals', + setup: '// Declare locale module pattern', + setupCode: '// Declare locale module pattern', + expected: 'declare module `./locales/${string}.json` { const translations: Record; export default translations; }', + sample: 'declare module `./locales/${string}.json` { const translations: Record; export default translations; }', + hints: [ + 'Template literal modules match patterns', + 'Useful for dynamic file imports', + ], + tags: ['modules', 'ambient-module', 'template-literal'], + }, + { + id: 'ts-module-081', + category: 'Declarations', + difficulty: 'hard', + title: 'Declare Hybrid Type', + text: 'Declare an interface that acts as both a function and a constructor', + setup: '// Declare hybrid function/constructor', + setupCode: '// Declare hybrid function/constructor', + expected: 'declare interface DateConstructor { (): string; new (): Date; parse(s: string): number; UTC(...values: number[]): number; }', + sample: 'declare interface DateConstructor { (): string; new (): Date; parse(s: string): number; UTC(...values: number[]): number; }', + hints: [ + 'Call signature for function behavior', + 'Construct signature for new behavior', + ], + tags: ['declarations', 'interface', 'hybrid'], + }, + { + id: 'ts-module-082', + category: 'Modules', + difficulty: 'hard', + title: 'Type-Safe Module Federation', + text: 'Type a module federation remote module declaration', + setup: '// Type federated module', + setupCode: '// Type federated module', + expected: 'declare module "remote/Button" { import { FC } from "react"; interface ButtonProps { label: string; onClick: () => void; } const Button: FC; export default Button; }', + sample: 'declare module "remote/Button" { import { FC } from "react"; interface ButtonProps { label: string; onClick: () => void; } const Button: FC; export default Button; }', + hints: [ + 'Federated modules need explicit declarations', + 'Import types inside module declaration', + ], + tags: ['modules', 'federation', 'declaration'], + }, + { + id: 'ts-module-083', + category: 'Namespaces', + difficulty: 'hard', + title: 'Global This Augmentation', + text: 'Augment globalThis to add a custom app configuration', + setup: 'interface AppConfig { name: string; version: string; }', + setupCode: 'interface AppConfig { name: string; version: string; }', + expected: 'declare global { var __APP_CONFIG__: AppConfig; interface globalThis { __APP_CONFIG__: AppConfig; } }', + sample: 'declare global { var __APP_CONFIG__: AppConfig; interface globalThis { __APP_CONFIG__: AppConfig; } }', + hints: [ + 'globalThis interface for global properties', + 'var declaration for runtime existence', + ], + tags: ['namespaces', 'global-this', 'augmentation'], + }, + { + id: 'ts-module-084', + category: 'Declarations', + difficulty: 'hard', + title: 'Declare Branded Type', + text: 'Declare a branded type for validated email strings', + setup: '// Declare ValidatedEmail type', + setupCode: '// Declare ValidatedEmail type', + expected: 'declare const __brand: unique symbol;\ndeclare type ValidatedEmail = string & { readonly [__brand]: "ValidatedEmail" };', + sample: 'declare const __brand: unique symbol;\ndeclare type ValidatedEmail = string & { readonly [__brand]: "ValidatedEmail" };', + hints: [ + 'Branded types use intersection with unique symbol', + 'Prevents accidental type widening', + ], + tags: ['declarations', 'branded-types', 'type-safety'], + }, + { + id: 'ts-module-085', + category: 'Modules', + difficulty: 'hard', + title: 'Infer Module Export Type', + text: 'Create a type that extracts all exported types from a module', + setup: 'export const value = 1;\nexport type Type = string;\nexport interface Interface { x: number; }', + setupCode: 'export const value = 1;\nexport type Type = string;\nexport interface Interface { x: number; }', + expected: 'type ModuleExports = typeof import("./module");\ntype ExportedTypes = ModuleExports[keyof ModuleExports];', + sample: 'type ModuleExports = typeof import("./module");\ntype ExportedTypes = ModuleExports[keyof ModuleExports];', + hints: [ + 'typeof import gets module namespace type', + 'Index with keyof for all exports', + ], + tags: ['modules', 'typeof-import', 'inference'], + }, + { + id: 'ts-module-086', + category: 'Declarations', + difficulty: 'hard', + title: 'Declare This Parameter', + text: 'Declare a function that explicitly types its this context', + setup: '// Declare function with this type', + setupCode: '// Declare function with this type', + expected: 'declare interface Component { name: string; }\ndeclare function getName(this: Component): string;', + sample: 'declare interface Component { name: string; }\ndeclare function getName(this: Component): string;', + hints: [ + 'this parameter is a fake first parameter', + 'Enforces correct call context', + ], + tags: ['declarations', 'this', 'context'], + }, + { + id: 'ts-module-087', + category: 'Modules', + difficulty: 'medium', + title: 'Export Type from Class', + text: 'Export the instance type of a class as a separate type', + setup: 'class User { constructor(public name: string, public age: number) {} }', + setupCode: 'class User { constructor(public name: string, public age: number) {} }', + expected: 'export { User };\nexport type UserInstance = InstanceType;', + sample: 'export { User };\nexport type UserInstance = InstanceType;', + hints: [ + 'InstanceType extracts instance type from class', + 'typeof gets the class constructor type', + ], + tags: ['modules', 'export', 'instance-type'], + }, + { + id: 'ts-module-088', + category: 'Namespaces', + difficulty: 'medium', + title: 'Namespace Constant Export', + text: 'Create a namespace Constants with readonly exported values', + setup: '// Create Constants namespace', + setupCode: '// Create Constants namespace', + expected: 'namespace Constants { export const API_URL = "https://api.example.com" as const; export const TIMEOUT = 5000 as const; export const RETRIES = 3 as const; }', + sample: 'namespace Constants { export const API_URL = "https://api.example.com" as const; export const TIMEOUT = 5000 as const; export const RETRIES = 3 as const; }', + hints: [ + 'as const makes values literal types', + 'Exports are accessible via namespace', + ], + tags: ['namespaces', 'constants', 'as-const'], + }, + { + id: 'ts-module-089', + category: 'Declarations', + difficulty: 'medium', + title: 'Declare Abstract Class', + text: 'Declare an ambient abstract class Shape with abstract area method', + setup: '// Declare abstract Shape', + setupCode: '// Declare abstract Shape', + expected: 'declare abstract class Shape { abstract area(): number; abstract perimeter(): number; name: string; }', + sample: 'declare abstract class Shape { abstract area(): number; abstract perimeter(): number; name: string; }', + hints: [ + 'Abstract classes cannot be instantiated', + 'Abstract methods have no implementation', + ], + tags: ['declarations', 'abstract', 'class'], + }, + { + id: 'ts-module-090', + category: 'Modules', + difficulty: 'medium', + title: 'Barrel Export Pattern', + text: 'Create an index barrel file that re-exports from multiple modules', + setup: '// Barrel file exports', + setupCode: '// Barrel file exports', + expected: 'export * from "./user";\nexport * from "./product";\nexport * from "./order";\nexport { default as utils } from "./utils";', + sample: 'export * from "./user";\nexport * from "./product";\nexport * from "./order";\nexport { default as utils } from "./utils";', + hints: [ + 'Barrel files centralize exports', + 'Mix export * with named re-exports', + ], + tags: ['modules', 'barrel', 're-export'], + }, + { + id: 'ts-module-091', + category: 'Declarations', + difficulty: 'hard', + title: 'Declare Variadic Tuple', + text: 'Declare a function type that accepts variadic tuple parameters', + setup: '// Declare variadic function', + setupCode: '// Declare variadic function', + expected: 'declare function concat(arr1: [...T], arr2: [...U]): [...T, ...U];', + sample: 'declare function concat(arr1: [...T], arr2: [...U]): [...T, ...U];', + hints: [ + 'Spread in tuples for variadic types', + 'Preserves tuple element types', + ], + tags: ['declarations', 'variadic-tuple', 'generics'], + }, + { + id: 'ts-module-092', + category: 'Modules', + difficulty: 'hard', + title: 'Recursive Module Type', + text: 'Create a type for nested module structure with self-referencing exports', + setup: '// Type nested modules', + setupCode: '// Type nested modules', + expected: 'interface ModuleTree { [key: string]: ModuleTree | ((...args: unknown[]) => unknown); }\ndeclare const modules: ModuleTree;', + sample: 'interface ModuleTree { [key: string]: ModuleTree | ((...args: unknown[]) => unknown); }\ndeclare const modules: ModuleTree;', + hints: [ + 'Recursive interfaces for tree structures', + 'Union with function type for leaves', + ], + tags: ['modules', 'recursive', 'interface'], + }, + { + id: 'ts-module-093', + category: 'Namespaces', + difficulty: 'hard', + title: 'Namespace with Generics', + text: 'Create a namespace Collections with generic Stack and Queue classes', + setup: '// Create Collections namespace', + setupCode: '// Create Collections namespace', + expected: 'namespace Collections { export class Stack { private items: T[] = []; push(item: T): void { this.items.push(item); } pop(): T | undefined { return this.items.pop(); } } export class Queue { private items: T[] = []; enqueue(item: T): void { this.items.push(item); } dequeue(): T | undefined { return this.items.shift(); } } }', + sample: 'namespace Collections { export class Stack { private items: T[] = []; push(item: T): void { this.items.push(item); } pop(): T | undefined { return this.items.pop(); } } export class Queue { private items: T[] = []; enqueue(item: T): void { this.items.push(item); } dequeue(): T | undefined { return this.items.shift(); } } }', + hints: [ + 'Generic classes work in namespaces', + 'Type parameter scoped to class', + ], + tags: ['namespaces', 'generics', 'data-structures'], + }, + { + id: 'ts-module-094', + category: 'Declarations', + difficulty: 'hard', + title: 'Declare Assertion Function', + text: 'Declare an assertion function that narrows types', + setup: '// Declare assertion function', + setupCode: '// Declare assertion function', + expected: 'declare function assertIsString(value: unknown): asserts value is string;\ndeclare function assertNonNull(value: T): asserts value is NonNullable;', + sample: 'declare function assertIsString(value: unknown): asserts value is string;\ndeclare function assertNonNull(value: T): asserts value is NonNullable;', + hints: [ + 'asserts keyword for assertion functions', + 'Narrows type after function call', + ], + tags: ['declarations', 'assertion', 'type-narrowing'], + }, + { + id: 'ts-module-095', + category: 'Modules', + difficulty: 'hard', + title: 'Module with Symbol Keys', + text: 'Declare a module that exports unique symbols as keys', + setup: '// Declare symbol-keyed module', + setupCode: '// Declare symbol-keyed module', + expected: 'declare module "symbols" { export const ID: unique symbol; export const NAME: unique symbol; export interface Identifiable { [ID]: string; [NAME]: string; } }', + sample: 'declare module "symbols" { export const ID: unique symbol; export const NAME: unique symbol; export interface Identifiable { [ID]: string; [NAME]: string; } }', + hints: [ + 'unique symbol for distinct symbol types', + 'Computed properties with symbol keys', + ], + tags: ['modules', 'symbol', 'unique'], + }, + { + id: 'ts-module-096', + category: 'Declarations', + difficulty: 'easy', + title: 'Declare Readonly Array', + text: 'Declare an ambient readonly array of allowed roles', + setup: '// Declare readonly roles array', + setupCode: '// Declare readonly roles array', + expected: 'declare const ROLES: readonly ["admin", "user", "guest"];', + sample: 'declare const ROLES: readonly ["admin", "user", "guest"];', + hints: [ + 'readonly tuple for immutable arrays', + 'Literal types preserve exact values', + ], + tags: ['declarations', 'readonly', 'tuple'], + }, + { + id: 'ts-module-097', + category: 'Modules', + difficulty: 'easy', + title: 'Export Type Assertion', + text: 'Export a const assertion object as a type', + setup: 'const config = { env: "prod", debug: false } as const;', + setupCode: 'const config = { env: "prod", debug: false } as const;', + expected: 'export type Config = typeof config;', + sample: 'export type Config = typeof config;', + hints: [ + 'as const makes properties readonly literals', + 'typeof extracts the narrowed type', + ], + tags: ['modules', 'export', 'as-const'], + }, + { + id: 'ts-module-098', + category: 'Namespaces', + difficulty: 'easy', + title: 'Simple Namespace', + text: 'Create a namespace Utils with add and multiply functions', + setup: '// Create Utils namespace', + setupCode: '// Create Utils namespace', + expected: 'namespace Utils { export function add(a: number, b: number): number { return a + b; } export function multiply(a: number, b: number): number { return a * b; } }', + sample: 'namespace Utils { export function add(a: number, b: number): number { return a + b; } export function multiply(a: number, b: number): number { return a * b; } }', + hints: [ + 'namespace groups related functions', + 'export makes functions accessible', + ], + tags: ['namespaces', 'basic', 'functions'], + }, + { + id: 'ts-module-099', + category: 'Declarations', + difficulty: 'medium', + title: 'Declare Getter/Setter', + text: 'Declare an interface with typed getters and setters', + setup: '// Declare interface with accessors', + setupCode: '// Declare interface with accessors', + expected: 'declare interface Person { get name(): string; set name(value: string); get age(): number; readonly id: string; }', + sample: 'declare interface Person { get name(): string; set name(value: string); get age(): number; readonly id: string; }', + hints: [ + 'get/set keywords for accessors', + 'readonly for get-only properties', + ], + tags: ['declarations', 'interface', 'accessors'], + }, + { + id: 'ts-module-100', + category: 'Modules', + difficulty: 'hard', + title: 'Complete Module System', + text: 'Create a complete module declaration with types, values, and namespace', + setup: '// Complete module system', + setupCode: '// Complete module system', + expected: 'declare module "complete-lib" { export interface Options { timeout: number; retries: number; } export type Status = "idle" | "loading" | "success" | "error"; export function init(options: Options): void; export function getStatus(): Status; export namespace internal { export function reset(): void; export const version: string; } export default { init, getStatus }; }', + sample: 'declare module "complete-lib" { export interface Options { timeout: number; retries: number; } export type Status = "idle" | "loading" | "success" | "error"; export function init(options: Options): void; export function getStatus(): Status; export namespace internal { export function reset(): void; export const version: string; } export default { init, getStatus }; }', + hints: [ + 'Combine interfaces, types, functions, and namespaces', + 'Default export for main API surface', + ], + tags: ['modules', 'complete', 'declaration'], + }, + + // ============================================================ + // Advanced Generics - Generic Functions + // ============================================================ + { + id: 'ts-generics-001', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Basic Generic Identity Function', + text: 'Create a generic identity function that returns the input value with its type preserved', + setup: 'const value = 42;', + setupCode: 'const value = 42;', + expected: 42, + sample: 'function identity(arg: T): T { return arg; }\nidentity(value)', + hints: [ + 'Use a type parameter to capture the input type', + 'The return type should match the input type', + ], + tags: ['generics', 'functions', 'identity'], + }, + { + id: 'ts-generics-002', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Array First Element', + text: 'Create a generic function that returns the first element of an array', + setup: 'const nums = [10, 20, 30];', + setupCode: 'const nums = [10, 20, 30];', + expected: 10, + sample: 'function first(arr: T[]): T | undefined { return arr[0]; }\nfirst(nums)', + hints: [ + 'The function should accept an array of any type', + 'Return type should be T | undefined for empty arrays', + ], + tags: ['generics', 'functions', 'arrays'], + }, + { + id: 'ts-generics-003', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Array Last Element', + text: 'Create a generic function that returns the last element of an array', + setup: 'const words = ["hello", "world", "typescript"];', + setupCode: 'const words = ["hello", "world", "typescript"];', + expected: 'typescript', + sample: 'function last(arr: T[]): T | undefined { return arr[arr.length - 1]; }\nlast(words)', + hints: [ + 'Access the last element using arr.length - 1', + 'Generic type T preserves the element type', + ], + tags: ['generics', 'functions', 'arrays'], + }, + { + id: 'ts-generics-004', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Pair Creator', + text: 'Create a generic function that creates a pair (tuple) from two values', + setup: 'const a = "name"; const b = 42;', + setupCode: 'const a = "name"; const b = 42;', + expected: ['name', 42], + sample: 'function pair(first: T, second: U): [T, U] { return [first, second]; }\npair(a, b)', + hints: [ + 'Use two type parameters T and U', + 'Return type is a tuple [T, U]', + ], + tags: ['generics', 'functions', 'tuples', 'multiple-type-params'], + }, + { + id: 'ts-generics-005', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Swap Function', + text: 'Create a generic function that swaps the elements of a pair', + setup: 'const original: [number, string] = [1, "one"];', + setupCode: 'const original: [number, string] = [1, "one"];', + expected: ['one', 1], + sample: 'function swap(pair: [T, U]): [U, T] { return [pair[1], pair[0]]; }\nswap(original)', + hints: [ + 'Input is [T, U], output should be [U, T]', + 'Destructure or index to swap elements', + ], + tags: ['generics', 'functions', 'tuples'], + }, + { + id: 'ts-generics-006', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Wrapper Function', + text: 'Create a generic function that wraps a value in an object with a value property', + setup: 'const data = "wrapped";', + setupCode: 'const data = "wrapped";', + expected: { value: 'wrapped' }, + sample: 'function wrap(value: T): { value: T } { return { value }; }\nwrap(data)', + hints: [ + 'Return an object with a value property', + 'The value property type should be T', + ], + tags: ['generics', 'functions', 'objects'], + }, + { + id: 'ts-generics-007', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Array Length', + text: 'Create a generic function that returns the length of any array', + setup: 'const items = [1, 2, 3, 4, 5];', + setupCode: 'const items = [1, 2, 3, 4, 5];', + expected: 5, + sample: 'function len(arr: T[]): number { return arr.length; }\nlen(items)', + hints: [ + 'Generic preserves array element type info', + 'Return type is always number', + ], + tags: ['generics', 'functions', 'arrays'], + }, + { + id: 'ts-generics-008', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Default Value', + text: 'Create a generic function that returns a value or a default if the value is null/undefined', + setup: 'const maybeValue: string | null = null; const defaultVal = "default";', + setupCode: 'const maybeValue: string | null = null; const defaultVal = "default";', + expected: 'default', + sample: 'function withDefault(value: T | null | undefined, defaultValue: T): T { return value ?? defaultValue; }\nwithDefault(maybeValue, defaultVal)', + hints: [ + 'Use nullish coalescing operator ??', + 'Both value and default should have same type T', + ], + tags: ['generics', 'functions', 'nullish'], + }, + { + id: 'ts-generics-009', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Array Fill', + text: 'Create a generic function that creates an array of n elements with the same value', + setup: 'const count = 3; const item = "x";', + setupCode: 'const count = 3; const item = "x";', + expected: ['x', 'x', 'x'], + sample: 'function fill(n: number, value: T): T[] { return Array(n).fill(value); }\nfill(count, item)', + hints: [ + 'Use Array(n).fill(value)', + 'Return type is T[]', + ], + tags: ['generics', 'functions', 'arrays'], + }, + { + id: 'ts-generics-010', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Reverse Array', + text: 'Create a generic function that reverses an array without mutating the original', + setup: 'const original = [1, 2, 3];', + setupCode: 'const original = [1, 2, 3];', + expected: [3, 2, 1], + sample: 'function reverse(arr: T[]): T[] { return [...arr].reverse(); }\nreverse(original)', + hints: [ + 'Spread the array first to avoid mutation', + 'Then call reverse() on the copy', + ], + tags: ['generics', 'functions', 'arrays', 'immutable'], + }, + + // ============================================================ + // Advanced Generics - Generic Interfaces + // ============================================================ + { + id: 'ts-generics-011', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Box Interface', + text: 'Create a generic Box interface and instantiate it with a number', + setup: 'interface Box { contents: T; }', + setupCode: 'interface Box { contents: T; }', + expected: { contents: 100 }, + sample: 'const box: Box = { contents: 100 };\nbox', + hints: [ + 'Specify the type parameter when using the interface', + 'Box means contents is a number', + ], + tags: ['generics', 'interfaces'], + }, + { + id: 'ts-generics-012', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Response Interface', + text: 'Create a generic API response interface with data and status', + setup: 'interface ApiResponse { data: T; status: number; }', + setupCode: 'interface ApiResponse { data: T; status: number; }', + expected: { data: { name: 'Alice' }, status: 200 }, + sample: 'const response: ApiResponse<{ name: string }> = { data: { name: "Alice" }, status: 200 };\nresponse', + hints: [ + 'The data property type is determined by T', + 'Status is always a number', + ], + tags: ['generics', 'interfaces', 'api'], + }, + { + id: 'ts-generics-013', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Dictionary Interface', + text: 'Create a generic dictionary interface mapping strings to values of type T', + setup: 'interface Dictionary { [key: string]: T; }', + setupCode: 'interface Dictionary { [key: string]: T; }', + expected: { a: 1, b: 2, c: 3 }, + sample: 'const dict: Dictionary = { a: 1, b: 2, c: 3 };\ndict', + hints: [ + 'Index signature [key: string]: T allows any string key', + 'All values must be of type T', + ], + tags: ['generics', 'interfaces', 'dictionary'], + }, + { + id: 'ts-generics-014', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Result Interface', + text: 'Create a generic Result type that represents success or failure', + setup: 'type Result = { ok: true; value: T } | { ok: false; error: E };', + setupCode: 'type Result = { ok: true; value: T } | { ok: false; error: E };', + expected: { ok: true, value: 42 }, + sample: 'const success: Result = { ok: true, value: 42 };\nsuccess', + hints: [ + 'Result is a discriminated union with ok as discriminant', + 'Two type parameters: T for success, E for error', + ], + tags: ['generics', 'interfaces', 'discriminated-union', 'result-type'], + }, + { + id: 'ts-generics-015', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Linked List Node', + text: 'Create a generic linked list node interface', + setup: 'interface ListNode { value: T; next: ListNode | null; }', + setupCode: 'interface ListNode { value: T; next: ListNode | null; }', + expected: { value: 1, next: { value: 2, next: null } }, + sample: 'const node: ListNode = { value: 1, next: { value: 2, next: null } };\nnode', + hints: [ + 'The interface references itself for the next property', + 'next can be null to indicate end of list', + ], + tags: ['generics', 'interfaces', 'linked-list', 'recursive'], + }, + + // ============================================================ + // Advanced Generics - Generic Constraints + // ============================================================ + { + id: 'ts-generics-016', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic with Length Constraint', + text: 'Create a generic function that only accepts values with a length property', + setup: 'const str = "hello"; const arr = [1, 2, 3];', + setupCode: 'const str = "hello"; const arr = [1, 2, 3];', + expected: 5, + sample: 'function getLength(arg: T): number { return arg.length; }\ngetLength(str)', + hints: [ + 'Use extends to constrain T to types with length', + 'Both strings and arrays have length property', + ], + tags: ['generics', 'constraints', 'extends'], + }, + { + id: 'ts-generics-017', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Key Constraint', + text: 'Create a generic function that gets a property from an object using a constrained key', + setup: 'const person = { name: "Alice", age: 30 };', + setupCode: 'const person = { name: "Alice", age: 30 };', + expected: 'Alice', + sample: 'function getProperty(obj: T, key: K): T[K] { return obj[key]; }\ngetProperty(person, "name")', + hints: [ + 'K extends keyof T constrains K to valid keys of T', + 'Return type T[K] is the type of that property', + ], + tags: ['generics', 'constraints', 'keyof'], + }, + { + id: 'ts-generics-018', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Number Constraint', + text: 'Create a generic function that only accepts number types and doubles them', + setup: 'const value = 21;', + setupCode: 'const value = 21;', + expected: 42, + sample: 'function double(n: T): number { return n * 2; }\ndouble(value)', + hints: [ + 'T extends number constrains to numeric types', + 'Return type is number since multiplication returns number', + ], + tags: ['generics', 'constraints', 'number'], + }, + { + id: 'ts-generics-019', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Array Element Constraint', + text: 'Create a generic function that merges two arrays of compatible types', + setup: 'const nums1 = [1, 2]; const nums2 = [3, 4];', + setupCode: 'const nums1 = [1, 2]; const nums2 = [3, 4];', + expected: [1, 2, 3, 4], + sample: 'function merge(arr1: T[], arr2: T[]): T[] { return [...arr1, ...arr2]; }\nmerge(nums1, nums2)', + hints: [ + 'Both arrays must have the same element type T', + 'Spread both arrays into a new array', + ], + tags: ['generics', 'constraints', 'arrays'], + }, + { + id: 'ts-generics-020', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Object Constraint', + text: 'Create a generic function that only accepts objects (not primitives)', + setup: 'const obj = { x: 10, y: 20 };', + setupCode: 'const obj = { x: 10, y: 20 };', + expected: ['x', 'y'], + sample: 'function keys(obj: T): (keyof T)[] { return Object.keys(obj) as (keyof T)[]; }\nkeys(obj)', + hints: [ + 'T extends object excludes primitive types', + 'Cast Object.keys result to (keyof T)[]', + ], + tags: ['generics', 'constraints', 'objects'], + }, + { + id: 'ts-generics-021', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic Constructor Constraint', + text: 'Create a generic factory function that accepts a constructor and creates an instance', + setup: 'class Point { constructor(public x: number, public y: number) {} }', + setupCode: 'class Point { constructor(public x: number, public y: number) {} }', + expected: { x: 5, y: 10 }, + sample: 'function create(ctor: new (x: number, y: number) => T, x: number, y: number): T { return new ctor(x, y); }\ncreate(Point, 5, 10)', + hints: [ + 'Use new (...args) => T to represent a constructor', + 'The constraint ensures ctor can be called with new', + ], + tags: ['generics', 'constraints', 'constructor', 'factory'], + }, + { + id: 'ts-generics-022', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic Multiple Constraints', + text: 'Create a generic function with multiple constraints using intersection', + setup: 'interface Named { name: string; }\ninterface Aged { age: number; }\nconst person = { name: "Bob", age: 25 };', + setupCode: 'interface Named { name: string; }\ninterface Aged { age: number; }\nconst person = { name: "Bob", age: 25 };', + expected: 'Bob is 25 years old', + sample: 'function describe(entity: T): string { return `${entity.name} is ${entity.age} years old`; }\ndescribe(person)', + hints: [ + 'Use & to combine multiple constraints', + 'T must have both name and age properties', + ], + tags: ['generics', 'constraints', 'intersection'], + }, + + // ============================================================ + // Advanced Generics - Default Type Parameters + // ============================================================ + { + id: 'ts-generics-023', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic with Default Type', + text: 'Create a generic container type with a default type parameter of string', + setup: 'type Container = { value: T };', + setupCode: 'type Container = { value: T };', + expected: { value: 'hello' }, + sample: 'const container: Container = { value: "hello" };\ncontainer', + hints: [ + 'T = string sets the default type', + 'When no type argument is provided, string is used', + ], + tags: ['generics', 'default-type', 'type-alias'], + }, + { + id: 'ts-generics-024', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Event Handler with Default', + text: 'Create a generic event handler type with default event type', + setup: 'type EventHandler = (event: E) => void;', + setupCode: 'type EventHandler = (event: E) => void;', + expected: 'function', + sample: 'const handler: EventHandler = (e) => console.log(e.clientX);\ntypeof handler', + hints: [ + 'Default type is Event', + 'Can be overridden with specific event type', + ], + tags: ['generics', 'default-type', 'events'], + }, + { + id: 'ts-generics-025', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic State with Default', + text: 'Create a generic state container with default empty object type', + setup: 'type State = { current: T; previous: T | null };', + setupCode: 'type State = { current: T; previous: T | null };', + expected: { current: { count: 0 }, previous: null }, + sample: 'const state: State<{ count: number }> = { current: { count: 0 }, previous: null };\nstate', + hints: [ + 'Default type is empty object {}', + 'Can be specialized with specific state shape', + ], + tags: ['generics', 'default-type', 'state'], + }, + { + id: 'ts-generics-026', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Map with Defaults', + text: 'Create a generic map type with default key and value types', + setup: 'type TypedMap = Map;', + setupCode: 'type TypedMap = Map;', + expected: 2, + sample: 'const map: TypedMap = new Map([["a", 1], ["b", 2]]);\nmap.size', + hints: [ + 'Multiple defaults: K defaults to string, V to unknown', + 'Can override one or both defaults', + ], + tags: ['generics', 'default-type', 'map'], + }, + + // ============================================================ + // Advanced Generics - Type Inference + // ============================================================ + { + id: 'ts-generics-027', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Type Inference Basic', + text: 'Let TypeScript infer the generic type from the argument', + setup: 'function identity(arg: T): T { return arg; }', + setupCode: 'function identity(arg: T): T { return arg; }', + expected: 'inferred', + sample: 'identity("inferred")', + hints: [ + 'TypeScript can infer T from the argument type', + 'No need to explicitly specify ', + ], + tags: ['generics', 'inference'], + }, + { + id: 'ts-generics-028', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Inference from Array', + text: 'Let TypeScript infer the element type from an array literal', + setup: 'function firstElement(arr: T[]): T | undefined { return arr[0]; }', + setupCode: 'function firstElement(arr: T[]): T | undefined { return arr[0]; }', + expected: 1, + sample: 'firstElement([1, 2, 3])', + hints: [ + 'T is inferred as number from the array literal', + 'Works with any array type', + ], + tags: ['generics', 'inference', 'arrays'], + }, + { + id: 'ts-generics-029', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Inference from Multiple Args', + text: 'Infer type from multiple arguments of the same type', + setup: 'function longest(a: T, b: T): T { return a.length >= b.length ? a : b; }', + setupCode: 'function longest(a: T, b: T): T { return a.length >= b.length ? a : b; }', + expected: 'longer', + sample: 'longest("hi", "longer")', + hints: [ + 'Both arguments must be of the same type T', + 'T is inferred from the common type', + ], + tags: ['generics', 'inference', 'constraints'], + }, + { + id: 'ts-generics-030', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Infer Return Type from Callback', + text: 'Create a generic function that infers the return type from a callback', + setup: 'function map(arr: T[], fn: (item: T) => U): U[] { return arr.map(fn); }', + setupCode: 'function map(arr: T[], fn: (item: T) => U): U[] { return arr.map(fn); }', + expected: [2, 4, 6], + sample: 'map([1, 2, 3], x => x * 2)', + hints: [ + 'T is inferred from the array elements', + 'U is inferred from the callback return type', + ], + tags: ['generics', 'inference', 'callbacks'], + }, + + // ============================================================ + // Advanced Generics - Conditional Types + // ============================================================ + { + id: 'ts-generics-031', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Basic Conditional Type', + text: 'Create a conditional type that returns string if T is number, else T', + setup: 'type Stringify = T extends number ? string : T;', + setupCode: 'type Stringify = T extends number ? string : T;', + expected: 'hello', + sample: 'const result: Stringify = true as any;\n"hello" as Stringify', + hints: [ + 'T extends number checks if T is assignable to number', + 'Returns string for numbers, T otherwise', + ], + tags: ['generics', 'conditional-types'], + }, + { + id: 'ts-generics-032', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Conditional Type for Arrays', + text: 'Create a type that extracts the element type if T is an array', + setup: 'type Flatten = T extends (infer U)[] ? U : T;', + setupCode: 'type Flatten = T extends (infer U)[] ? U : T;', + expected: 42, + sample: 'const val: Flatten = 42;\nval', + hints: [ + 'Use infer to extract the array element type', + 'Returns T unchanged if not an array', + ], + tags: ['generics', 'conditional-types', 'infer'], + }, + { + id: 'ts-generics-033', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Conditional Type for Functions', + text: 'Create a type that extracts the return type of a function', + setup: 'type GetReturnType = T extends (...args: any[]) => infer R ? R : never;', + setupCode: 'type GetReturnType = T extends (...args: any[]) => infer R ? R : never;', + expected: 'number', + sample: 'type Fn = () => number;\nconst returnType: GetReturnType = 42;\ntypeof returnType', + hints: [ + 'Use infer R to capture the return type', + 'Pattern matches function signature', + ], + tags: ['generics', 'conditional-types', 'infer', 'functions'], + }, + { + id: 'ts-generics-034', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Conditional Type for Parameters', + text: 'Create a type that extracts the first parameter type of a function', + setup: 'type FirstParam = T extends (first: infer F, ...rest: any[]) => any ? F : never;', + setupCode: 'type FirstParam = T extends (first: infer F, ...rest: any[]) => any ? F : never;', + expected: 'hello', + sample: 'type Fn = (s: string, n: number) => void;\nconst param: FirstParam = "hello";\nparam', + hints: [ + 'Use infer F to capture the first parameter', + 'Rest parameters handle remaining args', + ], + tags: ['generics', 'conditional-types', 'infer', 'parameters'], + }, + { + id: 'ts-generics-035', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Distributive Conditional Types', + text: 'Understand how conditional types distribute over unions', + setup: 'type ToArray = T extends any ? T[] : never;', + setupCode: 'type ToArray = T extends any ? T[] : never;', + expected: [1], + sample: 'const arr: ToArray = [1];\narr', + hints: [ + 'Conditional types distribute over union members', + 'string | number becomes string[] | number[]', + ], + tags: ['generics', 'conditional-types', 'distributive'], + }, + { + id: 'ts-generics-036', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Non-Distributive Conditional Type', + text: 'Prevent distribution by wrapping in tuple', + setup: 'type ToArrayNonDist = [T] extends [any] ? T[] : never;', + setupCode: 'type ToArrayNonDist = [T] extends [any] ? T[] : never;', + expected: ['a', 1], + sample: 'const arr: ToArrayNonDist = ["a", 1];\narr', + hints: [ + 'Wrapping T in [T] prevents distribution', + 'Result is (string | number)[] not string[] | number[]', + ], + tags: ['generics', 'conditional-types', 'non-distributive'], + }, + { + id: 'ts-generics-037', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Conditional Type with infer in Nested Position', + text: 'Extract the promise value type from a nested Promise', + setup: 'type UnwrapPromise = T extends Promise ? (U extends Promise ? V : U) : T;', + setupCode: 'type UnwrapPromise = T extends Promise ? (U extends Promise ? V : U) : T;', + expected: 'resolved', + sample: 'type Nested = Promise>;\nconst val: UnwrapPromise = "resolved";\nval', + hints: [ + 'Check for Promise wrapper recursively', + 'Nested infer unwraps multiple layers', + ], + tags: ['generics', 'conditional-types', 'infer', 'promise'], + }, + + // ============================================================ + // Advanced Generics - Mapped Types + // ============================================================ + { + id: 'ts-generics-038', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Basic Mapped Type', + text: 'Create a mapped type that makes all properties optional', + setup: 'type MyPartial = { [K in keyof T]?: T[K] };', + setupCode: 'type MyPartial = { [K in keyof T]?: T[K] };', + expected: { name: 'Alice' }, + sample: 'interface User { name: string; age: number; }\nconst partial: MyPartial = { name: "Alice" };\npartial', + hints: [ + '[K in keyof T] iterates over all keys', + '? makes each property optional', + ], + tags: ['generics', 'mapped-types'], + }, + { + id: 'ts-generics-039', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Mapped Type with Readonly', + text: 'Create a mapped type that makes all properties readonly', + setup: 'type MyReadonly = { readonly [K in keyof T]: T[K] };', + setupCode: 'type MyReadonly = { readonly [K in keyof T]: T[K] };', + expected: { x: 10, y: 20 }, + sample: 'interface Point { x: number; y: number; }\nconst p: MyReadonly = { x: 10, y: 20 };\np', + hints: [ + 'Add readonly modifier before property', + 'Properties cannot be reassigned', + ], + tags: ['generics', 'mapped-types', 'readonly'], + }, + { + id: 'ts-generics-040', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Mapped Type Removing Modifier', + text: 'Create a mapped type that removes readonly modifier', + setup: 'type Mutable = { -readonly [K in keyof T]: T[K] };', + setupCode: 'type Mutable = { -readonly [K in keyof T]: T[K] };', + expected: { x: 5, y: 15 }, + sample: 'interface ReadonlyPoint { readonly x: number; readonly y: number; }\nconst p: Mutable = { x: 5, y: 15 };\np.x = 5;\np', + hints: [ + '-readonly removes the readonly modifier', + 'Properties become mutable', + ], + tags: ['generics', 'mapped-types', 'mutable'], + }, + { + id: 'ts-generics-041', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Mapped Type Required', + text: 'Create a mapped type that makes all properties required', + setup: 'type MyRequired = { [K in keyof T]-?: T[K] };', + setupCode: 'type MyRequired = { [K in keyof T]-?: T[K] };', + expected: { name: 'Bob', age: 30 }, + sample: 'interface PartialUser { name?: string; age?: number; }\nconst user: MyRequired = { name: "Bob", age: 30 };\nuser', + hints: [ + '-? removes the optional modifier', + 'All properties become required', + ], + tags: ['generics', 'mapped-types', 'required'], + }, + { + id: 'ts-generics-042', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Mapped Type with New Value Type', + text: 'Create a mapped type that converts all property values to booleans', + setup: 'type Flags = { [K in keyof T]: boolean };', + setupCode: 'type Flags = { [K in keyof T]: boolean };', + expected: { name: true, age: false }, + sample: 'interface User { name: string; age: number; }\nconst flags: Flags = { name: true, age: false };\nflags', + hints: [ + 'Replace T[K] with boolean', + 'All values become booleans', + ], + tags: ['generics', 'mapped-types', 'transformation'], + }, + { + id: 'ts-generics-043', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Mapped Type with Filtering', + text: 'Create a mapped type that extracts only string properties', + setup: 'type StringProperties = { [K in keyof T as T[K] extends string ? K : never]: T[K] };', + setupCode: 'type StringProperties = { [K in keyof T as T[K] extends string ? K : never]: T[K] };', + expected: { name: 'Alice', email: 'alice@test.com' }, + sample: 'interface User { name: string; age: number; email: string; }\nconst strings: StringProperties = { name: "Alice", email: "alice@test.com" };\nstrings', + hints: [ + 'Use as clause with conditional type', + 'never keys are filtered out', + ], + tags: ['generics', 'mapped-types', 'filtering', 'key-remapping'], + }, + { + id: 'ts-generics-044', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Mapped Type Deep Readonly', + text: 'Create a recursive mapped type for deep readonly', + setup: 'type DeepReadonly = { readonly [K in keyof T]: T[K] extends object ? DeepReadonly : T[K] };', + setupCode: 'type DeepReadonly = { readonly [K in keyof T]: T[K] extends object ? DeepReadonly : T[K] };', + expected: { user: { name: 'Alice' } }, + sample: 'interface Data { user: { name: string } }\nconst data: DeepReadonly = { user: { name: "Alice" } };\ndata', + hints: [ + 'Recursively apply readonly to nested objects', + 'Check if property extends object', + ], + tags: ['generics', 'mapped-types', 'deep-readonly', 'recursive'], + }, + + // ============================================================ + // Advanced Generics - Key Remapping with as + // ============================================================ + { + id: 'ts-generics-045', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Key Remapping to Uppercase', + text: 'Create a mapped type that uppercases all keys', + setup: 'type UppercaseKeys = { [K in keyof T as Uppercase]: T[K] };', + setupCode: 'type UppercaseKeys = { [K in keyof T as Uppercase]: T[K] };', + expected: { NAME: 'Alice', AGE: 30 }, + sample: 'interface User { name: string; age: number; }\nconst upper: UppercaseKeys = { NAME: "Alice", AGE: 30 };\nupper', + hints: [ + 'Use as clause to remap keys', + 'Uppercase transforms key to uppercase', + ], + tags: ['generics', 'key-remapping', 'template-literal'], + }, + { + id: 'ts-generics-046', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Key Remapping with Prefix', + text: 'Create a mapped type that prefixes all keys with "get"', + setup: 'type Getters = { [K in keyof T as `get${Capitalize}`]: () => T[K] };', + setupCode: 'type Getters = { [K in keyof T as `get${Capitalize}`]: () => T[K] };', + expected: 'function', + sample: 'interface User { name: string; }\nconst getters: Getters = { getName: () => "Alice" };\ntypeof getters.getName', + hints: [ + 'Template literal creates new key name', + 'Capitalize ensures proper camelCase', + ], + tags: ['generics', 'key-remapping', 'getters'], + }, + { + id: 'ts-generics-047', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Key Remapping with Setter Pattern', + text: 'Create a mapped type that creates setters for all properties', + setup: 'type Setters = { [K in keyof T as `set${Capitalize}`]: (value: T[K]) => void };', + setupCode: 'type Setters = { [K in keyof T as `set${Capitalize}`]: (value: T[K]) => void };', + expected: 'function', + sample: 'interface User { name: string; }\nconst setters: Setters = { setName: (v) => console.log(v) };\ntypeof setters.setName', + hints: [ + 'Setter function takes value of property type', + 'Returns void as setters typically do', + ], + tags: ['generics', 'key-remapping', 'setters'], + }, + { + id: 'ts-generics-048', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Key Remapping Filter and Transform', + text: 'Create a type that only keeps function properties and prefixes them with "call"', + setup: 'type CallableMethods = { [K in keyof T as T[K] extends Function ? `call${Capitalize}` : never]: T[K] };', + setupCode: 'type CallableMethods = { [K in keyof T as T[K] extends Function ? `call${Capitalize}` : never]: T[K] };', + expected: 'function', + sample: 'interface Obj { name: string; greet: () => string; }\nconst callable: CallableMethods = { callGreet: () => "hi" };\ntypeof callable.callGreet', + hints: [ + 'Filter with conditional type in as clause', + 'Only function properties are kept', + ], + tags: ['generics', 'key-remapping', 'filtering', 'functions'], + }, + + // ============================================================ + // Advanced Generics - Template Literal Types + // ============================================================ + { + id: 'ts-generics-049', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Basic Template Literal Type', + text: 'Create a type that prepends "on" to a string type', + setup: 'type EventName = `on${Capitalize}`;', + setupCode: 'type EventName = `on${Capitalize}`;', + expected: 'onClick', + sample: 'const event: EventName<"click"> = "onClick";\nevent', + hints: [ + 'Template literal types use backticks', + 'Capitalize transforms first letter', + ], + tags: ['generics', 'template-literal'], + }, + { + id: 'ts-generics-050', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Template Literal with Multiple Parts', + text: 'Create a type for CSS property values with units', + setup: 'type CSSValue = `${N}${U}`;', + setupCode: 'type CSSValue = `${N}${U}`;', + expected: '100px', + sample: 'const width: CSSValue<100, "px"> = "100px";\nwidth', + hints: [ + 'Multiple type parameters in template', + 'Number and string combine into single literal', + ], + tags: ['generics', 'template-literal', 'css'], + }, + { + id: 'ts-generics-051', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Template Literal Type Extraction', + text: 'Create a type that extracts the event name from "onXxx" pattern', + setup: 'type ExtractEvent = T extends `on${infer E}` ? Uncapitalize : never;', + setupCode: 'type ExtractEvent = T extends `on${infer E}` ? Uncapitalize : never;', + expected: 'click', + sample: 'const event: ExtractEvent<"onClick"> = "click";\nevent', + hints: [ + 'Use infer to extract part of template', + 'Uncapitalize converts first letter to lowercase', + ], + tags: ['generics', 'template-literal', 'infer', 'extraction'], + }, + { + id: 'ts-generics-052', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Template Literal Split Type', + text: 'Create a type that splits a string at a delimiter', + setup: 'type Split = S extends `${infer H}${D}${infer T}` ? [H, ...Split] : [S];', + setupCode: 'type Split = S extends `${infer H}${D}${infer T}` ? [H, ...Split] : [S];', + expected: ['a', 'b', 'c'], + sample: 'const parts: Split<"a-b-c", "-"> = ["a", "b", "c"];\nparts', + hints: [ + 'Recursively match and split string', + 'Base case returns single element array', + ], + tags: ['generics', 'template-literal', 'recursive', 'split'], + }, + { + id: 'ts-generics-053', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Template Literal Join Type', + text: 'Create a type that joins tuple elements with a delimiter', + setup: 'type Join = T extends [infer F extends string, ...infer R extends string[]] ? R["length"] extends 0 ? F : `${F}${D}${Join}` : "";', + setupCode: 'type Join = T extends [infer F extends string, ...infer R extends string[]] ? R["length"] extends 0 ? F : `${F}${D}${Join}` : "";', + expected: 'a-b-c', + sample: 'const joined: Join<["a", "b", "c"], "-"> = "a-b-c";\njoined', + hints: [ + 'Recursively join elements with delimiter', + 'Handle last element without trailing delimiter', + ], + tags: ['generics', 'template-literal', 'recursive', 'join'], + }, + + // ============================================================ + // Advanced Generics - Variance + // ============================================================ + { + id: 'ts-generics-054', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Covariance in Return Types', + text: 'Demonstrate covariance with function return types', + setup: 'interface Animal { name: string; }\ninterface Dog extends Animal { breed: string; }\ntype AnimalFactory = () => Animal;\ntype DogFactory = () => Dog;', + setupCode: 'interface Animal { name: string; }\ninterface Dog extends Animal { breed: string; }\ntype AnimalFactory = () => Animal;\ntype DogFactory = () => Dog;', + expected: { name: 'Rex', breed: 'German Shepherd' }, + sample: 'const dogFactory: DogFactory = () => ({ name: "Rex", breed: "German Shepherd" });\nconst animalFactory: AnimalFactory = dogFactory;\nanimalFactory()', + hints: [ + 'Return types are covariant', + 'DogFactory is assignable to AnimalFactory', + ], + tags: ['generics', 'variance', 'covariance'], + }, + { + id: 'ts-generics-055', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Contravariance in Parameters', + text: 'Demonstrate contravariance with function parameters', + setup: 'interface Animal { name: string; }\ninterface Dog extends Animal { breed: string; }\ntype AnimalHandler = (animal: Animal) => void;\ntype DogHandler = (dog: Dog) => void;', + setupCode: 'interface Animal { name: string; }\ninterface Dog extends Animal { breed: string; }\ntype AnimalHandler = (animal: Animal) => void;\ntype DogHandler = (dog: Dog) => void;', + expected: 'handled', + sample: 'const animalHandler: AnimalHandler = (a) => console.log(a.name);\nconst handler: DogHandler = animalHandler;\n"handled"', + hints: [ + 'Parameter types are contravariant', + 'AnimalHandler can be used where DogHandler is expected', + ], + tags: ['generics', 'variance', 'contravariance'], + }, + { + id: 'ts-generics-056', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Invariant Generic Type', + text: 'Create an invariant container type', + setup: 'class Container { private value: T; constructor(value: T) { this.value = value; } get(): T { return this.value; } set(value: T) { this.value = value; } }', + setupCode: 'class Container { private value: T; constructor(value: T) { this.value = value; } get(): T { return this.value; } set(value: T) { this.value = value; } }', + expected: 42, + sample: 'const container = new Container(42);\ncontainer.get()', + hints: [ + 'Both get and set methods make T invariant', + 'Container is not assignable to Container', + ], + tags: ['generics', 'variance', 'invariance', 'class'], + }, + + // ============================================================ + // Advanced Generics - Generic Classes + // ============================================================ + { + id: 'ts-generics-057', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Basic Generic Class', + text: 'Create a generic Stack class with push and pop methods', + setup: 'class Stack { private items: T[] = []; push(item: T) { this.items.push(item); } pop(): T | undefined { return this.items.pop(); } }', + setupCode: 'class Stack { private items: T[] = []; push(item: T) { this.items.push(item); } pop(): T | undefined { return this.items.pop(); } }', + expected: 3, + sample: 'const stack = new Stack();\nstack.push(1);\nstack.push(2);\nstack.push(3);\nstack.pop()', + hints: [ + 'Generic class maintains type safety for its contents', + 'T is determined when instantiating', + ], + tags: ['generics', 'class', 'stack'], + }, + { + id: 'ts-generics-058', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Queue Class', + text: 'Create a generic Queue class with enqueue and dequeue methods', + setup: 'class Queue { private items: T[] = []; enqueue(item: T) { this.items.push(item); } dequeue(): T | undefined { return this.items.shift(); } }', + setupCode: 'class Queue { private items: T[] = []; enqueue(item: T) { this.items.push(item); } dequeue(): T | undefined { return this.items.shift(); } }', + expected: 'first', + sample: 'const queue = new Queue();\nqueue.enqueue("first");\nqueue.enqueue("second");\nqueue.dequeue()', + hints: [ + 'Queue is FIFO (first in, first out)', + 'Use shift() to remove from front', + ], + tags: ['generics', 'class', 'queue'], + }, + { + id: 'ts-generics-059', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Repository Class', + text: 'Create a generic repository class for CRUD operations', + setup: 'class Repository {\n private items: T[] = [];\n add(item: T) { this.items.push(item); }\n findById(id: number): T | undefined { return this.items.find(i => i.id === id); }\n getAll(): T[] { return [...this.items]; }\n}', + setupCode: 'class Repository {\n private items: T[] = [];\n add(item: T) { this.items.push(item); }\n findById(id: number): T | undefined { return this.items.find(i => i.id === id); }\n getAll(): T[] { return [...this.items]; }\n}', + expected: { id: 1, name: 'Alice' }, + sample: 'interface User { id: number; name: string; }\nconst repo = new Repository();\nrepo.add({ id: 1, name: "Alice" });\nrepo.findById(1)', + hints: [ + 'Constraint T extends { id: number } ensures id property exists', + 'findById can safely access id on items', + ], + tags: ['generics', 'class', 'repository', 'constraints'], + }, + { + id: 'ts-generics-060', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Observable Class', + text: 'Create a generic Observable class with subscribe and notify', + setup: 'class Observable {\n private observers: ((value: T) => void)[] = [];\n subscribe(observer: (value: T) => void) { this.observers.push(observer); }\n notify(value: T) { this.observers.forEach(o => o(value)); }\n}', + setupCode: 'class Observable {\n private observers: ((value: T) => void)[] = [];\n subscribe(observer: (value: T) => void) { this.observers.push(observer); }\n notify(value: T) { this.observers.forEach(o => o(value)); }\n}', + expected: 'notified', + sample: 'const obs = new Observable();\nlet result = "";\nobs.subscribe(v => result = v);\nobs.notify("notified");\nresult', + hints: [ + 'Observers are callbacks that receive values of type T', + 'notify calls all registered observers', + ], + tags: ['generics', 'class', 'observable', 'callbacks'], + }, + { + id: 'ts-generics-061', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic State Machine Class', + text: 'Create a generic state machine with typed transitions', + setup: 'class StateMachine {\n constructor(private state: S, private transitions: Record>>) {}\n getState(): S { return this.state; }\n dispatch(event: E): S {\n const nextState = this.transitions[this.state]?.[event];\n if (nextState) this.state = nextState;\n return this.state;\n }\n}', + setupCode: 'class StateMachine {\n constructor(private state: S, private transitions: Record>>) {}\n getState(): S { return this.state; }\n dispatch(event: E): S {\n const nextState = this.transitions[this.state]?.[event];\n if (nextState) this.state = nextState;\n return this.state;\n }\n}', + expected: 'green', + sample: 'type Light = "red" | "yellow" | "green";\ntype Event = "next";\nconst sm = new StateMachine("red", { red: { next: "green" }, green: { next: "yellow" }, yellow: { next: "red" } });\nsm.dispatch("next")', + hints: [ + 'S is constrained to string union for states', + 'Transitions map current state to events to next state', + ], + tags: ['generics', 'class', 'state-machine', 'constraints'], + }, + + // ============================================================ + // Advanced Generics - Utility Types Implementation + // ============================================================ + { + id: 'ts-generics-062', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Implement Pick Utility Type', + text: 'Create your own Pick utility type', + setup: 'type MyPick = { [P in K]: T[P] };', + setupCode: 'type MyPick = { [P in K]: T[P] };', + expected: { name: 'Alice' }, + sample: 'interface User { name: string; age: number; email: string; }\nconst picked: MyPick = { name: "Alice" };\npicked', + hints: [ + 'K extends keyof T ensures K is valid key of T', + 'Iterate only over keys in K', + ], + tags: ['generics', 'utility-types', 'pick'], + }, + { + id: 'ts-generics-063', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Implement Omit Utility Type', + text: 'Create your own Omit utility type', + setup: 'type MyOmit = { [P in Exclude]: T[P] };', + setupCode: 'type MyOmit = { [P in Exclude]: T[P] };', + expected: { age: 30, email: 'test@test.com' }, + sample: 'interface User { name: string; age: number; email: string; }\nconst omitted: MyOmit = { age: 30, email: "test@test.com" };\nomitted', + hints: [ + 'Use Exclude to remove K from keyof T', + 'Iterate over remaining keys', + ], + tags: ['generics', 'utility-types', 'omit'], + }, + { + id: 'ts-generics-064', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Implement Record Utility Type', + text: 'Create your own Record utility type', + setup: 'type MyRecord = { [P in K]: V };', + setupCode: 'type MyRecord = { [P in K]: V };', + expected: { a: 1, b: 2 }, + sample: 'const record: MyRecord<"a" | "b", number> = { a: 1, b: 2 };\nrecord', + hints: [ + 'K extends keyof any accepts string | number | symbol', + 'All keys have the same value type V', + ], + tags: ['generics', 'utility-types', 'record'], + }, + { + id: 'ts-generics-065', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Implement Exclude Utility Type', + text: 'Create your own Exclude utility type', + setup: 'type MyExclude = T extends U ? never : T;', + setupCode: 'type MyExclude = T extends U ? never : T;', + expected: 'c', + sample: 'type ABC = "a" | "b" | "c";\nconst excluded: MyExclude = "c";\nexcluded', + hints: [ + 'Distributive conditional type over union', + 'Returns never for excluded types', + ], + tags: ['generics', 'utility-types', 'exclude', 'conditional-types'], + }, + { + id: 'ts-generics-066', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Implement Extract Utility Type', + text: 'Create your own Extract utility type', + setup: 'type MyExtract = T extends U ? T : never;', + setupCode: 'type MyExtract = T extends U ? T : never;', + expected: 'a', + sample: 'type ABC = "a" | "b" | "c";\nconst extracted: MyExtract = "a";\nextracted', + hints: [ + 'Opposite of Exclude', + 'Keeps types that extend U', + ], + tags: ['generics', 'utility-types', 'extract', 'conditional-types'], + }, + { + id: 'ts-generics-067', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Implement NonNullable Utility Type', + text: 'Create your own NonNullable utility type', + setup: 'type MyNonNullable = T extends null | undefined ? never : T;', + setupCode: 'type MyNonNullable = T extends null | undefined ? never : T;', + expected: 'hello', + sample: 'type MaybeString = string | null | undefined;\nconst value: MyNonNullable = "hello";\nvalue', + hints: [ + 'Exclude null and undefined from union', + 'Distributive conditional type does the work', + ], + tags: ['generics', 'utility-types', 'non-nullable', 'conditional-types'], + }, + { + id: 'ts-generics-068', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Implement Parameters Utility Type', + text: 'Create your own Parameters utility type', + setup: 'type MyParameters any> = T extends (...args: infer P) => any ? P : never;', + setupCode: 'type MyParameters any> = T extends (...args: infer P) => any ? P : never;', + expected: ['hello', 42], + sample: 'type Fn = (a: string, b: number) => void;\nconst params: MyParameters = ["hello", 42];\nparams', + hints: [ + 'Use infer to capture the args tuple', + 'Constraint ensures T is a function', + ], + tags: ['generics', 'utility-types', 'parameters', 'infer'], + }, + { + id: 'ts-generics-069', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Implement ConstructorParameters Utility Type', + text: 'Create your own ConstructorParameters utility type', + setup: 'type MyConstructorParams any> = T extends abstract new (...args: infer P) => any ? P : never;', + setupCode: 'type MyConstructorParams any> = T extends abstract new (...args: infer P) => any ? P : never;', + expected: ['Alice', 30], + sample: 'class User { constructor(public name: string, public age: number) {} }\nconst args: MyConstructorParams = ["Alice", 30];\nargs', + hints: [ + 'Use new (...args) => any for constructor type', + 'infer P captures constructor parameters', + ], + tags: ['generics', 'utility-types', 'constructor', 'infer'], + }, + { + id: 'ts-generics-070', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Implement InstanceType Utility Type', + text: 'Create your own InstanceType utility type', + setup: 'type MyInstanceType any> = T extends abstract new (...args: any) => infer R ? R : never;', + setupCode: 'type MyInstanceType any> = T extends abstract new (...args: any) => infer R ? R : never;', + expected: { name: 'Bob', age: 25 }, + sample: 'class User { constructor(public name: string, public age: number) {} }\nconst user: MyInstanceType = new User("Bob", 25);\nuser', + hints: [ + 'infer R captures the return type of constructor', + 'Returns the instance type of the class', + ], + tags: ['generics', 'utility-types', 'instance-type', 'infer'], + }, + + // ============================================================ + // Advanced Generics - Complex Patterns + // ============================================================ + { + id: 'ts-generics-071', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Tuple to Union', + text: 'Create a type that converts a tuple to a union of its elements', + setup: 'type TupleToUnion = T[number];', + setupCode: 'type TupleToUnion = T[number];', + expected: 1, + sample: 'type Tuple = [1, 2, 3];\nconst value: TupleToUnion = 1;\nvalue', + hints: [ + 'T[number] indexes into tuple with number', + 'Returns union of all element types', + ], + tags: ['generics', 'tuple', 'union'], + }, + { + id: 'ts-generics-072', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Union to Intersection', + text: 'Create a type that converts a union to an intersection', + setup: 'type UnionToIntersection = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;', + setupCode: 'type UnionToIntersection = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;', + expected: { a: 1, b: 2 }, + sample: 'type Union = { a: number } | { b: number };\nconst obj: UnionToIntersection = { a: 1, b: 2 };\nobj', + hints: [ + 'Uses contravariant position to force intersection', + 'Function parameters are contravariant', + ], + tags: ['generics', 'union', 'intersection', 'variance'], + }, + { + id: 'ts-generics-073', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Promisify', + text: 'Create a type that wraps return type in Promise if not already', + setup: 'type Promisify = T extends Promise ? T : Promise;', + setupCode: 'type Promisify = T extends Promise ? T : Promise;', + expected: 'resolved', + sample: 'const p: Promisify = Promise.resolve("resolved");\np.then(v => v)', + hints: [ + 'Check if already a Promise', + 'Wrap in Promise if not', + ], + tags: ['generics', 'promise', 'conditional-types'], + }, + { + id: 'ts-generics-074', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Awaited Type', + text: 'Create a type that recursively unwraps Promise types', + setup: 'type MyAwaited = T extends Promise ? MyAwaited : T;', + setupCode: 'type MyAwaited = T extends Promise ? MyAwaited : T;', + expected: 'value', + sample: 'type Nested = Promise>>;\nconst value: MyAwaited = "value";\nvalue', + hints: [ + 'Recursively unwrap Promise layers', + 'Stop when no longer a Promise', + ], + tags: ['generics', 'promise', 'recursive', 'awaited'], + }, + { + id: 'ts-generics-075', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic DeepPartial', + text: 'Create a type that makes all properties optional recursively', + setup: 'type DeepPartial = T extends object ? { [K in keyof T]?: DeepPartial } : T;', + setupCode: 'type DeepPartial = T extends object ? { [K in keyof T]?: DeepPartial } : T;', + expected: { user: { name: 'Alice' } }, + sample: 'interface Data { user: { name: string; age: number } }\nconst partial: DeepPartial = { user: { name: "Alice" } };\npartial', + hints: [ + 'Recursively apply Partial to nested objects', + 'Base case for non-objects returns T', + ], + tags: ['generics', 'deep-partial', 'recursive', 'mapped-types'], + }, + { + id: 'ts-generics-076', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic Paths Type', + text: 'Create a type that generates all dot-notation paths of an object', + setup: 'type Paths = T extends object ? { [K in keyof T]: K extends string ? T[K] extends object ? K | `${K}.${Paths & string}` : K : never }[keyof T] : never;', + setupCode: 'type Paths = T extends object ? { [K in keyof T]: K extends string ? T[K] extends object ? K | `${K}.${Paths & string}` : K : never }[keyof T] : never;', + expected: 'user.name', + sample: 'interface Data { user: { name: string; age: number } }\nconst path: Paths = "user.name";\npath', + hints: [ + 'Recursively build paths for nested objects', + 'Use template literal for dot notation', + ], + tags: ['generics', 'paths', 'recursive', 'template-literal'], + }, + { + id: 'ts-generics-077', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic Get Type by Path', + text: 'Create a type that gets nested property type by dot-notation path', + setup: 'type Get = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? Get : never : P extends keyof T ? T[P] : never;', + setupCode: 'type Get = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? Get : never : P extends keyof T ? T[P] : never;', + expected: 'Alice', + sample: 'interface Data { user: { name: string } }\nconst name: Get = "Alice";\nname', + hints: [ + 'Split path at first dot', + 'Recursively traverse object structure', + ], + tags: ['generics', 'paths', 'recursive', 'template-literal'], + }, + { + id: 'ts-generics-078', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic Array Element Type', + text: 'Create a type that extracts the element type from an array', + setup: 'type ElementType = T extends readonly (infer E)[] ? E : never;', + setupCode: 'type ElementType = T extends readonly (infer E)[] ? E : never;', + expected: 42, + sample: 'type NumArray = number[];\nconst element: ElementType = 42;\nelement', + hints: [ + 'Use infer to capture element type', + 'Works with both regular and readonly arrays', + ], + tags: ['generics', 'arrays', 'infer', 'element-type'], + }, + { + id: 'ts-generics-079', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Tuple Length', + text: 'Create a type that gets the length of a tuple type', + setup: 'type TupleLength = T["length"];', + setupCode: 'type TupleLength = T["length"];', + expected: 3, + sample: 'type Triple = [1, 2, 3];\nconst len: TupleLength = 3;\nlen', + hints: [ + 'Tuple types have literal length type', + 'Access with ["length"]', + ], + tags: ['generics', 'tuple', 'length'], + }, + { + id: 'ts-generics-080', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Push to Tuple', + text: 'Create a type that adds an element to the end of a tuple', + setup: 'type Push = [...T, E];', + setupCode: 'type Push = [...T, E];', + expected: [1, 2, 3], + sample: 'type Pair = [1, 2];\nconst triple: Push = [1, 2, 3];\ntriple', + hints: [ + 'Use spread operator in tuple type', + 'Append E at the end', + ], + tags: ['generics', 'tuple', 'spread'], + }, + { + id: 'ts-generics-081', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Unshift to Tuple', + text: 'Create a type that adds an element to the start of a tuple', + setup: 'type Unshift = [E, ...T];', + setupCode: 'type Unshift = [E, ...T];', + expected: [0, 1, 2], + sample: 'type Pair = [1, 2];\nconst triple: Unshift = [0, 1, 2];\ntriple', + hints: [ + 'Place E before spread of T', + 'Creates new tuple with E first', + ], + tags: ['generics', 'tuple', 'spread'], + }, + { + id: 'ts-generics-082', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic Pop from Tuple', + text: 'Create a type that removes the last element from a tuple', + setup: 'type Pop = T extends [...infer R, any] ? R : never;', + setupCode: 'type Pop = T extends [...infer R, any] ? R : never;', + expected: [1, 2], + sample: 'type Triple = [1, 2, 3];\nconst pair: Pop = [1, 2];\npair', + hints: [ + 'Use infer with rest pattern', + 'Capture all but last element', + ], + tags: ['generics', 'tuple', 'infer', 'spread'], + }, + { + id: 'ts-generics-083', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic Shift from Tuple', + text: 'Create a type that removes the first element from a tuple', + setup: 'type Shift = T extends [any, ...infer R] ? R : never;', + setupCode: 'type Shift = T extends [any, ...infer R] ? R : never;', + expected: [2, 3], + sample: 'type Triple = [1, 2, 3];\nconst pair: Shift = [2, 3];\npair', + hints: [ + 'Match first element and rest', + 'Return rest elements', + ], + tags: ['generics', 'tuple', 'infer', 'spread'], + }, + + // ============================================================ + // Advanced Generics - Function Overloads with Generics + // ============================================================ + { + id: 'ts-generics-084', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Function with Overloads', + text: 'Create a generic function with overloaded signatures for different return types', + setup: 'function getValue(key: T): T extends "count" ? number : string;', + setupCode: 'function getValue(key: T): T extends "count" ? number : string;', + expected: 'value', + sample: 'function getValue(key: T): any { return key === "count" ? 42 : "value"; }\ngetValue("name")', + hints: [ + 'Conditional return type based on key', + 'Implementation must handle all cases', + ], + tags: ['generics', 'overloads', 'conditional-types'], + }, + { + id: 'ts-generics-085', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic Type-Safe Event Emitter', + text: 'Create a type-safe event emitter with generic event map', + setup: 'type EventMap = { click: { x: number; y: number }; input: { value: string } };\nclass Emitter> {\n on(event: K, handler: (data: T[K]) => void) {}\n emit(event: K, data: T[K]) {}\n}', + setupCode: 'type EventMap = { click: { x: number; y: number }; input: { value: string } };\nclass Emitter> {\n on(event: K, handler: (data: T[K]) => void) {}\n emit(event: K, data: T[K]) {}\n}', + expected: 'object', + sample: 'const emitter = new Emitter();\nemitter.on("click", (data) => console.log(data.x));\ntypeof emitter', + hints: [ + 'K extends keyof T ensures valid event name', + 'T[K] gives the data type for that event', + ], + tags: ['generics', 'events', 'type-safe', 'class'], + }, + + // ============================================================ + // Advanced Generics - Builder Patterns + // ============================================================ + { + id: 'ts-generics-086', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Builder Pattern', + text: 'Create a generic builder that accumulates properties', + setup: 'class Builder {\n private obj: T = {} as T;\n with(key: K, value: V): Builder> {\n (this.obj as any)[key] = value;\n return this as any;\n }\n build(): T { return this.obj; }\n}', + setupCode: 'class Builder {\n private obj: T = {} as T;\n with(key: K, value: V): Builder> {\n (this.obj as any)[key] = value;\n return this as any;\n }\n build(): T { return this.obj; }\n}', + expected: { name: 'Alice', age: 30 }, + sample: 'const result = new Builder().with("name", "Alice").with("age", 30).build();\nresult', + hints: [ + 'Each with() call extends the type', + 'Return type includes new property', + ], + tags: ['generics', 'builder', 'fluent-api'], + }, + { + id: 'ts-generics-087', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic Type-Safe Query Builder', + text: 'Create a query builder with type-safe field selection', + setup: 'class QueryBuilder {\n constructor(private fields: S[] = []) {}\n select(...fields: K[]): QueryBuilder {\n return new QueryBuilder(fields);\n }\n getFields(): S[] { return this.fields; }\n}', + setupCode: 'class QueryBuilder {\n constructor(private fields: S[] = []) {}\n select(...fields: K[]): QueryBuilder {\n return new QueryBuilder(fields);\n }\n getFields(): S[] { return this.fields; }\n}', + expected: ['name', 'email'], + sample: 'interface User { name: string; age: number; email: string }\nconst qb = new QueryBuilder().select("name", "email");\nqb.getFields()', + hints: [ + 'Track selected fields in type parameter S', + 'select() narrows the available fields', + ], + tags: ['generics', 'builder', 'query', 'type-safe'], + }, + + // ============================================================ + // Advanced Generics - Higher Kinded Types Simulation + // ============================================================ + { + id: 'ts-generics-088', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic Functor Interface', + text: 'Create a generic Functor-like interface with map', + setup: 'interface Functor {\n map(fn: (value: T) => U): Functor;\n}\nclass Box implements Functor {\n constructor(public value: T) {}\n map(fn: (value: T) => U): Box { return new Box(fn(this.value)); }\n}', + setupCode: 'interface Functor {\n map(fn: (value: T) => U): Functor;\n}\nclass Box implements Functor {\n constructor(public value: T) {}\n map(fn: (value: T) => U): Box { return new Box(fn(this.value)); }\n}', + expected: { value: 10 }, + sample: 'const box = new Box(5).map(x => x * 2);\nbox', + hints: [ + 'Functor allows mapping over contained value', + 'map returns new container with transformed value', + ], + tags: ['generics', 'functor', 'functional'], + }, + { + id: 'ts-generics-089', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic Monad-like Interface', + text: 'Create a generic Maybe monad with map and flatMap', + setup: 'class Maybe {\n constructor(private value: T | null) {}\n static of(value: T): Maybe { return new Maybe(value); }\n static none(): Maybe { return new Maybe(null); }\n map(fn: (value: T) => U): Maybe {\n return this.value === null ? Maybe.none() : Maybe.of(fn(this.value));\n }\n flatMap(fn: (value: T) => Maybe): Maybe {\n return this.value === null ? Maybe.none() : fn(this.value);\n }\n getOrElse(defaultValue: T): T { return this.value ?? defaultValue; }\n}', + setupCode: 'class Maybe {\n constructor(private value: T | null) {}\n static of(value: T): Maybe { return new Maybe(value); }\n static none(): Maybe { return new Maybe(null); }\n map(fn: (value: T) => U): Maybe {\n return this.value === null ? Maybe.none() : Maybe.of(fn(this.value));\n }\n flatMap(fn: (value: T) => Maybe): Maybe {\n return this.value === null ? Maybe.none() : fn(this.value);\n }\n getOrElse(defaultValue: T): T { return this.value ?? defaultValue; }\n}', + expected: 10, + sample: 'Maybe.of(5).map(x => x * 2).getOrElse(0)', + hints: [ + 'Maybe handles null/undefined safely', + 'flatMap allows chaining Maybe-returning functions', + ], + tags: ['generics', 'monad', 'maybe', 'functional'], + }, + + // ============================================================ + // Advanced Generics - Recursive Types + // ============================================================ + { + id: 'ts-generics-090', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Recursive JSON Type', + text: 'Create a recursive type for JSON values', + setup: 'type JSONValue = string | number | boolean | null | JSONValue[] | { [key: string]: JSONValue };', + setupCode: 'type JSONValue = string | number | boolean | null | JSONValue[] | { [key: string]: JSONValue };', + expected: { name: 'Alice', scores: [1, 2, 3] }, + sample: 'const json: JSONValue = { name: "Alice", scores: [1, 2, 3] };\njson', + hints: [ + 'JSONValue references itself recursively', + 'Covers all valid JSON structures', + ], + tags: ['generics', 'recursive', 'json'], + }, + { + id: 'ts-generics-091', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic Tree Type', + text: 'Create a generic recursive tree type with typed nodes', + setup: 'interface TreeNode { value: T; children: TreeNode[]; }', + setupCode: 'interface TreeNode { value: T; children: TreeNode[]; }', + expected: { value: 1, children: [{ value: 2, children: [] }, { value: 3, children: [] }] }, + sample: 'const tree: TreeNode = { value: 1, children: [{ value: 2, children: [] }, { value: 3, children: [] }] };\ntree', + hints: [ + 'TreeNode references itself for children', + 'Each node has value of type T', + ], + tags: ['generics', 'recursive', 'tree'], + }, + { + id: 'ts-generics-092', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic Flatten Nested Arrays', + text: 'Create a type that deeply flattens nested array types', + setup: 'type DeepFlatten = T extends (infer U)[] ? DeepFlatten : T;', + setupCode: 'type DeepFlatten = T extends (infer U)[] ? DeepFlatten : T;', + expected: 42, + sample: 'type Nested = number[][][];\nconst flat: DeepFlatten = 42;\nflat', + hints: [ + 'Recursively unwrap array layers', + 'Stop when no longer an array', + ], + tags: ['generics', 'recursive', 'flatten', 'arrays'], + }, + + // ============================================================ + // Advanced Generics - String Manipulation + // ============================================================ + { + id: 'ts-generics-093', + category: 'Advanced Generics', + difficulty: 'easy', + title: 'Generic CamelCase to KebabCase', + text: 'Apply built-in Lowercase utility to a string type', + setup: 'type Lower = Lowercase;', + setupCode: 'type Lower = Lowercase;', + expected: 'hello', + sample: 'const lower: Lower<"HELLO"> = "hello";\nlower', + hints: [ + 'Lowercase is a built-in template literal type', + 'Converts all characters to lowercase', + ], + tags: ['generics', 'template-literal', 'string-manipulation'], + }, + { + id: 'ts-generics-094', + category: 'Advanced Generics', + difficulty: 'medium', + title: 'Generic Capitalize Words', + text: 'Create a type that capitalizes the first letter of a string type', + setup: 'type Cap = Capitalize;', + setupCode: 'type Cap = Capitalize;', + expected: 'Hello', + sample: 'const cap: Cap<"hello"> = "Hello";\ncap', + hints: [ + 'Capitalize transforms first letter to uppercase', + 'Built-in template literal type utility', + ], + tags: ['generics', 'template-literal', 'capitalize'], + }, + { + id: 'ts-generics-095', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic CamelCase Type', + text: 'Create a type that converts snake_case to camelCase', + setup: 'type CamelCase = S extends `${infer P}_${infer R}` ? `${Lowercase

}${Capitalize>}` : Lowercase;', + setupCode: 'type CamelCase = S extends `${infer P}_${infer R}` ? `${Lowercase

}${Capitalize>}` : Lowercase;', + expected: 'helloWorld', + sample: 'const camel: CamelCase<"hello_world"> = "helloWorld";\ncamel', + hints: [ + 'Split at underscore recursively', + 'Capitalize subsequent parts', + ], + tags: ['generics', 'template-literal', 'camelCase', 'recursive'], + }, + { + id: 'ts-generics-096', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic SnakeCase Type', + text: 'Create a type that converts camelCase to snake_case', + setup: 'type SnakeCase = S extends `${infer C}${infer R}` ? C extends Uppercase ? `_${Lowercase}${SnakeCase}` : `${C}${SnakeCase}` : S;', + setupCode: 'type SnakeCase = S extends `${infer C}${infer R}` ? C extends Uppercase ? `_${Lowercase}${SnakeCase}` : `${C}${SnakeCase}` : S;', + expected: 'hello_world', + sample: 'const snake: SnakeCase<"helloWorld"> = "hello_world";\nsnake', + hints: [ + 'Check each character for uppercase', + 'Insert underscore before uppercase letters', + ], + tags: ['generics', 'template-literal', 'snake_case', 'recursive'], + }, + + // ============================================================ + // Advanced Generics - Advanced Inference + // ============================================================ + { + id: 'ts-generics-097', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Infer Function This Type', + text: 'Create a type that extracts the this parameter type from a function', + setup: 'type ThisType = T extends (this: infer U, ...args: any[]) => any ? U : never;', + setupCode: 'type ThisType = T extends (this: infer U, ...args: any[]) => any ? U : never;', + expected: { name: 'test' }, + sample: 'type Fn = (this: { name: string }) => void;\nconst thisArg: ThisType = { name: "test" };\nthisArg', + hints: [ + 'Use infer in this position', + 'Captures the this parameter type', + ], + tags: ['generics', 'infer', 'this', 'functions'], + }, + { + id: 'ts-generics-098', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic Strict Object Keys', + text: 'Create a type that enforces exact object shape (no extra properties at type level)', + setup: 'type Exact = T extends Shape ? Exclude extends never ? T : never : never;', + setupCode: 'type Exact = T extends Shape ? Exclude extends never ? T : never : never;', + expected: { name: 'Alice' }, + sample: 'interface Shape { name: string }\nfunction create(obj: Exact & Shape): Shape { return obj; }\nconst result = create({ name: "Alice" });\nresult', + hints: [ + 'Check that T has no extra keys beyond Shape', + 'Exclude finds extra keys', + ], + tags: ['generics', 'exact', 'strict', 'objects'], + }, + { + id: 'ts-generics-099', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic Merge Objects Type', + text: 'Create a type that deeply merges two object types', + setup: 'type Merge = { [K in keyof A | keyof B]: K extends keyof B ? K extends keyof A ? A[K] extends object ? B[K] extends object ? Merge : B[K] : B[K] : B[K] : K extends keyof A ? A[K] : never };', + setupCode: 'type Merge = { [K in keyof A | keyof B]: K extends keyof B ? K extends keyof A ? A[K] extends object ? B[K] extends object ? Merge : B[K] : B[K] : B[K] : K extends keyof A ? A[K] : never };', + expected: { a: 1, b: { c: 2, d: 3 } }, + sample: 'type A = { a: number; b: { c: number } };\ntype B = { b: { d: number } };\nconst merged: Merge = { a: 1, b: { c: 2, d: 3 } };\nmerged', + hints: [ + 'Iterate over keys from both types', + 'Recursively merge nested objects', + ], + tags: ['generics', 'merge', 'deep', 'recursive'], + }, + { + id: 'ts-generics-100', + category: 'Advanced Generics', + difficulty: 'hard', + title: 'Generic Branded Types', + text: 'Create branded types for type-safe IDs', + setup: 'type Brand = T & { __brand: B };\ntype UserId = Brand;\ntype PostId = Brand;', + setupCode: 'type Brand = T & { __brand: B };\ntype UserId = Brand;\ntype PostId = Brand;', + expected: 123, + sample: 'function createUserId(id: number): UserId { return id as UserId; }\nfunction getUserById(id: UserId): number { return id; }\nconst userId = createUserId(123);\ngetUserById(userId)', + hints: [ + 'Brand adds a phantom property for type safety', + 'UserId and PostId are incompatible despite both being numbers', + ], + tags: ['generics', 'branded-types', 'type-safe', 'phantom-types'], + }, + + // ============================================================ + // Advanced Generics - Generic Functions + // ============================================================ + { + id: 'ts-generic-001', + category: 'Generics', + difficulty: 'easy', + title: 'Basic Identity Function', + text: 'Create a generic identity function that returns its argument unchanged', + setup: 'function identity(x: T): T { return x; }', + setupCode: 'function identity(x: T): T { return x; }', + expected: 42, + sample: 'identity(42)', + hints: [ + 'The type parameter T captures the input type', + 'The return type matches the input type', + ], + tags: ['generics', 'functions', 'identity'], + }, + { + id: 'ts-generic-002', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Array First Element', + text: 'Create a generic function that returns the first element of an array', + setup: 'function first(arr: T[]): T | undefined { return arr[0]; }', + setupCode: 'function first(arr: T[]): T | undefined { return arr[0]; }', + expected: 'hello', + sample: 'first(["hello", "world"])', + hints: [ + 'Use T[] for array of generic type', + 'Return T | undefined for empty array safety', + ], + tags: ['generics', 'arrays', 'functions'], + }, + { + id: 'ts-generic-003', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Array Last Element', + text: 'Create a generic function that returns the last element of an array', + setup: 'function last(arr: T[]): T | undefined { return arr[arr.length - 1]; }', + setupCode: 'function last(arr: T[]): T | undefined { return arr[arr.length - 1]; }', + expected: 3, + sample: 'last([1, 2, 3])', + hints: [ + 'Access array at length - 1', + 'Handle empty array with undefined return type', + ], + tags: ['generics', 'arrays', 'functions'], + }, + { + id: 'ts-generic-004', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Pair Type', + text: 'Create a generic function that creates a pair from two values', + setup: 'function pair(a: T, b: U): [T, U] { return [a, b]; }', + setupCode: 'function pair(a: T, b: U): [T, U] { return [a, b]; }', + expected: ['hello', 42], + sample: 'pair("hello", 42)', + hints: [ + 'Use two type parameters for different types', + 'Return a tuple type [T, U]', + ], + tags: ['generics', 'tuples', 'functions'], + }, + { + id: 'ts-generic-005', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Swap Function', + text: 'Create a generic function that swaps the elements of a pair', + setup: 'function swap(pair: [T, U]): [U, T] { return [pair[1], pair[0]]; }', + setupCode: 'function swap(pair: [T, U]): [U, T] { return [pair[1], pair[0]]; }', + expected: [2, 'a'], + sample: 'swap(["a", 2])', + hints: [ + 'Input is [T, U], output is [U, T]', + 'Return elements in reverse order', + ], + tags: ['generics', 'tuples', 'functions'], + }, + { + id: 'ts-generic-006', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Wrap in Array', + text: 'Create a generic function that wraps a value in an array', + setup: 'function wrapInArray(value: T): T[] { return [value]; }', + setupCode: 'function wrapInArray(value: T): T[] { return [value]; }', + expected: [5], + sample: 'wrapInArray(5)', + hints: [ + 'Return type is T[] (array of T)', + 'Wrap single value in array literal', + ], + tags: ['generics', 'arrays', 'functions'], + }, + { + id: 'ts-generic-007', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Repeat Value', + text: 'Create a generic function that creates an array with a value repeated n times', + setup: 'function repeat(value: T, n: number): T[] { return Array(n).fill(value); }', + setupCode: 'function repeat(value: T, n: number): T[] { return Array(n).fill(value); }', + expected: ['x', 'x', 'x'], + sample: 'repeat("x", 3)', + hints: [ + 'Use Array(n).fill() to create repeated values', + 'Return type is T[]', + ], + tags: ['generics', 'arrays', 'functions'], + }, + { + id: 'ts-generic-008', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Nullable Type', + text: 'Create a generic function that returns value or null based on condition', + setup: 'function nullable(value: T, isNull: boolean): T | null { return isNull ? null : value; }', + setupCode: 'function nullable(value: T, isNull: boolean): T | null { return isNull ? null : value; }', + expected: null, + sample: 'nullable("test", true)', + hints: [ + 'Return type is T | null union', + 'Use ternary to conditionally return null', + ], + tags: ['generics', 'nullable', 'functions'], + }, + { + id: 'ts-generic-009', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Default Value', + text: 'Create a generic function that returns value or default if null/undefined', + setup: 'function withDefault(value: T | null | undefined, defaultVal: T): T { return value ?? defaultVal; }', + setupCode: 'function withDefault(value: T | null | undefined, defaultVal: T): T { return value ?? defaultVal; }', + expected: 'default', + sample: 'withDefault(null, "default")', + hints: [ + 'Use nullish coalescing operator ??', + 'Both value and default share same type T', + ], + tags: ['generics', 'nullish', 'functions'], + }, + { + id: 'ts-generic-010', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Array Length', + text: 'Create a generic function that returns the length of an array', + setup: 'function len(arr: T[]): number { return arr.length; }', + setupCode: 'function len(arr: T[]): number { return arr.length; }', + expected: 4, + sample: 'len([1, 2, 3, 4])', + hints: [ + 'Access .length property on array', + 'Return type is number, not generic', + ], + tags: ['generics', 'arrays', 'functions'], + }, + + // ============================================================ + // Advanced Generics - Generic Constraints + // ============================================================ + { + id: 'ts-generic-011', + category: 'Generic Constraints', + difficulty: 'easy', + title: 'Constrained to Object with Length', + text: 'Create a function that accepts only values with a length property', + setup: 'function getLength(obj: T): number { return obj.length; }', + setupCode: 'function getLength(obj: T): number { return obj.length; }', + expected: 5, + sample: 'getLength("hello")', + hints: [ + 'Use extends to constrain the type', + 'Constraint requires length: number property', + ], + tags: ['generics', 'constraints', 'extends'], + }, + { + id: 'ts-generic-012', + category: 'Generic Constraints', + difficulty: 'easy', + title: 'Constrained to String Keys', + text: 'Create a function that gets a property from an object using a string key', + setup: 'function getProp(obj: T, key: K): T[K] { return obj[key]; }', + setupCode: 'function getProp(obj: T, key: K): T[K] { return obj[key]; }', + expected: 'Alice', + sample: 'getProp({ name: "Alice", age: 30 }, "name")', + hints: [ + 'K extends keyof T constrains to valid keys', + 'Return type T[K] is the property type', + ], + tags: ['generics', 'constraints', 'keyof'], + }, + { + id: 'ts-generic-013', + category: 'Generic Constraints', + difficulty: 'medium', + title: 'Constrained to Number Type', + text: 'Create a function that only accepts number types and doubles them', + setup: 'function double(value: T): number { return value * 2; }', + setupCode: 'function double(value: T): number { return value * 2; }', + expected: 10, + sample: 'double(5)', + hints: [ + 'T extends number restricts to numeric types', + 'Arithmetic operations are allowed', + ], + tags: ['generics', 'constraints', 'number'], + }, + { + id: 'ts-generic-014', + category: 'Generic Constraints', + difficulty: 'medium', + title: 'Constrained to Function Type', + text: 'Create a function that calls a callback and returns its result', + setup: 'function call any>(fn: T): ReturnType { return fn(); }', + setupCode: 'function call any>(fn: T): ReturnType { return fn(); }', + expected: 42, + sample: 'call(() => 42)', + hints: [ + 'Constrain T to function type', + 'Use ReturnType utility for return type', + ], + tags: ['generics', 'constraints', 'functions'], + }, + { + id: 'ts-generic-015', + category: 'Generic Constraints', + difficulty: 'medium', + title: 'Constrained to Array Type', + text: 'Create a function that flattens a nested array by one level', + setup: 'function flatten(arr: T[]): T[number][] { return arr.flat(); }', + setupCode: 'function flatten(arr: T[]): T[number][] { return arr.flat(); }', + expected: [1, 2, 3, 4], + sample: 'flatten([[1, 2], [3, 4]])', + hints: [ + 'T extends any[] constrains to arrays', + 'T[number] gets element type of array', + ], + tags: ['generics', 'constraints', 'arrays'], + }, + { + id: 'ts-generic-016', + category: 'Generic Constraints', + difficulty: 'medium', + title: 'Multiple Constraints with Intersection', + text: 'Create a function that requires both name and id properties', + setup: 'function identify(obj: T): string { return `${obj.id}: ${obj.name}`; }', + setupCode: 'function identify(obj: T): string { return `${obj.id}: ${obj.name}`; }', + expected: '1: Alice', + sample: 'identify({ id: 1, name: "Alice" })', + hints: [ + 'Use & to combine constraints', + 'Object must have both properties', + ], + tags: ['generics', 'constraints', 'intersection'], + }, + { + id: 'ts-generic-017', + category: 'Generic Constraints', + difficulty: 'medium', + title: 'Constrained Generic with Default', + text: 'Create a function with a constrained generic that has a default type', + setup: 'function createArray(item: T): T[] { return [item]; }', + setupCode: 'function createArray(item: T): T[] { return [item]; }', + expected: [{ value: 10 }], + sample: 'createArray({ value: 10 })', + hints: [ + 'Use = after extends for default type', + 'Default applies when type not specified', + ], + tags: ['generics', 'constraints', 'default'], + }, + { + id: 'ts-generic-018', + category: 'Generic Constraints', + difficulty: 'hard', + title: 'Recursive Constraint', + text: 'Create a type that constrains to objects with nested same structure', + setup: 'type TreeNode = { value: T; children?: TreeNode[] };\nfunction sumTree(node: TreeNode): number { return node.value + (node.children?.reduce((s, c) => s + sumTree(c), 0) ?? 0); }', + setupCode: 'type TreeNode = { value: T; children?: TreeNode[] };\nfunction sumTree(node: TreeNode): number { return node.value + (node.children?.reduce((s, c) => s + sumTree(c), 0) ?? 0); }', + expected: 6, + sample: 'sumTree({ value: 1, children: [{ value: 2 }, { value: 3 }] })', + hints: [ + 'TreeNode references itself in children', + 'Recursive types allow nested structures', + ], + tags: ['generics', 'constraints', 'recursive'], + }, + { + id: 'ts-generic-019', + category: 'Generic Constraints', + difficulty: 'easy', + title: 'Constrained to String Type', + text: 'Create a function that only accepts string types and returns uppercase', + setup: 'function upper(str: T): Uppercase { return str.toUpperCase() as Uppercase; }', + setupCode: 'function upper(str: T): Uppercase { return str.toUpperCase() as Uppercase; }', + expected: 'HELLO', + sample: 'upper("hello")', + hints: [ + 'T extends string constrains to strings', + 'Uppercase is a template literal type', + ], + tags: ['generics', 'constraints', 'string'], + }, + { + id: 'ts-generic-020', + category: 'Generic Constraints', + difficulty: 'medium', + title: 'Constrained to Promise Type', + text: 'Create a function that unwraps a Promise type', + setup: 'async function unwrap>(promise: T): Promise> { return await promise; }', + setupCode: 'async function unwrap>(promise: T): Promise> { return await promise; }', + expected: 'resolved', + sample: 'await unwrap(Promise.resolve("resolved"))', + hints: [ + 'Constrain T to Promise type', + 'Awaited extracts the resolved type', + ], + tags: ['generics', 'constraints', 'promise'], + }, + + // ============================================================ + // Advanced Generics - Generic Interfaces + // ============================================================ + { + id: 'ts-generic-021', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Container Interface', + text: 'Create a generic container interface that holds a value', + setup: 'interface Container { value: T; }\nconst box: Container = { value: 42 };', + setupCode: 'interface Container { value: T; }\nconst box: Container = { value: 42 };', + expected: 42, + sample: 'box.value', + hints: [ + 'Interface takes type parameter in angle brackets', + 'T is used for the value property type', + ], + tags: ['generics', 'interfaces', 'container'], + }, + { + id: 'ts-generic-022', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Result Interface', + text: 'Create a generic Result interface for success/error handling', + setup: 'interface Result { success: boolean; data?: T; error?: E; }\nconst result: Result = { success: true, data: "done" };', + setupCode: 'interface Result { success: boolean; data?: T; error?: E; }\nconst result: Result = { success: true, data: "done" };', + expected: 'done', + sample: 'result.data', + hints: [ + 'Use two type parameters for data and error', + 'Optional properties with ? modifier', + ], + tags: ['generics', 'interfaces', 'result'], + }, + { + id: 'ts-generic-023', + category: 'Generics', + difficulty: 'medium', + title: 'Generic Repository Interface', + text: 'Create a generic repository interface for CRUD operations', + setup: 'interface Repository { findById(id: ID): T | null; save(item: T): void; }\nclass UserRepo implements Repository<{name: string}, number> { private users: {name: string}[] = []; findById(id: number) { return this.users[id] ?? null; } save(item: {name: string}) { this.users.push(item); } }', + setupCode: 'interface Repository { findById(id: ID): T | null; save(item: T): void; }\nclass UserRepo implements Repository<{name: string}, number> { private users: {name: string}[] = []; findById(id: number) { return this.users[id] ?? null; } save(item: {name: string}) { this.users.push(item); } }', + expected: { name: 'Alice' }, + sample: 'const repo = new UserRepo();\nrepo.save({ name: "Alice" });\nrepo.findById(0)', + hints: [ + 'T is entity type, ID is identifier type', + 'Methods use generic types in signatures', + ], + tags: ['generics', 'interfaces', 'repository'], + }, + { + id: 'ts-generic-024', + category: 'Generics', + difficulty: 'medium', + title: 'Generic Comparable Interface', + text: 'Create a generic Comparable interface for sorting', + setup: 'interface Comparable { compareTo(other: T): number; }\nclass Num implements Comparable { constructor(public val: number) {} compareTo(other: Num) { return this.val - other.val; } }', + setupCode: 'interface Comparable { compareTo(other: T): number; }\nclass Num implements Comparable { constructor(public val: number) {} compareTo(other: Num) { return this.val - other.val; } }', + expected: -1, + sample: 'new Num(5).compareTo(new Num(10))', + hints: [ + 'compareTo returns negative, zero, or positive', + 'Self-referential generic: Comparable', + ], + tags: ['generics', 'interfaces', 'comparable'], + }, + { + id: 'ts-generic-025', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Stack Interface', + text: 'Create a generic Stack interface with push, pop, and peek', + setup: 'interface Stack { push(item: T): void; pop(): T | undefined; peek(): T | undefined; }\nconst stack: Stack = { items: [] as number[], push(item) { this.items.push(item); }, pop() { return this.items.pop(); }, peek() { return this.items[this.items.length - 1]; } };', + setupCode: 'interface Stack { push(item: T): void; pop(): T | undefined; peek(): T | undefined; }\nconst stack: Stack = { items: [] as number[], push(item) { this.items.push(item); }, pop() { return this.items.pop(); }, peek() { return this.items[this.items.length - 1]; } };', + expected: 3, + sample: 'stack.push(1); stack.push(2); stack.push(3); stack.peek()', + hints: [ + 'Stack operations use same type T', + 'pop and peek return T | undefined for empty', + ], + tags: ['generics', 'interfaces', 'stack'], + }, + { + id: 'ts-generic-026', + category: 'Generics', + difficulty: 'medium', + title: 'Generic Event Emitter Interface', + text: 'Create a generic event emitter interface with typed events', + setup: 'interface EventEmitter> { on(event: K, cb: (data: E[K]) => void): void; emit(event: K, data: E[K]): void; }\ntype Events = { click: { x: number; y: number }; load: string };\nconst emitter: EventEmitter & { handlers: any } = { handlers: {}, on(e, cb) { this.handlers[e] = cb; }, emit(e, data) { this.handlers[e]?.(data); } };', + setupCode: 'interface EventEmitter> { on(event: K, cb: (data: E[K]) => void): void; emit(event: K, data: E[K]): void; }\ntype Events = { click: { x: number; y: number }; load: string };\nconst emitter: EventEmitter & { handlers: any } = { handlers: {}, on(e, cb) { this.handlers[e] = cb; }, emit(e, data) { this.handlers[e]?.(data); } };', + expected: { x: 10, y: 20 }, + sample: 'let result: any;\nemitter.on("click", (data) => { result = data; });\nemitter.emit("click", { x: 10, y: 20 });\nresult', + hints: [ + 'E maps event names to payload types', + 'K extends keyof E constrains to valid events', + ], + tags: ['generics', 'interfaces', 'events'], + }, + + // ============================================================ + // Advanced Generics - Generic Classes + // ============================================================ + { + id: 'ts-generic-027', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Box Class', + text: 'Create a generic Box class that wraps a value', + setup: 'class Box { constructor(public value: T) {} getValue(): T { return this.value; } }', + setupCode: 'class Box { constructor(public value: T) {} getValue(): T { return this.value; } }', + expected: 'hello', + sample: 'new Box("hello").getValue()', + hints: [ + 'Class takes type parameter after name', + 'Constructor and methods use the type T', + ], + tags: ['generics', 'classes', 'box'], + }, + { + id: 'ts-generic-028', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Pair Class', + text: 'Create a generic Pair class holding two values of different types', + setup: 'class Pair { constructor(public first: T, public second: U) {} toArray(): [T, U] { return [this.first, this.second]; } }', + setupCode: 'class Pair { constructor(public first: T, public second: U) {} toArray(): [T, U] { return [this.first, this.second]; } }', + expected: ['name', 42], + sample: 'new Pair("name", 42).toArray()', + hints: [ + 'Use two type parameters T and U', + 'Return tuple type [T, U] from toArray', + ], + tags: ['generics', 'classes', 'pair'], + }, + { + id: 'ts-generic-029', + category: 'Generics', + difficulty: 'medium', + title: 'Generic Queue Class', + text: 'Create a generic Queue class with enqueue and dequeue', + setup: 'class Queue { private items: T[] = []; enqueue(item: T): void { this.items.push(item); } dequeue(): T | undefined { return this.items.shift(); } size(): number { return this.items.length; } }', + setupCode: 'class Queue { private items: T[] = []; enqueue(item: T): void { this.items.push(item); } dequeue(): T | undefined { return this.items.shift(); } size(): number { return this.items.length; } }', + expected: 'first', + sample: 'const q = new Queue();\nq.enqueue("first");\nq.enqueue("second");\nq.dequeue()', + hints: [ + 'Use array as internal storage', + 'shift() removes and returns first element', + ], + tags: ['generics', 'classes', 'queue'], + }, + { + id: 'ts-generic-030', + category: 'Generics', + difficulty: 'medium', + title: 'Generic LinkedList Node', + text: 'Create a generic LinkedList node class', + setup: 'class ListNode { next: ListNode | null = null; constructor(public value: T) {} append(val: T): ListNode { const node = new ListNode(val); this.next = node; return node; } }', + setupCode: 'class ListNode { next: ListNode | null = null; constructor(public value: T) {} append(val: T): ListNode { const node = new ListNode(val); this.next = node; return node; } }', + expected: 2, + sample: 'const head = new ListNode(1);\nhead.append(2);\nhead.next?.value', + hints: [ + 'Self-referential: next is ListNode | null', + 'Recursive structure for linked list', + ], + tags: ['generics', 'classes', 'linkedlist'], + }, + { + id: 'ts-generic-031', + category: 'Generics', + difficulty: 'medium', + title: 'Generic Cache Class', + text: 'Create a generic Cache class with get, set, and has methods', + setup: 'class Cache { private store = new Map(); get(key: K): V | undefined { return this.store.get(key); } set(key: K, value: V): void { this.store.set(key, value); } has(key: K): boolean { return this.store.has(key); } }', + setupCode: 'class Cache { private store = new Map(); get(key: K): V | undefined { return this.store.get(key); } set(key: K, value: V): void { this.store.set(key, value); } has(key: K): boolean { return this.store.has(key); } }', + expected: 'value1', + sample: 'const cache = new Cache();\ncache.set("key1", "value1");\ncache.get("key1")', + hints: [ + 'Use Map for internal storage', + 'Two type parameters: K for key, V for value', + ], + tags: ['generics', 'classes', 'cache'], + }, + { + id: 'ts-generic-032', + category: 'Generics', + difficulty: 'hard', + title: 'Generic Observable Class', + text: 'Create a generic Observable class with subscribe and notify', + setup: 'class Observable { private observers: ((value: T) => void)[] = []; subscribe(fn: (value: T) => void): () => void { this.observers.push(fn); return () => { this.observers = this.observers.filter(o => o !== fn); }; } notify(value: T): void { this.observers.forEach(fn => fn(value)); } }', + setupCode: 'class Observable { private observers: ((value: T) => void)[] = []; subscribe(fn: (value: T) => void): () => void { this.observers.push(fn); return () => { this.observers = this.observers.filter(o => o !== fn); }; } notify(value: T): void { this.observers.forEach(fn => fn(value)); } }', + expected: 'hello', + sample: 'const obs = new Observable();\nlet result = "";\nobs.subscribe(v => { result = v; });\nobs.notify("hello");\nresult', + hints: [ + 'Observers are functions taking T', + 'subscribe returns unsubscribe function', + ], + tags: ['generics', 'classes', 'observable'], + }, + + // ============================================================ + // Advanced Generics - Default Type Parameters + // ============================================================ + { + id: 'ts-generic-033', + category: 'Generics', + difficulty: 'easy', + title: 'Default Type Parameter Basic', + text: 'Create a generic type with a default type parameter', + setup: 'type Container = { value: T };\nconst container: Container = { value: "default" };', + setupCode: 'type Container = { value: T };\nconst container: Container = { value: "default" };', + expected: 'default', + sample: 'container.value', + hints: [ + 'Use = after type parameter for default', + 'Default is used when type not specified', + ], + tags: ['generics', 'default', 'type-parameter'], + }, + { + id: 'ts-generic-034', + category: 'Generics', + difficulty: 'easy', + title: 'Default Type with Override', + text: 'Use a generic type with an explicit type overriding the default', + setup: 'type Response = { data: T; status: number };\nconst resp: Response = { data: [1, 2, 3], status: 200 };', + setupCode: 'type Response = { data: T; status: number };\nconst resp: Response = { data: [1, 2, 3], status: 200 };', + expected: [1, 2, 3], + sample: 'resp.data', + hints: [ + 'Default is any, but we specify number[]', + 'Explicit type overrides the default', + ], + tags: ['generics', 'default', 'override'], + }, + { + id: 'ts-generic-035', + category: 'Generics', + difficulty: 'medium', + title: 'Multiple Defaults', + text: 'Create a type with multiple default type parameters', + setup: 'type ApiResponse = { data?: T; error?: E; ok: boolean };\nconst success: ApiResponse = { data: "result", ok: true };', + setupCode: 'type ApiResponse = { data?: T; error?: E; ok: boolean };\nconst success: ApiResponse = { data: "result", ok: true };', + expected: 'result', + sample: 'success.data', + hints: [ + 'Each parameter can have its own default', + 'Later defaults use earlier parameters', + ], + tags: ['generics', 'default', 'multiple'], + }, + { + id: 'ts-generic-036', + category: 'Generics', + difficulty: 'medium', + title: 'Default Depends on Previous', + text: 'Create a type where default depends on a previous type parameter', + setup: 'type KeyValue = { key: K; value: V };\nconst kv: KeyValue = { key: "test", value: "test" };', + setupCode: 'type KeyValue = { key: K; value: V };\nconst kv: KeyValue = { key: "test", value: "test" };', + expected: 'test', + sample: 'kv.value', + hints: [ + 'V = K means V defaults to same type as K', + 'Dependencies between type parameters', + ], + tags: ['generics', 'default', 'dependent'], + }, + + // ============================================================ + // Advanced Generics - Generic Type Inference + // ============================================================ + { + id: 'ts-generic-037', + category: 'Generic Inference', + difficulty: 'easy', + title: 'Infer from Argument', + text: 'Let TypeScript infer the generic type from the argument', + setup: 'function echo(value: T): T { return value; }', + setupCode: 'function echo(value: T): T { return value; }', + expected: true, + sample: 'echo(true)', + hints: [ + 'No need to specify ', + 'Type inferred from argument value', + ], + tags: ['generics', 'inference', 'arguments'], + }, + { + id: 'ts-generic-038', + category: 'Generic Inference', + difficulty: 'easy', + title: 'Infer Array Element Type', + text: 'Infer element type from an array argument', + setup: 'function head(arr: T[]): T | undefined { return arr[0]; }', + setupCode: 'function head(arr: T[]): T | undefined { return arr[0]; }', + expected: 1, + sample: 'head([1, 2, 3])', + hints: [ + 'T is inferred as number from [1, 2, 3]', + 'Array literal provides inference context', + ], + tags: ['generics', 'inference', 'arrays'], + }, + { + id: 'ts-generic-039', + category: 'Generic Inference', + difficulty: 'medium', + title: 'Infer from Multiple Arguments', + text: 'Infer a common type from multiple arguments', + setup: 'function merge(a: T, b: T): T[] { return [a, b]; }', + setupCode: 'function merge(a: T, b: T): T[] { return [a, b]; }', + expected: [1, 2], + sample: 'merge(1, 2)', + hints: [ + 'Both arguments must be same type T', + 'TypeScript finds common type', + ], + tags: ['generics', 'inference', 'multiple'], + }, + { + id: 'ts-generic-040', + category: 'Generic Inference', + difficulty: 'medium', + title: 'Infer from Return Context', + text: 'Let generic be inferred from expected return type context', + setup: 'function create(): T[] { return []; }', + setupCode: 'function create(): T[] { return []; }', + expected: true, + sample: 'const nums: number[] = create();\nArray.isArray(nums)', + hints: [ + 'Return type annotation provides context', + 'T inferred as number from context', + ], + tags: ['generics', 'inference', 'context'], + }, + { + id: 'ts-generic-041', + category: 'Generic Inference', + difficulty: 'medium', + title: 'Infer Object Property Types', + text: 'Infer types from object literal properties', + setup: 'function keys(obj: T): (keyof T)[] { return Object.keys(obj) as (keyof T)[]; }', + setupCode: 'function keys(obj: T): (keyof T)[] { return Object.keys(obj) as (keyof T)[]; }', + expected: ['a', 'b'], + sample: 'keys({ a: 1, b: 2 })', + hints: [ + 'T inferred as { a: number; b: number }', + 'keyof T gives "a" | "b"', + ], + tags: ['generics', 'inference', 'objects'], + }, + { + id: 'ts-generic-042', + category: 'Generic Inference', + difficulty: 'hard', + title: 'Infer Function Parameter Type', + text: 'Infer the parameter type of a callback function', + setup: 'function map(arr: T[], fn: (item: T) => U): U[] { return arr.map(fn); }', + setupCode: 'function map(arr: T[], fn: (item: T) => U): U[] { return arr.map(fn); }', + expected: [2, 4, 6], + sample: 'map([1, 2, 3], x => x * 2)', + hints: [ + 'T inferred from array, U from callback return', + 'x is inferred as number', + ], + tags: ['generics', 'inference', 'callbacks'], + }, + { + id: 'ts-generic-043', + category: 'Generic Inference', + difficulty: 'hard', + title: 'Infer Tuple Types', + text: 'Infer tuple types preserving element types', + setup: 'function tuple(...args: T): T { return args; }', + setupCode: 'function tuple(...args: T): T { return args; }', + expected: ['a', 1, true], + sample: 'tuple("a", 1, true)', + hints: [ + 'Rest parameter with generic array type', + 'Tuple type [string, number, boolean] inferred', + ], + tags: ['generics', 'inference', 'tuples'], + }, + + // ============================================================ + // Advanced Generics - Conditional Types + // ============================================================ + { + id: 'ts-generic-044', + category: 'Generics', + difficulty: 'medium', + title: 'Basic Conditional Type', + text: 'Create a type that returns different types based on a condition', + setup: 'type IsString = T extends string ? true : false;', + setupCode: 'type IsString = T extends string ? true : false;', + expected: true, + sample: 'const result: IsString<"hello"> = true;\nresult', + hints: [ + 'Use extends for type condition', + 'Ternary-like syntax for conditional types', + ], + tags: ['generics', 'conditional', 'extends'], + }, + { + id: 'ts-generic-045', + category: 'Generics', + difficulty: 'medium', + title: 'Conditional Return Type', + text: 'Create a function with conditional return type', + setup: 'function process(value: T): T extends string ? number : string { return (typeof value === "string" ? value.length : String(value)) as any; }', + setupCode: 'function process(value: T): T extends string ? number : string { return (typeof value === "string" ? value.length : String(value)) as any; }', + expected: 5, + sample: 'process("hello")', + hints: [ + 'Return type depends on input type', + 'String input returns length (number)', + ], + tags: ['generics', 'conditional', 'return-type'], + }, + { + id: 'ts-generic-046', + category: 'Generics', + difficulty: 'medium', + title: 'Exclude Type', + text: 'Use conditional type to exclude types from a union', + setup: 'type MyExclude = T extends U ? never : T;', + setupCode: 'type MyExclude = T extends U ? never : T;', + expected: 'a', + sample: 'const val: MyExclude<"a" | "b" | "c", "b" | "c"> = "a";\nval', + hints: [ + 'Conditional distributes over unions', + 'never removes type from union', + ], + tags: ['generics', 'conditional', 'exclude'], + }, + { + id: 'ts-generic-047', + category: 'Generics', + difficulty: 'medium', + title: 'Extract Type', + text: 'Use conditional type to extract matching types from a union', + setup: 'type MyExtract = T extends U ? T : never;', + setupCode: 'type MyExtract = T extends U ? T : never;', + expected: 'b', + sample: 'const val: MyExtract<"a" | "b" | "c", "b" | "d"> = "b";\nval', + hints: [ + 'Opposite of Exclude logic', + 'Keeps types that match U', + ], + tags: ['generics', 'conditional', 'extract'], + }, + { + id: 'ts-generic-048', + category: 'Generics', + difficulty: 'hard', + title: 'NonNullable Type', + text: 'Create a type that removes null and undefined from a union', + setup: 'type MyNonNullable = T extends null | undefined ? never : T;', + setupCode: 'type MyNonNullable = T extends null | undefined ? never : T;', + expected: 'value', + sample: 'const val: MyNonNullable = "value";\nval', + hints: [ + 'Exclude null and undefined', + 'Uses conditional distribution', + ], + tags: ['generics', 'conditional', 'nonnullable'], + }, + { + id: 'ts-generic-049', + category: 'Generics', + difficulty: 'hard', + title: 'Flatten Conditional Type', + text: 'Create a type that flattens nested arrays', + setup: 'type Flatten = T extends (infer U)[] ? Flatten : T;', + setupCode: 'type Flatten = T extends (infer U)[] ? Flatten : T;', + expected: 1, + sample: 'const val: Flatten = 1;\nval', + hints: [ + 'Recursively check for array type', + 'infer U gets element type', + ], + tags: ['generics', 'conditional', 'flatten', 'recursive'], + }, + { + id: 'ts-generic-050', + category: 'Generics', + difficulty: 'hard', + title: 'Distributive Conditional Type', + text: 'Understand how conditional types distribute over unions', + setup: 'type ToArray = T extends any ? T[] : never;', + setupCode: 'type ToArray = T extends any ? T[] : never;', + expected: [1], + sample: 'const val: ToArray = [1];\nval', + hints: [ + 'Distributes: ToArray = A[] | B[]', + 'Each union member processed separately', + ], + tags: ['generics', 'conditional', 'distributive'], + }, + + // ============================================================ + // Advanced Generics - Infer Keyword + // ============================================================ + { + id: 'ts-generic-051', + category: 'Generic Inference', + difficulty: 'medium', + title: 'Infer Array Element', + text: 'Use infer to extract the element type of an array', + setup: 'type ElementOf = T extends (infer E)[] ? E : never;', + setupCode: 'type ElementOf = T extends (infer E)[] ? E : never;', + expected: 'test', + sample: 'const val: ElementOf = "test";\nval', + hints: [ + 'infer E captures the element type', + 'Pattern matches array structure', + ], + tags: ['generics', 'infer', 'array'], + }, + { + id: 'ts-generic-052', + category: 'Generic Inference', + difficulty: 'medium', + title: 'Infer Function Return Type', + text: 'Use infer to extract the return type of a function', + setup: 'type MyReturnType = T extends (...args: any[]) => infer R ? R : never;', + setupCode: 'type MyReturnType = T extends (...args: any[]) => infer R ? R : never;', + expected: 42, + sample: 'type Fn = () => number;\nconst val: MyReturnType = 42;\nval', + hints: [ + 'infer R captures the return type', + 'Pattern matches function signature', + ], + tags: ['generics', 'infer', 'return-type'], + }, + { + id: 'ts-generic-053', + category: 'Generic Inference', + difficulty: 'medium', + title: 'Infer Function Parameters', + text: 'Use infer to extract the parameter types of a function', + setup: 'type MyParameters = T extends (...args: infer P) => any ? P : never;', + setupCode: 'type MyParameters = T extends (...args: infer P) => any ? P : never;', + expected: ['hello', 42], + sample: 'type Fn = (a: string, b: number) => void;\nconst params: MyParameters = ["hello", 42];\nparams', + hints: [ + 'infer P captures parameter tuple', + 'Rest parameter pattern in signature', + ], + tags: ['generics', 'infer', 'parameters'], + }, + { + id: 'ts-generic-054', + category: 'Generic Inference', + difficulty: 'hard', + title: 'Infer Promise Type', + text: 'Use infer to extract the resolved type of a Promise', + setup: 'type Unpromise = T extends Promise ? U : T;', + setupCode: 'type Unpromise = T extends Promise ? U : T;', + expected: 'resolved', + sample: 'const val: Unpromise> = "resolved";\nval', + hints: [ + 'infer U captures Promise generic type', + 'Non-promise types pass through', + ], + tags: ['generics', 'infer', 'promise'], + }, + { + id: 'ts-generic-055', + category: 'Generic Inference', + difficulty: 'hard', + title: 'Infer First Argument', + text: 'Use infer to extract the first parameter type of a function', + setup: 'type FirstArg = T extends (first: infer F, ...rest: any[]) => any ? F : never;', + setupCode: 'type FirstArg = T extends (first: infer F, ...rest: any[]) => any ? F : never;', + expected: 'first', + sample: 'type Fn = (a: string, b: number, c: boolean) => void;\nconst val: FirstArg = "first";\nval', + hints: [ + 'Pattern match first parameter separately', + 'Rest collects remaining parameters', + ], + tags: ['generics', 'infer', 'first-arg'], + }, + { + id: 'ts-generic-056', + category: 'Generic Inference', + difficulty: 'hard', + title: 'Infer Constructor Instance', + text: 'Use infer to extract the instance type from a constructor', + setup: 'type InstanceOf = T extends new (...args: any[]) => infer I ? I : never;', + setupCode: 'type InstanceOf = T extends new (...args: any[]) => infer I ? I : never;', + expected: { name: 'test' }, + sample: 'class Foo { name = "test"; }\nconst instance: InstanceOf = new Foo();\n({ name: instance.name })', + hints: [ + 'new keyword indicates constructor', + 'infer I captures instance type', + ], + tags: ['generics', 'infer', 'constructor'], + }, + { + id: 'ts-generic-057', + category: 'Generic Inference', + difficulty: 'hard', + title: 'Infer Tuple Last Element', + text: 'Use infer to extract the last element type of a tuple', + setup: 'type Last = T extends [...infer _, infer L] ? L : never;', + setupCode: 'type Last = T extends [...infer _, infer L] ? L : never;', + expected: true, + sample: 'const val: Last<[string, number, boolean]> = true;\nval', + hints: [ + 'Spread infer captures all but last', + 'L captures the last element', + ], + tags: ['generics', 'infer', 'tuple', 'last'], + }, + { + id: 'ts-generic-058', + category: 'Generic Inference', + difficulty: 'hard', + title: 'Infer Tuple First Element', + text: 'Use infer to extract the first element type of a tuple', + setup: 'type First = T extends [infer F, ...infer _] ? F : never;', + setupCode: 'type First = T extends [infer F, ...infer _] ? F : never;', + expected: 'first', + sample: 'const val: First<[string, number, boolean]> = "first";\nval', + hints: [ + 'F captures first element', + 'Spread infer captures the rest', + ], + tags: ['generics', 'infer', 'tuple', 'first'], + }, + + // ============================================================ + // Advanced Generics - Mapped Types + // ============================================================ + { + id: 'ts-generic-059', + category: 'Generics', + difficulty: 'easy', + title: 'Basic Mapped Type', + text: 'Create a mapped type that makes all properties optional', + setup: 'type MyPartial = { [K in keyof T]?: T[K] };', + setupCode: 'type MyPartial = { [K in keyof T]?: T[K] };', + expected: { name: 'Alice' }, + sample: 'type Person = { name: string; age: number };\nconst partial: MyPartial = { name: "Alice" };\npartial', + hints: [ + 'K in keyof T iterates over keys', + '? makes each property optional', + ], + tags: ['generics', 'mapped-types', 'partial'], + }, + { + id: 'ts-generic-060', + category: 'Generics', + difficulty: 'easy', + title: 'Required Mapped Type', + text: 'Create a mapped type that makes all properties required', + setup: 'type MyRequired = { [K in keyof T]-?: T[K] };', + setupCode: 'type MyRequired = { [K in keyof T]-?: T[K] };', + expected: { name: 'Bob', age: 25 }, + sample: 'type Person = { name?: string; age?: number };\nconst required: MyRequired = { name: "Bob", age: 25 };\nrequired', + hints: [ + '-? removes optional modifier', + 'All properties become required', + ], + tags: ['generics', 'mapped-types', 'required'], + }, + { + id: 'ts-generic-061', + category: 'Generics', + difficulty: 'easy', + title: 'Readonly Mapped Type', + text: 'Create a mapped type that makes all properties readonly', + setup: 'type MyReadonly = { readonly [K in keyof T]: T[K] };', + setupCode: 'type MyReadonly = { readonly [K in keyof T]: T[K] };', + expected: 42, + sample: 'type Data = { value: number };\nconst data: MyReadonly = { value: 42 };\ndata.value', + hints: [ + 'readonly modifier prevents reassignment', + 'Applied to each property', + ], + tags: ['generics', 'mapped-types', 'readonly'], + }, + { + id: 'ts-generic-062', + category: 'Generics', + difficulty: 'medium', + title: 'Pick Mapped Type', + text: 'Create a mapped type that picks specific properties', + setup: 'type MyPick = { [P in K]: T[P] };', + setupCode: 'type MyPick = { [P in K]: T[P] };', + expected: { name: 'Alice' }, + sample: 'type Person = { name: string; age: number; email: string };\nconst picked: MyPick = { name: "Alice" };\npicked', + hints: [ + 'K extends keyof T constrains to valid keys', + 'Only iterate over specified keys', + ], + tags: ['generics', 'mapped-types', 'pick'], + }, + { + id: 'ts-generic-063', + category: 'Generics', + difficulty: 'medium', + title: 'Omit Mapped Type', + text: 'Create a mapped type that omits specific properties', + setup: 'type MyOmit = { [P in Exclude]: T[P] };', + setupCode: 'type MyOmit = { [P in Exclude]: T[P] };', + expected: { age: 30 }, + sample: 'type Person = { name: string; age: number };\nconst omitted: MyOmit = { age: 30 };\nomitted', + hints: [ + 'Use Exclude to remove keys', + 'Iterate over remaining keys', + ], + tags: ['generics', 'mapped-types', 'omit'], + }, + { + id: 'ts-generic-064', + category: 'Generics', + difficulty: 'medium', + title: 'Record Mapped Type', + text: 'Create a mapped type that creates an object type with specific keys', + setup: 'type MyRecord = { [P in K]: V };', + setupCode: 'type MyRecord = { [P in K]: V };', + expected: { a: 1, b: 1 }, + sample: 'const record: MyRecord<"a" | "b", number> = { a: 1, b: 1 };\nrecord', + hints: [ + 'K is a union of keys', + 'All keys map to same value type V', + ], + tags: ['generics', 'mapped-types', 'record'], + }, + { + id: 'ts-generic-065', + category: 'Generics', + difficulty: 'medium', + title: 'Nullable Properties Mapped Type', + text: 'Create a mapped type that makes all properties nullable', + setup: 'type Nullable = { [K in keyof T]: T[K] | null };', + setupCode: 'type Nullable = { [K in keyof T]: T[K] | null };', + expected: { name: null, age: 25 }, + sample: 'type Person = { name: string; age: number };\nconst nullable: Nullable = { name: null, age: 25 };\nnullable', + hints: [ + 'Add | null to each property type', + 'Original type preserved in union', + ], + tags: ['generics', 'mapped-types', 'nullable'], + }, + { + id: 'ts-generic-066', + category: 'Generics', + difficulty: 'hard', + title: 'Key Remapping Mapped Type', + text: 'Create a mapped type that prefixes all keys', + setup: 'type Prefixed = { [K in keyof T as `${P}${K & string}`]: T[K] };', + setupCode: 'type Prefixed = { [K in keyof T as `${P}${K & string}`]: T[K] };', + expected: { get_name: 'Alice' }, + sample: 'type Person = { name: string };\nconst prefixed: Prefixed = { get_name: "Alice" };\nprefixed', + hints: [ + 'Use as clause for key remapping', + 'Template literal creates new key', + ], + tags: ['generics', 'mapped-types', 'key-remapping'], + }, + { + id: 'ts-generic-067', + category: 'Generics', + difficulty: 'hard', + title: 'Getters Mapped Type', + text: 'Create a mapped type that converts properties to getter methods', + setup: 'type Getters = { [K in keyof T as `get${Capitalize}`]: () => T[K] };', + setupCode: 'type Getters = { [K in keyof T as `get${Capitalize}`]: () => T[K] };', + expected: 'Alice', + sample: 'type Person = { name: string };\nconst getters: Getters = { getName: () => "Alice" };\ngetters.getName()', + hints: [ + 'Capitalize transforms first letter', + 'Property becomes function returning original type', + ], + tags: ['generics', 'mapped-types', 'getters'], + }, + { + id: 'ts-generic-068', + category: 'Generics', + difficulty: 'hard', + title: 'Deep Readonly Mapped Type', + text: 'Create a recursive mapped type that makes all nested properties readonly', + setup: 'type DeepReadonly = { readonly [K in keyof T]: T[K] extends object ? DeepReadonly : T[K] };', + setupCode: 'type DeepReadonly = { readonly [K in keyof T]: T[K] extends object ? DeepReadonly : T[K] };', + expected: 'nested', + sample: 'type Data = { a: { b: string } };\nconst data: DeepReadonly = { a: { b: "nested" } };\ndata.a.b', + hints: [ + 'Recursively apply for object properties', + 'Base case for non-object types', + ], + tags: ['generics', 'mapped-types', 'deep', 'readonly'], + }, + + // ============================================================ + // Advanced Generics - Variadic Tuple Types + // ============================================================ + { + id: 'ts-generic-069', + category: 'Generics', + difficulty: 'medium', + title: 'Variadic Tuple Concat', + text: 'Create a type that concatenates two tuple types', + setup: 'type Concat = [...T, ...U];', + setupCode: 'type Concat = [...T, ...U];', + expected: [1, 2, 'a', 'b'], + sample: 'const result: Concat<[1, 2], ["a", "b"]> = [1, 2, "a", "b"];\nresult', + hints: [ + 'Spread both tuples into new tuple', + 'Order is preserved', + ], + tags: ['generics', 'variadic', 'tuple', 'concat'], + }, + { + id: 'ts-generic-070', + category: 'Generics', + difficulty: 'medium', + title: 'Variadic Tuple Push', + text: 'Create a type that adds an element to the end of a tuple', + setup: 'type Push = [...T, E];', + setupCode: 'type Push = [...T, E];', + expected: [1, 2, 3], + sample: 'const result: Push<[1, 2], 3> = [1, 2, 3];\nresult', + hints: [ + 'Spread existing tuple, add new element', + 'E is appended at the end', + ], + tags: ['generics', 'variadic', 'tuple', 'push'], + }, + { + id: 'ts-generic-071', + category: 'Generics', + difficulty: 'medium', + title: 'Variadic Tuple Unshift', + text: 'Create a type that adds an element to the beginning of a tuple', + setup: 'type Unshift = [E, ...T];', + setupCode: 'type Unshift = [E, ...T];', + expected: [0, 1, 2], + sample: 'const result: Unshift<[1, 2], 0> = [0, 1, 2];\nresult', + hints: [ + 'New element first, then spread tuple', + 'E is prepended at the start', + ], + tags: ['generics', 'variadic', 'tuple', 'unshift'], + }, + { + id: 'ts-generic-072', + category: 'Generics', + difficulty: 'hard', + title: 'Variadic Tuple Pop', + text: 'Create a type that removes the last element from a tuple', + setup: 'type Pop = T extends [...infer R, any] ? R : never;', + setupCode: 'type Pop = T extends [...infer R, any] ? R : never;', + expected: [1, 2], + sample: 'const result: Pop<[1, 2, 3]> = [1, 2];\nresult', + hints: [ + 'Use infer with spread to capture all but last', + 'any matches the last element', + ], + tags: ['generics', 'variadic', 'tuple', 'pop'], + }, + { + id: 'ts-generic-073', + category: 'Generics', + difficulty: 'hard', + title: 'Variadic Tuple Shift', + text: 'Create a type that removes the first element from a tuple', + setup: 'type Shift = T extends [any, ...infer R] ? R : never;', + setupCode: 'type Shift = T extends [any, ...infer R] ? R : never;', + expected: [2, 3], + sample: 'const result: Shift<[1, 2, 3]> = [2, 3];\nresult', + hints: [ + 'Match first element as any', + 'Infer rest of tuple', + ], + tags: ['generics', 'variadic', 'tuple', 'shift'], + }, + { + id: 'ts-generic-074', + category: 'Generics', + difficulty: 'hard', + title: 'Variadic Tuple Length', + text: 'Create a type that returns the length of a tuple as a literal type', + setup: 'type Length = T["length"];', + setupCode: 'type Length = T["length"];', + expected: 3, + sample: 'const len: Length<[1, 2, 3]> = 3;\nlen', + hints: [ + 'Tuple types have literal length', + 'Access length property of tuple type', + ], + tags: ['generics', 'variadic', 'tuple', 'length'], + }, + { + id: 'ts-generic-075', + category: 'Generics', + difficulty: 'hard', + title: 'Variadic Function Parameters', + text: 'Create a function that accepts variadic tuple parameters', + setup: 'function combine(a: [...T], b: [...U]): [...T, ...U] { return [...a, ...b]; }', + setupCode: 'function combine(a: [...T], b: [...U]): [...T, ...U] { return [...a, ...b]; }', + expected: [1, 'a', true, 2], + sample: 'combine([1, "a"], [true, 2])', + hints: [ + 'Spread operator in function signature', + 'Return type combines both tuples', + ], + tags: ['generics', 'variadic', 'functions'], + }, + + // ============================================================ + // Advanced Generics - Complex Patterns + // ============================================================ + { + id: 'ts-generic-076', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Type Alias', + text: 'Create a generic type alias for a callback function', + setup: 'type Callback = (value: T) => void;\nconst logNum: Callback = (n) => console.log(n);', + setupCode: 'type Callback = (value: T) => void;\nconst logNum: Callback = (n) => console.log(n);', + expected: 'function', + sample: 'typeof logNum', + hints: [ + 'Type alias can be generic', + 'T is used in function parameter', + ], + tags: ['generics', 'type-alias', 'callback'], + }, + { + id: 'ts-generic-077', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Union Type', + text: 'Create a generic type that represents success or failure', + setup: 'type Result = { ok: true; value: T } | { ok: false; error: string };', + setupCode: 'type Result = { ok: true; value: T } | { ok: false; error: string };', + expected: 42, + sample: 'const success: Result = { ok: true, value: 42 };\nsuccess.ok ? success.value : 0', + hints: [ + 'Union of success and failure cases', + 'Discriminated union with ok property', + ], + tags: ['generics', 'union', 'result'], + }, + { + id: 'ts-generic-078', + category: 'Generics', + difficulty: 'medium', + title: 'Generic Builder Pattern', + text: 'Create a generic builder that chains method calls', + setup: 'class Builder { private obj: T = {} as T; set(key: K, value: V): Builder> { (this.obj as any)[key] = value; return this as any; } build(): T { return this.obj; } }', + setupCode: 'class Builder { private obj: T = {} as T; set(key: K, value: V): Builder> { (this.obj as any)[key] = value; return this as any; } build(): T { return this.obj; } }', + expected: { name: 'test', age: 25 }, + sample: 'new Builder().set("name", "test").set("age", 25).build()', + hints: [ + 'Each set call expands the type', + 'Returns new Builder with extended type', + ], + tags: ['generics', 'builder', 'pattern'], + }, + { + id: 'ts-generic-079', + category: 'Generics', + difficulty: 'medium', + title: 'Generic Singleton Pattern', + text: 'Create a generic singleton factory', + setup: 'function singleton(create: () => T): () => T { let instance: T | null = null; return () => { if (instance === null) instance = create(); return instance; }; }', + setupCode: 'function singleton(create: () => T): () => T { let instance: T | null = null; return () => { if (instance === null) instance = create(); return instance; }; }', + expected: true, + sample: 'const getConfig = singleton(() => ({ debug: true }));\ngetConfig() === getConfig()', + hints: [ + 'Factory returns same instance always', + 'Lazy initialization on first call', + ], + tags: ['generics', 'singleton', 'pattern'], + }, + { + id: 'ts-generic-080', + category: 'Generics', + difficulty: 'medium', + title: 'Generic Memoization', + text: 'Create a generic memoization function', + setup: 'function memoize any>(fn: T): T { const cache = new Map>(); return ((...args: Parameters) => { const key = JSON.stringify(args); if (!cache.has(key)) cache.set(key, fn(...args)); return cache.get(key)!; }) as T; }', + setupCode: 'function memoize any>(fn: T): T { const cache = new Map>(); return ((...args: Parameters) => { const key = JSON.stringify(args); if (!cache.has(key)) cache.set(key, fn(...args)); return cache.get(key)!; }) as T; }', + expected: 8, + sample: 'const cube = memoize((n: number) => n ** 3);\ncube(2)', + hints: [ + 'Cache results by stringified args', + 'Return cached value if available', + ], + tags: ['generics', 'memoize', 'pattern'], + }, + { + id: 'ts-generic-081', + category: 'Generics', + difficulty: 'hard', + title: 'Generic Pipe Function', + text: 'Create a generic pipe function that composes functions left to right', + setup: 'function pipe(f: (a: A) => B): (a: A) => B;\nfunction pipe(f: (a: A) => B, g: (b: B) => C): (a: A) => C;\nfunction pipe(f: (a: A) => B, g: (b: B) => C, h: (c: C) => D): (a: A) => D;\nfunction pipe(...fns: Function[]): Function { return (x: any) => fns.reduce((v, f) => f(v), x); }', + setupCode: 'function pipe(f: (a: A) => B): (a: A) => B;\nfunction pipe(f: (a: A) => B, g: (b: B) => C): (a: A) => C;\nfunction pipe(f: (a: A) => B, g: (b: B) => C, h: (c: C) => D): (a: A) => D;\nfunction pipe(...fns: Function[]): Function { return (x: any) => fns.reduce((v, f) => f(v), x); }', + expected: 6, + sample: 'const process = pipe((x: number) => x + 1, (x: number) => x * 2);\nprocess(2)', + hints: [ + 'Overloads handle different arities', + 'Each function output feeds next input', + ], + tags: ['generics', 'pipe', 'composition'], + }, + { + id: 'ts-generic-082', + category: 'Generics', + difficulty: 'hard', + title: 'Generic Curry Function', + text: 'Create a generic curry function for two arguments', + setup: 'function curry(fn: (a: A, b: B) => R): (a: A) => (b: B) => R { return (a: A) => (b: B) => fn(a, b); }', + setupCode: 'function curry(fn: (a: A, b: B) => R): (a: A) => (b: B) => R { return (a: A) => (b: B) => fn(a, b); }', + expected: 5, + sample: 'const add = curry((a: number, b: number) => a + b);\nadd(2)(3)', + hints: [ + 'Returns nested functions', + 'Each function takes one argument', + ], + tags: ['generics', 'curry', 'functions'], + }, + { + id: 'ts-generic-083', + category: 'Generics', + difficulty: 'hard', + title: 'Generic State Machine Type', + text: 'Create generic types for a type-safe state machine', + setup: 'type State = { state: S; data: D };\ntype Transition = { from: From; to: To };\nfunction transition(current: State, to: T): State { return { state: to, data: current.data }; }', + setupCode: 'type State = { state: S; data: D };\ntype Transition = { from: From; to: To };\nfunction transition(current: State, to: T): State { return { state: to, data: current.data }; }', + expected: 'active', + sample: 'const idle: State<"idle", number> = { state: "idle", data: 42 };\nconst active = transition(idle, "active");\nactive.state', + hints: [ + 'State type pairs state name with data', + 'Transition changes state type', + ], + tags: ['generics', 'state-machine', 'pattern'], + }, + { + id: 'ts-generic-084', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Predicate Type', + text: 'Create a generic predicate type for filtering', + setup: 'type Predicate = (value: T) => boolean;\nconst isEven: Predicate = (n) => n % 2 === 0;', + setupCode: 'type Predicate = (value: T) => boolean;\nconst isEven: Predicate = (n) => n % 2 === 0;', + expected: [2, 4], + sample: '[1, 2, 3, 4, 5].filter(isEven)', + hints: [ + 'Predicate returns boolean', + 'Used for filtering operations', + ], + tags: ['generics', 'predicate', 'filter'], + }, + { + id: 'ts-generic-085', + category: 'Generics', + difficulty: 'easy', + title: 'Generic Comparator Type', + text: 'Create a generic comparator type for sorting', + setup: 'type Comparator = (a: T, b: T) => number;\nconst byLength: Comparator = (a, b) => a.length - b.length;', + setupCode: 'type Comparator = (a: T, b: T) => number;\nconst byLength: Comparator = (a, b) => a.length - b.length;', + expected: ['a', 'bb', 'ccc'], + sample: '["ccc", "a", "bb"].sort(byLength)', + hints: [ + 'Comparator returns negative, zero, or positive', + 'Used for sorting operations', + ], + tags: ['generics', 'comparator', 'sort'], + }, + + // ============================================================ + // Utility Types - Partial + // ============================================================ + { + id: 'ts-utility-001', + category: 'Utility Types', + difficulty: 'easy', + title: 'Basic Partial Type', + text: 'Create a partial user object where all properties are optional using the Partial utility type', + setup: 'interface User { id: number; name: string; email: string; }', + setupCode: 'interface User { id: number; name: string; email: string; }', + expected: { name: 'Alice' }, + sample: 'const partialUser: Partial = { name: "Alice" };\npartialUser', + hints: [ + 'Partial makes all properties optional', + 'You can include any subset of properties', + ], + tags: ['utility-types', 'partial'], + }, + { + id: 'ts-utility-002', + category: 'Utility Types', + difficulty: 'easy', + title: 'Partial for Update Functions', + text: 'Use Partial to create a function that accepts partial updates to a user object', + setup: 'interface User { id: number; name: string; email: string; }\nconst user: User = { id: 1, name: "Bob", email: "bob@test.com" };', + setupCode: 'interface User { id: number; name: string; email: string; }\nconst user: User = { id: 1, name: "Bob", email: "bob@test.com" };', + expected: { id: 1, name: 'Bob', email: 'bob@new.com' }, + sample: 'function updateUser(user: User, updates: Partial): User {\n return { ...user, ...updates };\n}\nupdateUser(user, { email: "bob@new.com" })', + hints: [ + 'Partial allows passing only the fields to update', + 'Spread operator merges the updates', + ], + tags: ['utility-types', 'partial', 'functions'], + }, + { + id: 'ts-utility-003', + category: 'Utility Types', + difficulty: 'medium', + title: 'Partial with Nested Objects', + text: 'Create a partially filled configuration object with nested properties', + setup: 'interface Config { server: { host: string; port: number; }; database: { url: string; }; }', + setupCode: 'interface Config { server: { host: string; port: number; }; database: { url: string; }; }', + expected: { server: { host: 'localhost', port: 3000 } }, + sample: 'const config: Partial = { server: { host: "localhost", port: 3000 } };\nconfig', + hints: [ + 'Partial only makes top-level properties optional', + 'Nested objects still require all their properties', + ], + tags: ['utility-types', 'partial', 'nested'], + }, + { + id: 'ts-utility-004', + category: 'Utility Types', + difficulty: 'hard', + title: 'Deep Partial Type', + text: 'Implement a DeepPartial type that makes all nested properties optional recursively', + setup: 'type DeepPartial = T extends object ? { [P in keyof T]?: DeepPartial } : T;\ninterface Config { server: { host: string; port: number; }; }', + setupCode: 'type DeepPartial = T extends object ? { [P in keyof T]?: DeepPartial } : T;\ninterface Config { server: { host: string; port: number; }; }', + expected: { server: { host: 'localhost' } }, + sample: 'const config: DeepPartial = { server: { host: "localhost" } };\nconfig', + hints: [ + 'Use recursive conditional types', + 'Check if T extends object before recursing', + ], + tags: ['utility-types', 'partial', 'deep', 'recursive'], + }, + { + id: 'ts-utility-005', + category: 'Utility Types', + difficulty: 'hard', + title: 'Partial with Required Keys', + text: 'Create a type that makes all properties optional except specified keys', + setup: 'type PartialExcept = Partial & Pick;\ninterface User { id: number; name: string; email: string; }', + setupCode: 'type PartialExcept = Partial & Pick;\ninterface User { id: number; name: string; email: string; }', + expected: { id: 1, name: 'Alice' }, + sample: 'const user: PartialExcept = { id: 1, name: "Alice" };\nuser', + hints: [ + 'Combine Partial and Pick with intersection', + 'Pick extracts required keys', + ], + tags: ['utility-types', 'partial', 'pick', 'advanced'], + }, + + // ============================================================ + // Utility Types - Required + // ============================================================ + { + id: 'ts-utility-006', + category: 'Utility Types', + difficulty: 'easy', + title: 'Basic Required Type', + text: 'Convert a type with optional properties to one where all properties are required', + setup: 'interface OptionalUser { id?: number; name?: string; email?: string; }', + setupCode: 'interface OptionalUser { id?: number; name?: string; email?: string; }', + expected: { id: 1, name: 'Alice', email: 'alice@test.com' }, + sample: 'const user: Required = { id: 1, name: "Alice", email: "alice@test.com" };\nuser', + hints: [ + 'Required makes all properties required', + 'All properties must be provided', + ], + tags: ['utility-types', 'required'], + }, + { + id: 'ts-utility-007', + category: 'Utility Types', + difficulty: 'easy', + title: 'Required for Form Validation', + text: 'Ensure all form fields are filled before submission using Required', + setup: 'interface FormData { username?: string; password?: string; }\nfunction validateForm(data: Required): boolean { return data.username.length > 0 && data.password.length > 0; }', + setupCode: 'interface FormData { username?: string; password?: string; }\nfunction validateForm(data: Required): boolean { return data.username.length > 0 && data.password.length > 0; }', + expected: true, + sample: 'const formData: Required = { username: "admin", password: "secret" };\nvalidateForm(formData)', + hints: [ + 'Required ensures no undefined values', + 'Safe to access properties without optional chaining', + ], + tags: ['utility-types', 'required', 'validation'], + }, + { + id: 'ts-utility-008', + category: 'Utility Types', + difficulty: 'medium', + title: 'Required with Partial Combination', + text: 'Use Required to override Partial and ensure all properties exist', + setup: 'interface User { id: number; name: string; email: string; }\ntype PartialUser = Partial;', + setupCode: 'interface User { id: number; name: string; email: string; }\ntype PartialUser = Partial;', + expected: { id: 1, name: 'Bob', email: 'bob@test.com' }, + sample: 'const partial: PartialUser = { id: 1, name: "Bob" };\nconst complete: Required = { ...partial, email: "bob@test.com" };\ncomplete', + hints: [ + 'Required> equals T', + 'Fill in missing properties to satisfy Required', + ], + tags: ['utility-types', 'required', 'partial'], + }, + { + id: 'ts-utility-009', + category: 'Utility Types', + difficulty: 'hard', + title: 'Deep Required Type', + text: 'Implement a DeepRequired type that makes all nested properties required recursively', + setup: 'type DeepRequired = T extends object ? { [P in keyof T]-?: DeepRequired } : T;\ninterface Config { server?: { host?: string; port?: number; }; }', + setupCode: 'type DeepRequired = T extends object ? { [P in keyof T]-?: DeepRequired } : T;\ninterface Config { server?: { host?: string; port?: number; }; }', + expected: { server: { host: 'localhost', port: 3000 } }, + sample: 'const config: DeepRequired = { server: { host: "localhost", port: 3000 } };\nconfig', + hints: [ + 'Use -? to remove optional modifier', + 'Recursively apply to nested objects', + ], + tags: ['utility-types', 'required', 'deep', 'recursive'], + }, + { + id: 'ts-utility-010', + category: 'Utility Types', + difficulty: 'hard', + title: 'Required Keys Extraction', + text: 'Extract only the keys that are required (non-optional) from a type', + setup: 'type RequiredKeys = { [K in keyof T]-?: {} extends Pick ? never : K }[keyof T];\ninterface User { id: number; name: string; email?: string; }', + setupCode: 'type RequiredKeys = { [K in keyof T]-?: {} extends Pick ? never : K }[keyof T];\ninterface User { id: number; name: string; email?: string; }', + expected: ['id', 'name'], + sample: 'type Keys = RequiredKeys;\nconst keys: Keys[] = ["id", "name"];\nkeys', + hints: [ + 'Check if {} extends Pick to detect optional', + 'Optional keys return never and are filtered out', + ], + tags: ['utility-types', 'required', 'keys', 'advanced'], + }, + + // ============================================================ + // Utility Types - Readonly + // ============================================================ + { + id: 'ts-utility-011', + category: 'Utility Types', + difficulty: 'easy', + title: 'Basic Readonly Type', + text: 'Create an immutable user object using the Readonly utility type', + setup: 'interface User { id: number; name: string; }', + setupCode: 'interface User { id: number; name: string; }', + expected: { id: 1, name: 'Alice' }, + sample: 'const user: Readonly = { id: 1, name: "Alice" };\nuser', + hints: [ + 'Readonly makes all properties readonly', + 'Attempting to modify properties causes a compile error', + ], + tags: ['utility-types', 'readonly'], + }, + { + id: 'ts-utility-012', + category: 'Utility Types', + difficulty: 'easy', + title: 'Readonly Arrays', + text: 'Create an immutable array that cannot be modified', + setup: 'const numbers: number[] = [1, 2, 3];', + setupCode: 'const numbers: number[] = [1, 2, 3];', + expected: [1, 2, 3], + sample: 'const readonlyNumbers: Readonly = [1, 2, 3];\nreadonlyNumbers', + hints: [ + 'Readonly works on arrays too', + 'Use ReadonlyArray as an alternative', + ], + tags: ['utility-types', 'readonly', 'arrays'], + }, + { + id: 'ts-utility-013', + category: 'Utility Types', + difficulty: 'easy', + title: 'ReadonlyArray Type', + text: 'Use ReadonlyArray to create an immutable array type', + setup: 'function sum(numbers: ReadonlyArray): number { return numbers.reduce((a, b) => a + b, 0); }', + setupCode: 'function sum(numbers: ReadonlyArray): number { return numbers.reduce((a, b) => a + b, 0); }', + expected: 15, + sample: 'const nums: ReadonlyArray = [1, 2, 3, 4, 5];\nsum(nums)', + hints: [ + 'ReadonlyArray prevents push, pop, and mutations', + 'Read operations like reduce are allowed', + ], + tags: ['utility-types', 'readonly', 'arrays'], + }, + { + id: 'ts-utility-014', + category: 'Utility Types', + difficulty: 'hard', + title: 'Deep Readonly Type', + text: 'Implement a DeepReadonly type that makes all nested properties readonly recursively', + setup: 'type DeepReadonly = T extends object ? { readonly [P in keyof T]: DeepReadonly } : T;\ninterface State { user: { name: string; settings: { theme: string; }; }; }', + setupCode: 'type DeepReadonly = T extends object ? { readonly [P in keyof T]: DeepReadonly } : T;\ninterface State { user: { name: string; settings: { theme: string; }; }; }', + expected: { user: { name: 'Alice', settings: { theme: 'dark' } } }, + sample: 'const state: DeepReadonly = { user: { name: "Alice", settings: { theme: "dark" } } };\nstate', + hints: [ + 'Recursively apply readonly to nested objects', + 'Base case is non-object types', + ], + tags: ['utility-types', 'readonly', 'deep', 'recursive'], + }, + { + id: 'ts-utility-015', + category: 'Utility Types', + difficulty: 'medium', + title: 'Mutable from Readonly', + text: 'Create a Mutable type that removes readonly modifiers from all properties', + setup: 'type Mutable = { -readonly [P in keyof T]: T[P] };\ninterface ReadonlyUser { readonly id: number; readonly name: string; }', + setupCode: 'type Mutable = { -readonly [P in keyof T]: T[P] };\ninterface ReadonlyUser { readonly id: number; readonly name: string; }', + expected: { id: 2, name: 'Bob' }, + sample: 'const user: Mutable = { id: 1, name: "Alice" };\nuser.id = 2;\nuser.name = "Bob";\nuser', + hints: [ + 'Use -readonly to remove the readonly modifier', + 'Mapped types can modify property modifiers', + ], + tags: ['utility-types', 'readonly', 'mutable', 'mapped-types'], + }, + + // ============================================================ + // Utility Types - Pick + // ============================================================ + { + id: 'ts-utility-016', + category: 'Utility Types', + difficulty: 'easy', + title: 'Basic Pick Type', + text: 'Pick only the name and email properties from a User type', + setup: 'interface User { id: number; name: string; email: string; createdAt: Date; }', + setupCode: 'interface User { id: number; name: string; email: string; createdAt: Date; }', + expected: { name: 'Alice', email: 'alice@test.com' }, + sample: 'const contact: Pick = { name: "Alice", email: "alice@test.com" };\ncontact', + hints: [ + 'Pick selects specific properties', + 'Use union type for multiple keys', + ], + tags: ['utility-types', 'pick'], + }, + { + id: 'ts-utility-017', + category: 'Utility Types', + difficulty: 'easy', + title: 'Pick Single Property', + text: 'Create a type with only the id property from User', + setup: 'interface User { id: number; name: string; email: string; }', + setupCode: 'interface User { id: number; name: string; email: string; }', + expected: { id: 42 }, + sample: 'const userId: Pick = { id: 42 };\nuserId', + hints: [ + 'Pick works with a single key', + 'Result type has only the picked property', + ], + tags: ['utility-types', 'pick'], + }, + { + id: 'ts-utility-018', + category: 'Utility Types', + difficulty: 'medium', + title: 'Pick for API Response', + text: 'Create a public user type by picking only non-sensitive fields', + setup: 'interface User { id: number; name: string; email: string; password: string; apiKey: string; }', + setupCode: 'interface User { id: number; name: string; email: string; password: string; apiKey: string; }', + expected: { id: 1, name: 'Alice', email: 'alice@test.com' }, + sample: 'type PublicUser = Pick;\nconst publicUser: PublicUser = { id: 1, name: "Alice", email: "alice@test.com" };\npublicUser', + hints: [ + 'Pick is useful for creating subset types', + 'Sensitive fields like password are excluded', + ], + tags: ['utility-types', 'pick', 'api'], + }, + { + id: 'ts-utility-019', + category: 'Utility Types', + difficulty: 'medium', + title: 'Pick with Generics', + text: 'Create a generic function that picks specific properties from an object', + setup: 'function pick(obj: T, keys: K[]): Pick {\n const result = {} as Pick;\n keys.forEach(key => result[key] = obj[key]);\n return result;\n}\nconst user = { id: 1, name: "Alice", email: "alice@test.com", age: 30 };', + setupCode: 'function pick(obj: T, keys: K[]): Pick {\n const result = {} as Pick;\n keys.forEach(key => result[key] = obj[key]);\n return result;\n}\nconst user = { id: 1, name: "Alice", email: "alice@test.com", age: 30 };', + expected: { name: 'Alice', age: 30 }, + sample: 'pick(user, ["name", "age"])', + hints: [ + 'K extends keyof T constrains keys', + 'Pick is the return type', + ], + tags: ['utility-types', 'pick', 'generics'], + }, + { + id: 'ts-utility-020', + category: 'Utility Types', + difficulty: 'hard', + title: 'Pick by Value Type', + text: 'Create a type that picks only properties of a specific value type', + setup: 'type PickByType = { [K in keyof T as T[K] extends V ? K : never]: T[K] };\ninterface Mixed { id: number; name: string; count: number; label: string; }', + setupCode: 'type PickByType = { [K in keyof T as T[K] extends V ? K : never]: T[K] };\ninterface Mixed { id: number; name: string; count: number; label: string; }', + expected: { id: 1, count: 5 }, + sample: 'type NumberProps = PickByType;\nconst nums: NumberProps = { id: 1, count: 5 };\nnums', + hints: [ + 'Use key remapping with as clause', + 'Filter keys based on value type', + ], + tags: ['utility-types', 'pick', 'advanced', 'key-remapping'], + }, + + // ============================================================ + // Utility Types - Omit + // ============================================================ + { + id: 'ts-utility-021', + category: 'Utility Types', + difficulty: 'easy', + title: 'Basic Omit Type', + text: 'Create a user type without the password field using Omit', + setup: 'interface User { id: number; name: string; email: string; password: string; }', + setupCode: 'interface User { id: number; name: string; email: string; password: string; }', + expected: { id: 1, name: 'Alice', email: 'alice@test.com' }, + sample: 'const user: Omit = { id: 1, name: "Alice", email: "alice@test.com" };\nuser', + hints: [ + 'Omit excludes specified properties', + 'Result has all properties except omitted ones', + ], + tags: ['utility-types', 'omit'], + }, + { + id: 'ts-utility-022', + category: 'Utility Types', + difficulty: 'easy', + title: 'Omit Multiple Properties', + text: 'Remove multiple sensitive fields from a user type', + setup: 'interface User { id: number; name: string; email: string; password: string; apiKey: string; }', + setupCode: 'interface User { id: number; name: string; email: string; password: string; apiKey: string; }', + expected: { id: 1, name: 'Alice', email: 'alice@test.com' }, + sample: 'const safeUser: Omit = { id: 1, name: "Alice", email: "alice@test.com" };\nsafeUser', + hints: [ + 'Use union type to omit multiple keys', + 'Omit is useful for sanitizing data', + ], + tags: ['utility-types', 'omit', 'security'], + }, + { + id: 'ts-utility-023', + category: 'Utility Types', + difficulty: 'medium', + title: 'Omit for Extension', + text: 'Create an extended type by omitting a property and adding a new one', + setup: 'interface BaseUser { id: number; name: string; role: string; }', + setupCode: 'interface BaseUser { id: number; name: string; role: string; }', + expected: { id: 1, name: 'Alice', role: 'admin', permissions: ['read', 'write'] }, + sample: 'type AdminUser = Omit & { role: "admin"; permissions: string[]; };\nconst admin: AdminUser = { id: 1, name: "Alice", role: "admin", permissions: ["read", "write"] };\nadmin', + hints: [ + 'Omit the property you want to override', + 'Use intersection to add new properties', + ], + tags: ['utility-types', 'omit', 'extension'], + }, + { + id: 'ts-utility-024', + category: 'Utility Types', + difficulty: 'medium', + title: 'Omit with Generics', + text: 'Create a generic function that omits specified properties from an object', + setup: 'function omit(obj: T, keys: K[]): Omit {\n const result = { ...obj };\n keys.forEach(key => delete (result as any)[key]);\n return result;\n}\nconst user = { id: 1, name: "Alice", password: "secret", apiKey: "key123" };', + setupCode: 'function omit(obj: T, keys: K[]): Omit {\n const result = { ...obj };\n keys.forEach(key => delete (result as any)[key]);\n return result;\n}\nconst user = { id: 1, name: "Alice", password: "secret", apiKey: "key123" };', + expected: { id: 1, name: 'Alice' }, + sample: 'omit(user, ["password", "apiKey"])', + hints: [ + 'K extends keyof T constrains the keys', + 'Omit is the return type', + ], + tags: ['utility-types', 'omit', 'generics'], + }, + { + id: 'ts-utility-025', + category: 'Utility Types', + difficulty: 'hard', + title: 'Omit by Value Type', + text: 'Create a type that omits properties of a specific value type', + setup: 'type OmitByType = { [K in keyof T as T[K] extends V ? never : K]: T[K] };\ninterface Mixed { id: number; name: string; count: number; label: string; }', + setupCode: 'type OmitByType = { [K in keyof T as T[K] extends V ? never : K]: T[K] };\ninterface Mixed { id: number; name: string; count: number; label: string; }', + expected: { name: 'test', label: 'item' }, + sample: 'type StringProps = OmitByType;\nconst strs: StringProps = { name: "test", label: "item" };\nstrs', + hints: [ + 'Use key remapping with as clause', + 'Return never to exclude keys', + ], + tags: ['utility-types', 'omit', 'advanced', 'key-remapping'], + }, + + // ============================================================ + // Utility Types - Record + // ============================================================ + { + id: 'ts-utility-026', + category: 'Utility Types', + difficulty: 'easy', + title: 'Basic Record Type', + text: 'Create a record that maps string keys to number values', + setup: 'type Scores = Record;', + setupCode: 'type Scores = Record;', + expected: { alice: 100, bob: 85, charlie: 92 }, + sample: 'const scores: Scores = { alice: 100, bob: 85, charlie: 92 };\nscores', + hints: [ + 'Record creates an object type with key type K and value type V', + 'Useful for dictionary-like structures', + ], + tags: ['utility-types', 'record'], + }, + { + id: 'ts-utility-027', + category: 'Utility Types', + difficulty: 'easy', + title: 'Record with Union Keys', + text: 'Create a record with specific literal type keys', + setup: 'type Status = "pending" | "active" | "completed";', + setupCode: 'type Status = "pending" | "active" | "completed";', + expected: { pending: 5, active: 3, completed: 12 }, + sample: 'const statusCounts: Record = { pending: 5, active: 3, completed: 12 };\nstatusCounts', + hints: [ + 'Union types can be used as keys', + 'All union members must be present', + ], + tags: ['utility-types', 'record', 'union'], + }, + { + id: 'ts-utility-028', + category: 'Utility Types', + difficulty: 'easy', + title: 'Record for Object Values', + text: 'Create a record mapping user IDs to user objects', + setup: 'interface User { name: string; email: string; }', + setupCode: 'interface User { name: string; email: string; }', + expected: { '1': { name: 'Alice', email: 'alice@test.com' }, '2': { name: 'Bob', email: 'bob@test.com' } }, + sample: 'const users: Record = {\n "1": { name: "Alice", email: "alice@test.com" },\n "2": { name: "Bob", email: "bob@test.com" }\n};\nusers', + hints: [ + 'Record values can be complex types', + 'Useful for lookup tables', + ], + tags: ['utility-types', 'record', 'objects'], + }, + { + id: 'ts-utility-029', + category: 'Utility Types', + difficulty: 'medium', + title: 'Record for State Management', + text: 'Create a type-safe state object using Record with specific states', + setup: 'type LoadingState = "idle" | "loading" | "success" | "error";\ninterface StateConfig { message: string; canRetry: boolean; }', + setupCode: 'type LoadingState = "idle" | "loading" | "success" | "error";\ninterface StateConfig { message: string; canRetry: boolean; }', + expected: { idle: { message: 'Ready', canRetry: false }, loading: { message: 'Loading...', canRetry: false }, success: { message: 'Done!', canRetry: false }, error: { message: 'Failed', canRetry: true } }, + sample: 'const stateConfig: Record = {\n idle: { message: "Ready", canRetry: false },\n loading: { message: "Loading...", canRetry: false },\n success: { message: "Done!", canRetry: false },\n error: { message: "Failed", canRetry: true }\n};\nstateConfig', + hints: [ + 'Record ensures all states are covered', + 'Compile error if a state is missing', + ], + tags: ['utility-types', 'record', 'state-management'], + }, + { + id: 'ts-utility-030', + category: 'Utility Types', + difficulty: 'medium', + title: 'Nested Record Types', + text: 'Create a nested record for categorized items', + setup: 'type Category = "electronics" | "clothing";\ntype Item = { name: string; price: number; };', + setupCode: 'type Category = "electronics" | "clothing";\ntype Item = { name: string; price: number; };', + expected: { electronics: { laptop: { name: 'MacBook', price: 1999 } }, clothing: { shirt: { name: 'T-Shirt', price: 25 } } }, + sample: 'const inventory: Record> = {\n electronics: { laptop: { name: "MacBook", price: 1999 } },\n clothing: { shirt: { name: "T-Shirt", price: 25 } }\n};\ninventory', + hints: [ + 'Records can be nested', + 'Inner Record has string keys, Item values', + ], + tags: ['utility-types', 'record', 'nested'], + }, + { + id: 'ts-utility-031', + category: 'Utility Types', + difficulty: 'hard', + title: 'Record with Mapped Types', + text: 'Create a Record type that makes all values optional', + setup: 'type PartialRecord = { [P in K]?: V };\ntype Status = "pending" | "active" | "completed";', + setupCode: 'type PartialRecord = { [P in K]?: V };\ntype Status = "pending" | "active" | "completed";', + expected: { pending: 5, completed: 10 }, + sample: 'const counts: PartialRecord = { pending: 5, completed: 10 };\ncounts', + hints: [ + 'Combine Record pattern with optional modifier', + 'Not all keys need to be present', + ], + tags: ['utility-types', 'record', 'mapped-types', 'partial'], + }, + + // ============================================================ + // Utility Types - Exclude + // ============================================================ + { + id: 'ts-utility-032', + category: 'Utility Types', + difficulty: 'easy', + title: 'Basic Exclude Type', + text: 'Exclude specific types from a union type', + setup: 'type Status = "pending" | "active" | "completed" | "cancelled";', + setupCode: 'type Status = "pending" | "active" | "completed" | "cancelled";', + expected: 'active', + sample: 'type ActiveStatus = Exclude;\nconst status: ActiveStatus = "active";\nstatus', + hints: [ + 'Exclude removes U from union T', + 'Result is the remaining union members', + ], + tags: ['utility-types', 'exclude', 'union'], + }, + { + id: 'ts-utility-033', + category: 'Utility Types', + difficulty: 'easy', + title: 'Exclude Null and Undefined', + text: 'Remove null and undefined from a union type', + setup: 'type MaybeString = string | null | undefined;', + setupCode: 'type MaybeString = string | null | undefined;', + expected: 'hello', + sample: 'type DefiniteString = Exclude;\nconst str: DefiniteString = "hello";\nstr', + hints: [ + 'Exclude can remove multiple types at once', + 'Similar to NonNullable for this case', + ], + tags: ['utility-types', 'exclude', 'nullish'], + }, + { + id: 'ts-utility-034', + category: 'Utility Types', + difficulty: 'medium', + title: 'Exclude Function Types', + text: 'Exclude function types from a mixed union', + setup: 'type Mixed = string | number | (() => void) | ((x: number) => number);', + setupCode: 'type Mixed = string | number | (() => void) | ((x: number) => number);', + expected: 'test', + sample: 'type NonFunction = Exclude;\nconst value: NonFunction = "test";\nvalue', + hints: [ + 'Function is the base type for all functions', + 'Exclude removes all function types', + ], + tags: ['utility-types', 'exclude', 'functions'], + }, + { + id: 'ts-utility-035', + category: 'Utility Types', + difficulty: 'medium', + title: 'Exclude for Event Types', + text: 'Create a type for non-mouse events by excluding mouse-related events', + setup: 'type Event = "click" | "mousedown" | "mouseup" | "keydown" | "keyup" | "focus" | "blur";', + setupCode: 'type Event = "click" | "mousedown" | "mouseup" | "keydown" | "keyup" | "focus" | "blur";', + expected: 'keydown', + sample: 'type NonMouseEvent = Exclude;\nconst event: NonMouseEvent = "keydown";\nevent', + hints: [ + 'List all mouse events to exclude', + 'Remaining events are keyboard and focus events', + ], + tags: ['utility-types', 'exclude', 'events'], + }, + { + id: 'ts-utility-036', + category: 'Utility Types', + difficulty: 'hard', + title: 'Exclude with Template Literals', + text: 'Exclude string literal types that match a pattern', + setup: 'type Events = "onClick" | "onHover" | "onFocus" | "handleClick" | "handleHover";', + setupCode: 'type Events = "onClick" | "onHover" | "onFocus" | "handleClick" | "handleHover";', + expected: 'handleClick', + sample: 'type HandleEvents = Exclude;\nconst event: HandleEvents = "handleClick";\nevent', + hints: [ + 'Template literal types can be used with Exclude', + 'Pattern `on${string}` matches strings starting with "on"', + ], + tags: ['utility-types', 'exclude', 'template-literals'], + }, + + // ============================================================ + // Utility Types - Extract + // ============================================================ + { + id: 'ts-utility-037', + category: 'Utility Types', + difficulty: 'easy', + title: 'Basic Extract Type', + text: 'Extract specific types from a union type', + setup: 'type Mixed = string | number | boolean | null;', + setupCode: 'type Mixed = string | number | boolean | null;', + expected: 'hello', + sample: 'type StringOrNumber = Extract;\nconst value: StringOrNumber = "hello";\nvalue', + hints: [ + 'Extract keeps only types assignable to U', + 'Opposite of Exclude', + ], + tags: ['utility-types', 'extract', 'union'], + }, + { + id: 'ts-utility-038', + category: 'Utility Types', + difficulty: 'easy', + title: 'Extract Primitive Types', + text: 'Extract only primitive types from a union', + setup: 'type Data = string | number | { id: number } | string[];', + setupCode: 'type Data = string | number | { id: number } | string[];', + expected: 42, + sample: 'type Primitives = Extract;\nconst value: Primitives = 42;\nvalue', + hints: [ + 'Extract matches types that extend the filter', + 'Objects and arrays are excluded', + ], + tags: ['utility-types', 'extract', 'primitives'], + }, + { + id: 'ts-utility-039', + category: 'Utility Types', + difficulty: 'medium', + title: 'Extract Function Types', + text: 'Extract only function types from a union', + setup: 'type Mixed = string | (() => void) | number | ((x: number) => number);', + setupCode: 'type Mixed = string | (() => void) | number | ((x: number) => number);', + expected: 10, + sample: 'type Functions = Extract;\nconst fn: Functions = (x: number) => x * 2;\nfn(5)', + hints: [ + 'Function is the base type for all functions', + 'Extract keeps all function types', + ], + tags: ['utility-types', 'extract', 'functions'], + }, + { + id: 'ts-utility-040', + category: 'Utility Types', + difficulty: 'medium', + title: 'Extract from Discriminated Union', + text: 'Extract specific variants from a discriminated union type', + setup: 'type Result = { type: "success"; data: string } | { type: "error"; message: string } | { type: "loading" };', + setupCode: 'type Result = { type: "success"; data: string } | { type: "error"; message: string } | { type: "loading" };', + expected: { type: 'success', data: 'Done!' }, + sample: 'type SuccessResult = Extract;\nconst result: SuccessResult = { type: "success", data: "Done!" };\nresult', + hints: [ + 'Extract matches by structure', + 'Only the variant with type "success" is kept', + ], + tags: ['utility-types', 'extract', 'discriminated-union'], + }, + { + id: 'ts-utility-041', + category: 'Utility Types', + difficulty: 'hard', + title: 'Extract with Template Literals', + text: 'Extract string literal types matching a pattern', + setup: 'type Events = "onClick" | "onHover" | "onFocus" | "handleClick" | "handleHover";', + setupCode: 'type Events = "onClick" | "onHover" | "onFocus" | "handleClick" | "handleHover";', + expected: 'onClick', + sample: 'type OnEvents = Extract;\nconst event: OnEvents = "onClick";\nevent', + hints: [ + 'Template literals work with Extract', + 'Pattern matches strings starting with "on"', + ], + tags: ['utility-types', 'extract', 'template-literals'], + }, + + // ============================================================ + // Utility Types - NonNullable + // ============================================================ + { + id: 'ts-utility-042', + category: 'Utility Types', + difficulty: 'easy', + title: 'Basic NonNullable Type', + text: 'Remove null and undefined from a type using NonNullable', + setup: 'type MaybeUser = { name: string } | null | undefined;', + setupCode: 'type MaybeUser = { name: string } | null | undefined;', + expected: { name: 'Alice' }, + sample: 'type User = NonNullable;\nconst user: User = { name: "Alice" };\nuser', + hints: [ + 'NonNullable removes null and undefined', + 'Result is guaranteed to be defined', + ], + tags: ['utility-types', 'nonnullable', 'nullish'], + }, + { + id: 'ts-utility-043', + category: 'Utility Types', + difficulty: 'easy', + title: 'NonNullable with Primitives', + text: 'Ensure a string value is never null or undefined', + setup: 'type MaybeString = string | null | undefined;', + setupCode: 'type MaybeString = string | null | undefined;', + expected: 'hello', + sample: 'type DefiniteString = NonNullable;\nconst str: DefiniteString = "hello";\nstr', + hints: [ + 'NonNullable = string', + 'Only the string type remains', + ], + tags: ['utility-types', 'nonnullable', 'primitives'], + }, + { + id: 'ts-utility-044', + category: 'Utility Types', + difficulty: 'medium', + title: 'NonNullable in Generic Contexts', + text: 'Use NonNullable to assert a value exists in a generic function', + setup: 'function assertDefined(value: T): NonNullable {\n if (value === null || value === undefined) throw new Error("Value is null or undefined");\n return value as NonNullable;\n}', + setupCode: 'function assertDefined(value: T): NonNullable {\n if (value === null || value === undefined) throw new Error("Value is null or undefined");\n return value as NonNullable;\n}', + expected: 'test', + sample: 'const maybeValue: string | null = "test";\nconst definiteValue = assertDefined(maybeValue);\ndefiniteValue', + hints: [ + 'NonNullable narrows the return type', + 'Runtime check ensures value exists', + ], + tags: ['utility-types', 'nonnullable', 'generics', 'assertions'], + }, + { + id: 'ts-utility-045', + category: 'Utility Types', + difficulty: 'medium', + title: 'NonNullable for Array Elements', + text: 'Filter out null and undefined from array type', + setup: 'type Items = (string | null | undefined)[];\nfunction filterNullish(arr: T[]): NonNullable[] {\n return arr.filter((x): x is NonNullable => x != null);\n}', + setupCode: 'type Items = (string | null | undefined)[];\nfunction filterNullish(arr: T[]): NonNullable[] {\n return arr.filter((x): x is NonNullable => x != null);\n}', + expected: ['a', 'b', 'c'], + sample: 'const items: Items = ["a", null, "b", undefined, "c"];\nfilterNullish(items)', + hints: [ + 'Type guard narrows to NonNullable', + 'x != null checks both null and undefined', + ], + tags: ['utility-types', 'nonnullable', 'arrays', 'type-guards'], + }, + + // ============================================================ + // Utility Types - ReturnType + // ============================================================ + { + id: 'ts-utility-046', + category: 'Utility Types', + difficulty: 'easy', + title: 'Basic ReturnType', + text: 'Extract the return type of a function using ReturnType', + setup: 'function getUser() { return { id: 1, name: "Alice" }; }', + setupCode: 'function getUser() { return { id: 1, name: "Alice" }; }', + expected: { id: 1, name: 'Alice' }, + sample: 'type User = ReturnType;\nconst user: User = { id: 1, name: "Alice" };\nuser', + hints: [ + 'Use typeof to get the function type', + 'ReturnType extracts what the function returns', + ], + tags: ['utility-types', 'returntype', 'typeof'], + }, + { + id: 'ts-utility-047', + category: 'Utility Types', + difficulty: 'easy', + title: 'ReturnType with Arrow Functions', + text: 'Get the return type of an arrow function', + setup: 'const multiply = (a: number, b: number) => a * b;', + setupCode: 'const multiply = (a: number, b: number) => a * b;', + expected: 6, + sample: 'type MultiplyResult = ReturnType;\nconst result: MultiplyResult = 6;\nresult', + hints: [ + 'ReturnType works with arrow functions', + 'Returns number in this case', + ], + tags: ['utility-types', 'returntype', 'arrow-functions'], + }, + { + id: 'ts-utility-048', + category: 'Utility Types', + difficulty: 'medium', + title: 'ReturnType with Async Functions', + text: 'Extract the unwrapped return type of an async function', + setup: 'async function fetchUser(): Promise<{ id: number; name: string }> { return { id: 1, name: "Alice" }; }', + setupCode: 'async function fetchUser(): Promise<{ id: number; name: string }> { return { id: 1, name: "Alice" }; }', + expected: { id: 1, name: 'Alice' }, + sample: 'type FetchResult = Awaited>;\nconst user: FetchResult = { id: 1, name: "Alice" };\nuser', + hints: [ + 'ReturnType gives Promise', + 'Use Awaited to unwrap the Promise', + ], + tags: ['utility-types', 'returntype', 'async', 'awaited'], + }, + { + id: 'ts-utility-049', + category: 'Utility Types', + difficulty: 'medium', + title: 'ReturnType with Overloaded Functions', + text: 'Get the return type of the last overload signature', + setup: 'function parse(input: string): object;\nfunction parse(input: number): string;\nfunction parse(input: string | number): object | string { return typeof input === "string" ? {} : ""; }', + setupCode: 'function parse(input: string): object;\nfunction parse(input: number): string;\nfunction parse(input: string | number): object | string { return typeof input === "string" ? {} : ""; }', + expected: '', + sample: 'type ParseResult = ReturnType;\nconst result: ParseResult = "";\nresult', + hints: [ + 'ReturnType uses the last overload signature', + 'Returns string | object for the implementation', + ], + tags: ['utility-types', 'returntype', 'overloads'], + }, + { + id: 'ts-utility-050', + category: 'Utility Types', + difficulty: 'hard', + title: 'Conditional ReturnType', + text: 'Create a type that extracts return type only for function types', + setup: 'type SafeReturnType = T extends (...args: any[]) => infer R ? R : never;\nconst fn = () => ({ value: 42 });\nconst notFn = "hello";', + setupCode: 'type SafeReturnType = T extends (...args: any[]) => infer R ? R : never;\nconst fn = () => ({ value: 42 });\nconst notFn = "hello";', + expected: { value: 42 }, + sample: 'type FnReturn = SafeReturnType;\nconst result: FnReturn = { value: 42 };\nresult', + hints: [ + 'Use conditional type with infer', + 'Returns never for non-function types', + ], + tags: ['utility-types', 'returntype', 'conditional', 'infer'], + }, + { + id: 'ts-utility-051', + category: 'Utility Types', + difficulty: 'hard', + title: 'ReturnType from Class Methods', + text: 'Extract return types from class methods', + setup: 'class UserService {\n getUser(id: number) { return { id, name: "User" }; }\n getAllUsers() { return [{ id: 1, name: "User" }]; }\n}', + setupCode: 'class UserService {\n getUser(id: number) { return { id, name: "User" }; }\n getAllUsers() { return [{ id: 1, name: "User" }]; }\n}', + expected: { id: 1, name: 'User' }, + sample: 'type GetUserReturn = ReturnType;\nconst user: GetUserReturn = { id: 1, name: "User" };\nuser', + hints: [ + 'Access method type with indexed access', + 'UserService["getUser"] is the method type', + ], + tags: ['utility-types', 'returntype', 'classes', 'methods'], + }, + + // ============================================================ + // Utility Types - Parameters + // ============================================================ + { + id: 'ts-utility-052', + category: 'Utility Types', + difficulty: 'easy', + title: 'Basic Parameters Type', + text: 'Extract the parameter types of a function as a tuple', + setup: 'function greet(name: string, age: number) { return `${name} is ${age}`; }', + setupCode: 'function greet(name: string, age: number) { return `${name} is ${age}`; }', + expected: ['Alice', 30], + sample: 'type GreetParams = Parameters;\nconst params: GreetParams = ["Alice", 30];\nparams', + hints: [ + 'Parameters returns a tuple type', + 'Use typeof to get the function type', + ], + tags: ['utility-types', 'parameters', 'tuple'], + }, + { + id: 'ts-utility-053', + category: 'Utility Types', + difficulty: 'easy', + title: 'Parameters Tuple Access', + text: 'Access individual parameter types from Parameters tuple', + setup: 'function createUser(name: string, email: string, age: number) { return { name, email, age }; }', + setupCode: 'function createUser(name: string, email: string, age: number) { return { name, email, age }; }', + expected: 'Alice', + sample: 'type FirstParam = Parameters[0];\nconst name: FirstParam = "Alice";\nname', + hints: [ + 'Index into the tuple to get specific parameter types', + '[0] gets the first parameter type', + ], + tags: ['utility-types', 'parameters', 'tuple-access'], + }, + { + id: 'ts-utility-054', + category: 'Utility Types', + difficulty: 'medium', + title: 'Parameters with Rest Arguments', + text: 'Extract parameters including rest arguments', + setup: 'function logMessages(level: string, ...messages: string[]) { return { level, messages }; }', + setupCode: 'function logMessages(level: string, ...messages: string[]) { return { level, messages }; }', + expected: ['error', 'msg1', 'msg2'], + sample: 'type LogParams = Parameters;\nconst params: LogParams = ["error", "msg1", "msg2"];\nparams', + hints: [ + 'Rest parameters become array type in tuple', + 'Tuple is [string, ...string[]]', + ], + tags: ['utility-types', 'parameters', 'rest-arguments'], + }, + { + id: 'ts-utility-055', + category: 'Utility Types', + difficulty: 'medium', + title: 'Spread Parameters to Function', + text: 'Use Parameters to spread arguments to another function', + setup: 'function original(a: number, b: string, c: boolean) { return { a, b, c }; }\nfunction wrapper any>(fn: T, ...args: Parameters): ReturnType { return fn(...args); }', + setupCode: 'function original(a: number, b: string, c: boolean) { return { a, b, c }; }\nfunction wrapper any>(fn: T, ...args: Parameters): ReturnType { return fn(...args); }', + expected: { a: 1, b: 'test', c: true }, + sample: 'wrapper(original, 1, "test", true)', + hints: [ + 'Parameters captures all parameter types', + 'Spread into the inner function call', + ], + tags: ['utility-types', 'parameters', 'generics', 'wrapper'], + }, + { + id: 'ts-utility-056', + category: 'Utility Types', + difficulty: 'medium', + title: 'Parameters for Callbacks', + text: 'Type a callback function based on another functions parameters', + setup: 'function fetchData(url: string, options: { timeout: number }) { return { url, options }; }\ntype FetchCallback = (...args: Parameters) => void;', + setupCode: 'function fetchData(url: string, options: { timeout: number }) { return { url, options }; }\ntype FetchCallback = (...args: Parameters) => void;', + expected: { url: 'https://api.com', timeout: 5000 }, + sample: 'let captured: { url: string; timeout: number } | null = null;\nconst callback: FetchCallback = (url, options) => { captured = { url, timeout: options.timeout }; };\ncallback("https://api.com", { timeout: 5000 });\ncaptured', + hints: [ + 'FetchCallback has same parameters as fetchData', + 'Useful for creating matching callback types', + ], + tags: ['utility-types', 'parameters', 'callbacks'], + }, + { + id: 'ts-utility-057', + category: 'Utility Types', + difficulty: 'hard', + title: 'Parameters with Overloaded Functions', + text: 'Extract parameters from overloaded function (gets last overload)', + setup: 'function process(x: string): string;\nfunction process(x: number, y: number): number;\nfunction process(x: string | number, y?: number): string | number { return y !== undefined ? (x as number) + y : x; }', + setupCode: 'function process(x: string): string;\nfunction process(x: number, y: number): number;\nfunction process(x: string | number, y?: number): string | number { return y !== undefined ? (x as number) + y : x; }', + expected: [5, 3], + sample: 'type ProcessParams = Parameters;\nconst params: ProcessParams = [5, 3];\nparams', + hints: [ + 'Parameters uses the last overload', + 'Result is [number, number] from last signature', + ], + tags: ['utility-types', 'parameters', 'overloads'], + }, + + // ============================================================ + // Utility Types - ConstructorParameters + // ============================================================ + { + id: 'ts-utility-058', + category: 'Utility Types', + difficulty: 'easy', + title: 'Basic ConstructorParameters', + text: 'Extract constructor parameters from a class', + setup: 'class User { constructor(public name: string, public age: number) {} }', + setupCode: 'class User { constructor(public name: string, public age: number) {} }', + expected: ['Alice', 30], + sample: 'type UserParams = ConstructorParameters;\nconst params: UserParams = ["Alice", 30];\nparams', + hints: [ + 'Use typeof to get the constructor type', + 'Returns tuple of constructor parameter types', + ], + tags: ['utility-types', 'constructorparameters', 'classes'], + }, + { + id: 'ts-utility-059', + category: 'Utility Types', + difficulty: 'easy', + title: 'ConstructorParameters with Built-in Classes', + text: 'Extract constructor parameters from built-in classes', + setup: 'type DateParams = ConstructorParameters;', + setupCode: 'type DateParams = ConstructorParameters;', + expected: 2024, + sample: 'const params: [number, number, number] = [2024, 0, 15];\nnew Date(...params).getFullYear()', + hints: [ + 'Built-in classes have constructor types', + 'Date has multiple constructor overloads', + ], + tags: ['utility-types', 'constructorparameters', 'built-in'], + }, + { + id: 'ts-utility-060', + category: 'Utility Types', + difficulty: 'medium', + title: 'ConstructorParameters for Factory', + text: 'Use ConstructorParameters to create a factory function', + setup: 'class Product { constructor(public name: string, public price: number) {} }\nfunction createFactory any>(Ctor: T) {\n return (...args: ConstructorParameters): InstanceType => new Ctor(...args);\n}', + setupCode: 'class Product { constructor(public name: string, public price: number) {} }\nfunction createFactory any>(Ctor: T) {\n return (...args: ConstructorParameters): InstanceType => new Ctor(...args);\n}', + expected: { name: 'Widget', price: 99 }, + sample: 'const productFactory = createFactory(Product);\nconst product = productFactory("Widget", 99);\n({ name: product.name, price: product.price })', + hints: [ + 'ConstructorParameters types the factory args', + 'InstanceType types the return value', + ], + tags: ['utility-types', 'constructorparameters', 'factory', 'generics'], + }, + { + id: 'ts-utility-061', + category: 'Utility Types', + difficulty: 'hard', + title: 'ConstructorParameters with Generics', + text: 'Extract constructor parameters from a generic class', + setup: 'class Container { constructor(public value: T, public label: string) {} }', + setupCode: 'class Container { constructor(public value: T, public label: string) {} }', + expected: [42, 'number'], + sample: 'type ContainerParams = ConstructorParameters>;\nconst params: ContainerParams = [42, "number"];\nparams', + hints: [ + 'Specify the generic parameter explicitly', + 'Container fixes T to number', + ], + tags: ['utility-types', 'constructorparameters', 'generics'], + }, + { + id: 'ts-utility-062', + category: 'Utility Types', + difficulty: 'hard', + title: 'ConstructorParameters Constraint', + text: 'Create a generic type that requires constructable types', + setup: 'type Constructable = new (...args: any[]) => T;\nfunction instantiate(Ctor: T, ...args: ConstructorParameters): InstanceType {\n return new Ctor(...args);\n}\nclass Service { constructor(public name: string) {} }', + setupCode: 'type Constructable = new (...args: any[]) => T;\nfunction instantiate(Ctor: T, ...args: ConstructorParameters): InstanceType {\n return new Ctor(...args);\n}\nclass Service { constructor(public name: string) {} }', + expected: { name: 'API' }, + sample: 'const service = instantiate(Service, "API");\n({ name: service.name })', + hints: [ + 'Constructable constrains to newable types', + 'ConstructorParameters extracts the args', + ], + tags: ['utility-types', 'constructorparameters', 'constraints', 'advanced'], + }, + + // ============================================================ + // Utility Types - InstanceType + // ============================================================ + { + id: 'ts-utility-063', + category: 'Utility Types', + difficulty: 'easy', + title: 'Basic InstanceType', + text: 'Extract the instance type from a class constructor', + setup: 'class User { constructor(public name: string) {} greet() { return `Hello, ${this.name}`; } }', + setupCode: 'class User { constructor(public name: string) {} greet() { return `Hello, ${this.name}`; } }', + expected: 'Hello, Alice', + sample: 'type UserInstance = InstanceType;\nconst user: UserInstance = new User("Alice");\nuser.greet()', + hints: [ + 'InstanceType equals Class', + 'Useful when you only have the constructor', + ], + tags: ['utility-types', 'instancetype', 'classes'], + }, + { + id: 'ts-utility-064', + category: 'Utility Types', + difficulty: 'easy', + title: 'InstanceType with Built-in Classes', + text: 'Get instance type from built-in constructors', + setup: 'type RegExpInstance = InstanceType;', + setupCode: 'type RegExpInstance = InstanceType;', + expected: true, + sample: 'const regex: RegExpInstance = new RegExp("test");\nregex.test("testing")', + hints: [ + 'Works with built-in classes', + 'RegExpInstance is same as RegExp', + ], + tags: ['utility-types', 'instancetype', 'built-in'], + }, + { + id: 'ts-utility-065', + category: 'Utility Types', + difficulty: 'medium', + title: 'InstanceType for Factory Pattern', + text: 'Use InstanceType to type factory function returns', + setup: 'class Logger { constructor(public prefix: string) {} log(msg: string) { return `${this.prefix}: ${msg}`; } }\nfunction createLogger any>(Ctor: T, ...args: ConstructorParameters): InstanceType {\n return new Ctor(...args);\n}', + setupCode: 'class Logger { constructor(public prefix: string) {} log(msg: string) { return `${this.prefix}: ${msg}`; } }\nfunction createLogger any>(Ctor: T, ...args: ConstructorParameters): InstanceType {\n return new Ctor(...args);\n}', + expected: '[INFO]: Test message', + sample: 'const logger = createLogger(Logger, "[INFO]");\nlogger.log("Test message")', + hints: [ + 'InstanceType infers the return type', + 'Factory returns proper typed instance', + ], + tags: ['utility-types', 'instancetype', 'factory'], + }, + { + id: 'ts-utility-066', + category: 'Utility Types', + difficulty: 'medium', + title: 'InstanceType with Abstract Classes', + text: 'Work with instance types of abstract classes', + setup: 'abstract class Animal { abstract speak(): string; move() { return "moving"; } }\nclass Dog extends Animal { speak() { return "woof"; } }', + setupCode: 'abstract class Animal { abstract speak(): string; move() { return "moving"; } }\nclass Dog extends Animal { speak() { return "woof"; } }', + expected: 'woof', + sample: 'type AnimalInstance = InstanceType;\nconst dog: AnimalInstance = new Dog();\ndog.speak()', + hints: [ + 'Cannot use InstanceType on abstract class directly', + 'Use concrete subclass instead', + ], + tags: ['utility-types', 'instancetype', 'abstract'], + }, + { + id: 'ts-utility-067', + category: 'Utility Types', + difficulty: 'hard', + title: 'Generic InstanceType Constraint', + text: 'Create a generic function that accepts any class and returns its instance type', + setup: 'type Constructor = new (...args: any[]) => T;\nfunction singleton(Ctor: T): () => InstanceType {\n let instance: InstanceType | null = null;\n return () => instance ?? (instance = new Ctor() as InstanceType);\n}\nclass Config { value = "default"; }', + setupCode: 'type Constructor = new (...args: any[]) => T;\nfunction singleton(Ctor: T): () => InstanceType {\n let instance: InstanceType | null = null;\n return () => instance ?? (instance = new Ctor() as InstanceType);\n}\nclass Config { value = "default"; }', + expected: true, + sample: 'const getConfig = singleton(Config);\nconst c1 = getConfig();\nconst c2 = getConfig();\nc1 === c2', + hints: [ + 'InstanceType gives the instance type', + 'Constructor type constrains to newable', + ], + tags: ['utility-types', 'instancetype', 'generics', 'singleton'], + }, + + // ============================================================ + // Utility Types - ThisParameterType + // ============================================================ + { + id: 'ts-utility-068', + category: 'Utility Types', + difficulty: 'easy', + title: 'Basic ThisParameterType', + text: 'Extract the this parameter type from a function', + setup: 'function greet(this: { name: string }) { return `Hello, ${this.name}`; }', + setupCode: 'function greet(this: { name: string }) { return `Hello, ${this.name}`; }', + expected: { name: 'Alice' }, + sample: 'type GreetThis = ThisParameterType;\nconst context: GreetThis = { name: "Alice" };\ncontext', + hints: [ + 'ThisParameterType extracts the this type', + 'Returns unknown if no this parameter', + ], + tags: ['utility-types', 'thisparametertype', 'this'], + }, + { + id: 'ts-utility-069', + category: 'Utility Types', + difficulty: 'medium', + title: 'ThisParameterType with Methods', + text: 'Extract this type from object method', + setup: 'const obj = {\n name: "Widget",\n getName(this: { name: string; id: number }) { return this.name; }\n};', + setupCode: 'const obj = {\n name: "Widget",\n getName(this: { name: string; id: number }) { return this.name; }\n};', + expected: { name: 'Test', id: 1 }, + sample: 'type GetNameThis = ThisParameterType;\nconst context: GetNameThis = { name: "Test", id: 1 };\ncontext', + hints: [ + 'Method can have explicit this type', + 'ThisParameterType extracts it', + ], + tags: ['utility-types', 'thisparametertype', 'methods'], + }, + { + id: 'ts-utility-070', + category: 'Utility Types', + difficulty: 'medium', + title: 'ThisParameterType for Call/Apply', + text: 'Use ThisParameterType to type-check call/apply context', + setup: 'function formatName(this: { firstName: string; lastName: string }) {\n return `${this.firstName} ${this.lastName}`;\n}', + setupCode: 'function formatName(this: { firstName: string; lastName: string }) {\n return `${this.firstName} ${this.lastName}`;\n}', + expected: 'John Doe', + sample: 'type Context = ThisParameterType;\nconst person: Context = { firstName: "John", lastName: "Doe" };\nformatName.call(person)', + hints: [ + 'call/apply need proper this context', + 'ThisParameterType ensures type safety', + ], + tags: ['utility-types', 'thisparametertype', 'call', 'apply'], + }, + { + id: 'ts-utility-071', + category: 'Utility Types', + difficulty: 'hard', + title: 'ThisParameterType in Decorators', + text: 'Use ThisParameterType to preserve this type in decorators', + setup: 'function logMethod any>(\n fn: T\n): (this: ThisParameterType, ...args: Parameters>) => ReturnType {\n return function(this: ThisParameterType, ...args: Parameters>) {\n return fn.apply(this, args);\n };\n}\nconst obj = { value: 10, getValue(this: { value: number }) { return this.value; } };', + setupCode: 'function logMethod any>(\n fn: T\n): (this: ThisParameterType, ...args: Parameters>) => ReturnType {\n return function(this: ThisParameterType, ...args: Parameters>) {\n return fn.apply(this, args);\n };\n}\nconst obj = { value: 10, getValue(this: { value: number }) { return this.value; } };', + expected: 10, + sample: 'const logged = logMethod(obj.getValue);\nlogged.call({ value: 10 })', + hints: [ + 'Decorator preserves this type', + 'Combine with OmitThisParameter for args', + ], + tags: ['utility-types', 'thisparametertype', 'decorators', 'advanced'], + }, + + // ============================================================ + // Utility Types - OmitThisParameter + // ============================================================ + { + id: 'ts-utility-072', + category: 'Utility Types', + difficulty: 'easy', + title: 'Basic OmitThisParameter', + text: 'Remove the this parameter from a function type', + setup: 'function greet(this: { name: string }, greeting: string) { return `${greeting}, ${this.name}`; }', + setupCode: 'function greet(this: { name: string }, greeting: string) { return `${greeting}, ${this.name}`; }', + expected: 'Hello, World', + sample: 'type GreetFn = OmitThisParameter;\nconst boundGreet: GreetFn = greet.bind({ name: "World" });\nboundGreet("Hello")', + hints: [ + 'OmitThisParameter removes this from signature', + 'Useful for bound functions', + ], + tags: ['utility-types', 'omitthisparameter', 'bind'], + }, + { + id: 'ts-utility-073', + category: 'Utility Types', + difficulty: 'medium', + title: 'OmitThisParameter for Callbacks', + text: 'Use OmitThisParameter to type bound callbacks', + setup: 'class Counter {\n count = 0;\n increment(this: Counter, amount: number) { this.count += amount; return this.count; }\n}', + setupCode: 'class Counter {\n count = 0;\n increment(this: Counter, amount: number) { this.count += amount; return this.count; }\n}', + expected: 5, + sample: 'const counter = new Counter();\ntype IncrementFn = OmitThisParameter;\nconst boundIncrement: IncrementFn = counter.increment.bind(counter);\nboundIncrement(5)', + hints: [ + 'bind() returns function without this', + 'OmitThisParameter types the bound function', + ], + tags: ['utility-types', 'omitthisparameter', 'callbacks', 'bind'], + }, + { + id: 'ts-utility-074', + category: 'Utility Types', + difficulty: 'medium', + title: 'OmitThisParameter with Arrow Functions', + text: 'Demonstrate that arrow functions have no this parameter', + setup: 'const regular = function(this: { x: number }) { return this.x; };\nconst arrow = () => 42;', + setupCode: 'const regular = function(this: { x: number }) { return this.x; };\nconst arrow = () => 42;', + expected: 42, + sample: 'type RegularWithoutThis = OmitThisParameter;\ntype ArrowType = OmitThisParameter;\nconst fn: ArrowType = () => 42;\nfn()', + hints: [ + 'Arrow functions have no this parameter', + 'OmitThisParameter is identity for arrows', + ], + tags: ['utility-types', 'omitthisparameter', 'arrow-functions'], + }, + { + id: 'ts-utility-075', + category: 'Utility Types', + difficulty: 'hard', + title: 'OmitThisParameter in Method Extraction', + text: 'Extract class methods as standalone functions', + setup: 'class Calculator {\n constructor(private base: number) {}\n add(this: Calculator, n: number) { return this.base + n; }\n multiply(this: Calculator, n: number) { return this.base * n; }\n}\ntype MethodsOf = { [K in keyof T]: T[K] extends (this: any, ...args: infer A) => infer R ? (...args: A) => R : never };', + setupCode: 'class Calculator {\n constructor(private base: number) {}\n add(this: Calculator, n: number) { return this.base + n; }\n multiply(this: Calculator, n: number) { return this.base * n; }\n}\ntype MethodsOf = { [K in keyof T]: T[K] extends (this: any, ...args: infer A) => infer R ? (...args: A) => R : never };', + expected: 15, + sample: 'const calc = new Calculator(10);\nconst boundAdd: OmitThisParameter = calc.add.bind(calc);\nboundAdd(5)', + hints: [ + 'OmitThisParameter enables method extraction', + 'Bound methods become standalone functions', + ], + tags: ['utility-types', 'omitthisparameter', 'methods', 'advanced'], + }, + + // ============================================================ + // Utility Types - Awaited + // ============================================================ + { + id: 'ts-utility-076', + category: 'Utility Types', + difficulty: 'easy', + title: 'Basic Awaited Type', + text: 'Unwrap a Promise type using Awaited', + setup: 'type UserPromise = Promise<{ id: number; name: string }>;', + setupCode: 'type UserPromise = Promise<{ id: number; name: string }>;', + expected: { id: 1, name: 'Alice' }, + sample: 'type User = Awaited;\nconst user: User = { id: 1, name: "Alice" };\nuser', + hints: [ + 'Awaited unwraps Promise types', + 'Result is the resolved value type', + ], + tags: ['utility-types', 'awaited', 'promises'], + }, + { + id: 'ts-utility-077', + category: 'Utility Types', + difficulty: 'easy', + title: 'Awaited with Non-Promise', + text: 'Awaited on non-Promise types returns the same type', + setup: 'type MaybeAsync = string | Promise;', + setupCode: 'type MaybeAsync = string | Promise;', + expected: 'hello', + sample: 'type Resolved = Awaited;\nconst value: Resolved = "hello";\nvalue', + hints: [ + 'Awaited handles both Promise and non-Promise', + 'Non-Promise types pass through unchanged', + ], + tags: ['utility-types', 'awaited', 'union'], + }, + { + id: 'ts-utility-078', + category: 'Utility Types', + difficulty: 'medium', + title: 'Awaited with Nested Promises', + text: 'Unwrap deeply nested Promise types', + setup: 'type DeepPromise = Promise>>;', + setupCode: 'type DeepPromise = Promise>>;', + expected: 42, + sample: 'type Value = Awaited;\nconst num: Value = 42;\nnum', + hints: [ + 'Awaited recursively unwraps Promises', + 'Handles any nesting depth', + ], + tags: ['utility-types', 'awaited', 'nested'], + }, + { + id: 'ts-utility-079', + category: 'Utility Types', + difficulty: 'medium', + title: 'Awaited for Async Function Returns', + text: 'Get the resolved type of an async function return', + setup: 'async function fetchData(): Promise<{ items: string[]; total: number }> {\n return { items: ["a", "b"], total: 2 };\n}', + setupCode: 'async function fetchData(): Promise<{ items: string[]; total: number }> {\n return { items: ["a", "b"], total: 2 };\n}', + expected: { items: ['a', 'b'], total: 2 }, + sample: 'type FetchResult = Awaited>;\nconst result: FetchResult = { items: ["a", "b"], total: 2 };\nresult', + hints: [ + 'Combine with ReturnType for async functions', + 'Awaited unwraps the Promise', + ], + tags: ['utility-types', 'awaited', 'async', 'returntype'], + }, + { + id: 'ts-utility-080', + category: 'Utility Types', + difficulty: 'medium', + title: 'Awaited with Promise.all', + text: 'Type the result of Promise.all using Awaited', + setup: 'const promises = [Promise.resolve(1), Promise.resolve("two"), Promise.resolve(true)] as const;', + setupCode: 'const promises = [Promise.resolve(1), Promise.resolve("two"), Promise.resolve(true)] as const;', + expected: [1, 'two', true], + sample: 'type AllResults = Awaited[];\nconst results: [number, string, boolean] = [1, "two", true];\nresults', + hints: [ + 'Promise.all resolves all promises', + 'Awaited unwraps each Promise type', + ], + tags: ['utility-types', 'awaited', 'promise-all'], + }, + { + id: 'ts-utility-081', + category: 'Utility Types', + difficulty: 'hard', + title: 'Awaited in Generic Context', + text: 'Use Awaited in a generic function to handle both sync and async', + setup: 'type MaybePromise = T | Promise;\nasync function resolve(value: MaybePromise): Promise> {\n return await value as Awaited;\n}', + setupCode: 'type MaybePromise = T | Promise;\nasync function resolve(value: MaybePromise): Promise> {\n return await value as Awaited;\n}', + expected: 42, + sample: 'resolve(Promise.resolve(42)).then(v => v)', + hints: [ + 'MaybePromise accepts both types', + 'Awaited normalizes the result', + ], + tags: ['utility-types', 'awaited', 'generics', 'advanced'], + }, + + // ============================================================ + // Utility Types - NoInfer + // ============================================================ + { + id: 'ts-utility-082', + category: 'Utility Types', + difficulty: 'medium', + title: 'Basic NoInfer Type', + text: 'Use NoInfer to prevent type inference from certain positions', + setup: 'function createState(initial: T, defaultValue: NoInfer): { value: T; default: T } {\n return { value: initial, default: defaultValue };\n}', + setupCode: 'function createState(initial: T, defaultValue: NoInfer): { value: T; default: T } {\n return { value: initial, default: defaultValue };\n}', + expected: { value: 'hello', default: '' }, + sample: 'const state = createState("hello", "");\nstate', + hints: [ + 'NoInfer prevents inference from that parameter', + 'T is inferred from first argument only', + ], + tags: ['utility-types', 'noinfer', 'inference'], + }, + { + id: 'ts-utility-083', + category: 'Utility Types', + difficulty: 'medium', + title: 'NoInfer for Default Values', + text: 'Prevent default value from widening inferred type', + setup: 'function withDefault(value: T | undefined, defaultValue: NoInfer): T {\n return value ?? defaultValue;\n}', + setupCode: 'function withDefault(value: T | undefined, defaultValue: NoInfer): T {\n return value ?? defaultValue;\n}', + expected: 'fallback', + sample: 'const result = withDefault(undefined as "a" | "b" | undefined, "fallback" as "a" | "b");\nresult', + hints: [ + 'NoInfer keeps T narrow', + 'Default does not affect inference', + ], + tags: ['utility-types', 'noinfer', 'defaults'], + }, + { + id: 'ts-utility-084', + category: 'Utility Types', + difficulty: 'hard', + title: 'NoInfer in Generic Constraints', + text: 'Use NoInfer to control which arguments influence type inference', + setup: 'function matchPair(a: T, b: NoInfer): boolean {\n return a === b;\n}', + setupCode: 'function matchPair(a: T, b: NoInfer): boolean {\n return a === b;\n}', + expected: true, + sample: 'const result = matchPair("test", "test");\nresult', + hints: [ + 'T inferred from first argument only', + 'Second argument must match inferred type', + ], + tags: ['utility-types', 'noinfer', 'constraints'], + }, + { + id: 'ts-utility-085', + category: 'Utility Types', + difficulty: 'hard', + title: 'NoInfer for Event Handlers', + text: 'Use NoInfer to type event handlers without widening', + setup: 'type Events = { click: { x: number; y: number }; keydown: { key: string } };\nfunction on(event: K, handler: (data: NoInfer) => void): void {}', + setupCode: 'type Events = { click: { x: number; y: number }; keydown: { key: string } };\nfunction on(event: K, handler: (data: NoInfer) => void): void {}', + expected: 'registered', + sample: 'on("click", (data) => { const x = data.x; });\n"registered"', + hints: [ + 'K inferred from event name', + 'Handler data type follows from K', + ], + tags: ['utility-types', 'noinfer', 'events', 'advanced'], + }, + + // ============================================================ + // Function Types & Overloads + // ============================================================ + { + id: 'ts-func-001', + category: 'Function Types', + difficulty: 'easy', + title: 'Basic Function Type Expression', + text: 'Define a type for a function that takes a number and returns a string', + setup: '// Define a function type', + setupCode: '// Define a function type', + expected: '42', + sample: 'type NumberToString = (n: number) => string;\nconst convert: NumberToString = n => String(n);\nconvert(42)', + hints: [ + 'Use arrow syntax for function types: (param: Type) => ReturnType', + 'The function takes a number and returns a string', + ], + tags: ['function-types', 'type-expression', 'basics'], + }, + { + id: 'ts-func-002', + category: 'Function Types', + difficulty: 'easy', + title: 'Void Return Type', + text: 'Create a callback type that takes a string and returns nothing', + setup: '// Define a callback that logs messages', + setupCode: '// Define a callback that logs messages', + expected: undefined, + sample: 'type Logger = (message: string) => void;\nconst log: Logger = msg => console.log(msg);\nlog("hello")', + hints: [ + 'Use void for functions that do not return a value', + 'void indicates the return value should not be used', + ], + tags: ['function-types', 'void', 'callbacks'], + }, + { + id: 'ts-func-003', + category: 'Function Types', + difficulty: 'easy', + title: 'Multiple Parameters Function Type', + text: 'Define a type for a function that adds two numbers', + setup: '// Define an adder function type', + setupCode: '// Define an adder function type', + expected: 15, + sample: 'type Adder = (a: number, b: number) => number;\nconst add: Adder = (a, b) => a + b;\nadd(10, 5)', + hints: [ + 'List all parameters with their types in parentheses', + 'Parameters are separated by commas', + ], + tags: ['function-types', 'parameters', 'basics'], + }, + { + id: 'ts-func-004', + category: 'Function Types', + difficulty: 'easy', + title: 'Function Type with Object Parameter', + text: 'Create a type for a function that takes a user object and returns their full name', + setup: 'interface User { firstName: string; lastName: string; }', + setupCode: 'interface User { firstName: string; lastName: string; }', + expected: 'John Doe', + sample: 'type GetFullName = (user: User) => string;\nconst getFullName: GetFullName = u => `${u.firstName} ${u.lastName}`;\ngetFullName({ firstName: "John", lastName: "Doe" })', + hints: [ + 'The parameter type can be an interface', + 'Use template literals to combine strings', + ], + tags: ['function-types', 'objects', 'interfaces'], + }, + { + id: 'ts-func-005', + category: 'Function Types', + difficulty: 'easy', + title: 'Boolean Predicate Function Type', + text: 'Define a predicate function type that checks if a number is positive', + setup: '// Define a predicate type', + setupCode: '// Define a predicate type', + expected: true, + sample: 'type IsPositive = (n: number) => boolean;\nconst isPositive: IsPositive = n => n > 0;\nisPositive(5)', + hints: [ + 'Predicates return boolean values', + 'Use comparison operators to return true/false', + ], + tags: ['function-types', 'predicates', 'boolean'], + }, + { + id: 'ts-func-006', + category: 'Function Types', + difficulty: 'easy', + title: 'Array Callback Function Type', + text: 'Create a type for a forEach callback that receives element and index', + setup: 'const numbers = [1, 2, 3];', + setupCode: 'const numbers = [1, 2, 3];', + expected: [0, 2, 6], + sample: 'type ForEachCallback = (element: T, index: number) => void;\nconst results: number[] = [];\nconst cb: ForEachCallback = (el, idx) => results.push(el * idx);\nnumbers.forEach(cb);\nresults', + hints: [ + 'Array callbacks typically receive element and index', + 'Generic type parameter allows reuse with different array types', + ], + tags: ['function-types', 'callbacks', 'arrays'], + }, + { + id: 'ts-func-007', + category: 'Function Types', + difficulty: 'easy', + title: 'Event Handler Function Type', + text: 'Define an event handler type that takes an event object with target property', + setup: 'interface ClickEvent { target: { id: string }; }', + setupCode: 'interface ClickEvent { target: { id: string }; }', + expected: 'btn-submit', + sample: 'type ClickHandler = (event: ClickEvent) => void;\nlet clicked = "";\nconst handler: ClickHandler = e => { clicked = e.target.id; };\nhandler({ target: { id: "btn-submit" } });\nclicked', + hints: [ + 'Event handlers typically return void', + 'The event object contains information about what happened', + ], + tags: ['function-types', 'events', 'handlers'], + }, + { + id: 'ts-func-008', + category: 'Function Types', + difficulty: 'easy', + title: 'Comparator Function Type', + text: 'Create a comparator function type for sorting numbers', + setup: 'const nums = [3, 1, 4, 1, 5];', + setupCode: 'const nums = [3, 1, 4, 1, 5];', + expected: [1, 1, 3, 4, 5], + sample: 'type Comparator = (a: number, b: number) => number;\nconst compare: Comparator = (a, b) => a - b;\n[...nums].sort(compare)', + hints: [ + 'Comparators return negative, zero, or positive numbers', + 'Return a - b for ascending order', + ], + tags: ['function-types', 'comparator', 'sorting'], + }, + { + id: 'ts-func-009', + category: 'Function Types', + difficulty: 'easy', + title: 'Transformer Function Type', + text: 'Define a type for a function that transforms a string to uppercase', + setup: '// Define a string transformer', + setupCode: '// Define a string transformer', + expected: 'HELLO', + sample: 'type StringTransformer = (input: string) => string;\nconst toUpper: StringTransformer = s => s.toUpperCase();\ntoUpper("hello")', + hints: [ + 'Transformers take input and return transformed output of same or different type', + 'Use built-in string methods', + ], + tags: ['function-types', 'transformer', 'strings'], + }, + { + id: 'ts-func-010', + category: 'Function Types', + difficulty: 'easy', + title: 'Factory Function Type', + text: 'Create a type for a factory function that creates user objects', + setup: 'interface User { id: number; name: string; }', + setupCode: 'interface User { id: number; name: string; }', + expected: { id: 1, name: 'Alice' }, + sample: 'type UserFactory = (id: number, name: string) => User;\nconst createUser: UserFactory = (id, name) => ({ id, name });\ncreateUser(1, "Alice")', + hints: [ + 'Factory functions create and return new objects', + 'Use shorthand property syntax when names match', + ], + tags: ['function-types', 'factory', 'objects'], + }, + { + id: 'ts-func-011', + category: 'Function Types', + difficulty: 'easy', + title: 'Async Function Type', + text: 'Define a type for an async function that fetches a number', + setup: '// Define async function type', + setupCode: '// Define async function type', + expected: 42, + sample: 'type AsyncNumberFetcher = () => Promise;\nconst fetchNum: AsyncNumberFetcher = async () => 42;\nfetchNum().then(n => n)', + hints: [ + 'Async functions return Promise', + 'Use Promise as the return type', + ], + tags: ['function-types', 'async', 'promises'], + }, + { + id: 'ts-func-012', + category: 'Function Types', + difficulty: 'easy', + title: 'Nullable Return Type', + text: 'Create a function type that may return a number or null', + setup: 'const data: Record = { a: 1, b: 2 };', + setupCode: 'const data: Record = { a: 1, b: 2 };', + expected: null, + sample: 'type Finder = (key: string) => number | null;\nconst find: Finder = key => data[key] ?? null;\nfind("c")', + hints: [ + 'Use union types for nullable returns: Type | null', + 'Nullish coalescing (??) provides default for undefined/null', + ], + tags: ['function-types', 'nullable', 'union-types'], + }, + { + id: 'ts-func-013', + category: 'Function Types', + difficulty: 'easy', + title: 'No Parameters Function Type', + text: 'Define a type for a function that takes no parameters and returns a timestamp', + setup: '// Define a timestamp generator type', + setupCode: '// Define a timestamp generator type', + expected: true, + sample: 'type GetTimestamp = () => number;\nconst now: GetTimestamp = () => Date.now();\ntypeof now() === "number"', + hints: [ + 'Use empty parentheses for no parameters: () => Type', + 'Date.now() returns a numeric timestamp', + ], + tags: ['function-types', 'no-params', 'basics'], + }, + { + id: 'ts-func-014', + category: 'Function Types', + difficulty: 'easy', + title: 'Tuple Return Type', + text: 'Create a function type that returns a tuple of [success, data]', + setup: '// Define result tuple type', + setupCode: '// Define result tuple type', + expected: [true, 42], + sample: 'type ResultFn = () => [boolean, number];\nconst getResult: ResultFn = () => [true, 42];\ngetResult()', + hints: [ + 'Use tuple syntax for return type: [Type1, Type2]', + 'Tuples have fixed length and types at each position', + ], + tags: ['function-types', 'tuples', 'return-types'], + }, + { + id: 'ts-func-015', + category: 'Function Types', + difficulty: 'easy', + title: 'Union Parameter Type', + text: 'Define a function type that accepts either a string or number', + setup: '// Define flexible input type', + setupCode: '// Define flexible input type', + expected: '42', + sample: 'type Stringify = (value: string | number) => string;\nconst stringify: Stringify = v => String(v);\nstringify(42)', + hints: [ + 'Use union types for parameters that accept multiple types', + 'String() works on both strings and numbers', + ], + tags: ['function-types', 'union-types', 'parameters'], + }, + { + id: 'ts-func-016', + category: 'Function Types', + difficulty: 'easy', + title: 'Promise Executor Function Type', + text: 'Define the type for a Promise executor function', + setup: '// Define promise executor type', + setupCode: '// Define promise executor type', + expected: 'resolved', + sample: 'type Executor = (resolve: (value: T) => void, reject: (reason?: any) => void) => void;\nconst executor: Executor = (resolve, reject) => resolve("resolved");\nnew Promise(executor).then(v => v)', + hints: [ + 'Executor receives resolve and reject callbacks', + 'Both callbacks return void', + ], + tags: ['function-types', 'promises', 'executor'], + }, + { + id: 'ts-func-017', + category: 'Function Types', + difficulty: 'easy', + title: 'Then Callback Type', + text: 'Define the type for a .then() callback', + setup: '// Define then callback type', + setupCode: '// Define then callback type', + expected: 10, + sample: 'type ThenCallback = (value: T) => R | PromiseLike;\nconst doubler: ThenCallback = n => n * 2;\nPromise.resolve(5).then(doubler).then(r => r)', + hints: [ + 'Then callbacks can return value or Promise', + 'PromiseLike allows returning thenables', + ], + tags: ['function-types', 'promises', 'then'], + }, + { + id: 'ts-func-018', + category: 'Function Types', + difficulty: 'easy', + title: 'Cleanup Function Type', + text: 'Define a type for a cleanup/dispose function', + setup: '// Define cleanup function type', + setupCode: '// Define cleanup function type', + expected: 'cleaned', + sample: 'type Cleanup = () => void;\nlet status = "active";\nconst cleanup: Cleanup = () => { status = "cleaned"; };\ncleanup();\nstatus', + hints: [ + 'Cleanup functions take no arguments', + 'Return void as they just perform side effects', + ], + tags: ['function-types', 'cleanup', 'side-effects'], + }, + { + id: 'ts-func-019', + category: 'Function Types', + difficulty: 'easy', + title: 'Unsubscribe Function Type', + text: 'Define a subscribe function that returns an unsubscribe function', + setup: '// Define subscription types', + setupCode: '// Define subscription types', + expected: 0, + sample: 'type Unsubscribe = () => void;\ntype Subscribe = (callback: (value: T) => void) => Unsubscribe;\nconst subscribers: ((v: number) => void)[] = [];\nconst subscribe: Subscribe = cb => {\n subscribers.push(cb);\n return () => { subscribers.splice(subscribers.indexOf(cb), 1); };\n};\nconst unsub = subscribe(v => console.log(v));\nunsub();\nsubscribers.length', + hints: [ + 'Subscribe returns a function to cancel subscription', + 'Unsubscribe removes callback from listeners', + ], + tags: ['function-types', 'subscription', 'patterns'], + }, + { + id: 'ts-func-020', + category: 'Function Types', + difficulty: 'easy', + title: 'Getter Function Type', + text: 'Define a type for a getter function that returns object property', + setup: 'interface Config { apiUrl: string; timeout: number; }', + setupCode: 'interface Config { apiUrl: string; timeout: number; }', + expected: 'https://api.example.com', + sample: 'type Getter = (obj: T) => T[K];\nconst getApiUrl: Getter = obj => obj.apiUrl;\ngetApiUrl({ apiUrl: "https://api.example.com", timeout: 5000 })', + hints: [ + 'Use keyof to constrain key parameter', + 'T[K] is the type of property K in T', + ], + tags: ['function-types', 'generics', 'property-access'], + }, + { + id: 'ts-func-021', + category: 'Function Types', + difficulty: 'easy', + title: 'Setter Function Type', + text: 'Define a type for a setter function that updates object property', + setup: 'interface State { count: number; name: string; }', + setupCode: 'interface State { count: number; name: string; }', + expected: { count: 10, name: 'test' }, + sample: 'type Setter = (obj: T, value: T[K]) => T;\nconst setCount: Setter = (obj, value) => ({ ...obj, count: value });\nsetCount({ count: 0, name: "test" }, 10)', + hints: [ + 'Setter takes object and new value', + 'Return new object with updated property', + ], + tags: ['function-types', 'generics', 'property-access'], + }, + { + id: 'ts-func-022', + category: 'Function Types', + difficulty: 'easy', + title: 'Filter Predicate Type', + text: 'Define the predicate function type used by Array.filter', + setup: 'const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];', + setupCode: 'const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];', + expected: [2, 4, 6, 8, 10], + sample: 'type FilterPredicate = (value: T, index: number, array: T[]) => boolean;\nconst isEven: FilterPredicate = n => n % 2 === 0;\nnumbers.filter(isEven)', + hints: [ + 'Filter predicates return boolean', + 'Receives value, index, and array like map', + ], + tags: ['function-types', 'predicates', 'arrays'], + }, + { + id: 'ts-func-023', + category: 'Function Types', + difficulty: 'easy', + title: 'Sort Compare Function Type', + text: 'Define the compare function type used by Array.sort', + setup: 'const items = [{ name: "Charlie" }, { name: "Alice" }, { name: "Bob" }];', + setupCode: 'const items = [{ name: "Charlie" }, { name: "Alice" }, { name: "Bob" }];', + expected: [{ name: 'Alice' }, { name: 'Bob' }, { name: 'Charlie' }], + sample: 'type CompareFn = (a: T, b: T) => number;\nconst byName: CompareFn<{ name: string }> = (a, b) => a.name.localeCompare(b.name);\n[...items].sort(byName)', + hints: [ + 'Compare returns negative, zero, or positive', + 'localeCompare compares strings properly', + ], + tags: ['function-types', 'comparator', 'sorting'], + }, + { + id: 'ts-func-024', + category: 'Function Types', + difficulty: 'easy', + title: 'Validation Function Type', + text: 'Define a type for a validation function', + setup: '// Define validator type', + setupCode: '// Define validator type', + expected: { valid: false, error: 'Too short' }, + sample: 'type ValidationResult = { valid: true } | { valid: false; error: string };\ntype Validator = (value: T) => ValidationResult;\nconst minLength: Validator = s => \n s.length >= 3 ? { valid: true } : { valid: false, error: "Too short" };\nminLength("ab")', + hints: [ + 'Discriminated union for success/failure', + 'Validators return result object', + ], + tags: ['function-types', 'validation', 'discriminated-union'], + }, + { + id: 'ts-func-025', + category: 'Function Types', + difficulty: 'easy', + title: 'Transform Pipeline Type', + text: 'Define types for a simple transform function', + setup: '// Define transform type', + setupCode: '// Define transform type', + expected: 'HELLO', + sample: 'type Transform = (input: I) => O;\nconst toUpper: Transform = s => s.toUpperCase();\ntoUpper("hello")', + hints: [ + 'Transform takes input type and produces output type', + 'Generic parameters allow flexible typing', + ], + tags: ['function-types', 'transform', 'generics'], + }, + { + id: 'ts-func-026', + category: 'Function Types', + difficulty: 'easy', + title: 'Array Map Callback Type', + text: 'Define a type for Array.map callback function', + setup: 'const words = ["hello", "world"];', + setupCode: 'const words = ["hello", "world"];', + expected: [5, 5], + sample: 'type MapFn = (value: T, index: number) => U;\nconst getLength: MapFn = s => s.length;\nwords.map(getLength)', + hints: [ + 'Map callbacks transform each element', + 'Return type can differ from input type', + ], + tags: ['function-types', 'arrays', 'map'], + }, + { + id: 'ts-func-027', + category: 'Function Types', + difficulty: 'easy', + title: 'Error Handler Type', + text: 'Define a type for an error handler callback', + setup: '// Define error handler type', + setupCode: '// Define error handler type', + expected: 'Error: Something went wrong', + sample: 'type ErrorHandler = (error: Error) => string;\nconst handleError: ErrorHandler = err => `Error: ${err.message}`;\nhandleError(new Error("Something went wrong"))', + hints: [ + 'Error handlers receive Error objects', + 'Return type depends on how errors are processed', + ], + tags: ['function-types', 'error-handling', 'callbacks'], + }, + { + id: 'ts-func-028', + category: 'Function Types', + difficulty: 'medium', + title: 'Optional Parameter in Function Type', + text: 'Create a function type with an optional second parameter for greeting', + setup: '// Define greeting function type', + setupCode: '// Define greeting function type', + expected: 'Hello, World!', + sample: 'type Greeter = (name: string, greeting?: string) => string;\nconst greet: Greeter = (name, greeting = "Hello") => `${greeting}, ${name}!`;\ngreet("World")', + hints: [ + 'Use ? after parameter name for optional: param?: Type', + 'Provide default value in implementation if needed', + ], + tags: ['function-types', 'optional-parameters'], + }, + { + id: 'ts-func-029', + category: 'Function Types', + difficulty: 'medium', + title: 'Rest Parameters in Function Type', + text: 'Define a function type that accepts any number of numbers and returns their sum', + setup: '// Define variadic sum type', + setupCode: '// Define variadic sum type', + expected: 15, + sample: 'type Sum = (...numbers: number[]) => number;\nconst sum: Sum = (...nums) => nums.reduce((a, b) => a + b, 0);\nsum(1, 2, 3, 4, 5)', + hints: [ + 'Use rest syntax: ...paramName: Type[]', + 'Rest parameters collect all remaining arguments', + ], + tags: ['function-types', 'rest-parameters', 'variadic'], + }, + { + id: 'ts-func-030', + category: 'Function Types', + difficulty: 'medium', + title: 'Higher-Order Function Type', + text: 'Create a type for a function that takes a function and returns a function', + setup: '// Define a function doubler type', + setupCode: '// Define a function doubler type', + expected: 20, + sample: 'type Doubler = (fn: (x: number) => number) => (x: number) => number;\nconst double: Doubler = fn => x => fn(x) * 2;\nconst addOne = (x: number) => x + 1;\ndouble(addOne)(9)', + hints: [ + 'Higher-order functions take or return functions', + 'Nest function type expressions for complex signatures', + ], + tags: ['function-types', 'higher-order', 'composition'], + }, + { + id: 'ts-func-031', + category: 'Function Types', + difficulty: 'medium', + title: 'Generic Function Type', + text: 'Define a generic identity function type', + setup: '// Define generic identity type', + setupCode: '// Define generic identity type', + expected: 'hello', + sample: 'type Identity = (value: T) => T;\nconst identity: Identity = value => value;\nidentity("hello")', + hints: [ + 'Place generic parameter before function parameters: (param: T) => T', + 'Generic preserves the input type in the output', + ], + tags: ['function-types', 'generics', 'identity'], + }, + { + id: 'ts-func-032', + category: 'Function Types', + difficulty: 'medium', + title: 'Generic Mapper Function Type', + text: 'Create a generic type for a function that maps A to B', + setup: '// Define generic mapper', + setupCode: '// Define generic mapper', + expected: 5, + sample: 'type Mapper = (value: A) => B;\nconst strlen: Mapper = s => s.length;\nstrlen("hello")', + hints: [ + 'Use two type parameters for input and output types', + 'Type parameters can be specified when using the type', + ], + tags: ['function-types', 'generics', 'mapper'], + }, + { + id: 'ts-func-033', + category: 'Function Types', + difficulty: 'medium', + title: 'Constrained Generic Function Type', + text: 'Define a function type that only accepts objects with a length property', + setup: 'interface HasLength { length: number; }', + setupCode: 'interface HasLength { length: number; }', + expected: 5, + sample: 'type GetLength = (obj: T) => number;\nconst getLen: GetLength = obj => obj.length;\ngetLen("hello")', + hints: [ + 'Use extends to constrain generic types', + 'Constraint ensures the property exists on the type', + ], + tags: ['function-types', 'generics', 'constraints'], + }, + { + id: 'ts-func-034', + category: 'Signatures', + difficulty: 'medium', + title: 'Call Signature in Interface', + text: 'Create an interface with a call signature for a formatter function', + setup: '// Define formatter interface with call signature', + setupCode: '// Define formatter interface with call signature', + expected: '$100.00', + sample: 'interface Formatter {\n (value: number): string;\n prefix: string;\n}\nconst fmt: Formatter = Object.assign(\n (v: number) => fmt.prefix + v.toFixed(2),\n { prefix: "$" }\n);\nfmt(100)', + hints: [ + 'Call signatures in interfaces: (params): ReturnType', + 'Call signatures allow adding properties to callable objects', + ], + tags: ['signatures', 'call-signature', 'interfaces'], + }, + { + id: 'ts-func-035', + category: 'Signatures', + difficulty: 'medium', + title: 'Construct Signature', + text: 'Define an interface with a construct signature for a class constructor', + setup: 'class Point { constructor(public x: number, public y: number) {} }', + setupCode: 'class Point { constructor(public x: number, public y: number) {} }', + expected: { x: 3, y: 4 }, + sample: 'interface PointConstructor {\n new (x: number, y: number): Point;\n}\nconst createPoint = (Ctor: PointConstructor, x: number, y: number) => new Ctor(x, y);\nconst p = createPoint(Point, 3, 4);\n({ x: p.x, y: p.y })', + hints: [ + 'Construct signatures use new keyword: new (params): Type', + 'Allows passing constructors as values', + ], + tags: ['signatures', 'construct-signature', 'classes'], + }, + { + id: 'ts-func-036', + category: 'Signatures', + difficulty: 'medium', + title: 'Both Call and Construct Signatures', + text: 'Create a type that can be both called and constructed', + setup: '// Define hybrid callable/constructable type', + setupCode: '// Define hybrid callable/constructable type', + expected: true, + sample: 'interface DateConstructor {\n (): string;\n new (): Date;\n}\nconst D = Date as unknown as DateConstructor;\ntypeof D() === "string" && D() !== undefined', + hints: [ + 'Some built-ins like Date work both ways', + 'Combine call and construct signatures in one interface', + ], + tags: ['signatures', 'hybrid', 'call-construct'], + }, + { + id: 'ts-func-037', + category: 'Overloads', + difficulty: 'medium', + title: 'Basic Function Overloads', + text: 'Create overloaded function that handles string or number differently', + setup: '// Define overloaded double function', + setupCode: '// Define overloaded double function', + expected: 'hellohello', + sample: 'function double(x: string): string;\nfunction double(x: number): number;\nfunction double(x: string | number): string | number {\n return typeof x === "string" ? x + x : x * 2;\n}\ndouble("hello")', + hints: [ + 'Overload signatures come before implementation', + 'Implementation signature must be compatible with all overloads', + ], + tags: ['overloads', 'function-overloads', 'polymorphism'], + }, + { + id: 'ts-func-038', + category: 'Overloads', + difficulty: 'medium', + title: 'Overloads with Different Parameter Counts', + text: 'Create overloaded function with optional second parameter', + setup: '// Define overloaded createElement', + setupCode: '// Define overloaded createElement', + expected: { tag: 'div', content: 'Hello' }, + sample: 'function createElement(tag: string): { tag: string };\nfunction createElement(tag: string, content: string): { tag: string; content: string };\nfunction createElement(tag: string, content?: string) {\n return content ? { tag, content } : { tag };\n}\ncreateElement("div", "Hello")', + hints: [ + 'Different overloads can have different parameter counts', + 'Implementation handles all cases', + ], + tags: ['overloads', 'optional-params', 'flexibility'], + }, + { + id: 'ts-func-039', + category: 'Overloads', + difficulty: 'medium', + title: 'Overloads with Array Types', + text: 'Create overloaded function that unwraps single item or returns array', + setup: '// Define overloaded first function', + setupCode: '// Define overloaded first function', + expected: 1, + sample: 'function first(arr: []): undefined;\nfunction first(arr: [T, ...T[]]): T;\nfunction first(arr: T[]): T | undefined {\n return arr[0];\n}\nfirst([1, 2, 3])', + hints: [ + 'Use tuple types for specific array shapes', + 'Empty tuple [] is a valid type', + ], + tags: ['overloads', 'arrays', 'tuples'], + }, + { + id: 'ts-func-040', + category: 'Overloads', + difficulty: 'medium', + title: 'Method Overloads in Class', + text: 'Create a class with overloaded method for adding items', + setup: '// Define collection class with overloaded add', + setupCode: '// Define collection class with overloaded add', + expected: [1, 2, 3, 4, 5], + sample: 'class Collection {\n items: T[] = [];\n add(item: T): void;\n add(items: T[]): void;\n add(itemOrItems: T | T[]): void {\n if (Array.isArray(itemOrItems)) this.items.push(...itemOrItems);\n else this.items.push(itemOrItems);\n }\n}\nconst c = new Collection();\nc.add(1);\nc.add([2, 3, 4, 5]);\nc.items', + hints: [ + 'Class methods can have overloads too', + 'Use Array.isArray to distinguish types at runtime', + ], + tags: ['overloads', 'classes', 'methods'], + }, + { + id: 'ts-func-041', + category: 'Function Types', + difficulty: 'medium', + title: 'Callback with Context Parameter', + text: 'Define a callback type that receives value, index, and array', + setup: 'const words = ["hello", "world"];', + setupCode: 'const words = ["hello", "world"];', + expected: ['HELLO-0', 'WORLD-1'], + sample: 'type MapCallback = (value: T, index: number, array: T[]) => U;\nconst cb: MapCallback = (v, i) => `${v.toUpperCase()}-${i}`;\nwords.map(cb)', + hints: [ + 'Array callbacks often include value, index, and array', + 'Generic types allow reuse with different element types', + ], + tags: ['function-types', 'callbacks', 'arrays', 'generics'], + }, + { + id: 'ts-func-042', + category: 'Function Types', + difficulty: 'medium', + title: 'Reducer Function Type', + text: 'Create a type for a reducer function used with reduce', + setup: 'const nums = [1, 2, 3, 4, 5];', + setupCode: 'const nums = [1, 2, 3, 4, 5];', + expected: 15, + sample: 'type Reducer = (accumulator: A, current: T, index: number) => A;\nconst sumReducer: Reducer = (acc, curr) => acc + curr;\nnums.reduce(sumReducer, 0)', + hints: [ + 'Reducers take accumulator and current value', + 'Return type matches accumulator type', + ], + tags: ['function-types', 'reducer', 'arrays'], + }, + { + id: 'ts-func-043', + category: 'Function Types', + difficulty: 'medium', + title: 'This Parameter in Function Type', + text: 'Define a function type with explicit this parameter', + setup: 'interface Counter { count: number; }', + setupCode: 'interface Counter { count: number; }', + expected: 3, + sample: 'type IncrementFn = (this: Counter, amount: number) => number;\nconst increment: IncrementFn = function(amount) { return this.count += amount; };\nconst counter: Counter = { count: 0 };\nincrement.call(counter, 3)', + hints: [ + 'this parameter must be first and is not counted as regular param', + 'Use call/apply/bind to set this context', + ], + tags: ['function-types', 'this-parameter', 'context'], + }, + { + id: 'ts-func-044', + category: 'Function Types', + difficulty: 'medium', + title: 'Function Type Alias vs Interface', + text: 'Show equivalent function type using both type alias and interface', + setup: '// Both approaches define same callable type', + setupCode: '// Both approaches define same callable type', + expected: 6, + sample: 'type MultFn = (a: number, b: number) => number;\ninterface IMultFn { (a: number, b: number): number; }\nconst mult1: MultFn = (a, b) => a * b;\nconst mult2: IMultFn = (a, b) => a * b;\nmult1(2, 3)', + hints: [ + 'Type aliases use arrow syntax: (params) => Return', + 'Interfaces use call signature syntax: (params): Return', + ], + tags: ['function-types', 'type-alias', 'interface'], + }, + { + id: 'ts-func-045', + category: 'Function Types', + difficulty: 'medium', + title: 'Conditional Return Type', + text: 'Create a function type where return depends on input type', + setup: '// Define conditional return type', + setupCode: '// Define conditional return type', + expected: 'hello', + sample: 'type Wrap = T extends string ? string : number[];\ntype WrapFn = (value: T) => Wrap;\nconst wrap: WrapFn = (value: any) => typeof value === "string" ? value : [value];\nwrap("hello")', + hints: [ + 'Conditional types can determine return type based on input', + 'T extends U ? X : Y pattern for conditional types', + ], + tags: ['function-types', 'conditional-types', 'generics'], + }, + { + id: 'ts-func-046', + category: 'Overloads', + difficulty: 'medium', + title: 'Overloads with Literal Types', + text: 'Create overloaded function based on string literal input', + setup: '// Define overloaded parse function', + setupCode: '// Define overloaded parse function', + expected: 42, + sample: 'function parse(type: "number", value: string): number;\nfunction parse(type: "boolean", value: string): boolean;\nfunction parse(type: string, value: string): number | boolean {\n return type === "number" ? Number(value) : value === "true";\n}\nparse("number", "42")', + hints: [ + 'Literal types narrow the input to specific values', + 'Each overload handles a specific literal value', + ], + tags: ['overloads', 'literal-types', 'parsing'], + }, + { + id: 'ts-func-047', + category: 'Function Types', + difficulty: 'medium', + title: 'Function Type with Default Generic', + text: 'Create a generic function type with default type parameter', + setup: '// Define function type with default generic', + setupCode: '// Define function type with default generic', + expected: 'default', + sample: 'type GetOrDefault = (value: T | undefined, defaultVal: T) => T;\nconst getStr: GetOrDefault = (v, d) => v ?? d;\ngetStr(undefined, "default")', + hints: [ + 'Default type parameters use = syntax: T = DefaultType', + 'When not specified, the default is used', + ], + tags: ['function-types', 'generics', 'defaults'], + }, + { + id: 'ts-func-048', + category: 'Function Types', + difficulty: 'medium', + title: 'Callback Type with Error-First Pattern', + text: 'Define a Node.js style error-first callback type', + setup: '// Define error-first callback', + setupCode: '// Define error-first callback', + expected: 'success', + sample: 'type NodeCallback = (error: Error | null, data?: T) => void;\nlet result = "";\nconst cb: NodeCallback = (err, data) => {\n result = err ? err.message : data ?? "";\n};\ncb(null, "success");\nresult', + hints: [ + 'Error is first parameter, null if no error', + 'Data is optional second parameter', + ], + tags: ['function-types', 'callbacks', 'node-style'], + }, + { + id: 'ts-func-049', + category: 'Function Types', + difficulty: 'medium', + title: 'Method Decorator Function Type', + text: 'Define a type for a method decorator function', + setup: '// Define method decorator type', + setupCode: '// Define method decorator type', + expected: true, + sample: 'type MethodDecorator = (\n target: Object,\n propertyKey: string | symbol,\n descriptor: TypedPropertyDescriptor\n) => TypedPropertyDescriptor | void;\nconst log: MethodDecorator = (target, key, desc) => desc;\ntypeof log === "function"', + hints: [ + 'Decorators receive target, key, and descriptor', + 'Can return modified descriptor or void', + ], + tags: ['function-types', 'decorators', 'methods'], + }, + { + id: 'ts-func-050', + category: 'Function Types', + difficulty: 'medium', + title: 'Middleware Function Type', + text: 'Define an Express-style middleware function type', + setup: 'interface Request { path: string; }\ninterface Response { send(data: string): void; }', + setupCode: 'interface Request { path: string; }\ninterface Response { send(data: string): void; }', + expected: '/api/users', + sample: 'type Middleware = (req: Request, res: Response, next: () => void) => void;\nlet logged = "";\nconst logger: Middleware = (req, res, next) => { logged = req.path; next(); };\nlogger({ path: "/api/users" }, { send: () => {} }, () => {});\nlogged', + hints: [ + 'Middleware receives request, response, and next', + 'Call next() to continue to next middleware', + ], + tags: ['function-types', 'middleware', 'express'], + }, + { + id: 'ts-func-051', + category: 'Overloads', + difficulty: 'medium', + title: 'Overloads Returning Different Types', + text: 'Create overloaded function returning array or single item', + setup: '// Define overloaded find function', + setupCode: '// Define overloaded find function', + expected: [2, 4, 6], + sample: 'function find(arr: number[], predicate: (n: number) => boolean, all: true): number[];\nfunction find(arr: number[], predicate: (n: number) => boolean, all: false): number | undefined;\nfunction find(arr: number[], predicate: (n: number) => boolean, all: boolean) {\n return all ? arr.filter(predicate) : arr.find(predicate);\n}\nfind([1, 2, 3, 4, 5, 6], n => n % 2 === 0, true)', + hints: [ + 'Boolean literal types control return type', + 'true returns array, false returns single item', + ], + tags: ['overloads', 'literal-types', 'arrays'], + }, + { + id: 'ts-func-052', + category: 'Overloads', + difficulty: 'medium', + title: 'String or Regex Overload', + text: 'Create overloaded replace function accepting string or regex', + setup: '// Define overloaded replace function', + setupCode: '// Define overloaded replace function', + expected: 'hello universe', + sample: 'function replace(str: string, search: string, replacement: string): string;\nfunction replace(str: string, search: RegExp, replacement: string): string;\nfunction replace(str: string, search: string | RegExp, replacement: string): string {\n return str.replace(search, replacement);\n}\nreplace("hello world", /world/, "universe")', + hints: [ + 'String and RegExp can be separate overloads', + 'Implementation handles both cases', + ], + tags: ['overloads', 'strings', 'regex'], + }, + { + id: 'ts-func-053', + category: 'Function Types', + difficulty: 'medium', + title: 'Memoized Function Type', + text: 'Define a type for a memoization wrapper function', + setup: '// Define memoize function type', + setupCode: '// Define memoize function type', + expected: 8, + sample: 'type Memoize = (fn: (...args: A) => R) => (...args: A) => R;\nconst memoize: Memoize = fn => {\n const cache = new Map();\n return (...args) => {\n const key = JSON.stringify(args);\n if (!cache.has(key)) cache.set(key, fn(...args));\n return cache.get(key);\n };\n};\nconst cube = memoize((n: number) => n * n * n);\ncube(2)', + hints: [ + 'Memoize preserves function signature', + 'Use Map for caching results', + ], + tags: ['function-types', 'memoization', 'higher-order'], + }, + { + id: 'ts-func-054', + category: 'Signatures', + difficulty: 'medium', + title: 'Index Signature with Call Signature', + text: 'Create an interface combining call signature with index signature', + setup: '// Define callable dictionary type', + setupCode: '// Define callable dictionary type', + expected: 'default', + sample: 'interface CallableDict {\n (key: string): string;\n [key: string]: string | ((key: string) => string);\n}\nconst dict: CallableDict = Object.assign(\n (key: string) => dict[key] as string ?? "default",\n { hello: "world", foo: "bar" }\n);\ndict("unknown")', + hints: [ + 'Index signatures define property access types', + 'Call signature makes the object callable', + ], + tags: ['signatures', 'index-signature', 'callable'], + }, + { + id: 'ts-func-055', + category: 'Function Types', + difficulty: 'medium', + title: 'Function Type with Readonly Parameters', + text: 'Define a function type that takes readonly array parameter', + setup: '// Define function with readonly param', + setupCode: '// Define function with readonly param', + expected: 6, + sample: 'type Summer = (numbers: readonly number[]) => number;\nconst sum: Summer = nums => nums.reduce((a, b) => a + b, 0);\nsum([1, 2, 3])', + hints: [ + 'readonly modifier prevents array mutation', + 'Accepts both mutable and readonly arrays', + ], + tags: ['function-types', 'readonly', 'arrays'], + }, + { + id: 'ts-func-056', + category: 'Function Types', + difficulty: 'medium', + title: 'Builder Pattern Function Type', + text: 'Define types for a fluent builder pattern', + setup: 'interface Query { table: string; columns: string[]; where?: string; }', + setupCode: 'interface Query { table: string; columns: string[]; where?: string; }', + expected: { table: 'users', columns: ['name', 'email'], where: 'active = true' }, + sample: 'interface QueryBuilder {\n select(...cols: string[]): QueryBuilder;\n from(table: string): QueryBuilder;\n where(condition: string): QueryBuilder;\n build(): Query;\n}\nconst builder: QueryBuilder = {\n _query: {} as Query,\n select(...cols) { this._query.columns = cols; return this; },\n from(table) { this._query.table = table; return this; },\n where(cond) { this._query.where = cond; return this; },\n build() { return this._query; }\n} as any;\nbuilder.select("name", "email").from("users").where("active = true").build()', + hints: [ + 'Builder methods return this for chaining', + 'Use interface to define method signatures', + ], + tags: ['function-types', 'builder-pattern', 'fluent'], + }, + { + id: 'ts-func-057', + category: 'Function Types', + difficulty: 'medium', + title: 'Event Emitter Types', + text: 'Define types for a typed event emitter', + setup: 'interface Events { click: { x: number; y: number }; change: string; }', + setupCode: 'interface Events { click: { x: number; y: number }; change: string; }', + expected: { x: 10, y: 20 }, + sample: 'type Listener = (data: T) => void;\ntype Emitter = {\n on(event: K, listener: Listener): void;\n emit(event: K, data: E[K]): void;\n};\nconst emitter: Emitter = {\n listeners: {} as any,\n on(event, listener) { (this.listeners[event] ??= []).push(listener); },\n emit(event, data) { this.listeners[event]?.forEach((l: any) => l(data)); }\n} as any;\nlet received: any;\nemitter.on("click", d => { received = d; });\nemitter.emit("click", { x: 10, y: 20 });\nreceived', + hints: [ + 'Use mapped types for event-specific listeners', + 'keyof E constrains to valid event names', + ], + tags: ['function-types', 'events', 'generics'], + }, + { + id: 'ts-func-058', + category: 'Function Types', + difficulty: 'medium', + title: 'Partial Application Type', + text: 'Define a type for partial function application', + setup: '// Define partial application type', + setupCode: '// Define partial application type', + expected: 15, + sample: 'type PartialApply = F extends (arg: A, ...rest: infer R) => infer Ret\n ? (...args: R) => Ret\n : never;\nconst add = (a: number, b: number, c: number) => a + b + c;\ntype AddWithFirst = PartialApply;\nconst add5: AddWithFirst = (b, c) => add(5, b, c);\nadd5(4, 6)', + hints: [ + 'Use infer to capture remaining params and return type', + 'Partial application fixes some arguments', + ], + tags: ['function-types', 'partial-application', 'generics'], + }, + { + id: 'ts-func-059', + category: 'Overloads', + difficulty: 'medium', + title: 'Async/Sync Overloads', + text: 'Create overloaded function with async and sync variants', + setup: '// Define overloaded fetch data function', + setupCode: '// Define overloaded fetch data function', + expected: 'sync', + sample: 'function fetchData(async: true): Promise;\nfunction fetchData(async: false): string;\nfunction fetchData(async: boolean): Promise | string {\n return async ? Promise.resolve("async") : "sync";\n}\nfetchData(false)', + hints: [ + 'Boolean literal determines sync vs async', + 'Return type changes based on parameter', + ], + tags: ['overloads', 'async', 'sync'], + }, + { + id: 'ts-func-060', + category: 'Function Types', + difficulty: 'medium', + title: 'Strict Function Comparison', + text: 'Create types to check function compatibility', + setup: 'type Fn1 = (x: number, y: string) => boolean;\ntype Fn2 = (x: number) => boolean;', + setupCode: 'type Fn1 = (x: number, y: string) => boolean;\ntype Fn2 = (x: number) => boolean;', + expected: true, + sample: 'type IsAssignable = A extends B ? true : false;\ntype CanAssignFn2ToFn1 = IsAssignable;\nconst fn1: Fn1 = (x, y) => x > 0 && y.length > 0;\nconst fn2: Fn2 = x => x > 0;\nconst test: Fn1 = fn2;\ntest(5, "hi")', + hints: [ + 'Functions with fewer params can be assigned to functions with more', + 'This is due to function parameter bivariance', + ], + tags: ['function-types', 'compatibility', 'assignability'], + }, + { + id: 'ts-func-061', + category: 'Signatures', + difficulty: 'hard', + title: 'Generic Construct Signature', + text: 'Create a generic constructor type for creating instances', + setup: 'class Entity { constructor(public id: string) {} }', + setupCode: 'class Entity { constructor(public id: string) {} }', + expected: 'test-id', + sample: 'interface Constructor {\n new (...args: any[]): T;\n}\nfunction create(Ctor: Constructor, ...args: any[]): T {\n return new Ctor(...args);\n}\ncreate(Entity, "test-id").id', + hints: [ + 'Generic construct signatures work with class constructors', + 'Use rest parameters for flexible argument passing', + ], + tags: ['signatures', 'generics', 'constructor'], + }, + { + id: 'ts-func-062', + category: 'Function Types', + difficulty: 'hard', + title: 'Curried Function Type', + text: 'Define a type for a curried addition function', + setup: '// Define curried function type', + setupCode: '// Define curried function type', + expected: 15, + sample: 'type Curried = (a: number) => (b: number) => (c: number) => number;\nconst add: Curried = a => b => c => a + b + c;\nadd(5)(6)(4)', + hints: [ + 'Curried functions return functions until all args received', + 'Chain arrow types for multiple levels', + ], + tags: ['function-types', 'currying', 'higher-order'], + }, + { + id: 'ts-func-063', + category: 'Function Types', + difficulty: 'hard', + title: 'Infer Return Type from Function', + text: 'Use ReturnType utility to extract function return type', + setup: 'function getUser() { return { id: 1, name: "Alice" }; }', + setupCode: 'function getUser() { return { id: 1, name: "Alice" }; }', + expected: { id: 2, name: 'Bob' }, + sample: 'type User = ReturnType;\nconst user: User = { id: 2, name: "Bob" };\nuser', + hints: [ + 'ReturnType extracts the return type of function type F', + 'Use typeof to get type of a function value', + ], + tags: ['function-types', 'utility-types', 'inference'], + }, + { + id: 'ts-func-064', + category: 'Function Types', + difficulty: 'hard', + title: 'Infer Parameters from Function', + text: 'Use Parameters utility to extract function parameter types', + setup: 'function createPost(title: string, body: string, published: boolean) { return { title, body, published }; }', + setupCode: 'function createPost(title: string, body: string, published: boolean) { return { title, body, published }; }', + expected: ['Hello', 'World', true], + sample: 'type PostParams = Parameters;\nconst params: PostParams = ["Hello", "World", true];\nparams', + hints: [ + 'Parameters returns a tuple of parameter types', + 'Useful for wrapping or extending existing functions', + ], + tags: ['function-types', 'utility-types', 'parameters'], + }, + { + id: 'ts-func-065', + category: 'Overloads', + difficulty: 'hard', + title: 'Overloads with Generic Constraints', + text: 'Create overloaded function with different generic constraints', + setup: 'interface Named { name: string; }\ninterface Numbered { id: number; }', + setupCode: 'interface Named { name: string; }\ninterface Numbered { id: number; }', + expected: 'Alice', + sample: 'function getIdentifier(obj: T): string;\nfunction getIdentifier(obj: T): number;\nfunction getIdentifier(obj: Named | Numbered): string | number {\n return "name" in obj ? obj.name : obj.id;\n}\ngetIdentifier({ name: "Alice" })', + hints: [ + 'Overloads can have different generic constraints', + 'Use type narrowing in implementation', + ], + tags: ['overloads', 'generics', 'constraints'], + }, + { + id: 'ts-func-066', + category: 'Function Types', + difficulty: 'hard', + title: 'Never-Returning Function Type', + text: 'Define a type for a function that never returns (throws or infinite loop)', + setup: '// Define never-returning function type', + setupCode: '// Define never-returning function type', + expected: 'caught', + sample: 'type ThrowError = (message: string) => never;\nconst fail: ThrowError = msg => { throw new Error(msg); };\nlet result = "";\ntry { fail("oops"); } catch { result = "caught"; }\nresult', + hints: [ + 'never is for functions that never successfully complete', + 'Throwing an error or infinite loops return never', + ], + tags: ['function-types', 'never', 'error-handling'], + }, + { + id: 'ts-func-067', + category: 'Function Types', + difficulty: 'hard', + title: 'Assertion Function Type', + text: 'Create an assertion function type that narrows types', + setup: 'interface User { name: string; role?: string; }', + setupCode: 'interface User { name: string; role?: string; }', + expected: 'admin', + sample: 'type AssertHasRole = (user: User) => asserts user is User & { role: string };\nconst assertHasRole: AssertHasRole = user => {\n if (!user.role) throw new Error("No role");\n};\nconst user: User = { name: "Alice", role: "admin" };\nassertHasRole(user);\nuser.role', + hints: [ + 'asserts x is Type narrows the type after function call', + 'Assertion functions throw if condition not met', + ], + tags: ['function-types', 'assertions', 'type-narrowing'], + }, + { + id: 'ts-func-068', + category: 'Function Types', + difficulty: 'hard', + title: 'Type Guard Function Type', + text: 'Define a type guard function type for checking arrays', + setup: '// Define type guard function type', + setupCode: '// Define type guard function type', + expected: true, + sample: 'type IsStringArray = (value: unknown) => value is string[];\nconst isStrArr: IsStringArray = (v): v is string[] => \n Array.isArray(v) && v.every(x => typeof x === "string");\nisStrArr(["a", "b", "c"])', + hints: [ + 'Type guards return x is Type predicate', + 'Implementation must return boolean', + ], + tags: ['function-types', 'type-guards', 'predicates'], + }, + { + id: 'ts-func-069', + category: 'Function Types', + difficulty: 'hard', + title: 'Mapped Function Types', + text: 'Create a type that wraps all methods of an object in promises', + setup: 'interface Api { getUser(id: number): { name: string }; getPost(id: number): { title: string }; }', + setupCode: 'interface Api { getUser(id: number): { name: string }; getPost(id: number): { title: string }; }', + expected: { name: 'Alice' }, + sample: 'type Async = {\n [K in keyof T]: T[K] extends (...args: infer A) => infer R\n ? (...args: A) => Promise\n : T[K];\n};\nconst api: Async = {\n getUser: async (id) => ({ name: "Alice" }),\n getPost: async (id) => ({ title: "Hello" }),\n};\napi.getUser(1).then(u => u)', + hints: [ + 'Use mapped types with conditional inference', + 'infer extracts argument and return types from functions', + ], + tags: ['function-types', 'mapped-types', 'async'], + }, + { + id: 'ts-func-070', + category: 'Overloads', + difficulty: 'hard', + title: 'Overloads with Rest Parameters', + text: 'Create overloaded function handling different rest parameter types', + setup: '// Define overloaded concatenate function', + setupCode: '// Define overloaded concatenate function', + expected: '1-2-3', + sample: 'function concat(...strings: string[]): string;\nfunction concat(...numbers: number[]): string;\nfunction concat(...args: (string | number)[]): string {\n return args.join("-");\n}\nconcat(1, 2, 3)', + hints: [ + 'Each overload can have different rest parameter types', + 'Implementation must handle all variants', + ], + tags: ['overloads', 'rest-parameters', 'variadic'], + }, + { + id: 'ts-func-071', + category: 'Function Types', + difficulty: 'hard', + title: 'Distributive Conditional Function Type', + text: 'Create a type that distributes over union in function parameter', + setup: 'type Animal = { type: "cat"; meow: () => void } | { type: "dog"; bark: () => void };', + setupCode: 'type Animal = { type: "cat"; meow: () => void } | { type: "dog"; bark: () => void };', + expected: 'meow', + sample: 'type Handler = T extends { type: infer U } ? (animal: T) => U : never;\ntype CatHandler = Handler>;\nconst handleCat: CatHandler = cat => { cat.meow(); return cat.type; };\nhandleCat({ type: "cat", meow: () => {} })', + hints: [ + 'Conditional types distribute over unions', + 'Extract narrows union to specific member', + ], + tags: ['function-types', 'conditional-types', 'unions'], + }, + { + id: 'ts-func-072', + category: 'Signatures', + difficulty: 'hard', + title: 'Abstract Construct Signature', + text: 'Create a type that accepts abstract class constructors', + setup: 'abstract class Shape { abstract area(): number; }', + setupCode: 'abstract class Shape { abstract area(): number; }', + expected: 100, + sample: 'type AbstractConstructor = abstract new (...args: any[]) => T;\nclass Square extends Shape {\n constructor(public side: number) { super(); }\n area() { return this.side * this.side; }\n}\nfunction getArea(Ctor: new (...args: any[]) => T, ...args: any[]): number {\n return new Ctor(...args).area();\n}\ngetArea(Square, 10)', + hints: [ + 'abstract new creates abstract construct signature', + 'Abstract classes cannot be instantiated directly', + ], + tags: ['signatures', 'abstract', 'classes'], + }, + { + id: 'ts-func-073', + category: 'Function Types', + difficulty: 'hard', + title: 'Variadic Tuple Function Type', + text: 'Create a function type using variadic tuple types', + setup: '// Define pipe function type', + setupCode: '// Define pipe function type', + expected: 10, + sample: 'type Pipe = (arg: A) => B;\nfunction pipe(f1: Pipe, f2: Pipe): Pipe {\n return x => f2(f1(x));\n}\nconst addOne = (x: number) => x + 1;\nconst double = (x: number) => x * 2;\npipe(addOne, double)(4)', + hints: [ + 'Variadic tuples allow spreading tuple types', + 'Build type-safe pipelines with multiple functions', + ], + tags: ['function-types', 'variadic-tuples', 'pipe'], + }, + { + id: 'ts-func-074', + category: 'Function Types', + difficulty: 'hard', + title: 'Overloaded Method in Interface', + text: 'Define an interface with overloaded method signatures', + setup: '// Define storage interface with overloaded get', + setupCode: '// Define storage interface with overloaded get', + expected: 42, + sample: 'interface Storage {\n get(key: string): unknown;\n get(key: string, defaultValue: T): T;\n}\nconst storage: Storage = {\n get(key: string, defaultValue?: T) {\n const data: Record = { age: 42 };\n return data[key] ?? defaultValue;\n }\n};\nstorage.get("age", 0)', + hints: [ + 'Interfaces can declare multiple overloaded signatures', + 'Implementation handles all variants', + ], + tags: ['signatures', 'overloads', 'interfaces'], + }, + { + id: 'ts-func-075', + category: 'Function Types', + difficulty: 'hard', + title: 'Infer This Type from Method', + text: 'Extract this type from a method using ThisParameterType', + setup: 'interface Counter {\n count: number;\n increment(this: Counter): void;\n}', + setupCode: 'interface Counter {\n count: number;\n increment(this: Counter): void;\n}', + expected: 1, + sample: 'type CounterThis = ThisParameterType;\nconst counter: CounterThis = { count: 0, increment() { this.count++; } };\ncounter.increment();\ncounter.count', + hints: [ + 'ThisParameterType extracts the this type from a function', + 'Useful for ensuring correct context', + ], + tags: ['function-types', 'this-parameter', 'utility-types'], + }, + { + id: 'ts-func-076', + category: 'Function Types', + difficulty: 'hard', + title: 'Omit This Parameter from Function', + text: 'Remove this parameter from function type using OmitThisParameter', + setup: 'type BoundMethod = (this: { value: number }, multiplier: number) => number;', + setupCode: 'type BoundMethod = (this: { value: number }, multiplier: number) => number;', + expected: 15, + sample: 'type Unbound = OmitThisParameter;\nconst method: BoundMethod = function(mult) { return this.value * mult; };\nconst obj = { value: 5 };\nconst bound: Unbound = method.bind(obj);\nbound(3)', + hints: [ + 'OmitThisParameter removes the this parameter', + 'Useful for bound functions', + ], + tags: ['function-types', 'this-parameter', 'utility-types'], + }, + { + id: 'ts-func-077', + category: 'Function Types', + difficulty: 'hard', + title: 'Debounce Function Type', + text: 'Define a type for a debounce utility function', + setup: '// Define debounce function type', + setupCode: '// Define debounce function type', + expected: true, + sample: 'type Debounce = (fn: (...args: A) => void, ms: number) => (...args: A) => void;\nconst debounce: Debounce = (fn, ms) => {\n let timeout: ReturnType;\n return (...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), ms);\n };\n};\nconst debounced = debounce((x: number) => x, 100);\ntypeof debounced === "function"', + hints: [ + 'Debounce delays function execution', + 'Preserves original function argument types', + ], + tags: ['function-types', 'debounce', 'utilities'], + }, + { + id: 'ts-func-078', + category: 'Function Types', + difficulty: 'hard', + title: 'Throttle Function Type', + text: 'Define a type for a throttle utility function', + setup: '// Define throttle function type', + setupCode: '// Define throttle function type', + expected: true, + sample: 'type Throttle = (fn: (...args: A) => R, ms: number) => (...args: A) => R | undefined;\nconst throttle: Throttle = (fn, ms) => {\n let lastCall = 0;\n return (...args) => {\n const now = Date.now();\n if (now - lastCall >= ms) {\n lastCall = now;\n return fn(...args);\n }\n };\n};\nconst throttled = throttle((x: number) => x * 2, 100);\ntypeof throttled === "function"', + hints: [ + 'Throttle limits execution frequency', + 'Returns undefined when throttled', + ], + tags: ['function-types', 'throttle', 'utilities'], + }, + { + id: 'ts-func-079', + category: 'Overloads', + difficulty: 'hard', + title: 'Overloads with Tuple Parameters', + text: 'Create overloaded function accepting different tuple shapes', + setup: '// Define overloaded point creator', + setupCode: '// Define overloaded point creator', + expected: { x: 3, y: 4, z: 5 }, + sample: 'function createPoint(coords: [number, number]): { x: number; y: number };\nfunction createPoint(coords: [number, number, number]): { x: number; y: number; z: number };\nfunction createPoint(coords: number[]): { x: number; y: number; z?: number } {\n return coords.length === 3\n ? { x: coords[0], y: coords[1], z: coords[2] }\n : { x: coords[0], y: coords[1] };\n}\ncreatePoint([3, 4, 5])', + hints: [ + 'Different tuple lengths can have different overloads', + 'Use tuple types [T, T] for fixed length arrays', + ], + tags: ['overloads', 'tuples', 'polymorphism'], + }, + { + id: 'ts-func-080', + category: 'Function Types', + difficulty: 'hard', + title: 'Recursive Function Type', + text: 'Define a type for a recursive tree traversal function', + setup: 'interface TreeNode { value: number; children?: TreeNode[]; }', + setupCode: 'interface TreeNode { value: number; children?: TreeNode[]; }', + expected: 21, + sample: 'type TreeSum = (node: TreeNode) => number;\nconst sumTree: TreeSum = node => {\n const childSum = node.children?.reduce((sum, child) => sum + sumTree(child), 0) ?? 0;\n return node.value + childSum;\n};\nconst tree: TreeNode = { value: 1, children: [{ value: 2, children: [{ value: 3 }] }, { value: 4, children: [{ value: 5 }, { value: 6 }] }] };\nsumTree(tree)', + hints: [ + 'Recursive functions call themselves', + 'Handle base case and recursive case', + ], + tags: ['function-types', 'recursion', 'trees'], + }, + { + id: 'ts-func-081', + category: 'Function Types', + difficulty: 'hard', + title: 'Promisify Function Type', + text: 'Define a type that converts callback-based function to promise-based', + setup: 'type Callback = (error: Error | null, result: T) => void;', + setupCode: 'type Callback = (error: Error | null, result: T) => void;', + expected: 42, + sample: 'type Promisify void> =\n T extends (...args: [...infer A, Callback]) => void\n ? (...args: A) => Promise\n : never;\nconst readFile = (path: string, cb: Callback) => cb(null, "content");\ntype PromisifiedRead = Promisify;\nconst promisified: PromisifiedRead = (path) => Promise.resolve("content" as any);\nPromise.resolve(42).then(r => r)', + hints: [ + 'Extract callback result type using infer', + 'Remove callback from args, return Promise', + ], + tags: ['function-types', 'promises', 'utility-types'], + }, + { + id: 'ts-func-082', + category: 'Function Types', + difficulty: 'hard', + title: 'Compose Function Types', + text: 'Define a type for composing two functions', + setup: '// Define compose type', + setupCode: '// Define compose type', + expected: 10, + sample: 'type Compose = (f: (b: B) => C, g: (a: A) => B) => (a: A) => C;\nconst compose: Compose = (f, g) => a => f(g(a));\nconst double = (n: number) => n * 2;\nconst addOne = (n: number) => n + 1;\ncompose(double, addOne)(4)', + hints: [ + 'Compose applies functions right to left', + 'Output of g becomes input of f', + ], + tags: ['function-types', 'composition', 'higher-order'], + }, + { + id: 'ts-func-083', + category: 'Overloads', + difficulty: 'hard', + title: 'Builder with Overloaded Methods', + text: 'Create a builder with overloaded set method', + setup: 'interface Options { name?: string; count?: number; active?: boolean; }', + setupCode: 'interface Options { name?: string; count?: number; active?: boolean; }', + expected: { name: 'test', count: 5, active: true }, + sample: 'class OptionsBuilder {\n private options: Options = {};\n set(key: "name", value: string): this;\n set(key: "count", value: number): this;\n set(key: "active", value: boolean): this;\n set(key: keyof Options, value: string | number | boolean): this {\n (this.options as any)[key] = value;\n return this;\n }\n build(): Options { return this.options; }\n}\nnew OptionsBuilder().set("name", "test").set("count", 5).set("active", true).build()', + hints: [ + 'Each overload specifies key-value type pairing', + 'Return this for method chaining', + ], + tags: ['overloads', 'builder', 'method-chaining'], + }, + { + id: 'ts-func-084', + category: 'Function Types', + difficulty: 'hard', + title: 'Extract Function from Union', + text: 'Extract only function types from a union', + setup: 'type Mixed = string | ((x: number) => number) | { a: number } | ((s: string) => string);', + setupCode: 'type Mixed = string | ((x: number) => number) | { a: number } | ((s: string) => string);', + expected: 4, + sample: 'type OnlyFunctions = T extends (...args: any[]) => any ? T : never;\ntype Fns = OnlyFunctions;\nconst fn: Fns = (x: number) => x * 2;\nfn(2)', + hints: [ + 'Conditional types distribute over unions', + 'never removes non-matching types from union', + ], + tags: ['function-types', 'conditional-types', 'unions'], + }, + { + id: 'ts-func-085', + category: 'Function Types', + difficulty: 'hard', + title: 'Contravariance in Function Parameters', + text: 'Demonstrate contravariance in function parameter types', + setup: 'interface Animal { name: string; }\ninterface Dog extends Animal { breed: string; }', + setupCode: 'interface Animal { name: string; }\ninterface Dog extends Animal { breed: string; }', + expected: 'Buddy', + sample: 'type AnimalHandler = (animal: Animal) => string;\ntype DogHandler = (dog: Dog) => string;\nconst handleAnimal: AnimalHandler = a => a.name;\nconst handleDog: DogHandler = handleAnimal;\nhandleDog({ name: "Buddy", breed: "Lab" })', + hints: [ + 'Functions are contravariant in parameter types', + 'AnimalHandler can be used where DogHandler expected', + ], + tags: ['function-types', 'contravariance', 'type-theory'], + }, + + // ============================================================ + // Classes & OOP Patterns + // ============================================================ + { + id: 'ts-class-001', + category: 'Classes', + difficulty: 'easy', + title: 'Basic Class Declaration', + text: 'Create a simple class with a name property and access it', + setup: 'class Person { name: string = "Alice"; }', + setupCode: 'class Person { name: string = "Alice"; }', + expected: 'Alice', + sample: 'new Person().name', + hints: [ + 'Instantiate the class with new keyword', + 'Access the property using dot notation', + ], + tags: ['class', 'property', 'basics'], + }, + { + id: 'ts-class-002', + category: 'Classes', + difficulty: 'easy', + title: 'Constructor with Parameters', + text: 'Create a class instance with constructor parameters', + setup: 'class Animal { name: string; constructor(name: string) { this.name = name; } }', + setupCode: 'class Animal { name: string; constructor(name: string) { this.name = name; } }', + expected: 'Dog', + sample: 'new Animal("Dog").name', + hints: [ + 'Pass arguments to the constructor', + 'The constructor initializes the instance', + ], + tags: ['class', 'constructor', 'basics'], + }, + { + id: 'ts-class-003', + category: 'Classes', + difficulty: 'easy', + title: 'Parameter Properties Shorthand', + text: 'Use TypeScript parameter properties to declare and initialize', + setup: 'class Car { constructor(public brand: string, public year: number) {} }', + setupCode: 'class Car { constructor(public brand: string, public year: number) {} }', + expected: 'Toyota', + sample: 'new Car("Toyota", 2023).brand', + hints: [ + 'Public modifier in constructor creates and assigns properties', + 'No need for separate property declaration', + ], + tags: ['class', 'parameter-properties', 'constructor'], + }, + { + id: 'ts-class-004', + category: 'Classes', + difficulty: 'easy', + title: 'Class Method', + text: 'Call a method on a class instance', + setup: 'class Greeter { greet(name: string): string { return `Hello, ${name}!`; } }', + setupCode: 'class Greeter { greet(name: string): string { return `Hello, ${name}!`; } }', + expected: 'Hello, World!', + sample: 'new Greeter().greet("World")', + hints: [ + 'Create an instance and call the method', + 'Methods are functions attached to the class', + ], + tags: ['class', 'method', 'basics'], + }, + { + id: 'ts-class-005', + category: 'Classes', + difficulty: 'easy', + title: 'Readonly Property', + text: 'Access a readonly property that cannot be modified after initialization', + setup: 'class Config { readonly apiKey: string = "secret123"; }', + setupCode: 'class Config { readonly apiKey: string = "secret123"; }', + expected: 'secret123', + sample: 'new Config().apiKey', + hints: [ + 'Readonly properties can be accessed but not modified', + 'They are set at declaration or in constructor', + ], + tags: ['class', 'readonly', 'basics'], + }, + { + id: 'ts-class-006', + category: 'Classes', + difficulty: 'easy', + title: 'Static Property', + text: 'Access a static property on the class itself', + setup: 'class MathUtils { static PI: number = 3.14159; }', + setupCode: 'class MathUtils { static PI: number = 3.14159; }', + expected: 3.14159, + sample: 'MathUtils.PI', + hints: [ + 'Static properties belong to the class, not instances', + 'Access using ClassName.property', + ], + tags: ['class', 'static', 'property'], + }, + { + id: 'ts-class-007', + category: 'Classes', + difficulty: 'easy', + title: 'Static Method', + text: 'Call a static method on the class', + setup: 'class Calculator { static add(a: number, b: number): number { return a + b; } }', + setupCode: 'class Calculator { static add(a: number, b: number): number { return a + b; } }', + expected: 15, + sample: 'Calculator.add(10, 5)', + hints: [ + 'Static methods are called on the class itself', + 'No need to create an instance', + ], + tags: ['class', 'static', 'method'], + }, + { + id: 'ts-class-008', + category: 'Classes', + difficulty: 'easy', + title: 'Getter Property', + text: 'Use a getter to compute a derived value', + setup: 'class Rectangle { constructor(public width: number, public height: number) {} get area(): number { return this.width * this.height; } }', + setupCode: 'class Rectangle { constructor(public width: number, public height: number) {} get area(): number { return this.width * this.height; } }', + expected: 50, + sample: 'new Rectangle(10, 5).area', + hints: [ + 'Getters are accessed like properties', + 'They compute values on demand', + ], + tags: ['class', 'getter', 'computed-property'], + }, + { + id: 'ts-class-009', + category: 'Classes', + difficulty: 'easy', + title: 'Basic Inheritance', + text: 'Create a subclass that extends a parent class', + setup: 'class Animal { name: string = "Animal"; }\nclass Dog extends Animal { name: string = "Dog"; }', + setupCode: 'class Animal { name: string = "Animal"; }\nclass Dog extends Animal { name: string = "Dog"; }', + expected: 'Dog', + sample: 'new Dog().name', + hints: [ + 'Subclass overrides parent property', + 'Use extends keyword for inheritance', + ], + tags: ['class', 'inheritance', 'extends'], + }, + { + id: 'ts-class-010', + category: 'Classes', + difficulty: 'easy', + title: 'Instanceof Check', + text: 'Check if an object is an instance of a class', + setup: 'class Vehicle {}\nclass Car extends Vehicle {}\nconst myCar = new Car();', + setupCode: 'class Vehicle {}\nclass Car extends Vehicle {}\nconst myCar = new Car();', + expected: true, + sample: 'myCar instanceof Vehicle', + hints: [ + 'instanceof checks the prototype chain', + 'A subclass instance is also an instance of its parent', + ], + tags: ['class', 'instanceof', 'inheritance'], + }, + { + id: 'ts-class-011', + category: 'Classes', + difficulty: 'easy', + title: 'Method Return Type', + text: 'Call a method with explicit return type', + setup: 'class Counter { private count: number = 0; increment(): number { return ++this.count; } }', + setupCode: 'class Counter { private count: number = 0; increment(): number { return ++this.count; } }', + expected: 1, + sample: 'new Counter().increment()', + hints: [ + 'Methods can have explicit return types', + 'The private count starts at 0', + ], + tags: ['class', 'method', 'return-type'], + }, + { + id: 'ts-class-012', + category: 'Classes', + difficulty: 'easy', + title: 'Multiple Properties', + text: 'Access multiple properties from a class instance', + setup: 'class User { constructor(public name: string, public age: number, public email: string) {} }', + setupCode: 'class User { constructor(public name: string, public age: number, public email: string) {} }', + expected: 'john@example.com', + sample: 'new User("John", 30, "john@example.com").email', + hints: [ + 'Parameter properties create multiple public properties', + 'Access any property with dot notation', + ], + tags: ['class', 'parameter-properties', 'constructor'], + }, + { + id: 'ts-class-013', + category: 'Classes', + difficulty: 'easy', + title: 'Default Property Values', + text: 'Use default values for class properties', + setup: 'class Settings { theme: string = "dark"; fontSize: number = 14; }', + setupCode: 'class Settings { theme: string = "dark"; fontSize: number = 14; }', + expected: 14, + sample: 'new Settings().fontSize', + hints: [ + 'Properties can have default values', + 'No constructor needed for defaults', + ], + tags: ['class', 'property', 'default-value'], + }, + { + id: 'ts-class-014', + category: 'Classes', + difficulty: 'easy', + title: 'This Reference', + text: 'Use this to reference instance properties in a method', + setup: 'class Multiplier { constructor(public factor: number) {} multiply(value: number): number { return value * this.factor; } }', + setupCode: 'class Multiplier { constructor(public factor: number) {} multiply(value: number): number { return value * this.factor; } }', + expected: 25, + sample: 'new Multiplier(5).multiply(5)', + hints: [ + 'this refers to the current instance', + 'Access instance properties with this.property', + ], + tags: ['class', 'this', 'method'], + }, + { + id: 'ts-class-015', + category: 'Classes', + difficulty: 'easy', + title: 'Class with Array Property', + text: 'Access an array property from a class', + setup: 'class TodoList { items: string[] = ["Buy milk", "Walk dog"]; }', + setupCode: 'class TodoList { items: string[] = ["Buy milk", "Walk dog"]; }', + expected: 2, + sample: 'new TodoList().items.length', + hints: [ + 'Array properties work like regular arrays', + 'Access length property of the array', + ], + tags: ['class', 'array', 'property'], + }, + { + id: 'ts-class-016', + category: 'Classes', + difficulty: 'easy', + title: 'Readonly Constructor Parameter', + text: 'Use readonly parameter property', + setup: 'class ImmutablePoint { constructor(public readonly x: number, public readonly y: number) {} }', + setupCode: 'class ImmutablePoint { constructor(public readonly x: number, public readonly y: number) {} }', + expected: 10, + sample: 'new ImmutablePoint(10, 20).x', + hints: [ + 'readonly with public creates immutable public properties', + 'Values cannot be changed after construction', + ], + tags: ['class', 'readonly', 'parameter-properties'], + }, + { + id: 'ts-class-017', + category: 'Classes', + difficulty: 'easy', + title: 'Method Chaining Setup', + text: 'Return this from a method to enable chaining', + setup: 'class Builder { value: number = 0; add(n: number): this { this.value += n; return this; } }', + setupCode: 'class Builder { value: number = 0; add(n: number): this { this.value += n; return this; } }', + expected: 15, + sample: 'new Builder().add(5).add(10).value', + hints: [ + 'Returning this enables method chaining', + 'Each call returns the same instance', + ], + tags: ['class', 'method-chaining', 'this'], + }, + { + id: 'ts-class-018', + category: 'Classes', + difficulty: 'easy', + title: 'String Method in Class', + text: 'Implement a toString method for a class', + setup: 'class Point { constructor(public x: number, public y: number) {} toString(): string { return `(${this.x}, ${this.y})`; } }', + setupCode: 'class Point { constructor(public x: number, public y: number) {} toString(): string { return `(${this.x}, ${this.y})`; } }', + expected: '(3, 4)', + sample: 'new Point(3, 4).toString()', + hints: [ + 'toString provides string representation', + 'Use template literals for formatting', + ], + tags: ['class', 'toString', 'method'], + }, + { + id: 'ts-class-019', + category: 'Classes', + difficulty: 'easy', + title: 'Protected Visibility in Subclass', + text: 'Access a protected property from within a subclass method', + setup: 'class Base { protected secret: string = "hidden"; }\nclass Derived extends Base { reveal(): string { return this.secret; } }', + setupCode: 'class Base { protected secret: string = "hidden"; }\nclass Derived extends Base { reveal(): string { return this.secret; } }', + expected: 'hidden', + sample: 'new Derived().reveal()', + hints: [ + 'Protected members are accessible in subclasses', + 'Use a public method to expose the value', + ], + tags: ['class', 'protected', 'inheritance'], + }, + { + id: 'ts-class-020', + category: 'Classes', + difficulty: 'easy', + title: 'Static Counter', + text: 'Use a static property to count instances', + setup: 'class Entity { static count: number = 0; constructor() { Entity.count++; } }', + setupCode: 'class Entity { static count: number = 0; constructor() { Entity.count++; } }', + expected: 3, + sample: 'new Entity(); new Entity(); new Entity(); Entity.count', + hints: [ + 'Static properties are shared across all instances', + 'Increment in constructor to count instances', + ], + tags: ['class', 'static', 'counter'], + }, + { + id: 'ts-class-021', + category: 'Classes', + difficulty: 'easy', + title: 'Optional Property', + text: 'Handle optional properties in a class', + setup: 'class Profile { constructor(public name: string, public bio?: string) {} }', + setupCode: 'class Profile { constructor(public name: string, public bio?: string) {} }', + expected: undefined, + sample: 'new Profile("Alice").bio', + hints: [ + 'Optional properties use ? in parameter', + 'They default to undefined if not provided', + ], + tags: ['class', 'optional', 'parameter-properties'], + }, + { + id: 'ts-class-022', + category: 'Classes', + difficulty: 'easy', + title: 'Default Parameter in Constructor', + text: 'Use default parameter values in constructor', + setup: 'class Greeting { constructor(public message: string = "Hello") {} }', + setupCode: 'class Greeting { constructor(public message: string = "Hello") {} }', + expected: 'Hello', + sample: 'new Greeting().message', + hints: [ + 'Default values are used when argument is omitted', + 'Parameter properties can have defaults', + ], + tags: ['class', 'default-parameter', 'constructor'], + }, + { + id: 'ts-class-023', + category: 'Classes', + difficulty: 'easy', + title: 'Class Expression', + text: 'Use a class expression to create a class', + setup: 'const MyClass = class { value: number = 42; };', + setupCode: 'const MyClass = class { value: number = 42; };', + expected: 42, + sample: 'new MyClass().value', + hints: [ + 'Classes can be defined as expressions', + 'Assign to a variable and use like a regular class', + ], + tags: ['class', 'class-expression', 'basics'], + }, + { + id: 'ts-class-024', + category: 'Classes', + difficulty: 'easy', + title: 'Getter Only Property', + text: 'Create a read-only computed property using only a getter', + setup: 'class Circle { constructor(public radius: number) {} get diameter(): number { return this.radius * 2; } }', + setupCode: 'class Circle { constructor(public radius: number) {} get diameter(): number { return this.radius * 2; } }', + expected: 20, + sample: 'new Circle(10).diameter', + hints: [ + 'Getter without setter is read-only', + 'Computed from other properties', + ], + tags: ['class', 'getter', 'readonly'], + }, + { + id: 'ts-class-025', + category: 'Classes', + difficulty: 'easy', + title: 'Method with Multiple Parameters', + text: 'Call a method with multiple typed parameters', + setup: 'class StringUtils { concat(a: string, b: string, separator: string): string { return a + separator + b; } }', + setupCode: 'class StringUtils { concat(a: string, b: string, separator: string): string { return a + separator + b; } }', + expected: 'Hello-World', + sample: 'new StringUtils().concat("Hello", "World", "-")', + hints: [ + 'Methods can have multiple parameters', + 'Each parameter has its own type', + ], + tags: ['class', 'method', 'parameters'], + }, + { + id: 'ts-class-026', + category: 'Classes', + difficulty: 'easy', + title: 'Boolean Property', + text: 'Use boolean property for state', + setup: 'class Toggle { isActive: boolean = false; activate(): void { this.isActive = true; } }', + setupCode: 'class Toggle { isActive: boolean = false; activate(): void { this.isActive = true; } }', + expected: true, + sample: 'const t = new Toggle(); t.activate(); t.isActive', + hints: [ + 'Boolean properties for state management', + 'Methods can modify instance state', + ], + tags: ['class', 'boolean', 'state'], + }, + { + id: 'ts-class-027', + category: 'Classes', + difficulty: 'easy', + title: 'Private Property with Getter', + text: 'Expose a private property through a getter', + setup: 'class BankAccount { private _balance: number = 100; get balance(): number { return this._balance; } }', + setupCode: 'class BankAccount { private _balance: number = 100; get balance(): number { return this._balance; } }', + expected: 100, + sample: 'new BankAccount().balance', + hints: [ + 'Private properties are prefixed with underscore by convention', + 'Getters provide controlled access', + ], + tags: ['class', 'private', 'getter'], + }, + { + id: 'ts-class-028', + category: 'Classes', + difficulty: 'easy', + title: 'Calling Super Constructor', + text: 'Call parent constructor from subclass', + setup: 'class Animal { constructor(public name: string) {} }\nclass Cat extends Animal { constructor(name: string, public color: string) { super(name); } }', + setupCode: 'class Animal { constructor(public name: string) {} }\nclass Cat extends Animal { constructor(name: string, public color: string) { super(name); } }', + expected: 'Whiskers', + sample: 'new Cat("Whiskers", "orange").name', + hints: [ + 'super() calls the parent constructor', + 'Must be called before accessing this', + ], + tags: ['class', 'super', 'inheritance'], + }, + { + id: 'ts-class-029', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Setter with Validation', + text: 'Use a setter to validate and set a value', + setup: 'class Temperature { private _celsius: number = 0; get celsius(): number { return this._celsius; } set celsius(value: number) { if (value >= -273.15) this._celsius = value; } }', + setupCode: 'class Temperature { private _celsius: number = 0; get celsius(): number { return this._celsius; } set celsius(value: number) { if (value >= -273.15) this._celsius = value; } }', + expected: 25, + sample: 'const t = new Temperature(); t.celsius = 25; t.celsius', + hints: [ + 'Setters can include validation logic', + 'Invalid values are rejected silently here', + ], + tags: ['class', 'setter', 'validation'], + }, + { + id: 'ts-class-030', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Method Overriding', + text: 'Override a parent method in a subclass', + setup: 'class Shape { getType(): string { return "Shape"; } }\nclass Circle extends Shape { getType(): string { return "Circle"; } }', + setupCode: 'class Shape { getType(): string { return "Shape"; } }\nclass Circle extends Shape { getType(): string { return "Circle"; } }', + expected: 'Circle', + sample: 'new Circle().getType()', + hints: [ + 'Subclass methods override parent methods', + 'Same method signature replaces parent implementation', + ], + tags: ['class', 'override', 'inheritance'], + }, + { + id: 'ts-class-031', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Calling Super Method', + text: 'Call parent method from overridden method', + setup: 'class Logger { log(msg: string): string { return `[LOG] ${msg}`; } }\nclass TimestampLogger extends Logger { log(msg: string): string { return `[${Date.now()}] ${super.log(msg)}`; } }', + setupCode: 'class Logger { log(msg: string): string { return `[LOG] ${msg}`; } }\nclass TimestampLogger extends Logger { log(msg: string): string { return `[${Date.now()}] ${super.log(msg)}`; } }', + expected: true, + sample: 'new TimestampLogger().log("test").includes("[LOG] test")', + hints: [ + 'super.method() calls the parent implementation', + 'Useful for extending functionality', + ], + tags: ['class', 'super', 'override'], + }, + { + id: 'ts-class-032', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Implement Interface', + text: 'Create a class that implements an interface', + setup: 'interface Printable { print(): string; }\nclass Document implements Printable { constructor(public content: string) {} print(): string { return this.content; } }', + setupCode: 'interface Printable { print(): string; }\nclass Document implements Printable { constructor(public content: string) {} print(): string { return this.content; } }', + expected: 'Hello Document', + sample: 'new Document("Hello Document").print()', + hints: [ + 'implements keyword enforces interface contract', + 'Class must provide all interface members', + ], + tags: ['class', 'interface', 'implements'], + }, + { + id: 'ts-class-033', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Multiple Interface Implementation', + text: 'Implement multiple interfaces in one class', + setup: 'interface Readable { read(): string; }\ninterface Writable { write(data: string): void; }\nclass File implements Readable, Writable { private data: string = ""; read(): string { return this.data; } write(data: string): void { this.data = data; } }', + setupCode: 'interface Readable { read(): string; }\ninterface Writable { write(data: string): void; }\nclass File implements Readable, Writable { private data: string = ""; read(): string { return this.data; } write(data: string): void { this.data = data; } }', + expected: 'Hello', + sample: 'const f = new File(); f.write("Hello"); f.read()', + hints: [ + 'Separate multiple interfaces with commas', + 'Must implement all methods from all interfaces', + ], + tags: ['class', 'interface', 'multiple-implements'], + }, + { + id: 'ts-class-034', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Abstract Class', + text: 'Create a concrete class from an abstract class', + setup: 'abstract class Animal { abstract makeSound(): string; move(): string { return "Moving"; } }\nclass Dog extends Animal { makeSound(): string { return "Woof!"; } }', + setupCode: 'abstract class Animal { abstract makeSound(): string; move(): string { return "Moving"; } }\nclass Dog extends Animal { makeSound(): string { return "Woof!"; } }', + expected: 'Woof!', + sample: 'new Dog().makeSound()', + hints: [ + 'Abstract classes cannot be instantiated directly', + 'Concrete subclasses must implement abstract methods', + ], + tags: ['class', 'abstract', 'inheritance'], + }, + { + id: 'ts-class-035', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Abstract Method with Concrete Method', + text: 'Use both abstract and concrete methods', + setup: 'abstract class Formatter { abstract format(data: string): string; wrap(data: string): string { return `[${this.format(data)}]`; } }\nclass UpperFormatter extends Formatter { format(data: string): string { return data.toUpperCase(); } }', + setupCode: 'abstract class Formatter { abstract format(data: string): string; wrap(data: string): string { return `[${this.format(data)}]`; } }\nclass UpperFormatter extends Formatter { format(data: string): string { return data.toUpperCase(); } }', + expected: '[HELLO]', + sample: 'new UpperFormatter().wrap("hello")', + hints: [ + 'Concrete methods can call abstract methods', + 'The subclass provides the abstract implementation', + ], + tags: ['class', 'abstract', 'template-method'], + }, + { + id: 'ts-class-036', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Private Constructor - Factory Pattern', + text: 'Use private constructor with static factory method', + setup: 'class Singleton { private static instance: Singleton | null = null; private constructor(public value: number) {} static create(value: number): Singleton { if (!Singleton.instance) { Singleton.instance = new Singleton(value); } return Singleton.instance; } }', + setupCode: 'class Singleton { private static instance: Singleton | null = null; private constructor(public value: number) {} static create(value: number): Singleton { if (!Singleton.instance) { Singleton.instance = new Singleton(value); } return Singleton.instance; } }', + expected: 42, + sample: 'Singleton.create(42).value', + hints: [ + 'Private constructor prevents direct instantiation', + 'Static method controls instance creation', + ], + tags: ['class', 'private-constructor', 'singleton', 'factory'], + }, + { + id: 'ts-class-037', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Getter/Setter Pair', + text: 'Use matched getter and setter for a property', + setup: 'class Person { private _age: number = 0; get age(): number { return this._age; } set age(value: number) { this._age = Math.max(0, value); } }', + setupCode: 'class Person { private _age: number = 0; get age(): number { return this._age; } set age(value: number) { this._age = Math.max(0, value); } }', + expected: 0, + sample: 'const p = new Person(); p.age = -5; p.age', + hints: [ + 'Setter validates and normalizes input', + 'Negative age becomes 0', + ], + tags: ['class', 'getter', 'setter', 'validation'], + }, + { + id: 'ts-class-038', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Static Factory Method', + text: 'Create instances using a static factory method', + setup: 'class Point { private constructor(public x: number, public y: number) {} static origin(): Point { return new Point(0, 0); } static fromCoords(x: number, y: number): Point { return new Point(x, y); } }', + setupCode: 'class Point { private constructor(public x: number, public y: number) {} static origin(): Point { return new Point(0, 0); } static fromCoords(x: number, y: number): Point { return new Point(x, y); } }', + expected: 0, + sample: 'Point.origin().x', + hints: [ + 'Factory methods provide named constructors', + 'Static methods can call private constructor', + ], + tags: ['class', 'static', 'factory-method'], + }, + { + id: 'ts-class-039', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Protected Method', + text: 'Use protected method in inheritance chain', + setup: 'class Base { protected helper(): number { return 10; } }\nclass Derived extends Base { compute(): number { return this.helper() * 2; } }', + setupCode: 'class Base { protected helper(): number { return 10; } }\nclass Derived extends Base { compute(): number { return this.helper() * 2; } }', + expected: 20, + sample: 'new Derived().compute()', + hints: [ + 'Protected methods are accessible in subclasses', + 'Not accessible from outside the class hierarchy', + ], + tags: ['class', 'protected', 'inheritance'], + }, + { + id: 'ts-class-040', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Generic Class', + text: 'Create and use a generic class', + setup: 'class Box { constructor(public value: T) {} getValue(): T { return this.value; } }', + setupCode: 'class Box { constructor(public value: T) {} getValue(): T { return this.value; } }', + expected: 'Hello', + sample: 'new Box("Hello").getValue()', + hints: [ + 'Generic classes work with any type', + 'Type parameter preserves type safety', + ], + tags: ['class', 'generics', 'type-parameter'], + }, + { + id: 'ts-class-041', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Generic Class with Constraint', + text: 'Use a constrained generic type in a class', + setup: 'interface HasLength { length: number; }\nclass Measurable { constructor(public item: T) {} getLength(): number { return this.item.length; } }', + setupCode: 'interface HasLength { length: number; }\nclass Measurable { constructor(public item: T) {} getLength(): number { return this.item.length; } }', + expected: 5, + sample: 'new Measurable("Hello").getLength()', + hints: [ + 'extends constraint limits acceptable types', + 'Type must have required properties', + ], + tags: ['class', 'generics', 'constraint'], + }, + { + id: 'ts-class-042', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Class with Index Signature', + text: 'Use index signature for dynamic properties', + setup: 'class Dictionary { [key: string]: string | undefined; set(key: string, value: string): void { this[key] = value; } }', + setupCode: 'class Dictionary { [key: string]: string | undefined; set(key: string, value: string): void { this[key] = value; } }', + expected: 'bar', + sample: 'const d = new Dictionary(); d.set("foo", "bar"); d["foo"]', + hints: [ + 'Index signatures allow dynamic property access', + 'Type includes undefined for safety', + ], + tags: ['class', 'index-signature', 'dynamic'], + }, + { + id: 'ts-class-043', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Static Block Initialization', + text: 'Use static block for complex initialization', + setup: 'class Config { static values: number[]; static { Config.values = [1, 2, 3].map(x => x * 10); } }', + setupCode: 'class Config { static values: number[]; static { Config.values = [1, 2, 3].map(x => x * 10); } }', + expected: 30, + sample: 'Config.values[2]', + hints: [ + 'Static blocks run once when class is loaded', + 'Useful for complex static initialization', + ], + tags: ['class', 'static', 'static-block'], + }, + { + id: 'ts-class-044', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Polymorphic this Type', + text: 'Use this type for method chaining in inheritance', + setup: 'class Builder { protected value: number = 0; setValue(n: number): this { this.value = n; return this; } }\nclass AdvancedBuilder extends Builder { double(): this { this.value *= 2; return this; } getResult(): number { return this.value; } }', + setupCode: 'class Builder { protected value: number = 0; setValue(n: number): this { this.value = n; return this; } }\nclass AdvancedBuilder extends Builder { double(): this { this.value *= 2; return this; } getResult(): number { return this.value; } }', + expected: 20, + sample: 'new AdvancedBuilder().setValue(10).double().getResult()', + hints: [ + 'this return type preserves subclass type', + 'Enables fluent chaining in inheritance', + ], + tags: ['class', 'this-type', 'method-chaining'], + }, + { + id: 'ts-class-045', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Interface Extending Class', + text: 'Create an interface that extends a class', + setup: 'class Point { x: number = 0; y: number = 0; }\ninterface Point3D extends Point { z: number; }\nconst p: Point3D = { x: 1, y: 2, z: 3 };', + setupCode: 'class Point { x: number = 0; y: number = 0; }\ninterface Point3D extends Point { z: number; }\nconst p: Point3D = { x: 1, y: 2, z: 3 };', + expected: 3, + sample: 'p.z', + hints: [ + 'Interfaces can extend classes', + 'Inherits class structure without implementation', + ], + tags: ['interface', 'class', 'extends'], + }, + { + id: 'ts-class-046', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Constructor Overloads', + text: 'Use constructor overloads for different initialization patterns', + setup: 'class Point { x: number; y: number; constructor(x: number, y: number);\nconstructor(coords: {x: number, y: number});\nconstructor(xOrCoords: number | {x: number, y: number}, y?: number) { if (typeof xOrCoords === "number") { this.x = xOrCoords; this.y = y!; } else { this.x = xOrCoords.x; this.y = xOrCoords.y; } } }', + setupCode: 'class Point { x: number; y: number; constructor(x: number, y: number);\nconstructor(coords: {x: number, y: number});\nconstructor(xOrCoords: number | {x: number, y: number}, y?: number) { if (typeof xOrCoords === "number") { this.x = xOrCoords; this.y = y!; } else { this.x = xOrCoords.x; this.y = xOrCoords.y; } } }', + expected: 5, + sample: 'new Point({x: 5, y: 10}).x', + hints: [ + 'Overloads provide multiple signatures', + 'Implementation handles all cases', + ], + tags: ['class', 'constructor', 'overloads'], + }, + { + id: 'ts-class-047', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Method Overloads', + text: 'Use method overloads for type-safe polymorphism', + setup: 'class Converter { convert(value: string): number;\nconvert(value: number): string;\nconvert(value: string | number): string | number { return typeof value === "string" ? parseInt(value) : value.toString(); } }', + setupCode: 'class Converter { convert(value: string): number;\nconvert(value: number): string;\nconvert(value: string | number): string | number { return typeof value === "string" ? parseInt(value) : value.toString(); } }', + expected: 42, + sample: 'new Converter().convert("42")', + hints: [ + 'Overloads define input/output type relationships', + 'Return type depends on input type', + ], + tags: ['class', 'method', 'overloads'], + }, + { + id: 'ts-class-048', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Composition over Inheritance', + text: 'Use composition to combine behaviors', + setup: 'class Engine { start(): string { return "Engine started"; } }\nclass Wheels { roll(): string { return "Wheels rolling"; } }\nclass Car { private engine = new Engine(); private wheels = new Wheels(); drive(): string { return `${this.engine.start()}, ${this.wheels.roll()}`; } }', + setupCode: 'class Engine { start(): string { return "Engine started"; } }\nclass Wheels { roll(): string { return "Wheels rolling"; } }\nclass Car { private engine = new Engine(); private wheels = new Wheels(); drive(): string { return `${this.engine.start()}, ${this.wheels.roll()}`; } }', + expected: 'Engine started, Wheels rolling', + sample: 'new Car().drive()', + hints: [ + 'Composition includes instances of other classes', + 'Delegate to composed objects', + ], + tags: ['class', 'composition', 'design-pattern'], + }, + { + id: 'ts-class-049', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Dependency Injection', + text: 'Inject dependencies through constructor', + setup: 'interface Logger { log(msg: string): string; }\nclass ConsoleLogger implements Logger { log(msg: string): string { return `Console: ${msg}`; } }\nclass Service { constructor(private logger: Logger) {} doWork(): string { return this.logger.log("Working"); } }', + setupCode: 'interface Logger { log(msg: string): string; }\nclass ConsoleLogger implements Logger { log(msg: string): string { return `Console: ${msg}`; } }\nclass Service { constructor(private logger: Logger) {} doWork(): string { return this.logger.log("Working"); } }', + expected: 'Console: Working', + sample: 'new Service(new ConsoleLogger()).doWork()', + hints: [ + 'Dependencies are passed to constructor', + 'Allows swapping implementations', + ], + tags: ['class', 'dependency-injection', 'interface'], + }, + { + id: 'ts-class-050', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Private Class Fields (ES2022)', + text: 'Use true private fields with # syntax', + setup: 'class Secret { #password: string = "secret123"; checkPassword(input: string): boolean { return input === this.#password; } }', + setupCode: 'class Secret { #password: string = "secret123"; checkPassword(input: string): boolean { return input === this.#password; } }', + expected: true, + sample: 'new Secret().checkPassword("secret123")', + hints: [ + '# prefix creates truly private fields', + 'Not accessible outside the class at all', + ], + tags: ['class', 'private-fields', 'es2022'], + }, + { + id: 'ts-class-051', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Static Private Field', + text: 'Use private static field for class-level secrets', + setup: 'class APIClient { static #apiKey: string = "key123"; static getKeyLength(): number { return APIClient.#apiKey.length; } }', + setupCode: 'class APIClient { static #apiKey: string = "key123"; static getKeyLength(): number { return APIClient.#apiKey.length; } }', + expected: 6, + sample: 'APIClient.getKeyLength()', + hints: [ + 'Static # fields are private to the class', + 'Combine static and private for class secrets', + ], + tags: ['class', 'static', 'private-fields'], + }, + { + id: 'ts-class-052', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Abstract Property', + text: 'Define abstract property in abstract class', + setup: 'abstract class Shape { abstract readonly name: string; describe(): string { return `This is a ${this.name}`; } }\nclass Square extends Shape { readonly name = "Square"; }', + setupCode: 'abstract class Shape { abstract readonly name: string; describe(): string { return `This is a ${this.name}`; } }\nclass Square extends Shape { readonly name = "Square"; }', + expected: 'This is a Square', + sample: 'new Square().describe()', + hints: [ + 'Abstract properties must be implemented', + 'Concrete class provides the value', + ], + tags: ['class', 'abstract', 'property'], + }, + { + id: 'ts-class-053', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Mixin Pattern', + text: 'Apply mixin to extend class functionality', + setup: 'type Constructor = new (...args: any[]) => T;\nfunction Timestamped(Base: TBase) { return class extends Base { timestamp = Date.now(); }; }\nclass User { constructor(public name: string) {} }\nconst TimestampedUser = Timestamped(User);', + setupCode: 'type Constructor = new (...args: any[]) => T;\nfunction Timestamped(Base: TBase) { return class extends Base { timestamp = Date.now(); }; }\nclass User { constructor(public name: string) {} }\nconst TimestampedUser = Timestamped(User);', + expected: true, + sample: 'typeof new TimestampedUser("Alice").timestamp === "number"', + hints: [ + 'Mixins are functions that extend classes', + 'Return a new class with added functionality', + ], + tags: ['class', 'mixin', 'composition'], + }, + { + id: 'ts-class-054', + category: 'OOP Patterns', + difficulty: 'medium', + title: 'Class Implementing Multiple Behaviors', + text: 'Implement interface with methods and properties', + setup: 'interface Identifiable { id: string; }\ninterface Timestampable { createdAt: Date; }\nclass Entity implements Identifiable, Timestampable { id: string = "1"; createdAt: Date = new Date(); }', + setupCode: 'interface Identifiable { id: string; }\ninterface Timestampable { createdAt: Date; }\nclass Entity implements Identifiable, Timestampable { id: string = "1"; createdAt: Date = new Date(); }', + expected: '1', + sample: 'new Entity().id', + hints: [ + 'Multiple interfaces separate concerns', + 'Class implements all required members', + ], + tags: ['class', 'interface', 'composition'], + }, + { + id: 'ts-class-055', + category: 'Inheritance', + difficulty: 'medium', + title: 'Deep Inheritance Chain', + text: 'Access properties through inheritance chain', + setup: 'class A { a: number = 1; }\nclass B extends A { b: number = 2; }\nclass C extends B { c: number = 3; }', + setupCode: 'class A { a: number = 1; }\nclass B extends A { b: number = 2; }\nclass C extends B { c: number = 3; }', + expected: 6, + sample: 'const obj = new C(); obj.a + obj.b + obj.c', + hints: [ + 'Properties inherit through the chain', + 'Access any ancestor property', + ], + tags: ['class', 'inheritance', 'chain'], + }, + { + id: 'ts-class-056', + category: 'Inheritance', + difficulty: 'medium', + title: 'Override with Different Return Type', + text: 'Override method with covariant return type', + setup: 'class Animal { clone(): Animal { return new Animal(); } }\nclass Dog extends Animal { clone(): Dog { return new Dog(); } breed: string = "Labrador"; }', + setupCode: 'class Animal { clone(): Animal { return new Animal(); } }\nclass Dog extends Animal { clone(): Dog { return new Dog(); } breed: string = "Labrador"; }', + expected: 'Labrador', + sample: 'new Dog().clone().breed', + hints: [ + 'Subclass can return more specific type', + 'Covariant return types are allowed', + ], + tags: ['class', 'override', 'covariance'], + }, + { + id: 'ts-class-057', + category: 'Inheritance', + difficulty: 'medium', + title: 'Constructor Property Promotion in Subclass', + text: 'Combine parameter properties with super call', + setup: 'class Person { constructor(public name: string) {} }\nclass Employee extends Person { constructor(name: string, public department: string) { super(name); } }', + setupCode: 'class Person { constructor(public name: string) {} }\nclass Employee extends Person { constructor(name: string, public department: string) { super(name); } }', + expected: 'Engineering', + sample: 'new Employee("Alice", "Engineering").department', + hints: [ + 'Super must be called with parent params', + 'Subclass adds its own parameter properties', + ], + tags: ['class', 'inheritance', 'parameter-properties'], + }, + { + id: 'ts-class-058', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Decorator Class Method', + text: 'Create a method decorator that logs calls', + setup: 'function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) { const original = descriptor.value; descriptor.value = function(...args: any[]) { console.log(`Calling ${propertyKey}`); return original.apply(this, args); }; return descriptor; }\nclass Calculator { @log add(a: number, b: number): number { return a + b; } }', + setupCode: 'function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) { const original = descriptor.value; descriptor.value = function(...args: any[]) { console.log(`Calling ${propertyKey}`); return original.apply(this, args); }; return descriptor; }\nclass Calculator { @log add(a: number, b: number): number { return a + b; } }', + expected: 7, + sample: 'new Calculator().add(3, 4)', + hints: [ + 'Decorators wrap method behavior', + 'Original method is preserved and called', + ], + tags: ['class', 'decorator', 'method'], + }, + { + id: 'ts-class-059', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Class Decorator', + text: 'Create a class decorator that seals the class', + setup: 'function sealed(constructor: Function) { Object.seal(constructor); Object.seal(constructor.prototype); }\n@sealed\nclass Greeter { greeting: string = "Hello"; greet(): string { return this.greeting; } }', + setupCode: 'function sealed(constructor: Function) { Object.seal(constructor); Object.seal(constructor.prototype); }\n@sealed\nclass Greeter { greeting: string = "Hello"; greet(): string { return this.greeting; } }', + expected: true, + sample: 'Object.isSealed(Greeter)', + hints: [ + 'Class decorators receive the constructor', + 'Can modify class behavior', + ], + tags: ['class', 'decorator', 'sealed'], + }, + { + id: 'ts-class-060', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Property Decorator', + text: 'Create a property decorator for validation', + setup: 'function positive(target: any, propertyKey: string) { let value: number; Object.defineProperty(target, propertyKey, { get: () => value, set: (newValue: number) => { value = Math.max(0, newValue); }, enumerable: true, configurable: true }); }\nclass Product { @positive price: number = 0; }', + setupCode: 'function positive(target: any, propertyKey: string) { let value: number; Object.defineProperty(target, propertyKey, { get: () => value, set: (newValue: number) => { value = Math.max(0, newValue); }, enumerable: true, configurable: true }); }\nclass Product { @positive price: number = 0; }', + expected: 0, + sample: 'const p = new Product(); p.price = -10; p.price', + hints: [ + 'Property decorators can add getters/setters', + 'Intercept property access and modification', + ], + tags: ['class', 'decorator', 'property'], + }, + { + id: 'ts-class-061', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Decorator Factory', + text: 'Create a parameterized decorator factory', + setup: 'function range(min: number, max: number) { return function(target: any, propertyKey: string) { let value: number; Object.defineProperty(target, propertyKey, { get: () => value, set: (newValue: number) => { value = Math.min(max, Math.max(min, newValue)); }, enumerable: true, configurable: true }); }; }\nclass Slider { @range(0, 100) position: number = 50; }', + setupCode: 'function range(min: number, max: number) { return function(target: any, propertyKey: string) { let value: number; Object.defineProperty(target, propertyKey, { get: () => value, set: (newValue: number) => { value = Math.min(max, Math.max(min, newValue)); }, enumerable: true, configurable: true }); }; }\nclass Slider { @range(0, 100) position: number = 50; }', + expected: 100, + sample: 'const s = new Slider(); s.position = 150; s.position', + hints: [ + 'Factory returns the actual decorator', + 'Outer function receives parameters', + ], + tags: ['class', 'decorator', 'factory'], + }, + { + id: 'ts-class-062', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Multiple Mixins', + text: 'Apply multiple mixins to a class', + setup: 'type Constructor = new (...args: any[]) => T;\nfunction Tagged(Base: TBase) { return class extends Base { tag: string = "tagged"; }; }\nfunction Versioned(Base: TBase) { return class extends Base { version: number = 1; }; }\nclass Entity { id: number = 1; }\nconst TaggedVersionedEntity = Tagged(Versioned(Entity));', + setupCode: 'type Constructor = new (...args: any[]) => T;\nfunction Tagged(Base: TBase) { return class extends Base { tag: string = "tagged"; }; }\nfunction Versioned(Base: TBase) { return class extends Base { version: number = 1; }; }\nclass Entity { id: number = 1; }\nconst TaggedVersionedEntity = Tagged(Versioned(Entity));', + expected: 'tagged', + sample: 'new TaggedVersionedEntity().tag', + hints: [ + 'Mixins can be composed together', + 'Each adds its own properties', + ], + tags: ['class', 'mixin', 'composition'], + }, + { + id: 'ts-class-063', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Abstract Generic Class', + text: 'Create abstract class with generic type parameter', + setup: 'abstract class Repository { protected items: T[] = []; add(item: T): void { this.items.push(item); } abstract findById(id: number): T | undefined; }\nclass UserRepo extends Repository<{id: number, name: string}> { findById(id: number) { return this.items.find(u => u.id === id); } }', + setupCode: 'abstract class Repository { protected items: T[] = []; add(item: T): void { this.items.push(item); } abstract findById(id: number): T | undefined; }\nclass UserRepo extends Repository<{id: number, name: string}> { findById(id: number) { return this.items.find(u => u.id === id); } }', + expected: 'Alice', + sample: 'const repo = new UserRepo(); repo.add({id: 1, name: "Alice"}); repo.findById(1)?.name', + hints: [ + 'Abstract classes can have generics', + 'Subclass specifies concrete type', + ], + tags: ['class', 'abstract', 'generics'], + }, + { + id: 'ts-class-064', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Constrained Mixin', + text: 'Create mixin that requires specific base class structure', + setup: 'interface Nameable { name: string; }\ntype Constructor = new (...args: any[]) => T;\nfunction Greetable>(Base: TBase) { return class extends Base { greet(): string { return `Hello, ${this.name}!`; } }; }\nclass Person { constructor(public name: string) {} }\nconst GreetablePerson = Greetable(Person);', + setupCode: 'interface Nameable { name: string; }\ntype Constructor = new (...args: any[]) => T;\nfunction Greetable>(Base: TBase) { return class extends Base { greet(): string { return `Hello, ${this.name}!`; } }; }\nclass Person { constructor(public name: string) {} }\nconst GreetablePerson = Greetable(Person);', + expected: 'Hello, Alice!', + sample: 'new GreetablePerson("Alice").greet()', + hints: [ + 'Mixin constraint requires interface implementation', + 'Can access constrained properties', + ], + tags: ['class', 'mixin', 'constraint'], + }, + { + id: 'ts-class-065', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Proxy Pattern with Class', + text: 'Implement proxy pattern for lazy loading', + setup: 'interface Image { display(): string; }\nclass RealImage implements Image { constructor(private filename: string) {} display(): string { return `Displaying ${this.filename}`; } }\nclass ProxyImage implements Image { private realImage: RealImage | null = null; constructor(private filename: string) {} display(): string { if (!this.realImage) { this.realImage = new RealImage(this.filename); } return this.realImage.display(); } }', + setupCode: 'interface Image { display(): string; }\nclass RealImage implements Image { constructor(private filename: string) {} display(): string { return `Displaying ${this.filename}`; } }\nclass ProxyImage implements Image { private realImage: RealImage | null = null; constructor(private filename: string) {} display(): string { if (!this.realImage) { this.realImage = new RealImage(this.filename); } return this.realImage.display(); } }', + expected: 'Displaying photo.jpg', + sample: 'new ProxyImage("photo.jpg").display()', + hints: [ + 'Proxy creates real object on demand', + 'Same interface as real object', + ], + tags: ['class', 'proxy', 'design-pattern'], + }, + { + id: 'ts-class-066', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Observer Pattern', + text: 'Implement observer pattern with typed events', + setup: 'type Observer = (data: T) => void;\nclass Subject { private observers: Observer[] = []; subscribe(observer: Observer): void { this.observers.push(observer); } notify(data: T): void { this.observers.forEach(o => o(data)); } }\nconst subject = new Subject();\nlet result = "";\nsubject.subscribe(data => { result = data; });', + setupCode: 'type Observer = (data: T) => void;\nclass Subject { private observers: Observer[] = []; subscribe(observer: Observer): void { this.observers.push(observer); } notify(data: T): void { this.observers.forEach(o => o(data)); } }\nconst subject = new Subject();\nlet result = "";\nsubject.subscribe(data => { result = data; });', + expected: 'Hello', + sample: 'subject.notify("Hello"); result', + hints: [ + 'Observers are notified of changes', + 'Generic type for event data', + ], + tags: ['class', 'observer', 'design-pattern'], + }, + { + id: 'ts-class-067', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Strategy Pattern', + text: 'Implement strategy pattern for interchangeable algorithms', + setup: 'interface SortStrategy { sort(data: T[]): T[]; }\nclass BubbleSort implements SortStrategy { sort(data: T[]): T[] { return [...data].sort(); } }\nclass Sorter { constructor(private strategy: SortStrategy) {} setStrategy(strategy: SortStrategy): void { this.strategy = strategy; } sort(data: T[]): T[] { return this.strategy.sort(data); } }', + setupCode: 'interface SortStrategy { sort(data: T[]): T[]; }\nclass BubbleSort implements SortStrategy { sort(data: T[]): T[] { return [...data].sort(); } }\nclass Sorter { constructor(private strategy: SortStrategy) {} setStrategy(strategy: SortStrategy): void { this.strategy = strategy; } sort(data: T[]): T[] { return this.strategy.sort(data); } }', + expected: '1,2,3', + sample: 'new Sorter(new BubbleSort()).sort([3, 1, 2]).join(",")', + hints: [ + 'Strategy encapsulates algorithm', + 'Can swap strategies at runtime', + ], + tags: ['class', 'strategy', 'design-pattern'], + }, + { + id: 'ts-class-068', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Command Pattern', + text: 'Implement command pattern with undo support', + setup: 'interface Command { execute(): void; undo(): void; }\nclass Calculator { value: number = 0; }\nclass AddCommand implements Command { constructor(private calc: Calculator, private amount: number) {} execute(): void { this.calc.value += this.amount; } undo(): void { this.calc.value -= this.amount; } }', + setupCode: 'interface Command { execute(): void; undo(): void; }\nclass Calculator { value: number = 0; }\nclass AddCommand implements Command { constructor(private calc: Calculator, private amount: number) {} execute(): void { this.calc.value += this.amount; } undo(): void { this.calc.value -= this.amount; } }', + expected: 5, + sample: 'const calc = new Calculator(); const cmd = new AddCommand(calc, 10); cmd.execute(); cmd.undo(); cmd.execute(); calc.value -= 5; calc.value', + hints: [ + 'Commands encapsulate operations', + 'Undo reverses the operation', + ], + tags: ['class', 'command', 'design-pattern'], + }, + { + id: 'ts-class-069', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'State Pattern', + text: 'Implement state pattern for state machine', + setup: 'interface State { handle(context: Context): void; getName(): string; }\nclass Context { constructor(public state: State) {} request(): void { this.state.handle(this); } }\nclass StateA implements State { handle(context: Context): void { context.state = new StateB(); } getName(): string { return "A"; } }\nclass StateB implements State { handle(context: Context): void { context.state = new StateA(); } getName(): string { return "B"; } }', + setupCode: 'interface State { handle(context: Context): void; getName(): string; }\nclass Context { constructor(public state: State) {} request(): void { this.state.handle(this); } }\nclass StateA implements State { handle(context: Context): void { context.state = new StateB(); } getName(): string { return "A"; } }\nclass StateB implements State { handle(context: Context): void { context.state = new StateA(); } getName(): string { return "B"; } }', + expected: 'B', + sample: 'const ctx = new Context(new StateA()); ctx.request(); ctx.state.getName()', + hints: [ + 'State objects control transitions', + 'Context delegates to current state', + ], + tags: ['class', 'state', 'design-pattern'], + }, + { + id: 'ts-class-070', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Builder Pattern with Fluent Interface', + text: 'Implement builder pattern with method chaining', + setup: 'class QueryBuilder { private parts: string[] = []; select(columns: string): this { this.parts.push(`SELECT ${columns}`); return this; } from(table: string): this { this.parts.push(`FROM ${table}`); return this; } where(condition: string): this { this.parts.push(`WHERE ${condition}`); return this; } build(): string { return this.parts.join(" "); } }', + setupCode: 'class QueryBuilder { private parts: string[] = []; select(columns: string): this { this.parts.push(`SELECT ${columns}`); return this; } from(table: string): this { this.parts.push(`FROM ${table}`); return this; } where(condition: string): this { this.parts.push(`WHERE ${condition}`); return this; } build(): string { return this.parts.join(" "); } }', + expected: 'SELECT * FROM users WHERE id = 1', + sample: 'new QueryBuilder().select("*").from("users").where("id = 1").build()', + hints: [ + 'Each method returns this for chaining', + 'build() produces final result', + ], + tags: ['class', 'builder', 'fluent-interface'], + }, + { + id: 'ts-class-071', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Abstract Factory Pattern', + text: 'Implement abstract factory for creating related objects', + setup: 'interface Button { render(): string; }\ninterface Checkbox { check(): string; }\nabstract class UIFactory { abstract createButton(): Button; abstract createCheckbox(): Checkbox; }\nclass DarkButton implements Button { render(): string { return "Dark Button"; } }\nclass DarkCheckbox implements Checkbox { check(): string { return "Dark Checkbox"; } }\nclass DarkUIFactory extends UIFactory { createButton(): Button { return new DarkButton(); } createCheckbox(): Checkbox { return new DarkCheckbox(); } }', + setupCode: 'interface Button { render(): string; }\ninterface Checkbox { check(): string; }\nabstract class UIFactory { abstract createButton(): Button; abstract createCheckbox(): Checkbox; }\nclass DarkButton implements Button { render(): string { return "Dark Button"; } }\nclass DarkCheckbox implements Checkbox { check(): string { return "Dark Checkbox"; } }\nclass DarkUIFactory extends UIFactory { createButton(): Button { return new DarkButton(); } createCheckbox(): Checkbox { return new DarkCheckbox(); } }', + expected: 'Dark Button', + sample: 'new DarkUIFactory().createButton().render()', + hints: [ + 'Factory creates families of objects', + 'Concrete factories produce concrete products', + ], + tags: ['class', 'abstract-factory', 'design-pattern'], + }, + { + id: 'ts-class-072', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Template Method Pattern', + text: 'Implement template method with hook', + setup: 'abstract class DataProcessor { process(data: string): string { const cleaned = this.clean(data); const transformed = this.transform(cleaned); return this.format(transformed); } protected clean(data: string): string { return data.trim(); } protected abstract transform(data: string): string; protected format(data: string): string { return `[${data}]`; } }\nclass UpperProcessor extends DataProcessor { protected transform(data: string): string { return data.toUpperCase(); } }', + setupCode: 'abstract class DataProcessor { process(data: string): string { const cleaned = this.clean(data); const transformed = this.transform(cleaned); return this.format(transformed); } protected clean(data: string): string { return data.trim(); } protected abstract transform(data: string): string; protected format(data: string): string { return `[${data}]`; } }\nclass UpperProcessor extends DataProcessor { protected transform(data: string): string { return data.toUpperCase(); } }', + expected: '[HELLO]', + sample: 'new UpperProcessor().process(" hello ")', + hints: [ + 'Template method defines algorithm skeleton', + 'Subclasses implement abstract steps', + ], + tags: ['class', 'template-method', 'design-pattern'], + }, + { + id: 'ts-class-073', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Adapter Pattern', + text: 'Implement adapter to convert interfaces', + setup: 'interface NewLogger { log(level: string, message: string): string; }\nclass OldLogger { writeLog(message: string): string { return `LOG: ${message}`; } }\nclass LoggerAdapter implements NewLogger { constructor(private oldLogger: OldLogger) {} log(level: string, message: string): string { return this.oldLogger.writeLog(`[${level}] ${message}`); } }', + setupCode: 'interface NewLogger { log(level: string, message: string): string; }\nclass OldLogger { writeLog(message: string): string { return `LOG: ${message}`; } }\nclass LoggerAdapter implements NewLogger { constructor(private oldLogger: OldLogger) {} log(level: string, message: string): string { return this.oldLogger.writeLog(`[${level}] ${message}`); } }', + expected: 'LOG: [INFO] Hello', + sample: 'new LoggerAdapter(new OldLogger()).log("INFO", "Hello")', + hints: [ + 'Adapter wraps incompatible interface', + 'Translates calls to adaptee', + ], + tags: ['class', 'adapter', 'design-pattern'], + }, + { + id: 'ts-class-074', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Decorator Pattern (OOP)', + text: 'Implement decorator pattern for extending behavior', + setup: 'interface Coffee { cost(): number; description(): string; }\nclass SimpleCoffee implements Coffee { cost(): number { return 5; } description(): string { return "Coffee"; } }\nclass MilkDecorator implements Coffee { constructor(private coffee: Coffee) {} cost(): number { return this.coffee.cost() + 2; } description(): string { return this.coffee.description() + " + Milk"; } }', + setupCode: 'interface Coffee { cost(): number; description(): string; }\nclass SimpleCoffee implements Coffee { cost(): number { return 5; } description(): string { return "Coffee"; } }\nclass MilkDecorator implements Coffee { constructor(private coffee: Coffee) {} cost(): number { return this.coffee.cost() + 2; } description(): string { return this.coffee.description() + " + Milk"; } }', + expected: 7, + sample: 'new MilkDecorator(new SimpleCoffee()).cost()', + hints: [ + 'Decorator wraps and extends object', + 'Same interface as wrapped object', + ], + tags: ['class', 'decorator-pattern', 'design-pattern'], + }, + { + id: 'ts-class-075', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Composite Pattern', + text: 'Implement composite pattern for tree structures', + setup: 'interface Component { getSize(): number; }\nclass File implements Component { constructor(private size: number) {} getSize(): number { return this.size; } }\nclass Folder implements Component { private children: Component[] = []; add(component: Component): void { this.children.push(component); } getSize(): number { return this.children.reduce((sum, c) => sum + c.getSize(), 0); } }', + setupCode: 'interface Component { getSize(): number; }\nclass File implements Component { constructor(private size: number) {} getSize(): number { return this.size; } }\nclass Folder implements Component { private children: Component[] = []; add(component: Component): void { this.children.push(component); } getSize(): number { return this.children.reduce((sum, c) => sum + c.getSize(), 0); } }', + expected: 30, + sample: 'const folder = new Folder(); folder.add(new File(10)); folder.add(new File(20)); folder.getSize()', + hints: [ + 'Composite contains components', + 'Uniform interface for leaf and composite', + ], + tags: ['class', 'composite', 'design-pattern'], + }, + { + id: 'ts-class-076', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Facade Pattern', + text: 'Implement facade to simplify complex subsystem', + setup: 'class CPU { freeze(): string { return "CPU frozen"; } execute(): string { return "CPU executing"; } }\nclass Memory { load(): string { return "Memory loaded"; } }\nclass HardDrive { read(): string { return "HD reading"; } }\nclass ComputerFacade { private cpu = new CPU(); private memory = new Memory(); private hd = new HardDrive(); start(): string { return [this.cpu.freeze(), this.memory.load(), this.hd.read(), this.cpu.execute()].join(", "); } }', + setupCode: 'class CPU { freeze(): string { return "CPU frozen"; } execute(): string { return "CPU executing"; } }\nclass Memory { load(): string { return "Memory loaded"; } }\nclass HardDrive { read(): string { return "HD reading"; } }\nclass ComputerFacade { private cpu = new CPU(); private memory = new Memory(); private hd = new HardDrive(); start(): string { return [this.cpu.freeze(), this.memory.load(), this.hd.read(), this.cpu.execute()].join(", "); } }', + expected: 'CPU frozen, Memory loaded, HD reading, CPU executing', + sample: 'new ComputerFacade().start()', + hints: [ + 'Facade provides simple interface', + 'Hides subsystem complexity', + ], + tags: ['class', 'facade', 'design-pattern'], + }, + { + id: 'ts-class-077', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Flyweight Pattern', + text: 'Implement flyweight pattern for memory optimization', + setup: 'class TreeType { constructor(public name: string, public color: string) {} }\nclass TreeFactory { private static types: Map = new Map(); static getTreeType(name: string, color: string): TreeType { const key = `${name}_${color}`; if (!TreeFactory.types.has(key)) { TreeFactory.types.set(key, new TreeType(name, color)); } return TreeFactory.types.get(key)!; } static getTypeCount(): number { return TreeFactory.types.size; } }', + setupCode: 'class TreeType { constructor(public name: string, public color: string) {} }\nclass TreeFactory { private static types: Map = new Map(); static getTreeType(name: string, color: string): TreeType { const key = `${name}_${color}`; if (!TreeFactory.types.has(key)) { TreeFactory.types.set(key, new TreeType(name, color)); } return TreeFactory.types.get(key)!; } static getTypeCount(): number { return TreeFactory.types.size; } }', + expected: 2, + sample: 'TreeFactory.getTreeType("Oak", "Green"); TreeFactory.getTreeType("Oak", "Green"); TreeFactory.getTreeType("Pine", "Green"); TreeFactory.getTypeCount()', + hints: [ + 'Flyweight shares common state', + 'Factory ensures single instance per type', + ], + tags: ['class', 'flyweight', 'design-pattern'], + }, + { + id: 'ts-class-078', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Chain of Responsibility', + text: 'Implement chain of responsibility pattern', + setup: 'abstract class Handler { protected next: Handler | null = null; setNext(handler: Handler): Handler { this.next = handler; return handler; } handle(request: number): string { if (this.next) { return this.next.handle(request); } return "End of chain"; } }\nclass LowHandler extends Handler { handle(request: number): string { if (request < 10) { return "Low handled"; } return super.handle(request); } }\nclass HighHandler extends Handler { handle(request: number): string { if (request >= 10) { return "High handled"; } return super.handle(request); } }', + setupCode: 'abstract class Handler { protected next: Handler | null = null; setNext(handler: Handler): Handler { this.next = handler; return handler; } handle(request: number): string { if (this.next) { return this.next.handle(request); } return "End of chain"; } }\nclass LowHandler extends Handler { handle(request: number): string { if (request < 10) { return "Low handled"; } return super.handle(request); } }\nclass HighHandler extends Handler { handle(request: number): string { if (request >= 10) { return "High handled"; } return super.handle(request); } }', + expected: 'High handled', + sample: 'const low = new LowHandler(); low.setNext(new HighHandler()); low.handle(15)', + hints: [ + 'Handlers form a chain', + 'Each handler decides to process or pass', + ], + tags: ['class', 'chain-of-responsibility', 'design-pattern'], + }, + { + id: 'ts-class-079', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Memento Pattern', + text: 'Implement memento pattern for state snapshot', + setup: 'class Memento { constructor(public state: string) {} }\nclass Originator { state: string = ""; createMemento(): Memento { return new Memento(this.state); } restore(memento: Memento): void { this.state = memento.state; } }\nclass Caretaker { private mementos: Memento[] = []; constructor(private originator: Originator) {} backup(): void { this.mementos.push(this.originator.createMemento()); } undo(): void { const memento = this.mementos.pop(); if (memento) { this.originator.restore(memento); } } }', + setupCode: 'class Memento { constructor(public state: string) {} }\nclass Originator { state: string = ""; createMemento(): Memento { return new Memento(this.state); } restore(memento: Memento): void { this.state = memento.state; } }\nclass Caretaker { private mementos: Memento[] = []; constructor(private originator: Originator) {} backup(): void { this.mementos.push(this.originator.createMemento()); } undo(): void { const memento = this.mementos.pop(); if (memento) { this.originator.restore(memento); } } }', + expected: 'State1', + sample: 'const orig = new Originator(); const care = new Caretaker(orig); orig.state = "State1"; care.backup(); orig.state = "State2"; care.undo(); orig.state', + hints: [ + 'Memento captures state snapshot', + 'Caretaker manages history', + ], + tags: ['class', 'memento', 'design-pattern'], + }, + { + id: 'ts-class-080', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Visitor Pattern', + text: 'Implement visitor pattern for operation dispatch', + setup: 'interface Visitor { visitCircle(circle: Circle): number; visitSquare(square: Square): number; }\ninterface Shape { accept(visitor: Visitor): number; }\nclass Circle implements Shape { constructor(public radius: number) {} accept(visitor: Visitor): number { return visitor.visitCircle(this); } }\nclass Square implements Shape { constructor(public side: number) {} accept(visitor: Visitor): number { return visitor.visitSquare(this); } }\nclass AreaVisitor implements Visitor { visitCircle(circle: Circle): number { return Math.PI * circle.radius ** 2; } visitSquare(square: Square): number { return square.side ** 2; } }', + setupCode: 'interface Visitor { visitCircle(circle: Circle): number; visitSquare(square: Square): number; }\ninterface Shape { accept(visitor: Visitor): number; }\nclass Circle implements Shape { constructor(public radius: number) {} accept(visitor: Visitor): number { return visitor.visitCircle(this); } }\nclass Square implements Shape { constructor(public side: number) {} accept(visitor: Visitor): number { return visitor.visitSquare(this); } }\nclass AreaVisitor implements Visitor { visitCircle(circle: Circle): number { return Math.PI * circle.radius ** 2; } visitSquare(square: Square): number { return square.side ** 2; } }', + expected: 25, + sample: 'new Square(5).accept(new AreaVisitor())', + hints: [ + 'Visitor separates algorithm from structure', + 'Double dispatch via accept method', + ], + tags: ['class', 'visitor', 'design-pattern'], + }, + { + id: 'ts-class-081', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Mediator Pattern', + text: 'Implement mediator pattern for component communication', + setup: 'interface Mediator { notify(sender: Component, event: string): void; }\nclass Component { constructor(protected mediator: Mediator) {} }\nclass Button extends Component { click(): void { this.mediator.notify(this, "click"); } }\nclass TextBox extends Component { value: string = ""; setValue(val: string): void { this.value = val; } }\nclass DialogMediator implements Mediator { constructor(public button: Button, public textBox: TextBox) {} notify(sender: Component, event: string): void { if (sender === this.button && event === "click") { this.textBox.setValue("Clicked!"); } } }', + setupCode: 'interface Mediator { notify(sender: Component, event: string): void; }\nclass Component { constructor(protected mediator: Mediator) {} }\nclass Button extends Component { click(): void { this.mediator.notify(this, "click"); } }\nclass TextBox extends Component { value: string = ""; setValue(val: string): void { this.value = val; } }\nclass DialogMediator implements Mediator { constructor(public button: Button, public textBox: TextBox) {} notify(sender: Component, event: string): void { if (sender === this.button && event === "click") { this.textBox.setValue("Clicked!"); } } }', + expected: 'Clicked!', + sample: 'const mediator = {} as DialogMediator; const btn = new Button(mediator); const txt = new TextBox(mediator); const dialog = new DialogMediator(btn, txt); (btn as any).mediator = dialog; btn.click(); txt.value', + hints: [ + 'Mediator coordinates components', + 'Components communicate through mediator', + ], + tags: ['class', 'mediator', 'design-pattern'], + }, + { + id: 'ts-class-082', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Iterator Pattern', + text: 'Implement custom iterator for collection', + setup: 'class NumberCollection { private items: number[] = []; add(item: number): void { this.items.push(item); } [Symbol.iterator](): Iterator { let index = 0; const items = this.items; return { next(): IteratorResult { if (index < items.length) { return { value: items[index++], done: false }; } return { value: undefined, done: true }; } }; } }', + setupCode: 'class NumberCollection { private items: number[] = []; add(item: number): void { this.items.push(item); } [Symbol.iterator](): Iterator { let index = 0; const items = this.items; return { next(): IteratorResult { if (index < items.length) { return { value: items[index++], done: false }; } return { value: undefined, done: true }; } }; } }', + expected: 6, + sample: 'const col = new NumberCollection(); col.add(1); col.add(2); col.add(3); let sum = 0; for (const n of col) { sum += n; } sum', + hints: [ + 'Symbol.iterator enables for...of', + 'next() returns value and done status', + ], + tags: ['class', 'iterator', 'symbol'], + }, + { + id: 'ts-class-083', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Prototype Pattern', + text: 'Implement prototype pattern for cloning', + setup: 'interface Prototype { clone(): Prototype; }\nclass ConcretePrototype implements Prototype { constructor(public primitive: number, public component: { value: string }) {} clone(): ConcretePrototype { return new ConcretePrototype(this.primitive, { ...this.component }); } }', + setupCode: 'interface Prototype { clone(): Prototype; }\nclass ConcretePrototype implements Prototype { constructor(public primitive: number, public component: { value: string }) {} clone(): ConcretePrototype { return new ConcretePrototype(this.primitive, { ...this.component }); } }', + expected: 'test', + sample: 'const original = new ConcretePrototype(42, { value: "test" }); const cloned = original.clone(); cloned.component.value', + hints: [ + 'Clone creates a copy of the object', + 'Deep copy nested objects', + ], + tags: ['class', 'prototype', 'design-pattern'], + }, + { + id: 'ts-class-084', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Bridge Pattern', + text: 'Implement bridge pattern to separate abstraction from implementation', + setup: 'interface Renderer { renderCircle(radius: number): string; }\nclass VectorRenderer implements Renderer { renderCircle(radius: number): string { return `Vector circle r=${radius}`; } }\nclass RasterRenderer implements Renderer { renderCircle(radius: number): string { return `Raster circle r=${radius}`; } }\nclass Circle { constructor(private renderer: Renderer, public radius: number) {} draw(): string { return this.renderer.renderCircle(this.radius); } }', + setupCode: 'interface Renderer { renderCircle(radius: number): string; }\nclass VectorRenderer implements Renderer { renderCircle(radius: number): string { return `Vector circle r=${radius}`; } }\nclass RasterRenderer implements Renderer { renderCircle(radius: number): string { return `Raster circle r=${radius}`; } }\nclass Circle { constructor(private renderer: Renderer, public radius: number) {} draw(): string { return this.renderer.renderCircle(this.radius); } }', + expected: 'Vector circle r=5', + sample: 'new Circle(new VectorRenderer(), 5).draw()', + hints: [ + 'Bridge separates interface from implementation', + 'Can vary both independently', + ], + tags: ['class', 'bridge', 'design-pattern'], + }, + { + id: 'ts-class-085', + category: 'OOP Patterns', + difficulty: 'hard', + title: 'Null Object Pattern', + text: 'Implement null object pattern for safe defaults', + setup: 'interface Logger { log(message: string): string; }\nclass ConsoleLogger implements Logger { log(message: string): string { return `Logged: ${message}`; } }\nclass NullLogger implements Logger { log(message: string): string { return ""; } }\nclass Application { constructor(private logger: Logger = new NullLogger()) {} doWork(): string { const result = this.logger.log("Working"); return result || "Silent"; } }', + setupCode: 'interface Logger { log(message: string): string; }\nclass ConsoleLogger implements Logger { log(message: string): string { return `Logged: ${message}`; } }\nclass NullLogger implements Logger { log(message: string): string { return ""; } }\nclass Application { constructor(private logger: Logger = new NullLogger()) {} doWork(): string { const result = this.logger.log("Working"); return result || "Silent"; } }', + expected: 'Silent', + sample: 'new Application().doWork()', + hints: [ + 'Null object provides default behavior', + 'Avoids null checks throughout code', + ], + tags: ['class', 'null-object', 'design-pattern'], + }, ]; // Helper functions From 8c6ad31666e7048fac7aef91216e9dfa4c78cde0 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 25 Jan 2026 23:33:31 +0000 Subject: [PATCH 2/2] chore: update package-lock.json --- package-lock.json | 21043 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 21043 insertions(+) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..2ecacfc --- /dev/null +++ b/package-lock.json @@ -0,0 +1,21043 @@ +{ + "name": "nextjs", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "nextjs", + "version": "0.1.0", + "dependencies": { + "@ai-sdk/openai": "^3.0.18", + "@ai-sdk/react": "^3.0.51", + "@hookform/resolvers": "^5.2.2", + "@mlc-ai/web-llm": "^0.2.80", + "@monaco-editor/react": "^4.7.0", + "@openfeature/react-sdk": "^1.2.0", + "@openfeature/web-sdk": "^1.7.2", + "@tanstack/react-query": "^5.90.20", + "ai": "^6.0.49", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "dompurify": "^3.3.1", + "html-react-parser": "^5.2.12", + "isomorphic-dompurify": "^2.35.0", + "lucide-react": "^0.563.0", + "monaco-editor": "^0.55.1", + "motion": "^12.29.0", + "next": "16.1.4", + "nuqs": "^2.8.6", + "react": "19.2.3", + "react-dom": "19.2.3", + "react-hook-form": "^7.71.1", + "tailwind-merge": "^3.4.0", + "zod": "^4.3.6", + "zustand": "^5.0.10" + }, + "devDependencies": { + "@biomejs/biome": "^2.3.12", + "@chromatic-com/storybook": "^5.0.0", + "@playwright/test": "^1.58.0", + "@storybook/addon-a11y": "^10.2.0", + "@storybook/addon-docs": "^10.2.0", + "@storybook/addon-onboarding": "^10.2.0", + "@storybook/addon-vitest": "^10.2.0", + "@storybook/nextjs-vite": "^10.2.0", + "@tailwindcss/postcss": "^4", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.2", + "@testing-library/user-event": "^14.6.1", + "@types/dompurify": "^3.0.5", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "@vitest/browser-playwright": "^4.0.18", + "@vitest/coverage-v8": "^4.0.18", + "chromatic": "^13.3.5", + "eslint": "^9", + "eslint-config-next": "16.1.4", + "eslint-plugin-storybook": "^10.2.0", + "husky": "^9.1.7", + "lint-staged": "^16.2.7", + "playwright": "^1.58.0", + "renovate": "^37.440.7", + "storybook": "^10.2.0", + "tailwindcss": "^4", + "tsx": "^4.21.0", + "typescript": "^5", + "vite": "^7.3.1", + "vitest": "^4.0.18" + } + }, + "node_modules/@acemir/cssom": { + "version": "0.9.31", + "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz", + "integrity": "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==", + "license": "MIT" + }, + "node_modules/@adobe/css-tools": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", + "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@ai-sdk/gateway": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-3.0.22.tgz", + "integrity": "sha512-NgnlY73JNuooACHqUIz5uMOEWvqR1MMVbb2soGLMozLY1fgwEIF5iJFDAGa5/YArlzw2ATVU7zQu7HkR/FUjgA==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "3.0.5", + "@ai-sdk/provider-utils": "4.0.9", + "@vercel/oidc": "3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/@ai-sdk/openai": { + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/@ai-sdk/openai/-/openai-3.0.18.tgz", + "integrity": "sha512-uYscTyoaWij9FoPpKRNK8YgtDEuPpQlqREYylJCA8o5YQVQXghV0Dwgk1ehPVpg6USIO4L0C8GqQJ4AMm/Xb1g==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "3.0.5", + "@ai-sdk/provider-utils": "4.0.9" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/@ai-sdk/provider": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-3.0.5.tgz", + "integrity": "sha512-2Xmoq6DBJqmSl80U6V9z5jJSJP7ehaJJQMy2iFUqTay06wdCqTnPVBBQbtEL8RCChenL+q5DC5H5WzU3vV3v8w==", + "license": "Apache-2.0", + "dependencies": { + "json-schema": "^0.4.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ai-sdk/provider-utils": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-4.0.9.tgz", + "integrity": "sha512-bB4r6nfhBOpmoS9mePxjRoCy+LnzP3AfhyMGCkGL4Mn9clVNlqEeKj26zEKEtB6yoSVcT1IQ0Zh9fytwMCDnow==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "3.0.5", + "@standard-schema/spec": "^1.1.0", + "eventsource-parser": "^3.0.6" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/@ai-sdk/react": { + "version": "3.0.51", + "resolved": "https://registry.npmjs.org/@ai-sdk/react/-/react-3.0.51.tgz", + "integrity": "sha512-7nmCwEJM52NQZB4/ED8qJ4wbDg7EEWh94qJ7K9GSJxD6sWF3GOKrRZ5ivm4qNmKhY+JfCxCAxfghGY5mTKOsxw==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider-utils": "4.0.9", + "ai": "6.0.49", + "swr": "^2.2.5", + "throttleit": "2.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^18 || ~19.0.1 || ~19.1.2 || ^19.2.1" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@arcanis/slice-ansi": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@arcanis/slice-ansi/-/slice-ansi-1.1.1.tgz", + "integrity": "sha512-xguP2WR2Dv0gQ7Ykbdb7BNCnPnIPB94uTi0Z2NvkRBEnhbwjOQ7QyQKJXrVQg4qDpiD9hA5l5cCwy/z2OXgc3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "grapheme-splitter": "^1.0.4" + } + }, + "node_modules/@asamuzakjp/css-color": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.1.tgz", + "integrity": "sha512-B0Hv6G3gWGMn0xKJ0txEi/jM5iFpT3MfDxmhZFb4W047GvytCf1DHQ1D69W3zHI4yWe2aTZAA0JnbMZ7Xc8DuQ==", + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "lru-cache": "^11.2.4" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.7.6", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.7.6.tgz", + "integrity": "sha512-hBaJER6A9MpdG3WgdlOolHmbOYvSk46y7IQN/1+iqiCuUu6iWdQrs9DGKF8ocqsEqWujWf/V7b7vaDgiUmIvUg==", + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.4" + } + }, + "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "license": "MIT" + }, + "node_modules/@aws-crypto/crc32": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", + "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/crc32c": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz", + "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha1-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-5.2.0.tgz", + "integrity": "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-codecommit": { + "version": "3.606.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-codecommit/-/client-codecommit-3.606.0.tgz", + "integrity": "sha512-zttJ22j5kwGDL0yj4haXNjMMVT06gUm7mqzPzc8rK3N4MSEVds5Q42vF5LeYcBjZ4OhnZg7zmVHL0dCtdsa8dQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.606.0", + "@aws-sdk/client-sts": "3.606.0", + "@aws-sdk/core": "3.598.0", + "@aws-sdk/credential-provider-node": "3.600.0", + "@aws-sdk/middleware-host-header": "3.598.0", + "@aws-sdk/middleware-logger": "3.598.0", + "@aws-sdk/middleware-recursion-detection": "3.598.0", + "@aws-sdk/middleware-user-agent": "3.598.0", + "@aws-sdk/region-config-resolver": "3.598.0", + "@aws-sdk/types": "3.598.0", + "@aws-sdk/util-endpoints": "3.598.0", + "@aws-sdk/util-user-agent-browser": "3.598.0", + "@aws-sdk/util-user-agent-node": "3.598.0", + "@smithy/config-resolver": "^3.0.2", + "@smithy/core": "^2.2.1", + "@smithy/fetch-http-handler": "^3.0.2", + "@smithy/hash-node": "^3.0.1", + "@smithy/invalid-dependency": "^3.0.1", + "@smithy/middleware-content-length": "^3.0.1", + "@smithy/middleware-endpoint": "^3.0.2", + "@smithy/middleware-retry": "^3.0.4", + "@smithy/middleware-serde": "^3.0.1", + "@smithy/middleware-stack": "^3.0.1", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/node-http-handler": "^3.0.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "@smithy/url-parser": "^3.0.1", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.4", + "@smithy/util-defaults-mode-node": "^3.0.4", + "@smithy/util-endpoints": "^2.0.2", + "@smithy/util-middleware": "^3.0.1", + "@smithy/util-retry": "^3.0.1", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity": { + "version": "3.606.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.606.0.tgz", + "integrity": "sha512-CJ3kovUg7HAn3trqo0WxVw3PJoaHxiGU1U+Ok8Vx/sL81+auyyiasT09M/NcchRqwAooKvUi44sVD0ih7Zi9Nw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.606.0", + "@aws-sdk/client-sts": "3.606.0", + "@aws-sdk/core": "3.598.0", + "@aws-sdk/credential-provider-node": "3.600.0", + "@aws-sdk/middleware-host-header": "3.598.0", + "@aws-sdk/middleware-logger": "3.598.0", + "@aws-sdk/middleware-recursion-detection": "3.598.0", + "@aws-sdk/middleware-user-agent": "3.598.0", + "@aws-sdk/region-config-resolver": "3.598.0", + "@aws-sdk/types": "3.598.0", + "@aws-sdk/util-endpoints": "3.598.0", + "@aws-sdk/util-user-agent-browser": "3.598.0", + "@aws-sdk/util-user-agent-node": "3.598.0", + "@smithy/config-resolver": "^3.0.2", + "@smithy/core": "^2.2.1", + "@smithy/fetch-http-handler": "^3.0.2", + "@smithy/hash-node": "^3.0.1", + "@smithy/invalid-dependency": "^3.0.1", + "@smithy/middleware-content-length": "^3.0.1", + "@smithy/middleware-endpoint": "^3.0.2", + "@smithy/middleware-retry": "^3.0.4", + "@smithy/middleware-serde": "^3.0.1", + "@smithy/middleware-stack": "^3.0.1", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/node-http-handler": "^3.0.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "@smithy/url-parser": "^3.0.1", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.4", + "@smithy/util-defaults-mode-node": "^3.0.4", + "@smithy/util-endpoints": "^2.0.2", + "@smithy/util-middleware": "^3.0.1", + "@smithy/util-retry": "^3.0.1", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ec2": { + "version": "3.606.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ec2/-/client-ec2-3.606.0.tgz", + "integrity": "sha512-7CxvJNs3I2PQsyAWCBtRy7TjtdA+/Jf1BhIO1hlCKh7JvlcUY0XNpgpg7a3VWm7UTarh9J8SH6aDIMROS2vkXw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.606.0", + "@aws-sdk/client-sts": "3.606.0", + "@aws-sdk/core": "3.598.0", + "@aws-sdk/credential-provider-node": "3.600.0", + "@aws-sdk/middleware-host-header": "3.598.0", + "@aws-sdk/middleware-logger": "3.598.0", + "@aws-sdk/middleware-recursion-detection": "3.598.0", + "@aws-sdk/middleware-sdk-ec2": "3.598.0", + "@aws-sdk/middleware-user-agent": "3.598.0", + "@aws-sdk/region-config-resolver": "3.598.0", + "@aws-sdk/types": "3.598.0", + "@aws-sdk/util-endpoints": "3.598.0", + "@aws-sdk/util-user-agent-browser": "3.598.0", + "@aws-sdk/util-user-agent-node": "3.598.0", + "@smithy/config-resolver": "^3.0.2", + "@smithy/core": "^2.2.1", + "@smithy/fetch-http-handler": "^3.0.2", + "@smithy/hash-node": "^3.0.1", + "@smithy/invalid-dependency": "^3.0.1", + "@smithy/middleware-content-length": "^3.0.1", + "@smithy/middleware-endpoint": "^3.0.2", + "@smithy/middleware-retry": "^3.0.4", + "@smithy/middleware-serde": "^3.0.1", + "@smithy/middleware-stack": "^3.0.1", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/node-http-handler": "^3.0.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "@smithy/url-parser": "^3.0.1", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.4", + "@smithy/util-defaults-mode-node": "^3.0.4", + "@smithy/util-endpoints": "^2.0.2", + "@smithy/util-middleware": "^3.0.1", + "@smithy/util-retry": "^3.0.1", + "@smithy/util-utf8": "^3.0.0", + "@smithy/util-waiter": "^3.0.1", + "tslib": "^2.6.2", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-ecr": { + "version": "3.606.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ecr/-/client-ecr-3.606.0.tgz", + "integrity": "sha512-WwSeHXrCCYx48IxrwBnGl4t0+hYhka151R/8QyPTMINB2TcVBqbBsOGqV9wWJh3d0vK+hOhSJoOoQWN1XnkQYQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.606.0", + "@aws-sdk/client-sts": "3.606.0", + "@aws-sdk/core": "3.598.0", + "@aws-sdk/credential-provider-node": "3.600.0", + "@aws-sdk/middleware-host-header": "3.598.0", + "@aws-sdk/middleware-logger": "3.598.0", + "@aws-sdk/middleware-recursion-detection": "3.598.0", + "@aws-sdk/middleware-user-agent": "3.598.0", + "@aws-sdk/region-config-resolver": "3.598.0", + "@aws-sdk/types": "3.598.0", + "@aws-sdk/util-endpoints": "3.598.0", + "@aws-sdk/util-user-agent-browser": "3.598.0", + "@aws-sdk/util-user-agent-node": "3.598.0", + "@smithy/config-resolver": "^3.0.2", + "@smithy/core": "^2.2.1", + "@smithy/fetch-http-handler": "^3.0.2", + "@smithy/hash-node": "^3.0.1", + "@smithy/invalid-dependency": "^3.0.1", + "@smithy/middleware-content-length": "^3.0.1", + "@smithy/middleware-endpoint": "^3.0.2", + "@smithy/middleware-retry": "^3.0.4", + "@smithy/middleware-serde": "^3.0.1", + "@smithy/middleware-stack": "^3.0.1", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/node-http-handler": "^3.0.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "@smithy/url-parser": "^3.0.1", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.4", + "@smithy/util-defaults-mode-node": "^3.0.4", + "@smithy/util-endpoints": "^2.0.2", + "@smithy/util-middleware": "^3.0.1", + "@smithy/util-retry": "^3.0.1", + "@smithy/util-utf8": "^3.0.0", + "@smithy/util-waiter": "^3.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-rds": { + "version": "3.606.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-rds/-/client-rds-3.606.0.tgz", + "integrity": "sha512-cedTB6Tu/komKp+kxqcVZx3mtOci2bpAJfeOCNBLkeWMaAnwEvUYRvoO2A2wJrvaLkDwT1zo2Iyl3FaXk3KQjw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.606.0", + "@aws-sdk/client-sts": "3.606.0", + "@aws-sdk/core": "3.598.0", + "@aws-sdk/credential-provider-node": "3.600.0", + "@aws-sdk/middleware-host-header": "3.598.0", + "@aws-sdk/middleware-logger": "3.598.0", + "@aws-sdk/middleware-recursion-detection": "3.598.0", + "@aws-sdk/middleware-sdk-rds": "3.598.0", + "@aws-sdk/middleware-user-agent": "3.598.0", + "@aws-sdk/region-config-resolver": "3.598.0", + "@aws-sdk/types": "3.598.0", + "@aws-sdk/util-endpoints": "3.598.0", + "@aws-sdk/util-user-agent-browser": "3.598.0", + "@aws-sdk/util-user-agent-node": "3.598.0", + "@smithy/config-resolver": "^3.0.2", + "@smithy/core": "^2.2.1", + "@smithy/fetch-http-handler": "^3.0.2", + "@smithy/hash-node": "^3.0.1", + "@smithy/invalid-dependency": "^3.0.1", + "@smithy/middleware-content-length": "^3.0.1", + "@smithy/middleware-endpoint": "^3.0.2", + "@smithy/middleware-retry": "^3.0.4", + "@smithy/middleware-serde": "^3.0.1", + "@smithy/middleware-stack": "^3.0.1", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/node-http-handler": "^3.0.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "@smithy/url-parser": "^3.0.1", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.4", + "@smithy/util-defaults-mode-node": "^3.0.4", + "@smithy/util-endpoints": "^2.0.2", + "@smithy/util-middleware": "^3.0.1", + "@smithy/util-retry": "^3.0.1", + "@smithy/util-utf8": "^3.0.0", + "@smithy/util-waiter": "^3.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-s3": { + "version": "3.606.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.606.0.tgz", + "integrity": "sha512-IGM/E8kVk/NY/kZwLdmGRsX1QYtuPljoNutM5kBRdtGahQL5VwVAve5PElPUArcsTkfTyW+LfXpznDeeHxMCcA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha1-browser": "5.2.0", + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.606.0", + "@aws-sdk/client-sts": "3.606.0", + "@aws-sdk/core": "3.598.0", + "@aws-sdk/credential-provider-node": "3.600.0", + "@aws-sdk/middleware-bucket-endpoint": "3.598.0", + "@aws-sdk/middleware-expect-continue": "3.598.0", + "@aws-sdk/middleware-flexible-checksums": "3.598.0", + "@aws-sdk/middleware-host-header": "3.598.0", + "@aws-sdk/middleware-location-constraint": "3.598.0", + "@aws-sdk/middleware-logger": "3.598.0", + "@aws-sdk/middleware-recursion-detection": "3.598.0", + "@aws-sdk/middleware-sdk-s3": "3.598.0", + "@aws-sdk/middleware-signing": "3.598.0", + "@aws-sdk/middleware-ssec": "3.598.0", + "@aws-sdk/middleware-user-agent": "3.598.0", + "@aws-sdk/region-config-resolver": "3.598.0", + "@aws-sdk/signature-v4-multi-region": "3.598.0", + "@aws-sdk/types": "3.598.0", + "@aws-sdk/util-endpoints": "3.598.0", + "@aws-sdk/util-user-agent-browser": "3.598.0", + "@aws-sdk/util-user-agent-node": "3.598.0", + "@aws-sdk/xml-builder": "3.598.0", + "@smithy/config-resolver": "^3.0.2", + "@smithy/core": "^2.2.1", + "@smithy/eventstream-serde-browser": "^3.0.2", + "@smithy/eventstream-serde-config-resolver": "^3.0.1", + "@smithy/eventstream-serde-node": "^3.0.2", + "@smithy/fetch-http-handler": "^3.0.2", + "@smithy/hash-blob-browser": "^3.1.0", + "@smithy/hash-node": "^3.0.1", + "@smithy/hash-stream-node": "^3.1.0", + "@smithy/invalid-dependency": "^3.0.1", + "@smithy/md5-js": "^3.0.1", + "@smithy/middleware-content-length": "^3.0.1", + "@smithy/middleware-endpoint": "^3.0.2", + "@smithy/middleware-retry": "^3.0.4", + "@smithy/middleware-serde": "^3.0.1", + "@smithy/middleware-stack": "^3.0.1", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/node-http-handler": "^3.0.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "@smithy/url-parser": "^3.0.1", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.4", + "@smithy/util-defaults-mode-node": "^3.0.4", + "@smithy/util-endpoints": "^2.0.2", + "@smithy/util-retry": "^3.0.1", + "@smithy/util-stream": "^3.0.2", + "@smithy/util-utf8": "^3.0.0", + "@smithy/util-waiter": "^3.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sso": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.598.0.tgz", + "integrity": "sha512-nOI5lqPYa+YZlrrzwAJywJSw3MKVjvu6Ge2fCqQUNYMfxFB0NAaDFnl0EPjXi+sEbtCuz/uWE77poHbqiZ+7Iw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.598.0", + "@aws-sdk/middleware-host-header": "3.598.0", + "@aws-sdk/middleware-logger": "3.598.0", + "@aws-sdk/middleware-recursion-detection": "3.598.0", + "@aws-sdk/middleware-user-agent": "3.598.0", + "@aws-sdk/region-config-resolver": "3.598.0", + "@aws-sdk/types": "3.598.0", + "@aws-sdk/util-endpoints": "3.598.0", + "@aws-sdk/util-user-agent-browser": "3.598.0", + "@aws-sdk/util-user-agent-node": "3.598.0", + "@smithy/config-resolver": "^3.0.2", + "@smithy/core": "^2.2.1", + "@smithy/fetch-http-handler": "^3.0.2", + "@smithy/hash-node": "^3.0.1", + "@smithy/invalid-dependency": "^3.0.1", + "@smithy/middleware-content-length": "^3.0.1", + "@smithy/middleware-endpoint": "^3.0.2", + "@smithy/middleware-retry": "^3.0.4", + "@smithy/middleware-serde": "^3.0.1", + "@smithy/middleware-stack": "^3.0.1", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/node-http-handler": "^3.0.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "@smithy/url-parser": "^3.0.1", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.4", + "@smithy/util-defaults-mode-node": "^3.0.4", + "@smithy/util-endpoints": "^2.0.2", + "@smithy/util-middleware": "^3.0.1", + "@smithy/util-retry": "^3.0.1", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sso-oidc": { + "version": "3.606.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.606.0.tgz", + "integrity": "sha512-gL1FHPS6hwgMNS/A+Qh5bUyHOeRVOqdb7c6+i+9gR3wtGvt2lvoSm8w5DhS08Xiiacz2AqYRDEapp0xuyCrbBQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.598.0", + "@aws-sdk/credential-provider-node": "3.600.0", + "@aws-sdk/middleware-host-header": "3.598.0", + "@aws-sdk/middleware-logger": "3.598.0", + "@aws-sdk/middleware-recursion-detection": "3.598.0", + "@aws-sdk/middleware-user-agent": "3.598.0", + "@aws-sdk/region-config-resolver": "3.598.0", + "@aws-sdk/types": "3.598.0", + "@aws-sdk/util-endpoints": "3.598.0", + "@aws-sdk/util-user-agent-browser": "3.598.0", + "@aws-sdk/util-user-agent-node": "3.598.0", + "@smithy/config-resolver": "^3.0.2", + "@smithy/core": "^2.2.1", + "@smithy/fetch-http-handler": "^3.0.2", + "@smithy/hash-node": "^3.0.1", + "@smithy/invalid-dependency": "^3.0.1", + "@smithy/middleware-content-length": "^3.0.1", + "@smithy/middleware-endpoint": "^3.0.2", + "@smithy/middleware-retry": "^3.0.4", + "@smithy/middleware-serde": "^3.0.1", + "@smithy/middleware-stack": "^3.0.1", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/node-http-handler": "^3.0.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "@smithy/url-parser": "^3.0.1", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.4", + "@smithy/util-defaults-mode-node": "^3.0.4", + "@smithy/util-endpoints": "^2.0.2", + "@smithy/util-middleware": "^3.0.1", + "@smithy/util-retry": "^3.0.1", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.606.0" + } + }, + "node_modules/@aws-sdk/client-sts": { + "version": "3.606.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.606.0.tgz", + "integrity": "sha512-b11mAhjrkm3MMiAPoMGcmd6vsaz2120lg8rHG/NZCo9vB1K6Kc7WP+a1Q05TRMseer2egTtpWJfn44aVO97VqA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.606.0", + "@aws-sdk/core": "3.598.0", + "@aws-sdk/credential-provider-node": "3.600.0", + "@aws-sdk/middleware-host-header": "3.598.0", + "@aws-sdk/middleware-logger": "3.598.0", + "@aws-sdk/middleware-recursion-detection": "3.598.0", + "@aws-sdk/middleware-user-agent": "3.598.0", + "@aws-sdk/region-config-resolver": "3.598.0", + "@aws-sdk/types": "3.598.0", + "@aws-sdk/util-endpoints": "3.598.0", + "@aws-sdk/util-user-agent-browser": "3.598.0", + "@aws-sdk/util-user-agent-node": "3.598.0", + "@smithy/config-resolver": "^3.0.2", + "@smithy/core": "^2.2.1", + "@smithy/fetch-http-handler": "^3.0.2", + "@smithy/hash-node": "^3.0.1", + "@smithy/invalid-dependency": "^3.0.1", + "@smithy/middleware-content-length": "^3.0.1", + "@smithy/middleware-endpoint": "^3.0.2", + "@smithy/middleware-retry": "^3.0.4", + "@smithy/middleware-serde": "^3.0.1", + "@smithy/middleware-stack": "^3.0.1", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/node-http-handler": "^3.0.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "@smithy/url-parser": "^3.0.1", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.4", + "@smithy/util-defaults-mode-node": "^3.0.4", + "@smithy/util-endpoints": "^2.0.2", + "@smithy/util-middleware": "^3.0.1", + "@smithy/util-retry": "^3.0.1", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.598.0.tgz", + "integrity": "sha512-HaSjt7puO5Cc7cOlrXFCW0rtA0BM9lvzjl56x0A20Pt+0wxXGeTOZZOkXQIepbrFkV2e/HYukuT9e99vXDm59g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^2.2.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/signature-v4": "^3.1.0", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "fast-xml-parser": "4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-cognito-identity": { + "version": "3.606.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.606.0.tgz", + "integrity": "sha512-4wGvXilFLkozs4/dMnn9NvxZbL9oyyReoF9aR3kGUZ0QVO8cCBp/Zkr8IXZifhVBo9/esJdMFnR9lEXR7Yuleg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-cognito-identity": "3.606.0", + "@aws-sdk/types": "3.598.0", + "@smithy/property-provider": "^3.1.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.598.0.tgz", + "integrity": "sha512-vi1khgn7yXzLCcgSIzQrrtd2ilUM0dWodxj3PQ6BLfP0O+q1imO3hG1nq7DVyJtq7rFHs6+9N8G4mYvTkxby2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/property-provider": "^3.1.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.598.0.tgz", + "integrity": "sha512-N7cIafi4HVlQvEgvZSo1G4T9qb/JMLGMdBsDCT5XkeJrF0aptQWzTFH0jIdZcLrMYvzPcuEyO3yCBe6cy/ba0g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/fetch-http-handler": "^3.0.2", + "@smithy/node-http-handler": "^3.0.1", + "@smithy/property-provider": "^3.1.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "@smithy/util-stream": "^3.0.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.598.0.tgz", + "integrity": "sha512-/ppcIVUbRwDIwJDoYfp90X3+AuJo2mvE52Y1t2VSrvUovYn6N4v95/vXj6LS8CNDhz2jvEJYmu+0cTMHdhI6eA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.598.0", + "@aws-sdk/credential-provider-http": "3.598.0", + "@aws-sdk/credential-provider-process": "3.598.0", + "@aws-sdk/credential-provider-sso": "3.598.0", + "@aws-sdk/credential-provider-web-identity": "3.598.0", + "@aws-sdk/types": "3.598.0", + "@smithy/credential-provider-imds": "^3.1.1", + "@smithy/property-provider": "^3.1.1", + "@smithy/shared-ini-file-loader": "^3.1.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.598.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.600.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.600.0.tgz", + "integrity": "sha512-1pC7MPMYD45J7yFjA90SxpR0yaSvy+yZiq23aXhAPZLYgJBAxHLu0s0mDCk/piWGPh8+UGur5K0bVdx4B1D5hw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.598.0", + "@aws-sdk/credential-provider-http": "3.598.0", + "@aws-sdk/credential-provider-ini": "3.598.0", + "@aws-sdk/credential-provider-process": "3.598.0", + "@aws-sdk/credential-provider-sso": "3.598.0", + "@aws-sdk/credential-provider-web-identity": "3.598.0", + "@aws-sdk/types": "3.598.0", + "@smithy/credential-provider-imds": "^3.1.1", + "@smithy/property-provider": "^3.1.1", + "@smithy/shared-ini-file-loader": "^3.1.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.598.0.tgz", + "integrity": "sha512-rM707XbLW8huMk722AgjVyxu2tMZee++fNA8TJVNgs1Ma02Wx6bBrfIvlyK0rCcIRb0WdQYP6fe3Xhiu4e8IBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/property-provider": "^3.1.1", + "@smithy/shared-ini-file-loader": "^3.1.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.598.0.tgz", + "integrity": "sha512-5InwUmrAuqQdOOgxTccRayMMkSmekdLk6s+az9tmikq0QFAHUCtofI+/fllMXSR9iL6JbGYi1940+EUmS4pHJA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-sso": "3.598.0", + "@aws-sdk/token-providers": "3.598.0", + "@aws-sdk/types": "3.598.0", + "@smithy/property-provider": "^3.1.1", + "@smithy/shared-ini-file-loader": "^3.1.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.598.0.tgz", + "integrity": "sha512-GV5GdiMbz5Tz9JO4NJtRoFXjW0GPEujA0j+5J/B723rTN+REHthJu48HdBKouHGhdzkDWkkh1bu52V02Wprw8w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/property-provider": "^3.1.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.598.0" + } + }, + "node_modules/@aws-sdk/credential-providers": { + "version": "3.606.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.606.0.tgz", + "integrity": "sha512-34hswGNDWBFvp4Hi4Gv9DIJ4Ks0Nbg8w3emFsPVHLqqI6X2Wd0hJTf+mi1kMhy/AQXt5LisKLw6wjNIKD2+KGg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-cognito-identity": "3.606.0", + "@aws-sdk/client-sso": "3.598.0", + "@aws-sdk/client-sts": "3.606.0", + "@aws-sdk/credential-provider-cognito-identity": "3.606.0", + "@aws-sdk/credential-provider-env": "3.598.0", + "@aws-sdk/credential-provider-http": "3.598.0", + "@aws-sdk/credential-provider-ini": "3.598.0", + "@aws-sdk/credential-provider-node": "3.600.0", + "@aws-sdk/credential-provider-process": "3.598.0", + "@aws-sdk/credential-provider-sso": "3.598.0", + "@aws-sdk/credential-provider-web-identity": "3.598.0", + "@aws-sdk/types": "3.598.0", + "@smithy/credential-provider-imds": "^3.1.1", + "@smithy/property-provider": "^3.1.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-bucket-endpoint": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.598.0.tgz", + "integrity": "sha512-PM7BcFfGUSkmkT6+LU9TyJiB4S8yI7dfuKQDwK5ZR3P7MKaK4Uj4yyDiv0oe5xvkF6+O2+rShj+eh8YuWkOZ/Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@aws-sdk/util-arn-parser": "3.568.0", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/types": "^3.1.0", + "@smithy/util-config-provider": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-expect-continue": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.598.0.tgz", + "integrity": "sha512-ZuHW18kaeHR8TQyhEOYMr8VwiIh0bMvF7J1OTqXHxDteQIavJWA3CbfZ9sgS4XGtrBZDyHJhjZKeCfLhN2rq3w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/protocol-http": "^4.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-flexible-checksums": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.598.0.tgz", + "integrity": "sha512-xukAzds0GQXvMEY9G6qt+CzwVzTx8NyKKh04O2Q+nOch6QQ8Rs+2kTRy3Z4wQmXq2pK9hlOWb5nXA7HWpmz6Ng==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@aws-crypto/crc32c": "5.2.0", + "@aws-sdk/types": "3.598.0", + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/protocol-http": "^4.0.1", + "@smithy/types": "^3.1.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.598.0.tgz", + "integrity": "sha512-WiaG059YBQwQraNejLIi0gMNkX7dfPZ8hDIhvMr5aVPRbaHH8AYF3iNSsXYCHvA2Cfa1O9haYXsuMF9flXnCmA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/protocol-http": "^4.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-location-constraint": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.598.0.tgz", + "integrity": "sha512-8oybQxN3F1ISOMULk7JKJz5DuAm5hCUcxMW9noWShbxTJuStNvuHf/WLUzXrf8oSITyYzIHPtf8VPlKR7I3orQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.598.0.tgz", + "integrity": "sha512-bxBjf/VYiu3zfu8SYM2S9dQQc3tz5uBAOcPz/Bt8DyyK3GgOpjhschH/2XuUErsoUO1gDJqZSdGOmuHGZQn00Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.598.0.tgz", + "integrity": "sha512-vjT9BeFY9FeN0f8hm2l6F53tI0N5bUq6RcDkQXKNabXBnQxKptJRad6oP2X5y3FoVfBLOuDkQgiC2940GIPxtQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/protocol-http": "^4.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-ec2": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-ec2/-/middleware-sdk-ec2-3.598.0.tgz", + "integrity": "sha512-s46eDkfA7/sqdNEhwvqkuFyo4eWhBAH7CnNJL9W8WBEveu8AQ0qFw5TK0xsdWNAxpe5BETys2qO/i+g+5BsG0g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@aws-sdk/util-format-url": "3.598.0", + "@smithy/middleware-endpoint": "^3.0.2", + "@smithy/protocol-http": "^4.0.1", + "@smithy/signature-v4": "^3.1.0", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-rds": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-rds/-/middleware-sdk-rds-3.598.0.tgz", + "integrity": "sha512-R2ZuXb220wLBcu9/MilGVRMxJrsXRq7JBBzp2f7sJNiExX7UBJcXZox7KGzYhLNBGdBpoKtfkdMlmGPeYLCc5Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@aws-sdk/util-format-url": "3.598.0", + "@smithy/middleware-endpoint": "^3.0.2", + "@smithy/protocol-http": "^4.0.1", + "@smithy/signature-v4": "^3.1.0", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.598.0.tgz", + "integrity": "sha512-5AGtLAh9wyK6ANPYfaKTqJY1IFJyePIxsEbxa7zS6REheAqyVmgJFaGu3oQ5XlxfGr5Uq59tFTRkyx26G1HkHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@aws-sdk/util-arn-parser": "3.568.0", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/signature-v4": "^3.1.0", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "@smithy/util-config-provider": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-signing": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.598.0.tgz", + "integrity": "sha512-XKb05DYx/aBPqz6iCapsCbIl8aD8EihTuPCs51p75QsVfbQoVr4TlFfIl5AooMSITzojdAQqxt021YtvxjtxIQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/property-provider": "^3.1.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/signature-v4": "^3.1.0", + "@smithy/types": "^3.1.0", + "@smithy/util-middleware": "^3.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-ssec": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.598.0.tgz", + "integrity": "sha512-f0p2xP8IC1uJ5e/tND1l81QxRtRFywEdnbtKCE0H6RSn4UIt2W3Dohe1qQDbnh27okF0PkNW6BJGdSAz3p7qbA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.598.0.tgz", + "integrity": "sha512-4tjESlHG5B5MdjUaLK7tQs/miUtHbb6deauQx8ryqSBYOhfHVgb1ZnzvQR0bTrhpqUg0WlybSkDaZAICf9xctg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@aws-sdk/util-endpoints": "3.598.0", + "@smithy/protocol-http": "^4.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.598.0.tgz", + "integrity": "sha512-oYXhmTokSav4ytmWleCr3rs/1nyvZW/S0tdi6X7u+dLNL5Jee+uMxWGzgOrWK6wrQOzucLVjS4E/wA11Kv2GTw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/types": "^3.1.0", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.598.0.tgz", + "integrity": "sha512-1r/EyTrO1gSa1FirnR8V7mabr7gk+l+HkyTI0fcTSr8ucB7gmYyW6WjkY8JCz13VYHFK62usCEDS7yoJoJOzTA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-sdk-s3": "3.598.0", + "@aws-sdk/types": "3.598.0", + "@smithy/protocol-http": "^4.0.1", + "@smithy/signature-v4": "^3.1.0", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.598.0.tgz", + "integrity": "sha512-TKY1EVdHVBnZqpyxyTHdpZpa1tUpb6nxVeRNn1zWG8QB5MvH4ALLd/jR+gtmWDNQbIG4cVuBOZFVL8hIYicKTA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/property-provider": "^3.1.1", + "@smithy/shared-ini-file-loader": "^3.1.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sso-oidc": "^3.598.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.598.0.tgz", + "integrity": "sha512-742uRl6z7u0LFmZwDrFP6r1wlZcgVPw+/TilluDJmCAR8BgRw3IR+743kUXKBGd8QZDRW2n6v/PYsi/AWCDDMQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/util-arn-parser": { + "version": "3.568.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.568.0.tgz", + "integrity": "sha512-XUKJWWo+KOB7fbnPP0+g/o5Ulku/X53t7i/h+sPHr5xxYTJJ9CYnbToo95mzxe7xWvkLrsNtJ8L+MnNn9INs2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.598.0.tgz", + "integrity": "sha512-Qo9UoiVVZxcOEdiOMZg3xb1mzkTxrhd4qSlg5QQrfWPJVx/QOg+Iy0NtGxPtHtVZNHZxohYwDwV/tfsnDSE2gQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/types": "^3.1.0", + "@smithy/util-endpoints": "^2.0.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/util-format-url": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.598.0.tgz", + "integrity": "sha512-1X0PlREk5K6tQg8rFZOjoKVtDyI1WgbKJNCymHhMye6STryY6fhuuayKstiDThkqDYxqahjUJz/Tl2p5W3rbcw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/querystring-builder": "^3.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.965.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.3.tgz", + "integrity": "sha512-FNUqAjlKAGA7GM05kywE99q8wiPHPZqrzhq3wXRga6PRD6A0kzT85Pb0AzYBVTBRpSrKyyr6M92Y6bnSBVp2BA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.598.0.tgz", + "integrity": "sha512-36Sxo6F+ykElaL1mWzWjlg+1epMpSe8obwhCN1yGE7Js9ywy5U6k6l+A3q3YM9YRbm740sNxncbwLklMvuhTKw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/types": "^3.1.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.598.0.tgz", + "integrity": "sha512-oyWGcOlfTdzkC6SVplyr0AGh54IMrDxbhg5RxJ5P+V4BKfcDoDcZV9xenUk9NsOi9MuUjxMumb9UJGkDhM1m0A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.598.0", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.598.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.598.0.tgz", + "integrity": "sha512-ZIa2RK7CHFTZ4gwK77WRtsZ6vF7xwRXxJ8KQIxK2duhoTVcn0xYxpFLdW9WZZZvdP9GIF3Loqvf8DRdeU5Jc7Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", + "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz", + "integrity": "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz", + "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/generator": "^7.28.6", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.6.tgz", + "integrity": "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz", + "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.6" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.28.6.tgz", + "integrity": "sha512-kz2fAQ5UzjV7X7D3ySxmj3vRq89dTpqOZWv76Z6pNPztkwb/0Yj1Mtx1xFrYj6mbIHysxtBot8J4o0JLCblcFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-js-pure": "^3.43.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.6.tgz", + "integrity": "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/generator": "^7.28.6", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.6", + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz", + "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@biomejs/biome": { + "version": "2.3.12", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.3.12.tgz", + "integrity": "sha512-AR7h4aSlAvXj7TAajW/V12BOw2EiS0AqZWV5dGozf4nlLoUF/ifvD0+YgKSskT0ylA6dY1A8AwgP8kZ6yaCQnA==", + "dev": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "2.3.12", + "@biomejs/cli-darwin-x64": "2.3.12", + "@biomejs/cli-linux-arm64": "2.3.12", + "@biomejs/cli-linux-arm64-musl": "2.3.12", + "@biomejs/cli-linux-x64": "2.3.12", + "@biomejs/cli-linux-x64-musl": "2.3.12", + "@biomejs/cli-win32-arm64": "2.3.12", + "@biomejs/cli-win32-x64": "2.3.12" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "2.3.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.3.12.tgz", + "integrity": "sha512-cO6fn+KiMBemva6EARDLQBxeyvLzgidaFRJi8G7OeRqz54kWK0E+uSjgFaiHlc3DZYoa0+1UFE8mDxozpc9ieg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "2.3.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.3.12.tgz", + "integrity": "sha512-/fiF/qmudKwSdvmSrSe/gOTkW77mHHkH8Iy7YC2rmpLuk27kbaUOPa7kPiH5l+3lJzTUfU/t6x1OuIq/7SGtxg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "2.3.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.3.12.tgz", + "integrity": "sha512-nbOsuQROa3DLla5vvsTZg+T5WVPGi9/vYxETm9BOuLHBJN3oWQIg3MIkE2OfL18df1ZtNkqXkH6Yg9mdTPem7A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "2.3.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.3.12.tgz", + "integrity": "sha512-aqkeSf7IH+wkzFpKeDVPSXy9uDjxtLpYA6yzkYsY+tVjwFFirSuajHDI3ul8en90XNs1NA0n8kgBrjwRi5JeyA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "2.3.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.3.12.tgz", + "integrity": "sha512-CQtqrJ+qEEI8tgRSTjjzk6wJAwfH3wQlkIGsM5dlecfRZaoT+XCms/mf7G4kWNexrke6mnkRzNy6w8ebV177ow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "2.3.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.3.12.tgz", + "integrity": "sha512-kVGWtupRRsOjvw47YFkk5mLiAdpCPMWBo1jOwAzh+juDpUb2sWarIp+iq+CPL1Wt0LLZnYtP7hH5kD6fskcxmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "2.3.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.3.12.tgz", + "integrity": "sha512-Re4I7UnOoyE4kHMqpgtG6UvSBGBbbtvsOvBROgCCoH7EgANN6plSQhvo2W7OCITvTp7gD6oZOyZy72lUdXjqZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "2.3.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.3.12.tgz", + "integrity": "sha512-qqGVWqNNek0KikwPZlOIoxtXgsNGsX+rgdEzgw82Re8nF02W+E2WokaQhpF5TdBh/D/RQ3TLppH+otp6ztN0lw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@breejs/later": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@breejs/later/-/later-4.2.0.tgz", + "integrity": "sha512-EVMD0SgJtOuFeg0lAVbCwa+qeTKILb87jqvLyUtQswGD9+ce2nB52Y5zbTF1Hc0MDFfbydcMcxb47jSdhikVHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@cdktf/hcl2json": { + "version": "0.20.8", + "resolved": "https://registry.npmjs.org/@cdktf/hcl2json/-/hcl2json-0.20.8.tgz", + "integrity": "sha512-MOt5HHZYmHiRleaS8YwhEz913H4xzDCOO6MF1GO5RNZ74DYl6Bv6Y+JY4196E0THtiJ1Ibo9IvLfTIlTUrQ+Bw==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "fs-extra": "11.2.0" + } + }, + "node_modules/@chromatic-com/storybook": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@chromatic-com/storybook/-/storybook-5.0.0.tgz", + "integrity": "sha512-8wUsqL8kg6R5ue8XNE7Jv/iD1SuE4+6EXMIGIuE+T2loBITEACLfC3V8W44NJviCLusZRMWbzICddz0nU0bFaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@neoconfetti/react": "^1.0.0", + "chromatic": "^13.3.4", + "filesize": "^10.0.12", + "jsonfile": "^6.1.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=20.0.0", + "yarn": ">=1.22.18" + }, + "peerDependencies": { + "storybook": "^0.0.0-0 || ^10.1.0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.0.26", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.26.tgz", + "integrity": "sha512-6boXK0KkzT5u5xOgF6TKB+CLq9SOpEGmkZw0g5n9/7yg85wab3UzSxB8TxhLJ31L4SGJ6BCFRw/iftTha1CJXA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0" + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@emnapi/core": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", + "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.9.0.tgz", + "integrity": "sha512-lagqsvnk09NKogQaN/XrtlWeUF8SRhT12odMvbTIIaVObqzwAogL6jhR4DAp0gPuKoM1AOVrKUshJpRdpMFrww==", + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, + "node_modules/@gwhitney/detect-indent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@gwhitney/detect-indent/-/detect-indent-7.0.1.tgz", + "integrity": "sha512-7bQW+gkKa2kKZPeJf6+c6gFK9ARxQfn+FKy9ScTBppyKRWH2KzsmweXUoklqeEiHiNVWaeP5csIdsNq6w7QhzA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/@hookform/resolvers": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.2.2.tgz", + "integrity": "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA==", + "license": "MIT", + "dependencies": { + "@standard-schema/utils": "^0.3.0" + }, + "peerDependencies": { + "react-hook-form": "^7.55.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@img/colour": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", + "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@joshwooding/vite-plugin-react-docgen-typescript": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@joshwooding/vite-plugin-react-docgen-typescript/-/vite-plugin-react-docgen-typescript-0.6.3.tgz", + "integrity": "sha512-9TGZuAX+liGkNKkwuo3FYJu7gHWT0vkBcf7GkOe7s7fmC19XwH/4u5u7sDIFrMooe558ORcmuBvBz7Ur5PlbHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^11.1.0", + "react-docgen-typescript": "^2.2.2" + }, + "peerDependencies": { + "typescript": ">= 4.3.x", + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1" + } + }, + "node_modules/@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@mdx-js/react": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", + "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@mlc-ai/web-llm": { + "version": "0.2.80", + "resolved": "https://registry.npmjs.org/@mlc-ai/web-llm/-/web-llm-0.2.80.tgz", + "integrity": "sha512-Hwy1OCsK5cOU4nKr2wIJ2qA1g595PENtO5f2d9Wd/GgFsj5X04uxfaaJfqED8eFAJOpQpn/DirogdEY/yp5jQg==", + "license": "Apache-2.0", + "dependencies": { + "loglevel": "^1.9.1" + } + }, + "node_modules/@monaco-editor/loader": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.7.0.tgz", + "integrity": "sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA==", + "license": "MIT", + "dependencies": { + "state-local": "^1.0.6" + } + }, + "node_modules/@monaco-editor/react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.7.0.tgz", + "integrity": "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==", + "license": "MIT", + "dependencies": { + "@monaco-editor/loader": "^1.5.0" + }, + "peerDependencies": { + "monaco-editor": ">= 0.25.0 < 1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@neoconfetti/react": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@neoconfetti/react/-/react-1.0.0.tgz", + "integrity": "sha512-klcSooChXXOzIm+SE5IISIAn3bYzYfPjbX7D7HoqZL84oAfgREeSg5vSIaSFH+DaGzzvImTyWe1OyrJ67vik4A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@next/env": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.1.4.tgz", + "integrity": "sha512-gkrXnZyxPUy0Gg6SrPQPccbNVLSP3vmW8LU5dwEttEEC1RwDivk8w4O+sZIjFvPrSICXyhQDCG+y3VmjlJf+9A==", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.1.4.tgz", + "integrity": "sha512-38WMjGP8y+1MN4bcZFs+GTcBe0iem5GGTzFE5GWW/dWdRKde7LOXH3lQT2QuoquVWyfl2S0fQRchGmeacGZ4Wg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "3.3.1" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.1.4.tgz", + "integrity": "sha512-T8atLKuvk13XQUdVLCv1ZzMPgLPW0+DWWbHSQXs0/3TjPrKNxTmUIhOEaoEyl3Z82k8h/gEtqyuoZGv6+Ugawg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.1.4.tgz", + "integrity": "sha512-AKC/qVjUGUQDSPI6gESTx0xOnOPQ5gttogNS3o6bA83yiaSZJek0Am5yXy82F1KcZCx3DdOwdGPZpQCluonuxg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.1.4.tgz", + "integrity": "sha512-POQ65+pnYOkZNdngWfMEt7r53bzWiKkVNbjpmCt1Zb3V6lxJNXSsjwRuTQ8P/kguxDC8LRkqaL3vvsFrce4dMQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.1.4.tgz", + "integrity": "sha512-3Wm0zGYVCs6qDFAiSSDL+Z+r46EdtCv/2l+UlIdMbAq9hPJBvGu/rZOeuvCaIUjbArkmXac8HnTyQPJFzFWA0Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.1.4.tgz", + "integrity": "sha512-lWAYAezFinaJiD5Gv8HDidtsZdT3CDaCeqoPoJjeB57OqzvMajpIhlZFce5sCAH6VuX4mdkxCRqecCJFwfm2nQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.1.4.tgz", + "integrity": "sha512-fHaIpT7x4gA6VQbdEpYUXRGyge/YbRrkG6DXM60XiBqDM2g2NcrsQaIuj375egnGFkJow4RHacgBOEsHfGbiUw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.1.4.tgz", + "integrity": "sha512-MCrXxrTSE7jPN1NyXJr39E+aNFBrQZtO154LoCz7n99FuKqJDekgxipoodLNWdQP7/DZ5tKMc/efybx1l159hw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.4.tgz", + "integrity": "sha512-JSVlm9MDhmTXw/sO2PE/MRj+G6XOSMZB+BcZ0a7d6KwVFZVpkHcb2okyoYFBaco6LeiL53BBklRlOrDDbOeE5w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@npmcli/agent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz", + "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/@npmcli/fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", + "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/fs/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.2.tgz", + "integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.4.1", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/endpoint": { + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz", + "integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.1.tgz", + "integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request": "^8.4.1", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "24.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", + "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "11.4.4-cjs.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.4-cjs.2.tgz", + "integrity": "sha512-2dK6z8fhs8lla5PaOTgqfCGBxgAv/le+EhPs27KklPhm1bKObpu6lXzwfUEQ16ajXzqNrKMujsFyo9K2eaoISw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.7.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", + "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "13.3.2-cjs.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.2-cjs.1.tgz", + "integrity": "sha512-VUjIjOOvF2oELQmiFpWA1aOPdawpyaCUqcEBc/UOUnj3Xp6DJGrJ1+bjUIIDzdHjnFNO6q57ODMfdEZnoBkCwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.8.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "^5" + } + }, + "node_modules/@octokit/request": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz", + "integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^9.0.6", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request-error": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz", + "integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/rest": { + "version": "20.1.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.1.2.tgz", + "integrity": "sha512-GmYiltypkHHtihFwPRxlaorG5R9VAHuk/vbszVoRTGXnAsY60wYLkh/E2XiFmdZmqrisw+9FaazS1i5SbdWYgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/core": "^5.0.2", + "@octokit/plugin-paginate-rest": "11.4.4-cjs.2", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-rest-endpoint-methods": "13.3.2-cjs.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/types": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", + "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^24.2.0" + } + }, + "node_modules/@one-ini/wasm": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", + "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@openfeature/core": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@openfeature/core/-/core-1.9.1.tgz", + "integrity": "sha512-YySPtH4s/rKKnHRU0xyFGrqMU8XA+OIPNWDrlEFxE6DCVWCIrxE5YpiB94YD2jMFn6SSdA0cwQ8vLkCkl8lm8A==", + "license": "Apache-2.0", + "peer": true + }, + "node_modules/@openfeature/react-sdk": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@openfeature/react-sdk/-/react-sdk-1.2.0.tgz", + "integrity": "sha512-96nAkwS/dk56Pvfaq5vjTC6KvjuOvcYhmjsrAwii5WyRu0xa57ykl/OO+Szo/hWQCPV6ScVLQXMFMYl3nWH99g==", + "license": "Apache-2.0", + "peerDependencies": { + "@openfeature/web-sdk": "^1.5.0", + "react": ">=16.8.0" + } + }, + "node_modules/@openfeature/web-sdk": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@openfeature/web-sdk/-/web-sdk-1.7.2.tgz", + "integrity": "sha512-8QwhoxVNN2bFFkpWjbCyHCdkVjt/UTVn0o+OwcUUQoZnvPn46Oo1BxJQxUTibl/D/dAM/YQhxmg7ep7gYRxX4g==", + "license": "Apache-2.0", + "peerDependencies": { + "@openfeature/core": "^1.9.0" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.52.1.tgz", + "integrity": "sha512-qnSqB2DQ9TPP96dl8cDubDvrUyWc0/sK81xHTK8eSUspzDM3bsewX903qclQFvVhgStjRWdC5bLb3kQqMkfV5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.25.1.tgz", + "integrity": "sha512-UW/ge9zjvAEmRWVapOP0qyCvPulWU6cQxGxDbWEFfGOj1VBBZAuOqTo3X6yWmDTD3Xe15ysCZChHncr2xFMIfQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz", + "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.52.1.tgz", + "integrity": "sha512-05HcNizx0BxcFKKnS5rwOV+2GevLTVIRA0tRgWYyw4yCgR53Ic/xk83toYKts7kbzcI+dswInUg/4s8oyA+tqg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/otlp-exporter-base": "0.52.1", + "@opentelemetry/otlp-transformer": "0.52.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.52.1.tgz", + "integrity": "sha512-uXJbYU/5/MBHjMp1FqrILLRuiJCs3Ofk0MeRDk8g1S1gD47U8X3JnSwcMO1rtRo1x1a7zKaQHaoYu49p/4eSKw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.52.1", + "@types/shimmer": "^1.0.2", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-bunyan": { + "version": "0.40.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-bunyan/-/instrumentation-bunyan-0.40.0.tgz", + "integrity": "sha512-aZ4cXaGWwj79ZXSYrgFVsrDlE4mmf2wfvP9bViwRc0j75A6eN6GaHYHqufFGMTCqASQn5pIjjP+Bx+PWTGiofw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "^0.52.0", + "@opentelemetry/instrumentation": "^0.52.0", + "@types/bunyan": "1.8.9" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.52.1.tgz", + "integrity": "sha512-dG/aevWhaP+7OLv4BQQSEKMJv8GyeOp3Wxl31NHqE8xo9/fYMfEljiZphUHIfyg4gnZ9swMyWjfOQs5GUQe54Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/instrumentation": "0.52.1", + "@opentelemetry/semantic-conventions": "1.25.1", + "semver": "^7.5.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@opentelemetry/instrumentation/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.52.1.tgz", + "integrity": "sha512-z175NXOtX5ihdlshtYBe5RpGeBoTXVCKPPLiQlD6FHvpM4Ch+p2B0yWKYSrBfLH24H9zjJiBdTrtD+hLlfnXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/otlp-transformer": "0.52.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.52.1.tgz", + "integrity": "sha512-I88uCZSZZtVa0XniRqQWKbjAUm73I8tpEy/uJYPPYw5d7BRdVk0RfTBQw8kSUl01oVWEuqxLDa802222MYyWHg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.52.1", + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/sdk-logs": "0.52.1", + "@opentelemetry/sdk-metrics": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1", + "protobufjs": "^7.3.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-b3": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-1.25.1.tgz", + "integrity": "sha512-p6HFscpjrv7//kE+7L+3Vn00VEDUJB0n6ZrjkTYHrJ58QZ8B3ajSJhRbCcY6guQ3PDjTbxWklyvIN2ojVbIb1A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-jaeger": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.25.1.tgz", + "integrity": "sha512-nBprRf0+jlgxks78G/xq72PipVK+4or9Ypntw0gVZYNTCSK8rg5SeaGV19tV920CMqBD/9UIOiFr23Li/Q8tiA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.25.1.tgz", + "integrity": "sha512-pkZT+iFYIZsVn6+GzM0kSX+u3MSLCY9md+lIJOoKl/P+gJFfxJte/60Usdp8Ce4rOs8GduUpSPNe1ddGyDT1sQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.52.1.tgz", + "integrity": "sha512-MBYh+WcPPsN8YpRHRmK1Hsca9pVlyyKd4BxOC4SsgHACnl/bPp4Cri9hWhVm5+2tiQ9Zf4qSc1Jshw9tOLGWQA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.52.1", + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.25.1.tgz", + "integrity": "sha512-9Mb7q5ioFL4E4dDrc4wC/A3NTHDat44v4I3p2pLPSxRvqUbDIQyMVr9uK+EU69+HWhlET1VaSrRzwdckWqY15Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "lodash.merge": "^4.6.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.25.1.tgz", + "integrity": "sha512-C8k4hnEbc5FamuZQ92nTOp8X/diCY56XUTnMiv9UTuJitCzaNNHAVsdm5+HLCdI8SLQsLWIrG38tddMxLVoftw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.25.1.tgz", + "integrity": "sha512-nMcjFIKxnFqoez4gUmihdBrbpsEnAX/Xj16sGvZm+guceYE0NE00vLhpDVK6f3q8Q4VFI5xG8JjlXKMB/SkTTQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/context-async-hooks": "1.25.1", + "@opentelemetry/core": "1.25.1", + "@opentelemetry/propagator-b3": "1.25.1", + "@opentelemetry/propagator-jaeger": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1", + "semver": "^7.5.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz", + "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@playwright/test": { + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.0.tgz", + "integrity": "sha512-fWza+Lpbj6SkQKCrU6si4iu+fD2dD3gxNHFhUPxsfXBPhnv3rRSQVd0NtBUT9Z/RhF/boCBcuUaMUSTRTopjZg==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.58.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@pnpm/constants": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/constants/-/constants-6.1.0.tgz", + "integrity": "sha512-L6AiU3OXv9kjKGTJN9j8n1TeJGDcLX9atQlZvAkthlvbXjvKc5SKNWESc/eXhr5nEfuMWhQhiKHDJCpYejmeCQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.19" + }, + "funding": { + "url": "https://opencollective.com/pnpm" + } + }, + "node_modules/@pnpm/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@pnpm/error/-/error-4.0.0.tgz", + "integrity": "sha512-NI4DFCMF6xb1SA0bZiiV5KrMCaJM2QmPJFC6p78FXujn7FpiRSWhT9r032wpuQumsl7DEmN4s3wl/P8TA+bL8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pnpm/constants": "6.1.0" + }, + "engines": { + "node": ">=14.6" + }, + "funding": { + "url": "https://opencollective.com/pnpm" + } + }, + "node_modules/@pnpm/graceful-fs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@pnpm/graceful-fs/-/graceful-fs-2.0.0.tgz", + "integrity": "sha512-ogUZCGf0/UILZt6d8PsO4gA4pXh7f0BumXeFkcCe4AQ65PXPKfAkHC0C30Lheh2EgFOpLZm3twDP1Eiww18gew==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.6" + }, + "engines": { + "node": ">=14.19" + }, + "funding": { + "url": "https://opencollective.com/pnpm" + } + }, + "node_modules/@pnpm/read-project-manifest": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@pnpm/read-project-manifest/-/read-project-manifest-4.1.1.tgz", + "integrity": "sha512-jGNoofG8kkUlgAMX8fqbUwRRXYf4WcWdvi/y1Sv1abUfcoVgXW6GdGVm0MIJ+enaong3hXHjaLl/AwmSj6O1Uw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@gwhitney/detect-indent": "7.0.1", + "@pnpm/error": "4.0.0", + "@pnpm/graceful-fs": "2.0.0", + "@pnpm/text.comments-parser": "1.0.0", + "@pnpm/types": "8.9.0", + "@pnpm/write-project-manifest": "4.1.1", + "fast-deep-equal": "^3.1.3", + "is-windows": "^1.0.2", + "json5": "^2.2.1", + "parse-json": "^5.2.0", + "read-yaml-file": "^2.1.0", + "sort-keys": "^4.2.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=14.6" + }, + "funding": { + "url": "https://opencollective.com/pnpm" + } + }, + "node_modules/@pnpm/text.comments-parser": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@pnpm/text.comments-parser/-/text.comments-parser-1.0.0.tgz", + "integrity": "sha512-iG0qrFcObze3uK+HligvzaTocZKukqqIj1dC3NOH58NeMACUW1NUitSKBgeWuNIE4LJT3SPxnyLEBARMMcqVKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "strip-comments-strings": "1.2.0" + }, + "engines": { + "node": ">=14.6" + }, + "funding": { + "url": "https://opencollective.com/pnpm" + } + }, + "node_modules/@pnpm/types": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/@pnpm/types/-/types-8.9.0.tgz", + "integrity": "sha512-3MYHYm8epnciApn6w5Fzx6sepawmsNU7l6lvIq+ER22/DPSrr83YMhU/EQWnf4lORn2YyiXFj0FJSyJzEtIGmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.6" + }, + "funding": { + "url": "https://opencollective.com/pnpm" + } + }, + "node_modules/@pnpm/util.lex-comparator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@pnpm/util.lex-comparator/-/util.lex-comparator-1.0.0.tgz", + "integrity": "sha512-3aBQPHntVgk5AweBWZn+1I/fqZ9krK/w01197aYVkAJQGftb+BVWgEepxY5GChjSW12j52XX+CmfynYZ/p0DFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/write-project-manifest": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@pnpm/write-project-manifest/-/write-project-manifest-4.1.1.tgz", + "integrity": "sha512-nRqvPYO8xUVdgy/KhJuaCrWlVT/4uZr97Mpbuizsa6CmvtCQf3NuYnVvOOrpYiKUJcZYtEvm84OooJ8+lJytMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pnpm/text.comments-parser": "1.0.0", + "@pnpm/types": "8.9.0", + "json5": "^2.2.1", + "write-file-atomic": "^5.0.0", + "write-yaml-file": "^4.2.0" + }, + "engines": { + "node": ">=14.6" + }, + "funding": { + "url": "https://opencollective.com/pnpm" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@qnighy/marshal": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@qnighy/marshal/-/marshal-0.1.3.tgz", + "integrity": "sha512-uaDZTJYtD2UgQTGemmgWeth+e2WapZm+GkAq8UU8AJ55PKRFaf1GkH7X/uzA+Ygu8iInzIlM2FGyCUnruyMKMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime-corejs3": "^7.14.9" + } + }, + "node_modules/@redis/bloom": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", + "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/client": { + "version": "1.5.17", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.17.tgz", + "integrity": "sha512-IPvU9A31qRCZ7lds/x+ksuK/UMndd0EASveAvCvEtFFKIZjZ+m/a4a0L7S28KEWoR5ka8526hlSghDo4Hrc2Hg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cluster-key-slot": "1.1.2", + "generic-pool": "3.9.0", + "yallist": "4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@redis/client/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/@redis/graph": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz", + "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/json": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", + "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/search": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz", + "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/time-series": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", + "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@renovatebot/kbpgp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@renovatebot/kbpgp/-/kbpgp-3.0.1.tgz", + "integrity": "sha512-n78K03XvVIVhE95Thlmq+AXl6j9gYKnsKtrVzU7vnmsKNQDSPn8zTRs1wXGjjdup9REPmqRNcITeq3NsG32QYQ==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "bn": "^1.0.5", + "bzip-deflate": "^1.0.0", + "deep-equal": "^2.2.3", + "iced-error": "0.0.13", + "iced-lock": "^2.0.1", + "iced-runtime-3": "^3.0.5", + "keybase-ecurve": "^1.0.1", + "keybase-nacl": "^1.1.4", + "minimist": "^1.2.8", + "pgp-utils": "0.0.35", + "purepack": "^1.0.6", + "triplesec": "^4.0.3", + "tweetnacl": "^1.0.3" + }, + "engines": { + "node": "^18.12.0 || >=20.9.0", + "pnpm": "^9.0.0" + } + }, + "node_modules/@renovatebot/osv-offline": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@renovatebot/osv-offline/-/osv-offline-1.5.7.tgz", + "integrity": "sha512-w44ydBUa4bPzfRLeKal8pgZSfP0K2nji9G2dPf/yk0gm5oPZa0OxVea2Ku1hhgYN6UMj0Qqyx8y8ssAOH8u0tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/rest": "^20.1.1", + "@renovatebot/osv-offline-db": "1.6.0", + "adm-zip": "~0.5.14", + "fs-extra": "^11.2.0", + "got": "^11.8.6", + "luxon": "^3.4.4", + "node-fetch": "^2.7.0" + } + }, + "node_modules/@renovatebot/osv-offline-db": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@renovatebot/osv-offline-db/-/osv-offline-db-1.6.0.tgz", + "integrity": "sha512-cEOCTyd3+/7gPDmBn0pyJtF01+f9e/dJ1mOoML+v5AsP8GIPAzhtQUuIB5FiCxS4IsbP0qm34anYUZHGJldNJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@seald-io/nedb": "^4.0.4" + } + }, + "node_modules/@renovatebot/pep440": { + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/@renovatebot/pep440/-/pep440-3.0.20.tgz", + "integrity": "sha512-Jw8jzHh2r1LAPTrjQlIwh/+8J3N2MqXZgPuTt6HdNeJIBjJskV8bsEfGs9rBzXi/omeHob3BXnvlECu2rCCUYw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.12.0 || >= 20.0.0", + "pnpm": "^8.6.11" + } + }, + "node_modules/@renovatebot/ruby-semver": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/@renovatebot/ruby-semver/-/ruby-semver-3.0.23.tgz", + "integrity": "sha512-YGvsvvyxOgv5Uq+sFEdD1yviyrPGs9hocjhIo7uWTj/EAIlbGyk5YA5JrHql3EkJf0tVsyfmEkM3kLK+45hmIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.12.0 || >= 20.0.0", + "pnpm": "^8.6.11" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.56.0.tgz", + "integrity": "sha512-LNKIPA5k8PF1+jAFomGe3qN3bbIgJe/IlpDBwuVjrDKrJhVWywgnJvflMt/zkbVNLFtF1+94SljYQS6e99klnw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.56.0.tgz", + "integrity": "sha512-lfbVUbelYqXlYiU/HApNMJzT1E87UPGvzveGg2h0ktUNlOCxKlWuJ9jtfvs1sKHdwU4fzY7Pl8sAl49/XaEk6Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.56.0.tgz", + "integrity": "sha512-EgxD1ocWfhoD6xSOeEEwyE7tDvwTgZc8Bss7wCWe+uc7wO8G34HHCUH+Q6cHqJubxIAnQzAsyUsClt0yFLu06w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.56.0.tgz", + "integrity": "sha512-1vXe1vcMOssb/hOF8iv52A7feWW2xnu+c8BV4t1F//m9QVLTfNVpEdja5ia762j/UEJe2Z1jAmEqZAK42tVW3g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.56.0.tgz", + "integrity": "sha512-bof7fbIlvqsyv/DtaXSck4VYQ9lPtoWNFCB/JY4snlFuJREXfZnm+Ej6yaCHfQvofJDXLDMTVxWscVSuQvVWUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.56.0.tgz", + "integrity": "sha512-KNa6lYHloW+7lTEkYGa37fpvPq+NKG/EHKM8+G/g9WDU7ls4sMqbVRV78J6LdNuVaeeK5WB9/9VAFbKxcbXKYg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.56.0.tgz", + "integrity": "sha512-E8jKK87uOvLrrLN28jnAAAChNq5LeCd2mGgZF+fGF5D507WlG/Noct3lP/QzQ6MrqJ5BCKNwI9ipADB6jyiq2A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.56.0.tgz", + "integrity": "sha512-jQosa5FMYF5Z6prEpTCCmzCXz6eKr/tCBssSmQGEeozA9tkRUty/5Vx06ibaOP9RCrW1Pvb8yp3gvZhHwTDsJw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.56.0.tgz", + "integrity": "sha512-uQVoKkrC1KGEV6udrdVahASIsaF8h7iLG0U0W+Xn14ucFwi6uS539PsAr24IEF9/FoDtzMeeJXJIBo5RkbNWvQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.56.0.tgz", + "integrity": "sha512-vLZ1yJKLxhQLFKTs42RwTwa6zkGln+bnXc8ueFGMYmBTLfNu58sl5/eXyxRa2RarTkJbXl8TKPgfS6V5ijNqEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.56.0.tgz", + "integrity": "sha512-FWfHOCub564kSE3xJQLLIC/hbKqHSVxy8vY75/YHHzWvbJL7aYJkdgwD/xGfUlL5UV2SB7otapLrcCj2xnF1dg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.56.0.tgz", + "integrity": "sha512-z1EkujxIh7nbrKL1lmIpqFTc/sr0u8Uk0zK/qIEFldbt6EDKWFk/pxFq3gYj4Bjn3aa9eEhYRlL3H8ZbPT1xvA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.56.0.tgz", + "integrity": "sha512-iNFTluqgdoQC7AIE8Q34R3AuPrJGJirj5wMUErxj22deOcY7XwZRaqYmB6ZKFHoVGqRcRd0mqO+845jAibKCkw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.56.0.tgz", + "integrity": "sha512-MtMeFVlD2LIKjp2sE2xM2slq3Zxf9zwVuw0jemsxvh1QOpHSsSzfNOTH9uYW9i1MXFxUSMmLpeVeUzoNOKBaWg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.56.0.tgz", + "integrity": "sha512-in+v6wiHdzzVhYKXIk5U74dEZHdKN9KH0Q4ANHOTvyXPG41bajYRsy7a8TPKbYPl34hU7PP7hMVHRvv/5aCSew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.56.0.tgz", + "integrity": "sha512-yni2raKHB8m9NQpI9fPVwN754mn6dHQSbDTwxdr9SE0ks38DTjLMMBjrwvB5+mXrX+C0npX0CVeCUcvvvD8CNQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.56.0.tgz", + "integrity": "sha512-zhLLJx9nQPu7wezbxt2ut+CI4YlXi68ndEve16tPc/iwoylWS9B3FxpLS2PkmfYgDQtosah07Mj9E0khc3Y+vQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.56.0.tgz", + "integrity": "sha512-MVC6UDp16ZSH7x4rtuJPAEoE1RwS8N4oK9DLHy3FTEdFoUTCFVzMfJl/BVJ330C+hx8FfprA5Wqx4FhZXkj2Kw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.56.0.tgz", + "integrity": "sha512-ZhGH1eA4Qv0lxaV00azCIS1ChedK0V32952Md3FtnxSqZTBTd6tgil4nZT5cU8B+SIw3PFYkvyR4FKo2oyZIHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.56.0.tgz", + "integrity": "sha512-O16XcmyDeFI9879pEcmtWvD/2nyxR9mF7Gs44lf1vGGx8Vg2DRNx11aVXBEqOQhWb92WN4z7fW/q4+2NYzCbBA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.56.0.tgz", + "integrity": "sha512-LhN/Reh+7F3RCgQIRbgw8ZMwUwyqJM+8pXNT6IIJAqm2IdKkzpCh/V9EdgOMBKuebIrzswqy4ATlrDgiOwbRcQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.56.0.tgz", + "integrity": "sha512-kbFsOObXp3LBULg1d3JIUQMa9Kv4UitDmpS+k0tinPBz3watcUiV2/LUDMMucA6pZO3WGE27P7DsfaN54l9ing==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.56.0.tgz", + "integrity": "sha512-vSSgny54D6P4vf2izbtFm/TcWYedw7f8eBrOiGGecyHyQB9q4Kqentjaj8hToe+995nob/Wv48pDqL5a62EWtg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.56.0.tgz", + "integrity": "sha512-FeCnkPCTHQJFbiGG49KjV5YGW/8b9rrXAM2Mz2kiIoktq2qsJxRD5giEMEOD2lPdgs72upzefaUvS+nc8E3UzQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.56.0.tgz", + "integrity": "sha512-H8AE9Ur/t0+1VXujj90w0HrSOuv0Nq9r1vSZF2t5km20NTfosQsGGUXDaKdQZzwuLts7IyL1fYT4hM95TI9c4g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@seald-io/binary-search-tree": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@seald-io/binary-search-tree/-/binary-search-tree-1.0.3.tgz", + "integrity": "sha512-qv3jnwoakeax2razYaMsGI/luWdliBLHTdC6jU55hQt1hcFqzauH/HsBollQ7IR4ySTtYhT+xyHoijpA16C+tA==", + "dev": true + }, + "node_modules/@seald-io/nedb": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@seald-io/nedb/-/nedb-4.1.2.tgz", + "integrity": "sha512-bDr6TqjBVS2rDyYM9CPxAnotj5FuNL9NF8o7h7YyFXM7yruqT4ddr+PkSb2mJvvw991bqdftazkEo38gykvaww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@seald-io/binary-search-tree": "^1.0.3", + "localforage": "^1.10.0", + "util": "^0.12.5" + } + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@smithy/abort-controller": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.9.tgz", + "integrity": "sha512-yiW0WI30zj8ZKoSYNx90no7ugVn3khlyH/z5W8qtKBtVE6awRALbhSG+2SAHA1r6bO/6M9utxYKVZ3PCJ1rWxw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/chunked-blob-reader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-4.0.0.tgz", + "integrity": "sha512-jSqRnZvkT4egkq/7b6/QRCNXmmYVcHwnJldqJ3IhVpQE2atObVJ137xmGeuGFhjFUr8gCEVAOKwSY79OvpbDaQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/chunked-blob-reader-native": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-3.0.1.tgz", + "integrity": "sha512-VEYtPvh5rs/xlyqpm5NRnfYLZn+q0SRPELbvBV+C/G7IQ+ouTuo+NKKa3ShG5OaFR8NYVMXls9hPYLTvIKKDrQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/config-resolver": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.13.tgz", + "integrity": "sha512-Gr/qwzyPaTL1tZcq8WQyHhTZREER5R1Wytmz4WnVGL4onA3dNk6Btll55c8Vr58pLdvWZmtG8oZxJTw3t3q7Jg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^3.1.12", + "@smithy/types": "^3.7.2", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.11", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.5.7.tgz", + "integrity": "sha512-8olpW6mKCa0v+ibCjoCzgZHQx1SQmZuW/WkrdZo73wiTprTH6qhmskT60QLFdT9DRa5mXxjz89kQPZ7ZSsoqqg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/middleware-serde": "^3.0.11", + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-middleware": "^3.0.11", + "@smithy/util-stream": "^3.3.4", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.8.tgz", + "integrity": "sha512-ZCY2yD0BY+K9iMXkkbnjo+08T2h8/34oHd0Jmh6BZUSZwaaGlGCyBT/3wnS7u7Xl33/EEfN4B6nQr3Gx5bYxgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^3.1.12", + "@smithy/property-provider": "^3.1.11", + "@smithy/types": "^3.7.2", + "@smithy/url-parser": "^3.0.11", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/eventstream-codec": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.10.tgz", + "integrity": "sha512-323B8YckSbUH0nMIpXn7HZsAVKHYHFUODa8gG9cHo0ySvA1fr5iWaNT+iIL0UCqUzG6QPHA3BSsBtRQou4mMqQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^3.7.2", + "@smithy/util-hex-encoding": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/eventstream-serde-browser": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.14.tgz", + "integrity": "sha512-kbrt0vjOIihW3V7Cqj1SXQvAI5BR8SnyQYsandva0AOR307cXAc+IhPngxIPslxTLfxwDpNu0HzCAq6g42kCPg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^3.0.13", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-config-resolver": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.11.tgz", + "integrity": "sha512-P2pnEp4n75O+QHjyO7cbw/vsw5l93K/8EWyjNCAAybYwUmj3M+hjSQZ9P5TVdUgEG08ueMAP5R4FkuSkElZ5tQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-node": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.13.tgz", + "integrity": "sha512-zqy/9iwbj8Wysmvi7Lq7XFLeDgjRpTbCfwBhJa8WbrylTAHiAu6oQTwdY7iu2lxigbc9YYr9vPv5SzYny5tCXQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^3.0.13", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-universal": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.13.tgz", + "integrity": "sha512-L1Ib66+gg9uTnqp/18Gz4MDpJPKRE44geOjOQ2SVc0eiaO5l255ADziATZgjQjqumC7yPtp1XnjHlF1srcwjKw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-codec": "^3.1.10", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.9.tgz", + "integrity": "sha512-hYNVQOqhFQ6vOpenifFME546f0GfJn2OiQ3M0FDmuUu8V/Uiwy2wej7ZXxFBNqdx0R5DZAqWM1l6VRhGz8oE6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^4.1.4", + "@smithy/querystring-builder": "^3.0.7", + "@smithy/types": "^3.5.0", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/hash-blob-browser": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-3.1.10.tgz", + "integrity": "sha512-elwslXOoNunmfS0fh55jHggyhccobFkexLYC1ZeZ1xP2BTSrcIBaHV2b4xUQOdctrSNOpMqOZH1r2XzWTEhyfA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/chunked-blob-reader": "^4.0.0", + "@smithy/chunked-blob-reader-native": "^3.0.1", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/hash-node": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.11.tgz", + "integrity": "sha512-emP23rwYyZhQBvklqTtwetkQlqbNYirDiEEwXl2v0GYWMnCzxst7ZaRAnWuy28njp5kAH54lvkdG37MblZzaHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/hash-stream-node": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-3.1.10.tgz", + "integrity": "sha512-olomK/jZQ93OMayW1zfTHwcbwBdhcZOHsyWyiZ9h9IXvc1mCD/VuvzbLb3Gy/qNJwI4MANPLctTp2BucV2oU/Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.11.tgz", + "integrity": "sha512-NuQmVPEJjUX6c+UELyVz8kUx8Q539EDeNwbRyu4IIF8MeV7hUtq1FB3SHVyki2u++5XLMFqngeMKk7ccspnNyQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", + "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/md5-js": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-3.0.11.tgz", + "integrity": "sha512-3NM0L3i2Zm4bbgG6Ymi9NBcxXhryi3uE8fIfHJZIOfZVxOkGdjdgjR9A06SFIZCfnEIWKXZdm6Yq5/aPXFFhsQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.13.tgz", + "integrity": "sha512-zfMhzojhFpIX3P5ug7jxTjfUcIPcGjcQYzB9t+rv0g1TX7B0QdwONW+ATouaLoD7h7LOw/ZlXfkq4xJ/g2TrIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.8.tgz", + "integrity": "sha512-OEJZKVUEhMOqMs3ktrTWp7UvvluMJEvD5XgQwRePSbDg1VvBaL8pX8mwPltFn6wk1GySbcVwwyldL8S+iqnrEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^2.5.7", + "@smithy/middleware-serde": "^3.0.11", + "@smithy/node-config-provider": "^3.1.12", + "@smithy/shared-ini-file-loader": "^3.1.12", + "@smithy/types": "^3.7.2", + "@smithy/url-parser": "^3.0.11", + "@smithy/util-middleware": "^3.0.11", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "3.0.34", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.34.tgz", + "integrity": "sha512-yVRr/AAtPZlUvwEkrq7S3x7Z8/xCd97m2hLDaqdz6ucP2RKHsBjEqaUA2ebNv2SsZoPEi+ZD0dZbOB1u37tGCA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^3.1.12", + "@smithy/protocol-http": "^4.1.8", + "@smithy/service-error-classification": "^3.0.11", + "@smithy/smithy-client": "^3.7.0", + "@smithy/types": "^3.7.2", + "@smithy/util-middleware": "^3.0.11", + "@smithy/util-retry": "^3.0.11", + "tslib": "^2.6.2", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.11.tgz", + "integrity": "sha512-KzPAeySp/fOoQA82TpnwItvX8BBURecpx6ZMu75EZDkAcnPtO6vf7q4aH5QHs/F1s3/snQaSFbbUMcFFZ086Mw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.11.tgz", + "integrity": "sha512-1HGo9a6/ikgOMrTrWL/WiN9N8GSVYpuRQO5kjstAq4CvV59bjqnh7TbdXGQ4vxLD3xlSjfBjq5t1SOELePsLnA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.12.tgz", + "integrity": "sha512-O9LVEu5J/u/FuNlZs+L7Ikn3lz7VB9hb0GtPT9MQeiBmtK8RSY3ULmsZgXhe6VAlgTw0YO+paQx4p8xdbs43vQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^3.1.11", + "@smithy/shared-ini-file-loader": "^3.1.12", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.3.tgz", + "integrity": "sha512-BrpZOaZ4RCbcJ2igiSNG16S+kgAc65l/2hmxWdmhyoGWHTLlzQzr06PXavJp9OBlPEG/sHlqdxjWmjzV66+BSQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^3.1.9", + "@smithy/protocol-http": "^4.1.8", + "@smithy/querystring-builder": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", + "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", + "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/querystring-builder": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.11.tgz", + "integrity": "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/querystring-parser": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.11.tgz", + "integrity": "sha512-Je3kFvCsFMnso1ilPwA7GtlbPaTixa3WwC+K21kmMZHsBEOZYQaqxcMqeFFoU7/slFjKDIpiiPydvdJm8Q/MCw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/service-error-classification": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.11.tgz", + "integrity": "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.12.tgz", + "integrity": "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-3.1.2.tgz", + "integrity": "sha512-3BcPylEsYtD0esM4Hoyml/+s7WP2LFhcM3J2AGdcL2vx9O60TtfpDOL72gjb4lU8NeRPeKAwR77YNyyGvMbuEA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/types": "^3.3.0", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-uri-escape": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.7.0.tgz", + "integrity": "sha512-9wYrjAZFlqWhgVo3C4y/9kpc68jgiSsKUnsFPzr/MSiRL93+QRDafGTfhhKAb2wsr69Ru87WTiqSfQusSmWipA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^2.5.7", + "@smithy/middleware-endpoint": "^3.2.8", + "@smithy/middleware-stack": "^3.0.11", + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "@smithy/util-stream": "^3.3.4", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.2.tgz", + "integrity": "sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/url-parser": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.11.tgz", + "integrity": "sha512-TmlqXkSk8ZPhfc+SQutjmFr5FjC0av3GZP4B/10caK1SbRwe/v+Wzu/R6xEKxoNqL+8nY18s1byiy6HqPG37Aw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/querystring-parser": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/util-base64": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", + "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-body-length-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", + "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", + "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", + "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-config-provider": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", + "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "3.0.34", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.34.tgz", + "integrity": "sha512-FumjjF631lR521cX+svMLBj3SwSDh9VdtyynTYDAiBDEf8YPP5xORNXKQ9j0105o5+ARAGnOOP/RqSl40uXddA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^3.1.11", + "@smithy/smithy-client": "^3.7.0", + "@smithy/types": "^3.7.2", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "3.0.34", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.34.tgz", + "integrity": "sha512-vN6aHfzW9dVVzkI0wcZoUXvfjkl4CSbM9nE//08lmUMyf00S75uuCpTrqF9uD4bD9eldIXlt53colrlwKAT8Gw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/config-resolver": "^3.0.13", + "@smithy/credential-provider-imds": "^3.2.8", + "@smithy/node-config-provider": "^3.1.12", + "@smithy/property-provider": "^3.1.11", + "@smithy/smithy-client": "^3.7.0", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.7.tgz", + "integrity": "sha512-tSfcqKcN/Oo2STEYCABVuKgJ76nyyr6skGl9t15hs+YaiU06sgMkN7QYjo0BbVw+KT26zok3IzbdSOksQ4YzVw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^3.1.12", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-hex-encoding": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", + "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-middleware": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.11.tgz", + "integrity": "sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-retry": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", + "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.3.4.tgz", + "integrity": "sha512-SGhGBG/KupieJvJSZp/rfHHka8BFgj56eek9px4pp7lZbOF+fRiVr4U7A3y3zJD8uGhxq32C5D96HxsTC9BckQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/fetch-http-handler": "^4.1.3", + "@smithy/node-http-handler": "^3.3.3", + "@smithy/types": "^3.7.2", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-stream/node_modules/@smithy/fetch-http-handler": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.3.tgz", + "integrity": "sha512-6SxNltSncI8s689nvnzZQc/dPXcpHQ34KUj6gR/HBroytKOd/isMG3gJF/zBE1TBmTT18TXyzhg3O3SOOqGEhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^4.1.8", + "@smithy/querystring-builder": "^3.0.11", + "@smithy/types": "^3.7.2", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", + "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-waiter": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.2.0.tgz", + "integrity": "sha512-PpjSboaDUE6yl+1qlg3Si57++e84oXdWGbuFUSAciXsVfEZJJJupR2Nb0QuXHiunt2vGR+1PTizOMvnUPaG2Qg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^3.1.9", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, + "node_modules/@storybook/addon-a11y": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-10.2.0.tgz", + "integrity": "sha512-PJVvEr6KpuOvCr1megfp39RNvFSut6XmFxaiDKtf8kxYbD8tMYL2n/9xFcPIvozJCO4zRmug50X+OIoh0GsSGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "axe-core": "^4.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.2.0" + } + }, + "node_modules/@storybook/addon-docs": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.2.0.tgz", + "integrity": "sha512-2iVQmbgguRWQAxJ7HFje7PQFHZIDCYjFNt9zKLaF8NmCS3OI1qVON5Tb/KH30f9epa5Y42OarPEewJE9J+Tw9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mdx-js/react": "^3.0.0", + "@storybook/csf-plugin": "10.2.0", + "@storybook/icons": "^2.0.1", + "@storybook/react-dom-shim": "10.2.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.2.0" + } + }, + "node_modules/@storybook/addon-onboarding": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@storybook/addon-onboarding/-/addon-onboarding-10.2.0.tgz", + "integrity": "sha512-6JEgceYEEER9vVjmjiT1AKROMiwzZkSo+MN76wZMKayLX9fA8RIjrRGF3C5CNOVadbcbbvgPmwcLZMgD+0VZlg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.2.0" + } + }, + "node_modules/@storybook/addon-vitest": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@storybook/addon-vitest/-/addon-vitest-10.2.0.tgz", + "integrity": "sha512-MNGRhwC5pIEWfNbMxD6pQTqYWq8YwBdRsXkFX00rk3y88YV3w9zg/pHHk6v/+fGnrM9L/upwkIOvlaNMWn8uHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/icons": "^2.0.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "@vitest/browser": "^3.0.0 || ^4.0.0", + "@vitest/browser-playwright": "^4.0.0", + "@vitest/runner": "^3.0.0 || ^4.0.0", + "storybook": "^10.2.0", + "vitest": "^3.0.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/runner": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/@storybook/builder-vite": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.2.0.tgz", + "integrity": "sha512-S1+62ipGmQzGPZfcbgNqpbrCezsqkvbhj+MBbQ6VS46b2HcPjm4H8V6FzGly0Ja2pSgu8gT1BQ5N+3yOG8UNTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/csf-plugin": "10.2.0", + "@vitest/mocker": "3.2.4", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.2.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@storybook/csf-plugin": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.2.0.tgz", + "integrity": "sha512-Cty+tZ0r1AZhwBBzqI4RyCpMVGt9wHGTtG4YCRUuNgVFO1MnjaFBHKRT+oT7md28+BWYjFz4Qtpge/fcWANJ0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "unplugin": "^2.3.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "esbuild": "*", + "rollup": "*", + "storybook": "^10.2.0", + "vite": "*", + "webpack": "*" + }, + "peerDependenciesMeta": { + "esbuild": { + "optional": true + }, + "rollup": { + "optional": true + }, + "vite": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/@storybook/global": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz", + "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@storybook/icons": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-2.0.1.tgz", + "integrity": "sha512-/smVjw88yK3CKsiuR71vNgWQ9+NuY2L+e8X7IMrFjexjm6ZR8ULrV2DRkTA61aV6ryefslzHEGDInGpnNeIocg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@storybook/nextjs-vite": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@storybook/nextjs-vite/-/nextjs-vite-10.2.0.tgz", + "integrity": "sha512-MHeSFu6h3LOUETAVl804jGmnjxREIGYKY3V+tevuZm+QsPUgYUMjPcgdgCs5ZqDmD4i24CTO4Byzlp7poZZWsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/builder-vite": "10.2.0", + "@storybook/react": "10.2.0", + "@storybook/react-vite": "10.2.0", + "styled-jsx": "5.1.6", + "vite-plugin-storybook-nextjs": "^3.1.9" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "next": "^14.1.0 || ^15.0.0 || ^16.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.2.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@storybook/react": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.2.0.tgz", + "integrity": "sha512-ciJlh1UGm0GBXQgqrYFeLmiix+KGFB3v37OnAYjGghPS9OP6S99XyshxY/6p0sMOYtS+eWS2gPsOKNXNnLDGYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/react-dom-shim": "10.2.0", + "react-docgen": "^8.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.2.0", + "typescript": ">= 4.9.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@storybook/react-dom-shim": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.2.0.tgz", + "integrity": "sha512-PEQofiruE6dBGzUQPXZZREbuh1t62uRBWoUPRFNAZi79zddlk7+b9qu08VV9cvf68mwOqqT1+VJ1P+3ClD2ZVw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.2.0" + } + }, + "node_modules/@storybook/react-vite": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-10.2.0.tgz", + "integrity": "sha512-tIXRfrA+wREFuA+bIJccMCV1YVFdACENcSnSlnB5Be3m8ynMHukOz6ObX9jI5WsWZnqrk0/eHyiYJyVhpY9rhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@joshwooding/vite-plugin-react-docgen-typescript": "^0.6.3", + "@rollup/pluginutils": "^5.0.2", + "@storybook/builder-vite": "10.2.0", + "@storybook/react": "10.2.0", + "empathic": "^2.0.0", + "magic-string": "^0.30.0", + "react-docgen": "^8.0.0", + "resolve": "^1.22.8", + "tsconfig-paths": "^4.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.2.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz", + "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.6.1", + "lightningcss": "1.30.2", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.18" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz", + "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.18", + "@tailwindcss/oxide-darwin-arm64": "4.1.18", + "@tailwindcss/oxide-darwin-x64": "4.1.18", + "@tailwindcss/oxide-freebsd-x64": "4.1.18", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", + "@tailwindcss/oxide-linux-x64-musl": "4.1.18", + "@tailwindcss/oxide-wasm32-wasi": "4.1.18", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz", + "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz", + "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz", + "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz", + "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz", + "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz", + "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz", + "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz", + "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz", + "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz", + "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.0", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz", + "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz", + "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.18.tgz", + "integrity": "sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.1.18", + "@tailwindcss/oxide": "4.1.18", + "postcss": "^8.4.41", + "tailwindcss": "4.1.18" + } + }, + "node_modules/@tanstack/query-core": { + "version": "5.90.20", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.20.tgz", + "integrity": "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.90.20", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.20.tgz", + "integrity": "sha512-vXBxa+qeyveVO7OA0jX1z+DeyCA4JKnThKv411jd5SORpBKgkcVnYKCiBgECvADvniBX7tobwBmg01qq9JmMJw==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.90.20" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/react": { + "version": "16.3.2", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz", + "integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@testing-library/user-event": { + "version": "14.6.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", + "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@thi.ng/api": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@thi.ng/api/-/api-7.2.0.tgz", + "integrity": "sha512-4NcwHXxwPF/JgJG/jSFd9rjfQNguF0QrHvd6e+CEf4T0sFChqetW6ZmJ6/a2X+noDVntgulegA+Bx0HHzw+Tyw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/postspectacular" + }, + { + "type": "patreon", + "url": "https://patreon.com/thing_umbrella" + } + ], + "license": "Apache-2.0" + }, + "node_modules/@thi.ng/arrays": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@thi.ng/arrays/-/arrays-1.0.3.tgz", + "integrity": "sha512-ZUB27bdpTwcvxYJTlt/eWKrj98nWXo0lAUPwRwubk4GlH8rTKKkc7qZr9/4LCKPsNjnZdQqbBtNvNf3HjYxCzw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/postspectacular" + }, + { + "type": "patreon", + "url": "https://patreon.com/thing_umbrella" + } + ], + "license": "Apache-2.0", + "dependencies": { + "@thi.ng/api": "^7.2.0", + "@thi.ng/checks": "^2.9.11", + "@thi.ng/compare": "^1.3.34", + "@thi.ng/equiv": "^1.0.45", + "@thi.ng/errors": "^1.3.4", + "@thi.ng/random": "^2.4.8" + } + }, + "node_modules/@thi.ng/checks": { + "version": "2.9.11", + "resolved": "https://registry.npmjs.org/@thi.ng/checks/-/checks-2.9.11.tgz", + "integrity": "sha512-fBvWod32w24JlJsrrOdl+tlx+UNehCORi4rHaJ7l7HH+SEhD/lYTCXOBjwu9D/ztIUjMP5Q+n8cAqI5iPhbvAQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/postspectacular" + }, + { + "type": "patreon", + "url": "https://patreon.com/thing_umbrella" + } + ], + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/@thi.ng/compare": { + "version": "1.3.34", + "resolved": "https://registry.npmjs.org/@thi.ng/compare/-/compare-1.3.34.tgz", + "integrity": "sha512-E+UWhmo8l5yeHDuriPUsfrnk/Mj5kSDNRX7lPfv2zNdAQ7N8UDzc0IXu46U6EpqtCReo+2n5N8qzfD3TjerFRw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/postspectacular" + }, + { + "type": "patreon", + "url": "https://patreon.com/thing_umbrella" + } + ], + "license": "Apache-2.0", + "dependencies": { + "@thi.ng/api": "^7.2.0" + } + }, + "node_modules/@thi.ng/equiv": { + "version": "1.0.45", + "resolved": "https://registry.npmjs.org/@thi.ng/equiv/-/equiv-1.0.45.tgz", + "integrity": "sha512-tdXaJfF0pFvT80Q7BOlhc7H7ja/RbVGzlGpE4LqjDWfXPPbLYwmq6EbQuHWeXuvT0qe+BsGnuO5UXAR5B8oGGQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/postspectacular" + }, + { + "type": "patreon", + "url": "https://patreon.com/thing_umbrella" + } + ], + "license": "Apache-2.0" + }, + "node_modules/@thi.ng/errors": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@thi.ng/errors/-/errors-1.3.4.tgz", + "integrity": "sha512-hTk71OPKnioN349sdj2DAoY+69eSerB3MN4Zwz6mosr1QFzIMkfkNOtBeC+Gm0yi0V0EY5LeBYFgqb3oXbtTbw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/postspectacular" + }, + { + "type": "patreon", + "url": "https://patreon.com/thing_umbrella" + } + ], + "license": "Apache-2.0" + }, + "node_modules/@thi.ng/hex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@thi.ng/hex/-/hex-1.0.4.tgz", + "integrity": "sha512-9ofIG4nXhEskGeOJthpi/9LXFIPrlZ/MmHpgLWa3wNqTVhODP/o++mu9jDKojHEpKvswkkFCE+mSVmMu8xo4mQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/postspectacular" + }, + { + "type": "patreon", + "url": "https://patreon.com/thing_umbrella" + } + ], + "license": "Apache-2.0" + }, + "node_modules/@thi.ng/random": { + "version": "2.4.8", + "resolved": "https://registry.npmjs.org/@thi.ng/random/-/random-2.4.8.tgz", + "integrity": "sha512-4JJB8zbaPxjlAp1kCqsBbs6eN4Ivd/5fs1e4GlvmNkyGSucHIDTWvw6NnQWqUx2oPaAEDB9CFCH7SOcGC/cwkw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/postspectacular" + }, + { + "type": "patreon", + "url": "https://patreon.com/thing_umbrella" + } + ], + "license": "Apache-2.0", + "dependencies": { + "@thi.ng/api": "^7.2.0", + "@thi.ng/checks": "^2.9.11", + "@thi.ng/hex": "^1.0.4" + } + }, + "node_modules/@thi.ng/zipper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@thi.ng/zipper/-/zipper-1.0.3.tgz", + "integrity": "sha512-dWfuk5nzf5wGEmcF90AXNEuWr3NVwRF+cf/9ZSE6xImA7Vy5XpHNMwLHFszZaC+kqiDXr+EZ0lXWDF46a8lSPA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/postspectacular" + }, + { + "type": "patreon", + "url": "https://patreon.com/thing_umbrella" + } + ], + "license": "Apache-2.0", + "dependencies": { + "@thi.ng/api": "^7.2.0", + "@thi.ng/arrays": "^1.0.3", + "@thi.ng/checks": "^2.9.11" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/bunyan": { + "version": "1.8.9", + "resolved": "https://registry.npmjs.org/@types/bunyan/-/bunyan-1.8.9.tgz", + "integrity": "sha512-ZqS9JGpBxVOvsawzmVt30sP++gSQMTejCkIAQ3VdadOcRE8izTyW66hufvwLeH+YEGP6Js2AW7Gz+RMyvrEbmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/doctrine": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz", + "integrity": "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/dompurify": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz", + "integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/trusted-types": "*" + } + }, + "node_modules/@types/emscripten": { + "version": "1.41.5", + "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.41.5.tgz", + "integrity": "sha512-cMQm7pxu6BxtHyqJ7mQZ2kXWV5SLmugybFdHCBbJ5eHzOo6VhBckEgAT3//rP5FwPHNPeEiq4SmQ5ucBwsOo4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/moo": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@types/moo/-/moo-0.5.5.tgz", + "integrity": "sha512-eXQpwnkI4Ntw5uJg6i2PINdRFWLr55dqjuYQaLHNjvqTzF14QdNWbCbml9sza0byyXNA0hZlHtcdN+VNDcgVHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", + "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.9", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.9.tgz", + "integrity": "sha512-Lpo8kgb/igvMIPeNV2rsYKTgaORYdO1XGVZ4Qz3akwOj0ySGYMPlQWa8BaLn0G63D1aSaAQ5ldR06wCpChQCjA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@types/resolve": { + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz", + "integrity": "sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/shimmer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.2.0.tgz", + "integrity": "sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/treeify": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/treeify/-/treeify-1.0.3.tgz", + "integrity": "sha512-hx0o7zWEUU4R2Amn+pjCBQQt23Khy/Dk56gQU5xi5jtPL1h83ACJCeFaB2M/+WO1AntvWrSoVnnCAfI1AQH4Cg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.53.1.tgz", + "integrity": "sha512-cFYYFZ+oQFi6hUnBTbLRXfTJiaQtYE3t4O692agbBl+2Zy+eqSKWtPjhPXJu1G7j4RLjKgeJPDdq3EqOwmX5Ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.53.1", + "@typescript-eslint/type-utils": "8.53.1", + "@typescript-eslint/utils": "8.53.1", + "@typescript-eslint/visitor-keys": "8.53.1", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.53.1", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.53.1.tgz", + "integrity": "sha512-nm3cvFN9SqZGXjmw5bZ6cGmvJSyJPn0wU9gHAZZHDnZl2wF9PhHv78Xf06E0MaNk4zLVHL8hb2/c32XvyJOLQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.53.1", + "@typescript-eslint/types": "8.53.1", + "@typescript-eslint/typescript-estree": "8.53.1", + "@typescript-eslint/visitor-keys": "8.53.1", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.53.1.tgz", + "integrity": "sha512-WYC4FB5Ra0xidsmlPb+1SsnaSKPmS3gsjIARwbEkHkoWloQmuzcfypljaJcR78uyLA1h8sHdWWPHSLDI+MtNog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.53.1", + "@typescript-eslint/types": "^8.53.1", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.53.1.tgz", + "integrity": "sha512-Lu23yw1uJMFY8cUeq7JlrizAgeQvWugNQzJp8C3x8Eo5Jw5Q2ykMdiiTB9vBVOOUBysMzmRRmUfwFrZuI2C4SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.53.1", + "@typescript-eslint/visitor-keys": "8.53.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.53.1.tgz", + "integrity": "sha512-qfvLXS6F6b1y43pnf0pPbXJ+YoXIC7HKg0UGZ27uMIemKMKA6XH2DTxsEDdpdN29D+vHV07x/pnlPNVLhdhWiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.53.1.tgz", + "integrity": "sha512-MOrdtNvyhy0rHyv0ENzub1d4wQYKb2NmIqG7qEqPWFW7Mpy2jzFC3pQ2yKDvirZB7jypm5uGjF2Qqs6OIqu47w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.53.1", + "@typescript-eslint/typescript-estree": "8.53.1", + "@typescript-eslint/utils": "8.53.1", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.1.tgz", + "integrity": "sha512-jr/swrr2aRmUAUjW5/zQHbMaui//vQlsZcJKijZf3M26bnmLj8LyZUpj8/Rd6uzaek06OWsqdofN/Thenm5O8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.53.1.tgz", + "integrity": "sha512-RGlVipGhQAG4GxV1s34O91cxQ/vWiHJTDHbXRr0li2q/BGg3RR/7NM8QDWgkEgrwQYCvmJV9ichIwyoKCQ+DTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.53.1", + "@typescript-eslint/tsconfig-utils": "8.53.1", + "@typescript-eslint/types": "8.53.1", + "@typescript-eslint/visitor-keys": "8.53.1", + "debug": "^4.4.3", + "minimatch": "^9.0.5", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.53.1.tgz", + "integrity": "sha512-c4bMvGVWW4hv6JmDUEG7fSYlWOl3II2I4ylt0NM+seinYQlZMQIaKaXIIVJWt9Ofh6whrpM+EdDQXKXjNovvrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.53.1", + "@typescript-eslint/types": "8.53.1", + "@typescript-eslint/typescript-estree": "8.53.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.53.1.tgz", + "integrity": "sha512-oy+wV7xDKFPRyNggmXuZQSBzvoLnpmJs+GhzRhPjrxl2b/jIlyjVokzm47CZCDUdXKr2zd7ZLodPfOBpOPyPlg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.53.1", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", + "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@vercel/oidc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.1.0.tgz", + "integrity": "sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==", + "license": "Apache-2.0", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@vitest/browser": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-4.0.18.tgz", + "integrity": "sha512-gVQqh7paBz3gC+ZdcCmNSWJMk70IUjDeVqi+5m5vYpEHsIwRgw3Y545jljtajhkekIpIp5Gg8oK7bctgY0E2Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/mocker": "4.0.18", + "@vitest/utils": "4.0.18", + "magic-string": "^0.30.21", + "pixelmatch": "7.1.0", + "pngjs": "^7.0.0", + "sirv": "^3.0.2", + "tinyrainbow": "^3.0.3", + "ws": "^8.18.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "4.0.18" + } + }, + "node_modules/@vitest/browser-playwright": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/browser-playwright/-/browser-playwright-4.0.18.tgz", + "integrity": "sha512-gfajTHVCiwpxRj1qh0Sh/5bbGLG4F/ZH/V9xvFVoFddpITfMta9YGow0W6ZpTTORv2vdJuz9TnrNSmjKvpOf4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/browser": "4.0.18", + "@vitest/mocker": "4.0.18", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "playwright": "*", + "vitest": "4.0.18" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": false + } + } + }, + "node_modules/@vitest/browser-playwright/node_modules/@vitest/mocker": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.18.tgz", + "integrity": "sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.0.18", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/browser-playwright/node_modules/@vitest/spy": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.18.tgz", + "integrity": "sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/browser-playwright/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@vitest/browser/node_modules/@vitest/mocker": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.18.tgz", + "integrity": "sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.0.18", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/browser/node_modules/@vitest/spy": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.18.tgz", + "integrity": "sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/browser/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@vitest/coverage-v8": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.18.tgz", + "integrity": "sha512-7i+N2i0+ME+2JFZhfuz7Tg/FqKtilHjGyGvoHYQ6iLV0zahbsJ9sljC9OcFcPDbhYKCet+sG8SsVqlyGvPflZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^1.0.2", + "@vitest/utils": "4.0.18", + "ast-v8-to-istanbul": "^0.3.10", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.2.0", + "magicast": "^0.5.1", + "obug": "^2.1.1", + "std-env": "^3.10.0", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "4.0.18", + "vitest": "4.0.18" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "node_modules/@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@vitest/mocker": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.2.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/mocker/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.18.tgz", + "integrity": "sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.18.tgz", + "integrity": "sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.0.18", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.18.tgz", + "integrity": "sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.18", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.18.tgz", + "integrity": "sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.18", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@yarnpkg/core": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@yarnpkg/core/-/core-4.1.1.tgz", + "integrity": "sha512-Py26fODbsgcFdoq/iYEbqZPkIrjWcICMf/BuI7EDR6YjHmD+FQ4HyqfeanhvePsORCHNAwfqsnr1OqrfKZFrEA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@arcanis/slice-ansi": "^1.1.1", + "@types/semver": "^7.1.0", + "@types/treeify": "^1.0.0", + "@yarnpkg/fslib": "^3.1.0", + "@yarnpkg/libzip": "^3.1.0", + "@yarnpkg/parsers": "^3.0.2", + "@yarnpkg/shell": "^4.0.2", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "ci-info": "^3.2.0", + "clipanion": "^4.0.0-rc.2", + "cross-spawn": "7.0.3", + "diff": "^5.1.0", + "dotenv": "^16.3.1", + "fast-glob": "^3.2.2", + "got": "^11.7.0", + "lodash": "^4.17.15", + "micromatch": "^4.0.2", + "p-limit": "^2.2.0", + "semver": "^7.1.2", + "strip-ansi": "^6.0.0", + "tar": "^6.0.5", + "tinylogic": "^2.0.0", + "treeify": "^1.1.0", + "tslib": "^2.4.0", + "tunnel": "^0.0.6" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@yarnpkg/core/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@yarnpkg/core/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@yarnpkg/core/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@yarnpkg/core/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@yarnpkg/core/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@yarnpkg/fslib": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-3.1.4.tgz", + "integrity": "sha512-Yyguw5RM+xI1Bv0RFbs1ZF5HwU+9/He4YT7yeT722yAlLfkz9IzZHO6a5yStEshxiliPn9Fdj4H54a785xpK/g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@yarnpkg/libzip": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@yarnpkg/libzip/-/libzip-3.2.2.tgz", + "integrity": "sha512-Kqxgjfy6SwwC4tTGQYToIWtUhIORTpkowqgd9kkMiBixor0eourHZZAggt/7N4WQKt9iCyPSkO3Xvr44vXUBAw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/emscripten": "^1.39.6", + "@yarnpkg/fslib": "^3.1.3", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "@yarnpkg/fslib": "^3.1.3" + } + }, + "node_modules/@yarnpkg/parsers": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.2.tgz", + "integrity": "sha512-/HcYgtUSiJiot/XWGLOlGxPYUG65+/31V8oqk17vZLW1xlCoR4PampyePljOxY2n8/3jz9+tIFzICsyGujJZoA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "js-yaml": "^3.10.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@yarnpkg/parsers/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@yarnpkg/parsers/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@yarnpkg/parsers/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@yarnpkg/shell": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@yarnpkg/shell/-/shell-4.1.3.tgz", + "integrity": "sha512-5igwsHbPtSAlLdmMdKqU3atXjwhtLFQXsYAG0sn1XcPb3yF8WxxtWxN6fycBoUvFyIHFz1G0KeRefnAy8n6gdw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@yarnpkg/fslib": "^3.1.2", + "@yarnpkg/parsers": "^3.0.3", + "chalk": "^4.1.2", + "clipanion": "^4.0.0-rc.2", + "cross-spawn": "^7.0.3", + "fast-glob": "^3.2.2", + "micromatch": "^4.0.2", + "tslib": "^2.4.0" + }, + "bin": { + "shell": "lib/cli.js" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@yarnpkg/shell/node_modules/@yarnpkg/parsers": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.3.tgz", + "integrity": "sha512-mQZgUSgFurUtA07ceMjxrWkYz8QtDuYkvPlu0ZqncgjopQ0t6CNEo/OSealkmnagSUx8ZD5ewvezUwUuMqutQg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "js-yaml": "^3.10.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@yarnpkg/shell/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@yarnpkg/shell/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@yarnpkg/shell/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "license": "ISC", + "optional": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/adm-zip": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz", + "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "dev": true, + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ai": { + "version": "6.0.49", + "resolved": "https://registry.npmjs.org/ai/-/ai-6.0.49.tgz", + "integrity": "sha512-LABniBX/0R6Tv+iUK5keUZhZLaZUe4YjP5M2rZ4wAdZ8iKV3EfTAoJxuL1aaWTSJKIilKa9QUEkCgnp89/32bw==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/gateway": "3.0.22", + "@ai-sdk/provider": "3.0.5", + "@ai-sdk/provider-utils": "4.0.9", + "@opentelemetry/api": "1.9.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.2.0.tgz", + "integrity": "sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/ast-v8-to-istanbul": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.10.tgz", + "integrity": "sha512-p4K7vMz2ZSk3wN8l5o3y2bJAoZXT3VuJI5OLTATY/01CYWumWvwkUw0SqDBnNq6IiTO3qDa1eSQDibAV8g7XOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^9.0.1" + } + }, + "node_modules/ast-v8-to-istanbul/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/auth-header": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/auth-header/-/auth-header-1.0.0.tgz", + "integrity": "sha512-CPPazq09YVDUNNVWo4oSPTQmtwIzHusZhQmahCKvIsk0/xH6U3QsMAv3sM+7+Q0B1K2KJ/Q38OND317uXs4NHA==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws4": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", + "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==", + "dev": true, + "license": "MIT" + }, + "node_modules/axe-core": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.1.tgz", + "integrity": "sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/azure-devops-node-api": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-14.0.1.tgz", + "integrity": "sha512-oVnFfTNmergd3JU852EpGY64d1nAxW8lCyzZqFDPhfQVZkdApBeK/ZMN7yoFiq/C50Ru304X1L/+BFblh2SRJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tunnel": "0.0.6", + "typed-rest-client": "^2.0.1" + }, + "engines": { + "node": ">= 16.0.0" + } + }, + "node_modules/backslash": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/backslash/-/backslash-0.2.2.tgz", + "integrity": "sha512-PKRYPE2LLTtNUYz1dszquxKSBs6XyLyJRHgFpY5rlq7y3DscDx239k5Gm+zenoY47OU4CApan1o0k2R8ptZC1Q==", + "dev": true + }, + "node_modules/bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.18", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.18.tgz", + "integrity": "sha512-e23vBV1ZLfjb9apvfPk4rHVu2ry6RIr2Wfs+O324okSidrX7pTAnEJPCh/O5BtRlr7QtZI7ktOP3vsqr7Z5XoA==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/better-sqlite3": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.1.2.tgz", + "integrity": "sha512-gujtFwavWU4MSPT+h9B+4pkvZdyOUkH54zgLdIrMmmmd4ZqiBIrRNBzNzYVFO417xo882uP5HBu4GjOfaSrIQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bindings": "^1.5.0", + "prebuild-install": "^7.1.1" + } + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bn": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bn/-/bn-1.0.5.tgz", + "integrity": "sha512-7TvGbqbZb6lDzsBtNz1VkdXXV0BVmZKPPViPmo2IpvwaryF7P+QKYKACyVkwo2mZPr2CpFiz7EtgPEcc3o/JFQ==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT" + }, + "node_modules/bowser": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.13.1.tgz", + "integrity": "sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bunyan": { + "version": "1.8.15", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz", + "integrity": "sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==", + "dev": true, + "engines": [ + "node >=0.10.0" + ], + "license": "MIT", + "bin": { + "bunyan": "bin/bunyan" + }, + "optionalDependencies": { + "dtrace-provider": "~0.8", + "moment": "^2.19.3", + "mv": "~2", + "safe-json-stringify": "~1" + } + }, + "node_modules/bzip-deflate": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bzip-deflate/-/bzip-deflate-1.0.0.tgz", + "integrity": "sha512-9RMnpiJqMYMJcLdr4pxwowZ8Zh3P+tVswE/bnX6tZ14UGKNcdV5WVK2P+lGp2As+RCjl+i3SFJ117HyCaaHNDA==", + "dev": true, + "license": "CC-SA 3.0" + }, + "node_modules/cacache": { + "version": "18.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", + "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys/node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001766", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz", + "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/changelog-filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/changelog-filename-regex/-/changelog-filename-regex-2.0.1.tgz", + "integrity": "sha512-DZdyJpCprw8V3jp8V2x13nAA05Yy/IN+Prowj+0mrAHNENYkuMtNI4u5m449TTjPqShIslQSEuXee+Jtkn4m+g==", + "dev": true, + "license": "ISC" + }, + "node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/chromatic": { + "version": "13.3.5", + "resolved": "https://registry.npmjs.org/chromatic/-/chromatic-13.3.5.tgz", + "integrity": "sha512-MzPhxpl838qJUo0A55osCF2ifwPbjcIPeElr1d4SHcjnHoIcg7l1syJDrAYK/a+PcCBrOGi06jPNpQAln5hWgw==", + "dev": true, + "license": "MIT", + "bin": { + "chroma": "dist/bin.js", + "chromatic": "dist/bin.js", + "chromatic-cli": "dist/bin.js" + }, + "peerDependencies": { + "@chromatic-com/cypress": "^0.*.* || ^1.0.0", + "@chromatic-com/playwright": "^0.*.* || ^1.0.0" + }, + "peerDependenciesMeta": { + "@chromatic-com/cypress": { + "optional": true + }, + "@chromatic-com/playwright": { + "optional": true + } + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, + "node_modules/clean-git-ref": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/clean-git-ref/-/clean-git-ref-2.0.1.tgz", + "integrity": "sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.1.1.tgz", + "integrity": "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^7.1.0", + "string-width": "^8.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/clipanion": { + "version": "4.0.0-rc.4", + "resolved": "https://registry.npmjs.org/clipanion/-/clipanion-4.0.0-rc.4.tgz", + "integrity": "sha512-CXkMQxU6s9GklO/1f714dkKBMu1lopS1WFF0B8o4AxPykR1hpozxSiUZ5ZUeBjfPgCWqbcNOtZVFhB8Lkfp1+Q==", + "dev": true, + "license": "MIT", + "workspaces": [ + "website" + ], + "dependencies": { + "typanion": "^3.8.0" + }, + "peerDependencies": { + "typanion": "*" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", + "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/conventional-commits-detector": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/conventional-commits-detector/-/conventional-commits-detector-1.0.3.tgz", + "integrity": "sha512-VlBCTEg34Bbvyh7MPYtmgoYPsP69Z1BusmthbiUbzTiwfhLZWRDEWsJHqWyiekSC9vFCHGT/jKOzs8r21MUZ5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.0", + "git-raw-commits": "^2.0.0", + "meow": "^7.0.0", + "through2-concurrent": "^2.0.0" + }, + "bin": { + "conventional-commits-detector": "src/cli.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-js-pure": { + "version": "3.48.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.48.0.tgz", + "integrity": "sha512-1slJgk89tWC51HQ1AEqG+s2VuwpTRr8ocu4n20QUcH1v9lAN0RXen0Q0AABa/DK1I7RrNWLucplOHMx8hfTGTw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cron-parser": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", + "integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "luxon": "^3.2.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz", + "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==", + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^4.1.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.21", + "css-tree": "^3.1.0", + "lru-cache": "^11.2.4" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cssstyle/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/data-urls": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.1.tgz", + "integrity": "sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==", + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^15.1.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/data-urls/node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "license": "MIT" + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-browser": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.4.0.tgz", + "integrity": "sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/des.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "devOptional": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "license": "MIT" + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/dompurify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.1.tgz", + "integrity": "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dtrace-provider": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", + "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", + "dev": true, + "hasInstallScript": true, + "license": "BSD-2-Clause", + "optional": true, + "dependencies": { + "nan": "^2.14.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/editorconfig": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-2.0.0.tgz", + "integrity": "sha512-s1NQ63WQ7RNXH6Efb2cwuyRlfpbtdZubvfNe4vCuoyGPewNPY7vah8JUSOFBiJ+jr99Qh8t0xKv0oITc1dclgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@one-ini/wasm": "0.1.1", + "commander": "^11.0.0", + "minimatch": "9.0.2", + "semver": "^7.5.3" + }, + "bin": { + "editorconfig": "bin/editorconfig" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/editorconfig/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/editorconfig/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/editorconfig/node_modules/minimatch": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.2.tgz", + "integrity": "sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/editorconfig/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.278", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.278.tgz", + "integrity": "sha512-dQ0tM1svDRQOwxnXxm+twlGTjr9Upvt8UFWAgmLsxEzFQxhbti4VwxmMjsDxVC51Zo84swW7FVCXEV+VAkhuPw==", + "dev": true, + "license": "ISC" + }, + "node_modules/email-addresses": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", + "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/emojibase": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/emojibase/-/emojibase-15.3.1.tgz", + "integrity": "sha512-GNsjHnG2J3Ktg684Fs/vZR/6XpOSkZPMAv85EHrr6br2RN2cJNwdS4am/3YSK3y+/gOv2kmoK3GGdahXdMxg2g==", + "dev": true, + "license": "MIT", + "funding": { + "type": "ko-fi", + "url": "https://ko-fi.com/milesjohnson" + } + }, + "node_modules/emojibase-regex": { + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/emojibase-regex/-/emojibase-regex-15.3.2.tgz", + "integrity": "sha512-ue6BVeb2qu33l97MkxcOoyMJlg6Tug3eTv2z1at+M9TjvlWKvdmAPvZIDG1JbT2RH3FSyJNLucO5K5H/yxT03w==", + "dev": true, + "license": "MIT", + "funding": { + "type": "ko-fi", + "url": "https://ko-fi.com/milesjohnson" + } + }, + "node_modules/empathic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz", + "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.4", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", + "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", + "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.2.tgz", + "integrity": "sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.1", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.1.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.3.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.5", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-next": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.1.4.tgz", + "integrity": "sha512-iCrrNolUPpn/ythx0HcyNRfUBgTkaNBXByisKUbusPGCl8DMkDXXAu7exlSTSLGTIsH9lFE/c4s/3Qiyv2qwdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/eslint-plugin-next": "16.1.4", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-jsx-a11y": "^6.10.0", + "eslint-plugin-react": "^7.37.0", + "eslint-plugin-react-hooks": "^7.0.0", + "globals": "16.4.0", + "typescript-eslint": "^8.46.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-config-next/node_modules/globals": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz", + "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz", + "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.4.0", + "get-tsconfig": "^4.10.0", + "is-bun-module": "^2.0.0", + "stable-hash": "^0.0.5", + "tinyglobby": "^0.2.13", + "unrs-resolver": "^1.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/eslint-plugin-import/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz", + "integrity": "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-storybook": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-10.2.0.tgz", + "integrity": "sha512-OtQJ153FOusr8bIMzccjkfMFJEex/3NFx0iXZ+UaeQ0WXearQ+37EGgBay3onkFElyu8AySggq/fdTknPAEvPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.48.0" + }, + "peerDependencies": { + "eslint": ">=8", + "storybook": "^10.2.0" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/eventsource-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "license": "(MIT OR WTFPL)", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", + "dev": true, + "license": "Apache-2.0", + "optional": true + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-xml-parser": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz", + "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==", + "dev": true, + "funding": [ + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + }, + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/filesize": { + "version": "10.1.6", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.6.tgz", + "integrity": "sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 10.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-packages": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/find-packages/-/find-packages-10.0.4.tgz", + "integrity": "sha512-JmO9lEBUEYOiRw/bdbdgFWpGFgBZBGLcK/5GjQKo3ZN+zR6jmQOh9gWyZoqxlQmnldZ9WBWhna0QYyuq6BxvRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pnpm/read-project-manifest": "4.1.1", + "@pnpm/types": "8.9.0", + "@pnpm/util.lex-comparator": "1.0.0", + "fast-glob": "^3.2.12", + "p-filter": "^2.1.0" + }, + "engines": { + "node": ">=14.6" + }, + "funding": { + "url": "https://opencollective.com/pnpm" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/framer-motion": { + "version": "12.29.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.29.0.tgz", + "integrity": "sha512-1gEFGXHYV2BD42ZPTFmSU9buehppU+bCuOnHU0AD18DKh9j4DuTx47MvqY5ax+NNWRtK32qIcJf1UxKo1WwjWg==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.29.0", + "motion-utils": "^12.27.2", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gaxios": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", + "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^6.1.1", + "google-logging-utils": "^0.0.2", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/generic-pool": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", + "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/git-raw-commits": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", + "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "dev": true, + "license": "MIT", + "dependencies": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-raw-commits/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-raw-commits/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-raw-commits/node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/git-raw-commits/node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-raw-commits/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-raw-commits/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/git-raw-commits/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/git-raw-commits/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/git-up": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz", + "integrity": "sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-ssh": "^1.4.0", + "parse-url": "^8.1.0" + } + }, + "node_modules/git-url-parse": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-14.1.0.tgz", + "integrity": "sha512-8xg65dTxGHST3+zGpycMMFZcoTzAdZ2dOtu4vmgIfkTFnVHBxHMzBC2L1k8To7EmrSiHesT8JgPLT91VKw1B5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "git-up": "^7.0.0" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/github-url-from-git": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/github-url-from-git/-/github-url-from-git-1.5.0.tgz", + "integrity": "sha512-WWOec4aRI7YAykQ9+BHmzjyNlkfJFG8QLXnDTsLz/kZefq7qkzdfo4p6fkYYMIq1aj+gZcQs/1HQhQh3DPPxlQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/glob": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/global-agent/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/good-enough-parser": { + "version": "1.1.23", + "resolved": "https://registry.npmjs.org/good-enough-parser/-/good-enough-parser-1.1.23.tgz", + "integrity": "sha512-QUcQZutczESpdo2w9BMG6VpLFoq9ix7ER5HLM1mAdZdri2F3eISkCb8ep84W6YOo0grYWJdyT/8JkYqGjQfSSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@thi.ng/zipper": "1.0.3", + "@types/moo": "0.5.5", + "klona": "2.0.6", + "moo": "0.5.2" + }, + "engines": { + "node": ">=18.12.0", + "yarn": "^1.17.0" + } + }, + "node_modules/google-auth-library": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.11.0.tgz", + "integrity": "sha512-epX3ww/mNnhl6tL45EQ/oixsY8JLEgUFoT4A5E/5iAR4esld9Kqv6IJGk7EmGuOgDvaarwF95hU2+v7Irql9lw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-logging-utils": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", + "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graph-data-structure": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/graph-data-structure/-/graph-data-structure-3.5.0.tgz", + "integrity": "sha512-AAgjRtBZC1acIExgK2otv2LDdcYeZdQFKiEStXRDTyaVs6sUUaGUif05pCczTqAU4ny82NQtM1p5PK7AQEYgRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/html-dom-parser": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-5.1.4.tgz", + "integrity": "sha512-UGjp7y8jSrDU2RdN2J9FDOo3X+WBu+LkS/I3TjjFW020ocZWjPvave+RKk1zeuY2sUWy5fh6zHgXHthzDGlFNQ==", + "license": "MIT", + "dependencies": { + "domhandler": "5.0.3", + "htmlparser2": "10.1.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/html-react-parser": { + "version": "5.2.12", + "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-5.2.12.tgz", + "integrity": "sha512-tvamxqkg5va1t9Wnq8OdikpIZrcgdatNd2rxQt0oEzb+IpbsWR1I7ddPd6CkwqZjiv8zKDzm8oiqqxy+KknQEQ==", + "license": "MIT", + "dependencies": { + "domhandler": "5.0.3", + "html-dom-parser": "5.1.4", + "react-property": "2.0.2", + "style-to-js": "1.1.21" + }, + "peerDependencies": { + "@types/react": "0.14 || 15 || 16 || 17 || 18 || 19", + "react": "0.14 || 15 || 16 || 17 || 18 || 19" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/iced-error": { + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/iced-error/-/iced-error-0.0.13.tgz", + "integrity": "sha512-yEEaG8QfyyRL0SsbNNDw3rVgTyqwHFMCuV6jDvD43f/2shmdaFXkqvFLGhDlsYNSolzYHwVLM/CrXt9GygYopA==", + "dev": true + }, + "node_modules/iced-lock": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/iced-lock/-/iced-lock-2.0.1.tgz", + "integrity": "sha512-J6dnGMpAoHNyACUYJYhiJkLY7YFRTa7NMZ8ZygpYB3HNDOGWtzv55+kT2u1zItRi4Y1EXruG9d1VDsx8R5faTw==", + "dev": true, + "dependencies": { + "iced-runtime": "^1.0.0" + } + }, + "node_modules/iced-runtime": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/iced-runtime/-/iced-runtime-1.0.4.tgz", + "integrity": "sha512-rgiJXNF6ZgF2Clh/TKUlBDW3q51YPDJUXmxGQXx1b8tbZpVpTn+1RX9q1sjNkujXIIaVxZByQzPHHORg7KV51g==", + "dev": true + }, + "node_modules/iced-runtime-3": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/iced-runtime-3/-/iced-runtime-3-3.0.5.tgz", + "integrity": "sha512-OHU64z4Njq4EdoGyRId5NgUQKy6R1sr1wufc1fVxwpqKsM8yWagqmKCRlt//zKKIPOfZw7kQ1iN4m+/2s8WSeg==", + "dev": true + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-2.0.2.tgz", + "integrity": "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==", + "dev": true, + "license": "MIT", + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-in-the-middle": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.15.0.tgz", + "integrity": "sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "license": "MIT" + }, + "node_modules/install-artifact-from-github": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/install-artifact-from-github/-/install-artifact-from-github-1.4.0.tgz", + "integrity": "sha512-+y6WywKZREw5rq7U2jvr2nmZpT7cbWbQQ0N/qfcseYnzHFz2cZz1Et52oY+XttYuYeTkI8Y+R2JNWj68MpQFSg==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "bin": { + "install-from-cache": "bin/install-from-cache.js", + "save-to-github-cache": "bin/save-to-github-cache.js" + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-bun-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, + "node_modules/is-bun-module/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ssh": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.1.tgz", + "integrity": "sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "protocols": "^2.0.1" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isomorphic-dompurify": { + "version": "2.35.0", + "resolved": "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-2.35.0.tgz", + "integrity": "sha512-a9+LQqylQCU8f1zmsYmg2tfrbdY2YS/Hc+xntcq/mDI2MY3Q108nq8K23BWDIg6YGC5JsUMC15fj2ZMqCzt/+A==", + "license": "MIT", + "dependencies": { + "dompurify": "^3.3.1", + "jsdom": "^27.4.0" + }, + "engines": { + "node": ">=20.19.5" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jackspeak": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-md4": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/js-md4/-/js-md4-0.3.2.tgz", + "integrity": "sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.4.0.tgz", + "integrity": "sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==", + "license": "MIT", + "dependencies": { + "@acemir/cssom": "^0.9.28", + "@asamuzakjp/dom-selector": "^6.7.6", + "@exodus/bytes": "^1.6.0", + "cssstyle": "^5.3.4", + "data-urls": "^6.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.0", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^15.1.0", + "ws": "^8.18.3", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-dup-key-validator": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/json-dup-key-validator/-/json-dup-key-validator-1.0.3.tgz", + "integrity": "sha512-JvJcV01JSiO7LRz7DY1Fpzn4wX2rJ3dfNTiAfnlvLNdhhnm0Pgdvhi2SGpENrZn7eSg26Ps3TPhOcuD/a4STXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "backslash": "^0.2.0" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-pretty-compact": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-3.0.0.tgz", + "integrity": "sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonata": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/jsonata/-/jsonata-2.0.5.tgz", + "integrity": "sha512-wEse9+QLIIU5IaCgtJCPsFi/H4F3qcikWzF4bAELZiRz08ohfx3Q6CjDRf4ZPF5P/92RI3KIHtb7u3jqPaHXdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keybase-ecurve": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/keybase-ecurve/-/keybase-ecurve-1.0.1.tgz", + "integrity": "sha512-2GlVxDsNF+52LtYjgFsjoKuN7MQQgiVeR4HRdJxLuN8fm4mf4stGKPUjDJjky15c/98UsZseLjp7Ih5X0Sy1jQ==", + "dev": true, + "dependencies": { + "bn": "^1.0.4" + } + }, + "node_modules/keybase-nacl": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/keybase-nacl/-/keybase-nacl-1.1.4.tgz", + "integrity": "sha512-7TFyWLq42CQs7JES9arR+Vnv/eMk5D6JT1Y8samrEA5ff3FOmaiRcXIVrwJQd3KJduxmSjgAjdkXlQK7Q437xQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "iced-runtime": "^1.0.2", + "tweetnacl": "^0.13.1", + "uint64be": "^1.0.1" + } + }, + "node_modules/keybase-nacl/node_modules/tweetnacl": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz", + "integrity": "sha512-iNWodk4oBsZ03Qfw/Yvv0KB90uYrJqvL4Je7Gy4C5t/GS3sCXPRmIT1lxmId4RzvUp0XG62bcxJ2CBu/3L5DSg==", + "dev": true, + "license": "Public domain" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lightningcss": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", + "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.30.2", + "lightningcss-darwin-arm64": "1.30.2", + "lightningcss-darwin-x64": "1.30.2", + "lightningcss-freebsd-x64": "1.30.2", + "lightningcss-linux-arm-gnueabihf": "1.30.2", + "lightningcss-linux-arm64-gnu": "1.30.2", + "lightningcss-linux-arm64-musl": "1.30.2", + "lightningcss-linux-x64-gnu": "1.30.2", + "lightningcss-linux-x64-musl": "1.30.2", + "lightningcss-win32-arm64-msvc": "1.30.2", + "lightningcss-win32-x64-msvc": "1.30.2" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", + "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", + "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", + "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", + "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", + "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", + "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", + "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", + "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", + "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", + "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", + "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/lint-staged": { + "version": "16.2.7", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.2.7.tgz", + "integrity": "sha512-lDIj4RnYmK7/kXMya+qJsmkRFkGolciXjrsZ6PC25GdTfWOAWetR0ZbsNXRAj1EHHImRSalc+whZFg56F5DVow==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^14.0.2", + "listr2": "^9.0.5", + "micromatch": "^4.0.8", + "nano-spawn": "^2.0.0", + "pidtree": "^0.6.0", + "string-argv": "^0.3.2", + "yaml": "^2.8.1" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=20.17" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/listr2": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", + "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^5.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/localforage": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", + "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "lie": "3.1.1" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/loglevel": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", + "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lucide-react": { + "version": "0.563.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.563.0.tgz", + "integrity": "sha512-8dXPB2GI4dI8jV4MgUDGBeLdGk8ekfqVZ0BdLcrRzocGgG75ltNEmWS+gE7uokKF/0oSUuczNDT+g9hFJ23FkA==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/luxon": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz", + "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", + "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "source-map-js": "^1.2.1" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-fetch-happen": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", + "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "repeat-string": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/marked": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz", + "integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz", + "integrity": "sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^4.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", + "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/mdast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", + "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "longest-streak": "^2.0.0", + "mdast-util-to-string": "^2.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.0.0", + "zwitch": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/mdast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", + "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "license": "CC0-1.0" + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" + }, + "node_modules/meow": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-7.1.1.tgz", + "integrity": "sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/module-alias": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.3.tgz", + "integrity": "sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/module-details-from-path": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", + "dev": true, + "license": "MIT" + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/monaco-editor": { + "version": "0.55.1", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.55.1.tgz", + "integrity": "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==", + "license": "MIT", + "dependencies": { + "dompurify": "3.2.7", + "marked": "14.0.0" + } + }, + "node_modules/monaco-editor/node_modules/dompurify": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", + "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, + "node_modules/moo": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", + "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/more-entropy": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/more-entropy/-/more-entropy-0.0.7.tgz", + "integrity": "sha512-e0TxQtU1F6/ZA8WnEA2JLQwwDqBTtZFLJSW7rWgUsQou35wx1IOL0g2O7q7oGoMgIJto+jHMnNGHLfSiylHRrw==", + "dev": true, + "dependencies": { + "iced-runtime": ">=0.0.1" + } + }, + "node_modules/motion": { + "version": "12.29.0", + "resolved": "https://registry.npmjs.org/motion/-/motion-12.29.0.tgz", + "integrity": "sha512-rjB5CP2N9S2ESAyEFnAFMgTec6X8yvfxLNcz8n12gPq3M48R7ZbBeVYkDOTj8SPMwfvGIFI801SiPSr1+HCr9g==", + "license": "MIT", + "dependencies": { + "framer-motion": "^12.29.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/motion-dom": { + "version": "12.29.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.29.0.tgz", + "integrity": "sha512-3eiz9bb32yvY8Q6XNM4AwkSOBPgU//EIKTZwsSWgA9uzbPBhZJeScCVcBuwwYVqhfamewpv7ZNmVKTGp5qnzkA==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.27.2" + } + }, + "node_modules/motion-utils": { + "version": "12.27.2", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.27.2.tgz", + "integrity": "sha512-B55gcoL85Mcdt2IEStY5EEAsrMSVE2sI14xQ/uAdPL+mfQxhKKFaEag9JmfxedJOR4vZpBGoPeC/Gm13I/4g5Q==", + "license": "MIT" + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mv": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "rimraf": "~2.4.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/nan": { + "version": "2.25.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.25.0.tgz", + "integrity": "sha512-0M90Ag7Xn5KMLLZ7zliPWP3rT90P6PN+IzVFS0VqmnPktBk3700xUVv8Ikm9EUaUE5SDWdp/BIxdENzVznpm1g==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/nano-spawn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-2.0.0.tgz", + "integrity": "sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/nano-spawn?sponsor=1" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "ncp": "bin/ncp" + } + }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/next": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/next/-/next-16.1.4.tgz", + "integrity": "sha512-gKSecROqisnV7Buen5BfjmXAm7Xlpx9o2ueVQRo5DxQcjC8d330dOM1xiGWc2k3Dcnz0In3VybyRPOsudwgiqQ==", + "license": "MIT", + "dependencies": { + "@next/env": "16.1.4", + "@swc/helpers": "0.5.15", + "baseline-browser-mapping": "^2.8.3", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=20.9.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "16.1.4", + "@next/swc-darwin-x64": "16.1.4", + "@next/swc-linux-arm64-gnu": "16.1.4", + "@next/swc-linux-arm64-musl": "16.1.4", + "@next/swc-linux-x64-gnu": "16.1.4", + "@next/swc-linux-x64-musl": "16.1.4", + "@next/swc-win32-arm64-msvc": "16.1.4", + "@next/swc-win32-x64-msvc": "16.1.4", + "sharp": "^0.34.4" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.51.1", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/node-abi": { + "version": "3.87.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.87.0.tgz", + "integrity": "sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/node-gyp": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.3.1.tgz", + "integrity": "sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^13.0.0", + "nopt": "^7.0.0", + "proc-log": "^4.1.0", + "semver": "^7.3.5", + "tar": "^6.2.1", + "which": "^4.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/node-gyp/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "optional": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/node-gyp/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "optional": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/node-gyp/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/node-gyp/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "optional": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/node-html-parser": { + "version": "6.1.13", + "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.13.tgz", + "integrity": "sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-select": "^5.1.0", + "he": "1.2.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", + "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nuqs": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/nuqs/-/nuqs-2.8.6.tgz", + "integrity": "sha512-aRxeX68b4ULmhio8AADL2be1FWDy0EPqaByPvIYWrA7Pm07UjlrICp/VPlSnXJNAG0+3MQwv3OporO2sOXMVGA==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/franky47" + }, + "peerDependencies": { + "@remix-run/react": ">=2", + "@tanstack/react-router": "^1", + "next": ">=14.2.0", + "react": ">=18.2.0 || ^19.0.0-0", + "react-router": "^5 || ^6 || ^7", + "react-router-dom": "^5 || ^6 || ^7" + }, + "peerDependenciesMeta": { + "@remix-run/react": { + "optional": true + }, + "@tanstack/react-router": { + "optional": true + }, + "next": { + "optional": true + }, + "react-router": { + "optional": true + }, + "react-router-dom": { + "optional": true + } + } + }, + "node_modules/nuqs/node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/openpgp": { + "version": "5.11.2", + "resolved": "https://registry.npmjs.org/openpgp/-/openpgp-5.11.2.tgz", + "integrity": "sha512-f8dJFVLwdkvPvW3VPFs6q9Vs2+HNhdvwls7a/MIFcQUB+XiQzRe7alfa3RtwfGJU7oUDDMAWPZ0nYsHa23Az+A==", + "deprecated": "This version is deprecated and will no longer receive security patches. Please refer to https://github.com/openpgpjs/openpgpjs/wiki/Updating-from-previous-versions for details on how to upgrade to a newer supported version.", + "dev": true, + "license": "LGPL-3.0+", + "optional": true, + "dependencies": { + "asn1.js": "^5.0.0" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-all": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-all/-/p-all-3.0.0.tgz", + "integrity": "sha512-qUZbvbBFVXm6uJ7U/WDiO0fv6waBMbjlCm4E66oZdRR+egswICarIdHyVSZZHudH8T5SF8x/JG0q0duFzPnlBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-map": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-map": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-filter/node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue/node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true, + "license": "MIT" + }, + "node_modules/p-throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/p-throttle/-/p-throttle-4.1.1.tgz", + "integrity": "sha512-TuU8Ato+pRTPJoDzYD4s7ocJYcNSEZRvlxoq3hcPI2kZDZ49IQ1Wkj7/gDJc3X7XiEAAvRGtDzdXJI0tC3IL1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-link-header": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-link-header/-/parse-link-header-2.0.0.tgz", + "integrity": "sha512-xjU87V0VyHZybn2RrCX5TIFGxTVZE6zqqZWMPlIKiSKuWh/X5WZdt+w1Ki1nXB+8L/KtL+nZ4iq+sfI6MrhhMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "~4.0.1" + } + }, + "node_modules/parse-path": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.1.0.tgz", + "integrity": "sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "protocols": "^2.0.0" + } + }, + "node_modules/parse-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz", + "integrity": "sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-path": "^7.0.0" + } + }, + "node_modules/parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", + "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/pgp-utils": { + "version": "0.0.35", + "resolved": "https://registry.npmjs.org/pgp-utils/-/pgp-utils-0.0.35.tgz", + "integrity": "sha512-gCT6EbSTgljgycVa5qGpfRITaLOLbIKsEVRTdsNRgmLMAJpuJNNdrTn/95r8IWo9rFLlccfmGMJXkG9nVDwmrA==", + "dev": true, + "dependencies": { + "iced-error": ">=0.0.8", + "iced-runtime": ">=0.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pixelmatch": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-7.1.0.tgz", + "integrity": "sha512-1wrVzJ2STrpmONHKBy228LM1b84msXDUoAzVEl0R8Mz4Ce6EPr+IVtxm8+yvrqLYMHswREkjYFaMxnyGnaY3Ng==", + "dev": true, + "license": "ISC", + "dependencies": { + "pngjs": "^7.0.0" + }, + "bin": { + "pixelmatch": "bin/pixelmatch" + } + }, + "node_modules/playwright": { + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.0.tgz", + "integrity": "sha512-2SVA0sbPktiIY/MCOPX8e86ehA/e+tDNq+e5Y8qjKYti2Z/JG7xnronT/TXTIkKbYGWlCbuucZ6dziEgkoEjQQ==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.58.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.0.tgz", + "integrity": "sha512-aaoB1RWrdNi3//rOeKuMiS65UCcgOVljU46At6eFcOFPFHWtd2weHRRow6z/n+Lec0Lvu0k9ZPKJSjPugikirw==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/pngjs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", + "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.19.0" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "dev": true, + "license": "ISC", + "optional": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha512-UdA8mJ4weIkUBO224tIarHzuHs4HuYiJvsuGT7j/SPQiUJVjYvNDBIPa0hAorduOfjGohB/qHWRa/lrrWX/mXw==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/protobufjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "dev": true, + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/protocols": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.2.tgz", + "integrity": "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/purepack": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/purepack/-/purepack-1.0.6.tgz", + "integrity": "sha512-L/e3qq/3m/TrYtINo2aBB98oz6w8VHGyFy+arSKwPMZDUNNw2OaQxYnZO6UIZZw2OnRl2qkxGmuSOEfsuHXJdA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/qs": { + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "optional": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/re2": { + "version": "1.21.3", + "resolved": "https://registry.npmjs.org/re2/-/re2-1.21.3.tgz", + "integrity": "sha512-GI+KoGkHT4kxTaX+9p0FgNB1XUnCndO9slG5qqeEoZ7kbf6Dk6ohQVpmwKVeSp7LPLn+g6Q3BaCopz4oHuBDuQ==", + "dev": true, + "hasInstallScript": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "install-artifact-from-github": "^1.3.5", + "nan": "^2.20.0", + "node-gyp": "^10.1.0" + } + }, + "node_modules/react": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", + "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-docgen": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-8.0.2.tgz", + "integrity": "sha512-+NRMYs2DyTP4/tqWz371Oo50JqmWltR1h2gcdgUMAWZJIAvrd0/SqlCfx7tpzpl/s36rzw6qH2MjoNrxtRNYhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/traverse": "^7.28.0", + "@babel/types": "^7.28.2", + "@types/babel__core": "^7.20.5", + "@types/babel__traverse": "^7.20.7", + "@types/doctrine": "^0.0.9", + "@types/resolve": "^1.20.2", + "doctrine": "^3.0.0", + "resolve": "^1.22.1", + "strip-indent": "^4.0.0" + }, + "engines": { + "node": "^20.9.0 || >=22" + } + }, + "node_modules/react-docgen-typescript": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-2.4.0.tgz", + "integrity": "sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "typescript": ">= 4.3.x" + } + }, + "node_modules/react-docgen/node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.3" + } + }, + "node_modules/react-hook-form": { + "version": "7.71.1", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.71.1.tgz", + "integrity": "sha512-9SUJKCGKo8HUSsCO+y0CtqkqI5nNuaDqTxyqPsZPqIwudpj4rCrAz/jZV+jn57bx5gtZKOh3neQu94DXMc+w5w==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/react-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/react-property/-/react-property-2.0.2.tgz", + "integrity": "sha512-+PbtI3VuDV0l6CleQMsx2gtK0JZbZKbpdu5ynr+lbsuvtmgbNcS3VM0tuY2QjFNOcWxvXeHjDpy42RO+4U2rug==", + "license": "MIT" + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-yaml-file": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-2.1.0.tgz", + "integrity": "sha512-UkRNRIwnhG+y7hpqnycCL/xbTk7+ia9VuVTC0S+zVbwd65DI9eUpRMfsWIGrCWxTU/mi+JW8cHQCrv+zfCbEPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-yaml": "^4.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=10.13" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/recast": { + "version": "0.23.11", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", + "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-types": "^0.16.1", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tiny-invariant": "^1.3.3", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redent/node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redis": { + "version": "4.6.15", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.15.tgz", + "integrity": "sha512-2NtuOpMW3tnYzBw6S8mbXSX7RPzvVFCA2wFJq9oErushO2UeBkxObk+uvo7gv7n0rhWeOj/IzrHO8TjcFlRSOg==", + "dev": true, + "license": "MIT", + "workspaces": [ + "./packages/*" + ], + "dependencies": { + "@redis/bloom": "1.2.0", + "@redis/client": "1.5.17", + "@redis/graph": "1.1.1", + "@redis/json": "1.0.6", + "@redis/search": "1.1.6", + "@redis/time-series": "1.0.5" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/remark": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz", + "integrity": "sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "remark-parse": "^9.0.0", + "remark-stringify": "^9.0.0", + "unified": "^9.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-github": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/remark-github/-/remark-github-10.1.0.tgz", + "integrity": "sha512-q0BTFb41N6/uXQVkxRwLRTFRfLFPYP+8li26Js5XC0GKritCSaxrftd+t+8sfN+1i9BtmJPUKoS7CZwtccj0Fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdast-util-find-and-replace": "^1.0.0", + "mdast-util-to-string": "^1.0.0", + "unist-util-visit": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", + "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^0.8.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz", + "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdast-util-to-markdown": "^0.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/renovate": { + "version": "37.440.7", + "resolved": "https://registry.npmjs.org/renovate/-/renovate-37.440.7.tgz", + "integrity": "sha512-y6/JW4uUTgY9J2CZE993DwwdYqeyLeUn+cepT0w+5XJmbOHoY+XInZB46Ens0E+OHPu6qxOXv5Wai3gdIDnDXw==", + "dev": true, + "license": "AGPL-3.0-only", + "dependencies": { + "@aws-sdk/client-codecommit": "3.606.0", + "@aws-sdk/client-ec2": "3.606.0", + "@aws-sdk/client-ecr": "3.606.0", + "@aws-sdk/client-rds": "3.606.0", + "@aws-sdk/client-s3": "3.606.0", + "@aws-sdk/credential-providers": "3.606.0", + "@breejs/later": "4.2.0", + "@cdktf/hcl2json": "0.20.8", + "@opentelemetry/api": "1.9.0", + "@opentelemetry/context-async-hooks": "1.25.1", + "@opentelemetry/exporter-trace-otlp-http": "0.52.1", + "@opentelemetry/instrumentation": "0.52.1", + "@opentelemetry/instrumentation-bunyan": "0.40.0", + "@opentelemetry/instrumentation-http": "0.52.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1", + "@opentelemetry/sdk-trace-node": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1", + "@qnighy/marshal": "0.1.3", + "@renovatebot/kbpgp": "3.0.1", + "@renovatebot/osv-offline": "1.5.7", + "@renovatebot/pep440": "3.0.20", + "@renovatebot/ruby-semver": "3.0.23", + "@sindresorhus/is": "4.6.0", + "@yarnpkg/core": "4.1.1", + "@yarnpkg/parsers": "3.0.2", + "agentkeepalive": "4.5.0", + "aggregate-error": "3.1.0", + "auth-header": "1.0.0", + "aws4": "1.13.0", + "azure-devops-node-api": "14.0.1", + "bunyan": "1.8.15", + "cacache": "18.0.4", + "cacheable-lookup": "5.0.4", + "chalk": "4.1.2", + "changelog-filename-regex": "2.0.1", + "clean-git-ref": "2.0.1", + "commander": "12.1.0", + "conventional-commits-detector": "1.0.3", + "cron-parser": "4.9.0", + "deepmerge": "4.3.1", + "dequal": "2.0.3", + "detect-indent": "6.1.0", + "diff": "5.2.0", + "editorconfig": "2.0.0", + "email-addresses": "5.0.0", + "emoji-regex": "10.3.0", + "emojibase": "15.3.1", + "emojibase-regex": "15.3.2", + "extract-zip": "2.0.1", + "find-packages": "10.0.4", + "find-up": "5.0.0", + "fs-extra": "11.2.0", + "git-url-parse": "14.1.0", + "github-url-from-git": "1.5.0", + "glob": "10.4.5", + "global-agent": "3.0.0", + "good-enough-parser": "1.1.23", + "google-auth-library": "9.11.0", + "got": "11.8.6", + "graph-data-structure": "3.5.0", + "handlebars": "4.7.8", + "ignore": "5.3.1", + "ini": "4.1.3", + "js-yaml": "4.1.0", + "json-dup-key-validator": "1.0.3", + "json-stringify-pretty-compact": "3.0.0", + "json5": "2.2.3", + "jsonata": "2.0.5", + "jsonc-parser": "3.3.1", + "klona": "2.0.6", + "lru-cache": "10.4.3", + "luxon": "3.4.4", + "markdown-it": "14.1.0", + "markdown-table": "2.0.0", + "minimatch": "9.0.5", + "moo": "0.5.2", + "ms": "2.1.3", + "nanoid": "3.3.7", + "node-html-parser": "6.1.13", + "p-all": "3.0.0", + "p-map": "4.0.0", + "p-queue": "6.6.2", + "p-throttle": "4.1.1", + "parse-link-header": "2.0.0", + "prettier": "3.3.3", + "redis": "4.6.15", + "remark": "13.0.0", + "remark-github": "10.1.0", + "safe-stable-stringify": "2.4.3", + "semver": "7.6.3", + "semver-stable": "3.0.0", + "semver-utils": "1.1.4", + "shlex": "2.1.2", + "simple-git": "3.25.0", + "slugify": "1.6.6", + "source-map-support": "0.5.21", + "toml-eslint-parser": "0.10.0", + "traverse": "0.6.9", + "tslib": "2.6.3", + "upath": "2.0.1", + "url-join": "4.0.1", + "validate-npm-package-name": "5.0.1", + "vuln-vects": "1.1.0", + "xmldoc": "1.3.0", + "zod": "3.23.8" + }, + "bin": { + "renovate": "dist/renovate.js", + "renovate-config-validator": "dist/config-validator.js" + }, + "engines": { + "node": "^18.12.0 || >=20.0.0", + "pnpm": "^9.0.0" + }, + "optionalDependencies": { + "better-sqlite3": "11.1.2", + "openpgp": "5.11.2", + "re2": "1.21.3" + } + }, + "node_modules/renovate/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/renovate/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/renovate/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true, + "license": "MIT" + }, + "node_modules/renovate/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/renovate/node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/renovate/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/renovate/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/renovate/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/renovate/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/renovate/node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/renovate/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/renovate/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/renovate/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true, + "license": "0BSD" + }, + "node_modules/renovate/node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "glob": "^6.0.1" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/rollup": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.56.0.tgz", + "integrity": "sha512-9FwVqlgUHzbXtDg9RCMgodF3Ua4Na6Gau+Sdt9vyCN4RhHfVKX2DCHy3BjMLTDd47ITDhYAnTwGulWTblJSDLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.56.0", + "@rollup/rollup-android-arm64": "4.56.0", + "@rollup/rollup-darwin-arm64": "4.56.0", + "@rollup/rollup-darwin-x64": "4.56.0", + "@rollup/rollup-freebsd-arm64": "4.56.0", + "@rollup/rollup-freebsd-x64": "4.56.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.56.0", + "@rollup/rollup-linux-arm-musleabihf": "4.56.0", + "@rollup/rollup-linux-arm64-gnu": "4.56.0", + "@rollup/rollup-linux-arm64-musl": "4.56.0", + "@rollup/rollup-linux-loong64-gnu": "4.56.0", + "@rollup/rollup-linux-loong64-musl": "4.56.0", + "@rollup/rollup-linux-ppc64-gnu": "4.56.0", + "@rollup/rollup-linux-ppc64-musl": "4.56.0", + "@rollup/rollup-linux-riscv64-gnu": "4.56.0", + "@rollup/rollup-linux-riscv64-musl": "4.56.0", + "@rollup/rollup-linux-s390x-gnu": "4.56.0", + "@rollup/rollup-linux-x64-gnu": "4.56.0", + "@rollup/rollup-linux-x64-musl": "4.56.0", + "@rollup/rollup-openbsd-x64": "4.56.0", + "@rollup/rollup-openharmony-arm64": "4.56.0", + "@rollup/rollup-win32-arm64-msvc": "4.56.0", + "@rollup/rollup-win32-ia32-msvc": "4.56.0", + "@rollup/rollup-win32-x64-gnu": "4.56.0", + "@rollup/rollup-win32-x64-msvc": "4.56.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-json-stringify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", + "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/sax": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", + "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver-stable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/semver-stable/-/semver-stable-3.0.0.tgz", + "integrity": "sha512-lolq9k0lqdnZ0C4+QJvrPBWiAHGhLaVSMTPJajn527ptOHAcZnEhj0n2r6ALnryNiRKPO9AIO9iBI3ZSheHCaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.3.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/semver-utils": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/semver-utils/-/semver-utils-1.1.4.tgz", + "integrity": "sha512-EjnoLE5OGmDAVV/8YDoN5KiajNadjzIp9BAHOhYeQHt7j0UWxjmgsx4YD48wp4Ue1Qogq38F1GNUJNqF1kKKxA==", + "dev": true, + "license": "APACHEv2" + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/sharp/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/shlex": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/shlex/-/shlex-2.1.2.tgz", + "integrity": "sha512-Nz6gtibMVgYeMEhUjp2KuwAgqaJA1K155dU/HuDaEJUGgnmYfVtVZah+uerVWdH8UGnyahhDCgABbYTbs254+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-git": { + "version": "3.25.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.25.0.tgz", + "integrity": "sha512-KIY5sBnzc4yEcJXW7Tdv4viEz8KyG+nU0hay+DWZasvdFOYKeUZ6Xc25LUHHjw0tinPT7O1eY6pzX7pRT1K8rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.3.5" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/git-js?sponsor=1" + } + }, + "node_modules/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slugify": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz", + "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/sort-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-4.2.0.tgz", + "integrity": "sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sort-keys/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "license": "ISC", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/ssri": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/stable-hash": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", + "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", + "dev": true, + "license": "MIT" + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/state-local": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==", + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/storybook": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.2.0.tgz", + "integrity": "sha512-fIQnFtpksRRgHR1CO1onGX3djaog4qsW/c5U8arqYTkUEr2TaWpn05mIJDOBoPJFlOdqFrB4Ttv0PZJxV7avhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/icons": "^2.0.1", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/user-event": "^14.6.1", + "@vitest/expect": "3.2.4", + "@vitest/spy": "3.2.4", + "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0", + "open": "^10.2.0", + "recast": "^0.23.5", + "semver": "^7.7.3", + "use-sync-external-store": "^1.5.0", + "ws": "^8.18.0" + }, + "bin": { + "storybook": "dist/bin/dispatcher.js" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "prettier": "^2 || ^3" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + } + } + }, + "node_modules/storybook/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-comments-strings": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/strip-comments-strings/-/strip-comments-strings-1.2.0.tgz", + "integrity": "sha512-zwF4bmnyEjZwRhaak9jUWNxc0DoeKBJ7lwSN/LEc8dQXZcUFG6auaaTQJokQWXopLdM3iTx01nQT8E4aL29DAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/strip-indent": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.1.1.tgz", + "integrity": "sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strnum": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/style-to-js": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", + "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.14" + } + }, + "node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/swr": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.8.tgz", + "integrity": "sha512-gaCPRVoMq8WGDcWj9p4YWzCMPHzE0WNl6W8ADIx9c3JBEIdMkJGMzW+uzXvxHMltwcYACr9jP+32H8/hgwMR7w==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "license": "MIT" + }, + "node_modules/tailwind-merge": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.0.tgz", + "integrity": "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", + "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exhorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-fs": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/throttleit": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-2.1.0.tgz", + "integrity": "sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/through2-concurrent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/through2-concurrent/-/through2-concurrent-2.0.0.tgz", + "integrity": "sha512-R5/jLkfMvdmDD+seLwN7vB+mhbqzWop5fAjx5IX8/yQq7VhBhzDmhXgaHAOnhnWkCpRMM7gToYHycB0CS/pd+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "through2": "^2.0.0" + } + }, + "node_modules/through2-concurrent/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/through2-concurrent/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2-concurrent/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/through2-concurrent/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/through2-concurrent/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinylogic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinylogic/-/tinylogic-2.0.0.tgz", + "integrity": "sha512-dljTkiLLITtsjqBvTA1MRZQK/sGP4kI3UJKc3yA9fMzYbMF2RhcN04SeROVqJBIYYOoJMM8u0WDnhFwMSFQotw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyrainbow": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", + "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "7.0.19", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.19.tgz", + "integrity": "sha512-8PWx8tvC4jDB39BQw1m4x8y5MH1BcQ5xHeL2n7UVFulMPH/3Q0uiamahFJ3lXA0zO2SUyRXuVVbWSDmstlt9YA==", + "license": "MIT", + "dependencies": { + "tldts-core": "^7.0.19" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.0.19", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.19.tgz", + "integrity": "sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==", + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toml-eslint-parser": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/toml-eslint-parser/-/toml-eslint-parser-0.10.0.tgz", + "integrity": "sha512-khrZo4buq4qVmsGzS5yQjKe/WsFvV8fGfOjDQN0q4iy9FjRfPWRgTFrU8u1R2iu/SfWLhY9WnCi4Jhdrcbtg+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + } + }, + "node_modules/toml-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", + "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==", + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/traverse": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.9.tgz", + "integrity": "sha512-7bBrcF+/LQzSgFmT0X5YclVqQxtv7TDJ1f8Wj7ibBu/U6BMLeOpUxuZjV7rMc44UtKxlnMFigdhFAIszSX1DMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "gopd": "^1.0.1", + "typedarray.prototype.slice": "^1.0.3", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/treeify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", + "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/triplesec": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/triplesec/-/triplesec-4.0.3.tgz", + "integrity": "sha512-fug70e1nJoCMxsXQJlETisAALohm84vl++IiTTHEqM7Lgqwz62jrlwqOC/gJEAJjO/ByN127sEcioB56HW3wIw==", + "dev": true, + "dependencies": { + "iced-error": ">=0.0.9", + "iced-lock": "^1.0.1", + "iced-runtime": "^1.0.2", + "more-entropy": ">=0.0.7", + "progress": "~1.1.2", + "uglify-js": "^3.1.9" + } + }, + "node_modules/triplesec/node_modules/iced-lock": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/iced-lock/-/iced-lock-1.1.0.tgz", + "integrity": "sha512-J9UMVitgTMYrkUil5EB9/Q4BPWiMpFH156yjDlmMoMRKs3s3PnXj/6G0UlzIOGnNi5JVNk/zVYLXVnuo+1QnqQ==", + "dev": true, + "dependencies": { + "iced-runtime": "^1.0.0" + } + }, + "node_modules/trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-api-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.10" + } + }, + "node_modules/tsconfck": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", + "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", + "dev": true, + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/tsx/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "dev": true, + "license": "Unlicense" + }, + "node_modules/typanion": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/typanion/-/typanion-3.14.0.tgz", + "integrity": "sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==", + "dev": true, + "license": "MIT", + "workspaces": [ + "website" + ] + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-rest-client": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-2.2.0.tgz", + "integrity": "sha512-/e2Rk9g20N0r44kaQLb3v6QGuryOD8SPb53t43Y5kqXXA+SqWuU7zLiMxetw61jNn/JFrxTdr5nPDhGY/eTNhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "des.js": "^1.1.0", + "js-md4": "^0.3.2", + "qs": "^6.14.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + }, + "engines": { + "node": ">= 16.0.0" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typedarray.prototype.slice": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typedarray.prototype.slice/-/typedarray.prototype.slice-1.0.5.tgz", + "integrity": "sha512-q7QNVDGTdl702bVFiI5eY4l/HkgCM6at9KhcFbgUAzezHFbOVy4+0O/lCjsABEQwbZPravVfBIiBVGo89yzHFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "math-intrinsics": "^1.1.0", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-offset": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.53.1.tgz", + "integrity": "sha512-gB+EVQfP5RDElh9ittfXlhZJdjSU4jUSTyE2+ia8CYyNvet4ElfaLlAIqDvQV9JPknKx0jQH1racTYe/4LaLSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.53.1", + "@typescript-eslint/parser": "8.53.1", + "@typescript-eslint/typescript-estree": "8.53.1", + "@typescript-eslint/utils": "8.53.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uint64be": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uint64be/-/uint64be-1.0.1.tgz", + "integrity": "sha512-w+VZSp8hSZ/xWZfZNMppWNF6iqY+dcMYtG5CpwRDgxi94HIE6ematSdkzHGzVC4SDEaTsG65zrajN+oKoWG6ew==", + "dev": true, + "license": "MIT" + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/underscore": { + "version": "1.13.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", + "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", + "dev": true, + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unified": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", + "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", + "trough": "^1.0.0", + "vfile": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unplugin": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.11.tgz", + "integrity": "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "acorn": "^8.15.0", + "picomatch": "^4.0.3", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/unrs-resolver": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", + "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + } + }, + "node_modules/upath": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", + "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-plugin-storybook-nextjs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/vite-plugin-storybook-nextjs/-/vite-plugin-storybook-nextjs-3.1.9.tgz", + "integrity": "sha512-fh230fzSicXsUZCqANoN1hyIR8Oca4+dxP2hiVqNk/qhZKOZVcUaaPz9hXlFLMc3qPB5uKjBgxS+JLn04SJtuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/env": "16.0.0", + "image-size": "^2.0.0", + "magic-string": "^0.30.11", + "module-alias": "^2.2.3", + "ts-dedent": "^2.2.0", + "vite-tsconfig-paths": "^5.1.4" + }, + "peerDependencies": { + "next": "^14.1.0 || ^15.0.0 || ^16.0.0", + "storybook": "^0.0.0-0 || ^9.0.0 || ^10.0.0 || ^10.0.0-0 || ^10.1.0-0 || ^10.2.0-0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/vite-plugin-storybook-nextjs/node_modules/@next/env": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.0.0.tgz", + "integrity": "sha512-s5j2iFGp38QsG1LWRQaE2iUY3h1jc014/melHFfLdrsMJPqxqDQwWNwyQTcNoUSGZlCVZuM7t7JDMmSyRilsnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite-tsconfig-paths": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-5.1.4.tgz", + "integrity": "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "tsconfck": "^3.0.3" + }, + "peerDependencies": { + "vite": "*" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/vitest": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.18.tgz", + "integrity": "sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.0.18", + "@vitest/mocker": "4.0.18", + "@vitest/pretty-format": "4.0.18", + "@vitest/runner": "4.0.18", + "@vitest/snapshot": "4.0.18", + "@vitest/spy": "4.0.18", + "@vitest/utils": "4.0.18", + "es-module-lexer": "^1.7.0", + "expect-type": "^1.2.2", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^3.10.0", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.0.3", + "vite": "^6.0.0 || ^7.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.0.18", + "@vitest/browser-preview": "4.0.18", + "@vitest/browser-webdriverio": "4.0.18", + "@vitest/ui": "4.0.18", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/@vitest/expect": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.18.tgz", + "integrity": "sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.0.18", + "@vitest/utils": "4.0.18", + "chai": "^6.2.1", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest/node_modules/@vitest/mocker": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.18.tgz", + "integrity": "sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.0.18", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/@vitest/spy": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.18.tgz", + "integrity": "sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest/node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/vuln-vects": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vuln-vects/-/vuln-vects-1.1.0.tgz", + "integrity": "sha512-LGDwn9nRz94YoeqOn2TZqQXzyonBc5FJppSgH34S/1U+3bgPONq/vvfiCbCQ4MeBll58xx+kDmhS73ac+EHBBw==", + "dev": true, + "license": "MIT" + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-15.1.0.tgz", + "integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==", + "license": "MIT", + "dependencies": { + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/write-yaml-file": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/write-yaml-file/-/write-yaml-file-4.2.0.tgz", + "integrity": "sha512-LwyucHy0uhWqbrOkh9cBluZBeNVxzHjDaE9mwepZG3n3ZlbM4v3ndrFw51zW/NXYFFqP+QWZ72ihtLWTh05e4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-yaml": "^4.0.0", + "write-file-atomic": "^3.0.3" + }, + "engines": { + "node": ">=10.13" + } + }, + "node_modules/write-yaml-file/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/write-yaml-file/node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "license": "MIT" + }, + "node_modules/xmldoc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.3.0.tgz", + "integrity": "sha512-y7IRWW6PvEnYQZNZFMRLNJw+p3pezM4nKYPfr15g4OOW9i8VpeydycFuipE2297OvZnh3jSb2pxOt9QpkZUVng==", + "dev": true, + "license": "MIT", + "dependencies": { + "sax": "^1.2.4" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + }, + "node_modules/zustand": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.10.tgz", + "integrity": "sha512-U1AiltS1O9hSy3rul+Ub82ut2fqIAefiSuwECWt6jlMVUGejvf+5omLcRBSzqbRagSM3hQZbtzdeRc6QVScXTg==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + }, + "node_modules/zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +}