Initial commit: notification-elements-demo app

Interactive Angular 19 demo for @sda/notification-elements-ui with
6 sections: Bell & Feed, Notification Center, Inbox, Comments &
Threads, Mention Input, and Full-Featured layout. Includes mock
data, dark mode toggle, and real-time event log.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Giuliano Silvestro
2026-02-13 21:49:19 +10:00
commit 5d0c9ec7eb
36473 changed files with 3778146 additions and 0 deletions

103
node_modules/glob-to-regex.js/README.md generated vendored Normal file
View File

@@ -0,0 +1,103 @@
# glob-to-regex.js
Transform GLOB patterns to JavaScript regular expressions for fast file path matching.
This tiny library converts familiar shell-style glob patterns like `**/*.ts` or `src/{a,b}/**/*.js` into JavaScript `RegExp` objects and provides a convenient matcher utility.
## Install
```bash
yarn add glob-to-regex.js
# or
npm i glob-to-regex.js
```
## Quick start
```ts
import {toRegex, toMatcher} from 'glob-to-regex.js';
// Build a RegExp from a glob
const re = toRegex('src/**/test.ts');
re.test('src/a/b/test.ts'); // true
re.test('src/test.ts'); // true
re.test('src/test.tsx'); // false
// Build a predicate function from a pattern or an array of patterns
const match = toMatcher(['**/*.ts', '!**/*.d.ts']); // negative patterns are not special; use a RegExp if needed
match('index.ts'); // true
match('types.d.ts'); // true (negation is not parsed specially)
```
## API
- toRegex(pattern: string): RegExp
- Converts a glob pattern to an anchored regular expression (`^...$`).
- toMatcher(pattern: string | RegExp | Array<string | RegExp>): (path: string) => boolean
- Accepts a glob string, a RegExp, or an array of them. If given an array, it returns true if any item matches (logical OR, short-circuited).
- Strings starting with `/` and ending with `/flags?` are treated as regular expressions (e.g. `"/\\.test\\.ts$/"`).
## Supported glob features
- `/` separates path segments
- `*` matches zero or more characters within a single segment (does not cross `/`)
- `?` matches exactly one character within a single segment
- `**` matches across path segments, including none
- `{a,b,c}` alternation groups (no nesting). Each item inside can itself contain glob syntax
- Character classes: `[abc]`, `[a-z]`, `[!a-z]`, `[!abc]`
- **Extended globbing** (when `extglob: true` option is set):
- `?(pattern-list)` matches zero or one occurrence of the given patterns
- `*(pattern-list)` matches zero or more occurrences of the given patterns
- `+(pattern-list)` matches one or more occurrences of the given patterns
- `@(pattern-list)` matches exactly one of the given patterns
- `!(pattern-list)` matches anything except one of the given patterns
- Pattern lists use `|` as separator (e.g., `@(jpg|png|gif)`)
Notes:
- The produced RegExp is anchored at start and end (`^...$`).
- Character classes are copied through to the output regex. Use standard JavaScript class syntax.
- Brace groups are not nestable. If an unmatched `{` is found, it is treated literally.
## Examples
```ts
toRegex('a/b/c.txt').test('a/b/c.txt'); // true
toRegex('a/*.txt').test('a/file.txt'); // true
toRegex('a/*.txt').test('a/x/y.txt'); // false
toRegex('file?.js').test('file1.js'); // true
toRegex('src/**/test.ts').test('src/a/b/test.ts'); // true
toRegex('assets/**').test('assets/a/b.png'); // true
toRegex('*.{html,txt}').test('page.html'); // true
toRegex('src/{a,b}/**/*.ts').test('src/b/x/y.ts'); // true
toRegex('file[0-9].txt').test('file5.txt'); // true
toRegex('file[!0-9].txt').test('filea.txt'); // true
toRegex('**/*.[jt]s{,x}').test('dir/a/b.jsx'); // true
// Extended globbing examples
toRegex('file?(s).txt', {extglob: true}).test('file.txt'); // true
toRegex('file?(s).txt', {extglob: true}).test('files.txt'); // true
toRegex('file.@(jpg|png|gif)', {extglob: true}).test('file.jpg'); // true
toRegex('/var/log/!(*.gz)', {extglob: true}).test('/var/log/syslog'); // true
toRegex('/var/log/!(*.gz)', {extglob: true}).test('/var/log/error.log.gz'); // false
toRegex('src/**/!(*.test).js', {extglob: true}).test('src/app.test.js'); // false
toRegex('src/**/!(*.test).js', {extglob: true}).test('src/index.js'); // true
```
## TypeScript
Types are bundled. The library targets modern Node.js and browsers.
## Performance
`toRegex` performs a single pass over the pattern and creates a native RegExp. Matching is then performed by V8's highly optimized engine.
## Limitations
- Brace groups are not nested.
- Negated globs like `!**/*.d.ts` are not parsed specially. If you need exclusion, combine multiple matchers or filter results separately.
## License
Apache-2.0 © streamich

36
node_modules/glob-to-regex.js/lib/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,36 @@
export interface GlobOptions {
/** Treat pattern as case insensitive */
nocase?: boolean;
/** Enable extended globbing: ?(pattern), *(pattern), +(pattern), @(pattern), !(pattern) */
extglob?: boolean;
}
/**
* Convert a glob pattern to a regular expression
*
* Supports:
* - `/` to separate path segments
* - `*` to match zero or more characters in a path segment
* - `?` to match one character in a path segment
* - `**` to match any number of path segments, including none
* - `{}` to group conditions (e.g. `{html,txt}`)
* - `[abc]`, `[a-z]`, `[!a-z]`, `[!abc]` character classes
* - Extended globbing (when `extglob: true` option is set):
* - `?(pattern-list)` zero or one occurrence
* - `*(pattern-list)` zero or more occurrences
* - `+(pattern-list)` one or more occurrences
* - `@(pattern-list)` exactly one of the patterns
* - `!(pattern-list)` anything except the patterns
*/
export declare const toRegex: (pattern: string, options?: GlobOptions) => RegExp;
/**
* A glob pattern to match files paths against. An array or a single pattern
* can be provided, if an array is given, then individual patterns will be
* tested in order until one matches (OR short-circuits).
*
* For each pattern a string or a regular expression can be provided. If the
* string starts with `/` and ends with `/<flags>?` it is treated as a regular
* expression.
*/
export type Pattern = string | RegExp | (string | RegExp)[];
export type Matcher = (path: string) => boolean;
export declare const toMatcher: (pattern: Pattern, options?: GlobOptions) => Matcher;

245
node_modules/glob-to-regex.js/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,245 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.toMatcher = exports.toRegex = void 0;
const escapeRe = (ch) => (/[.^$+{}()|\\]/.test(ch) ? `\\${ch}` : ch);
/**
* Parse an extended glob pattern like ?(a|b|c)
* Returns the regex string equivalent and the new index position
*/
const parseExtGlob = (pattern, startIdx, prefix, options) => {
let i = startIdx; // startIdx should be pointing at the character after '('
const parts = [];
let cur = '';
let depth = 1; // Track parenthesis depth for nested patterns
while (i < pattern.length && depth > 0) {
const ch = pattern[i];
if (ch === '(') {
depth++;
cur += ch;
i++;
}
else if (ch === ')') {
depth--;
if (depth === 0) {
// Found the closing parenthesis
parts.push(cur);
i++; // consume ')'
break;
}
else {
cur += ch;
i++;
}
}
else if (ch === '|' && depth === 1) {
// Pipe separator at top level of this extglob
parts.push(cur);
cur = '';
i++;
}
else {
cur += ch;
i++;
}
}
if (depth !== 0)
return; // Unclosed parenthesis
let alternatives = '';
const length = parts.length;
for (let j = 0; j < length; j++)
alternatives += (alternatives ? '|' : '') + (0, exports.toRegex)(parts[j], options).source.replace(/^\^/, '').replace(/\$$/, '');
switch (prefix) {
case '?': // zero or one
return [`(?:${alternatives})?`, i];
case '*': // zero or more
return [`(?:${alternatives})*`, i];
case '+': // one or more
return [`(?:${alternatives})+`, i];
case '@': // exactly one
return [`(?:${alternatives})`, i];
case '!': // none of (negative match)
// For negation, we need to match anything that doesn't match the pattern
// Use negative lookahead without consuming characters after
return [`(?!${alternatives})[^/]*`, i];
}
return;
};
/**
* Convert a glob pattern to a regular expression
*
* Supports:
* - `/` to separate path segments
* - `*` to match zero or more characters in a path segment
* - `?` to match one character in a path segment
* - `**` to match any number of path segments, including none
* - `{}` to group conditions (e.g. `{html,txt}`)
* - `[abc]`, `[a-z]`, `[!a-z]`, `[!abc]` character classes
* - Extended globbing (when `extglob: true` option is set):
* - `?(pattern-list)` zero or one occurrence
* - `*(pattern-list)` zero or more occurrences
* - `+(pattern-list)` one or more occurrences
* - `@(pattern-list)` exactly one of the patterns
* - `!(pattern-list)` anything except the patterns
*/
const toRegex = (pattern, options) => {
let regexStr = '';
let i = 0;
// Helper to parse a brace group like {a,b,c}. No nesting support.
const parseBraceGroup = () => {
// Assume current char is '{'
i++; // skip '{'
const parts = [];
let cur = '';
let closed = false;
while (i < pattern.length) {
const ch = pattern[i];
if (ch === '}') {
parts.push(cur);
i++; // consume '}'
closed = true;
break;
}
if (ch === ',') {
parts.push(cur);
cur = '';
i++;
continue;
}
cur += ch;
i++;
}
if (!closed) {
// treat as literal '{...'
return '\\{' + escapeRe(cur);
}
// Convert each part recursively to support globs inside braces
const alt = parts.map((p) => (0, exports.toRegex)(p, options).source.replace(/^\^/, '').replace(/\$$/, '')).join('|');
return `(?:${alt})`;
};
const extglob = !!options?.extglob;
while (i < pattern.length) {
const char = pattern[i];
// Check for extended glob patterns when extglob is enabled
if (extglob && pattern[i + 1] === '(') {
if (char === '?' || char === '*' || char === '+' || char === '@' || char === '!') {
const result = parseExtGlob(pattern, i + 2, char, options);
if (result) {
regexStr += result[0];
i = result[1];
continue;
}
// If parse failed, fall through to normal handling
}
}
switch (char) {
case '*': {
// Check for double star **
if (pattern[i + 1] === '*') {
// Collapse consecutive * beyond two (e.g., *** -> **)
let j = i + 2;
while (pattern[j] === '*')
j++;
// If followed by a slash, make it optional to allow zero segments
if (pattern[j] === '/') {
regexStr += '(?:.*/)?';
i = j + 1; // consume **/
}
else {
regexStr += '.*';
i = j; // consume **
}
}
else {
regexStr += '[^/]*';
i++;
}
break;
}
case '?':
regexStr += '[^/]';
i++;
break;
case '[': {
// Copy character class as-is with support for leading '!'
let cls = '[';
i++;
if (i < pattern.length && pattern[i] === '!') {
cls += '^';
i++;
}
// if first after [ or [^ is ']' include it literally
if (i < pattern.length && pattern[i] === ']') {
cls += ']';
i++;
}
while (i < pattern.length && pattern[i] !== ']') {
const ch = pattern[i];
// Escape backslash inside class
cls += ch === '\\' ? '\\\\' : ch;
i++;
}
if (i < pattern.length && pattern[i] === ']') {
cls += ']';
i++;
}
else {
// Unclosed class -> treat '[' literally
regexStr += '\\[';
continue;
}
regexStr += cls;
break;
}
case '{': {
regexStr += parseBraceGroup();
break;
}
case '/':
regexStr += '/';
i++;
break;
case '.':
case '^':
case '$':
case '+':
case '(':
case ')':
case '|':
case '\\':
regexStr += `\\${char}`;
i++;
break;
default:
regexStr += char;
i++;
break;
}
}
const flags = options?.nocase ? 'i' : '';
return new RegExp('^' + regexStr + '$', flags);
};
exports.toRegex = toRegex;
const isRegExp = /^\/(.{1,4096})\/([gimsuy]{0,6})$/;
const toMatcher = (pattern, options) => {
const regexes = [];
const patterns = Array.isArray(pattern) ? pattern : [pattern];
for (const pat of patterns) {
if (typeof pat === 'string') {
const match = isRegExp.exec(pat);
if (match) {
const [, expr, flags] = match;
regexes.push(new RegExp(expr, flags));
}
else {
regexes.push((0, exports.toRegex)(pat, options));
}
}
else {
regexes.push(pat);
}
}
return regexes.length
? new Function('p', 'return ' + regexes.map((r) => r + '.test(p)').join('||'))
: () => false;
};
exports.toMatcher = toMatcher;

65
node_modules/glob-to-regex.js/package.json generated vendored Normal file
View File

@@ -0,0 +1,65 @@
{
"name": "glob-to-regex.js",
"packageManager": "yarn@4.9.4",
"publishConfig": {
"access": "public"
},
"version": "1.2.0",
"description": "Transform GLOB patterns to JavaScript regular expressions for fast file path matching.",
"author": {
"name": "streamich",
"url": "https://github.com/streamich"
},
"homepage": "https://github.com/streamich/glob-to-regex",
"repository": "streamich/glob-to-regex",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/streamich"
},
"keywords": [
"glob",
"regex",
"regexp",
"pattern",
"matcher",
"path",
"filesystem",
"wildcard"
],
"engines": {
"node": ">=10.0"
},
"main": "lib/index.js",
"types": "lib/index.d.ts",
"typings": "lib/index.d.ts",
"files": [
"LICENSE",
"lib/"
],
"license": "Apache-2.0",
"scripts": {
"format": "biome format ./src",
"format:fix": "biome format --write ./src",
"lint": "biome lint ./src",
"lint:fix": "biome lint --apply ./src",
"clean": "npx rimraf@6.0.1 lib typedocs coverage gh-pages yarn-error.log",
"build": "tsc --project tsconfig.build.json --module commonjs --target es2020 --outDir lib",
"test": "vitest ./src",
"coverage": "vitest run --coverage",
"typedoc": "npx typedoc@0.25.13 --tsconfig tsconfig.build.json",
"build:pages": "npx rimraf@6.0.1 gh-pages && mkdir -p gh-pages && cp -r typedocs/* gh-pages && cp -r coverage gh-pages/coverage",
"deploy:pages": "gh-pages -d gh-pages",
"publish-coverage-and-typedocs": "yarn typedoc && yarn coverage && yarn build:pages && yarn deploy:pages"
},
"peerDependencies": {
"tslib": "2"
},
"devDependencies": {
"@biomejs/biome": "^2.1.2",
"@vitest/coverage-v8": "^3.2.4",
"config-galore": "^1.0.0",
"tslib": "^2.8.1",
"typescript": "^5.8.3",
"vitest": "^3.2.4"
}
}