ngx-transforms 0.0.5 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ngx-transforms.mjs +969 -651
- package/fesm2022/ngx-transforms.mjs.map +1 -1
- package/package.json +8 -3
- package/types/ngx-transforms.d.ts +483 -345
|
@@ -60,8 +60,6 @@ import * as QRCode from 'qrcode';
|
|
|
60
60
|
* @example
|
|
61
61
|
* // With inverted colors
|
|
62
62
|
* {{ 'DARK' | asciiArt:{ inverted: true, charset: CharsetPreset.MINIMAL } }}
|
|
63
|
-
*
|
|
64
|
-
* @author Mofiro Jean
|
|
65
63
|
*/
|
|
66
64
|
class AsciiArtPipe {
|
|
67
65
|
generator;
|
|
@@ -119,94 +117,615 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
119
117
|
}], ctorParameters: () => [] });
|
|
120
118
|
|
|
121
119
|
/**
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* @param {string} value - The value to encode (e.g., '123456789').
|
|
125
|
-
* @param {BarcodeOptions} [options={}] - Configuration options.
|
|
120
|
+
* CamelCasePipe: Converts text to camelCase (e.g., "hello world" → "helloWorld").
|
|
126
121
|
*
|
|
127
|
-
* @
|
|
122
|
+
* @param {string} value - The input string to transform.
|
|
123
|
+
* @returns {string} The string in camelCase, or an empty string if input is invalid.
|
|
128
124
|
*
|
|
129
125
|
* @example
|
|
130
|
-
*
|
|
131
|
-
*
|
|
126
|
+
* ```html
|
|
127
|
+
* {{ 'hello world' | camelCase }} <!-- Outputs: helloWorld -->
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
class CamelCasePipe {
|
|
131
|
+
transform(value) {
|
|
132
|
+
if (!value || typeof value !== 'string')
|
|
133
|
+
return '';
|
|
134
|
+
return value
|
|
135
|
+
.toLowerCase()
|
|
136
|
+
.replace(/[^a-zA-Z0-9]+/g, ' ')
|
|
137
|
+
.trim()
|
|
138
|
+
.split(' ')
|
|
139
|
+
.filter(word => word.length > 0)
|
|
140
|
+
.map((word, index) => index === 0
|
|
141
|
+
? word.toLowerCase()
|
|
142
|
+
: word.charAt(0).toUpperCase() + word.slice(1))
|
|
143
|
+
.join('');
|
|
144
|
+
}
|
|
145
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CamelCasePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
146
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: CamelCasePipe, isStandalone: true, name: "camelCase" });
|
|
147
|
+
}
|
|
148
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CamelCasePipe, decorators: [{
|
|
149
|
+
type: Pipe,
|
|
150
|
+
args: [{
|
|
151
|
+
name: 'camelCase',
|
|
152
|
+
standalone: true
|
|
153
|
+
}]
|
|
154
|
+
}] });
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* HighlightPipe: Highlights occurrences of a search term within a string.
|
|
158
|
+
*
|
|
159
|
+
* This Angular pipe transforms a string input by wrapping all occurrences of a specified
|
|
160
|
+
* search term with a `<span>` element that has the class "highlight".
|
|
161
|
+
* It uses the Angular `DomSanitizer` to bypass security and render the highlighted HTML.
|
|
162
|
+
*
|
|
163
|
+
* @param {string} value - The input string in which to highlight the search term.
|
|
164
|
+
* @param {string} searchTerm - The string to search for and highlight.
|
|
165
|
+
* @returns {SafeHtml} - The input string with the search term highlighted, or an empty string if input or searchTerm are falsy.
|
|
132
166
|
*
|
|
133
|
-
* @
|
|
167
|
+
* @example
|
|
168
|
+
* {{ 'This is a test string' | highlight: 'test' }} // Returns 'This is a <span class="highlight">test</span> string'
|
|
169
|
+
* {{ 'This is a test TEST string' | highlight: 'test' }} // Returns 'This is a <span class="highlight">test</span> <span class="highlight">TEST</span> string'
|
|
170
|
+
* {{ 'This is a test string' | highlight: '' }} // Returns 'This is a test string'
|
|
171
|
+
* {{ null | highlight: 'test' }} // Returns ''
|
|
172
|
+
* {{ undefined | highlight: 'test' }} // Returns ''
|
|
134
173
|
*/
|
|
135
|
-
class
|
|
174
|
+
class HighlightPipe {
|
|
136
175
|
sanitizer = inject(DomSanitizer);
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
return '';
|
|
141
|
-
}
|
|
142
|
-
// Sanitize the value to prevent XSS
|
|
143
|
-
const sanitizedValue = value.replace(/</g, '<').replace(/>/g, '>');
|
|
144
|
-
try {
|
|
145
|
-
const config = { format, lineColor, width, height, displayValue };
|
|
146
|
-
if (elementType === 'svg') {
|
|
147
|
-
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
148
|
-
JsBarcode(svg, sanitizedValue, config);
|
|
149
|
-
return this.sanitizer.bypassSecurityTrustHtml(svg.outerHTML);
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
const canvas = document.createElement('canvas');
|
|
153
|
-
JsBarcode(canvas, sanitizedValue, config);
|
|
154
|
-
const dataUrl = canvas.toDataURL('image/png');
|
|
155
|
-
return this.sanitizer.bypassSecurityTrustResourceUrl(dataUrl);
|
|
156
|
-
}
|
|
176
|
+
transform(value, searchTerm) {
|
|
177
|
+
if (!value || !searchTerm) {
|
|
178
|
+
return this.sanitizer.bypassSecurityTrustHtml(value || '');
|
|
157
179
|
}
|
|
158
|
-
|
|
159
|
-
|
|
180
|
+
const escapedSearch = searchTerm.replace(/[.*+?${}()|[\\]/g, '\\$&');
|
|
181
|
+
const regex = new RegExp(`(${escapedSearch})`, 'gi');
|
|
182
|
+
const highlighed = value.replace(regex, '<span class="highlight">$1</span>');
|
|
183
|
+
return this.sanitizer.bypassSecurityTrustHtml(highlighed);
|
|
184
|
+
}
|
|
185
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: HighlightPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
186
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: HighlightPipe, isStandalone: true, name: "highlight" });
|
|
187
|
+
}
|
|
188
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: HighlightPipe, decorators: [{
|
|
189
|
+
type: Pipe,
|
|
190
|
+
args: [{
|
|
191
|
+
name: 'highlight',
|
|
192
|
+
standalone: true
|
|
193
|
+
}]
|
|
194
|
+
}] });
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* InitialsPipe: Extracts initials from a name.
|
|
198
|
+
*
|
|
199
|
+
* @param {string} value - The full name.
|
|
200
|
+
*
|
|
201
|
+
* @returns {string} - The initials (e.g., 'John Doe' → 'JD').
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* {{ 'John Doe' | initials }} // Outputs: JD
|
|
205
|
+
* {{ 'Mary Jane Watson' | initials }} // Outputs: MJW
|
|
206
|
+
*/
|
|
207
|
+
class InitialsPipe {
|
|
208
|
+
transform(value) {
|
|
209
|
+
if (!value)
|
|
160
210
|
return '';
|
|
161
|
-
|
|
211
|
+
return value
|
|
212
|
+
.trim()
|
|
213
|
+
.split(/\s+/)
|
|
214
|
+
.map(word => word.charAt(0).toUpperCase())
|
|
215
|
+
.join('');
|
|
162
216
|
}
|
|
163
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
164
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type:
|
|
217
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: InitialsPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
218
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: InitialsPipe, isStandalone: true, name: "initials" });
|
|
165
219
|
}
|
|
166
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
220
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: InitialsPipe, decorators: [{
|
|
167
221
|
type: Pipe,
|
|
168
222
|
args: [{
|
|
169
|
-
name: '
|
|
170
|
-
standalone: true
|
|
223
|
+
name: 'initials',
|
|
224
|
+
standalone: true
|
|
171
225
|
}]
|
|
172
226
|
}] });
|
|
173
227
|
|
|
174
228
|
/**
|
|
175
|
-
*
|
|
229
|
+
* KebabCasePipe: Converts text to kebab-case (e.g., "hello world" → "hello-world").
|
|
176
230
|
*
|
|
177
231
|
* @param {string} value - The input string to transform.
|
|
178
|
-
* @returns {string} The string in
|
|
232
|
+
* @returns {string} The string in kebab-case, or an empty string if input is invalid.
|
|
179
233
|
*
|
|
180
234
|
* @example
|
|
181
235
|
* ```html
|
|
182
|
-
* {{ 'hello world' |
|
|
236
|
+
* {{ 'hello world' | kebabCase }} <!-- Outputs: hello-world -->
|
|
183
237
|
* ```
|
|
184
|
-
*
|
|
185
|
-
* @author Mofiro Jean
|
|
186
238
|
*/
|
|
187
|
-
class
|
|
239
|
+
class KebabCasePipe {
|
|
188
240
|
transform(value) {
|
|
189
241
|
if (!value || typeof value !== 'string')
|
|
190
242
|
return '';
|
|
191
|
-
return value
|
|
192
|
-
.
|
|
193
|
-
.replace(/[
|
|
194
|
-
.
|
|
195
|
-
.
|
|
196
|
-
.
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
243
|
+
return value
|
|
244
|
+
.trim()
|
|
245
|
+
.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2') // Add hyphen between camelCase words
|
|
246
|
+
.toLowerCase()
|
|
247
|
+
.replace(/[^a-z0-9-]+/g, '-') // Replace non-alphanumeric (except hyphen) with hyphen
|
|
248
|
+
.replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
|
|
249
|
+
}
|
|
250
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: KebabCasePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
251
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: KebabCasePipe, isStandalone: true, name: "kebabCase" });
|
|
252
|
+
}
|
|
253
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: KebabCasePipe, decorators: [{
|
|
254
|
+
type: Pipe,
|
|
255
|
+
args: [{
|
|
256
|
+
name: 'kebabCase',
|
|
257
|
+
standalone: true
|
|
258
|
+
}]
|
|
259
|
+
}] });
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* MorseCodePipe: Converts text to Morse code.
|
|
263
|
+
*
|
|
264
|
+
* @param {string} value - The text to convert to Morse code.
|
|
265
|
+
*
|
|
266
|
+
* @returns {string} - The Morse code representation (e.g., 'SOS' → '... --- ...').
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* {{ 'SOS' | morseCode }} // Outputs: '... --- ...'
|
|
270
|
+
* {{ 'HELP' | morseCode }} // Outputs: '.... . .-.. .--.'
|
|
271
|
+
* <p>{{ userInput | morseCode }}</p>
|
|
272
|
+
*/
|
|
273
|
+
class MorseCodePipe {
|
|
274
|
+
morseCodeMap = {
|
|
275
|
+
'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.',
|
|
276
|
+
'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..',
|
|
277
|
+
'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.',
|
|
278
|
+
'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-',
|
|
279
|
+
'Y': '-.--', 'Z': '--..', '0': '-----', '1': '.----', '2': '..---',
|
|
280
|
+
'3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...',
|
|
281
|
+
'8': '---..', '9': '----.'
|
|
282
|
+
};
|
|
283
|
+
transform(value) {
|
|
284
|
+
if (!value || typeof value !== 'string') {
|
|
285
|
+
return '';
|
|
286
|
+
}
|
|
287
|
+
return value
|
|
288
|
+
.toUpperCase()
|
|
289
|
+
.split('')
|
|
290
|
+
.map(char => this.morseCodeMap[char] || '')
|
|
291
|
+
.filter(code => code)
|
|
292
|
+
.join(' ');
|
|
293
|
+
}
|
|
294
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MorseCodePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
295
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: MorseCodePipe, isStandalone: true, name: "morseCode" });
|
|
296
|
+
}
|
|
297
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MorseCodePipe, decorators: [{
|
|
298
|
+
type: Pipe,
|
|
299
|
+
args: [{
|
|
300
|
+
name: 'morseCode',
|
|
301
|
+
standalone: true
|
|
302
|
+
}]
|
|
303
|
+
}] });
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* ReplacePipe: A custom Angular pipe that either highlights or replaces text based on a pattern.
|
|
307
|
+
*
|
|
308
|
+
* - If `isReplace` is `false`, it highlights occurrences of the pattern (if `highlightClass` is provided).
|
|
309
|
+
* - If `isReplace` is `true`, it replaces occurrences of the pattern with the replacement string, optionally highlighting the replacement.
|
|
310
|
+
*
|
|
311
|
+
* @param {string} value - The input string to transform.
|
|
312
|
+
* @param {string | RegExp} pattern - The pattern to match (string or RegExp). If an empty string, the value is returned as-is.
|
|
313
|
+
* @param {string} replacement - The string to replace matches with.
|
|
314
|
+
* @param {string} [highlightClass] - Optional CSS class for highlighting matched or replaced text (e.g., 'highlight').
|
|
315
|
+
* @param {boolean} [isReplace=true] - Whether to perform replacement (true) or only highlight matches (false).
|
|
316
|
+
*
|
|
317
|
+
* @returns {string | SafeHtml} - Returns the transformed string or SafeHtml with highlights.
|
|
318
|
+
*
|
|
319
|
+
* @example
|
|
320
|
+
* {{ 'Hello World' | replace:'World':'Universe' }}
|
|
321
|
+
* // Output: Hello Universe
|
|
322
|
+
*
|
|
323
|
+
* {{ 'test123' | replace:/\d+/g:'X':'highlight' }}
|
|
324
|
+
* // Output: test<span class="highlight">X</span>
|
|
325
|
+
*
|
|
326
|
+
* {{ 'Angular is great' | replace:'great':'awesome':'highlight':true }}
|
|
327
|
+
* // Output: Angular is <span class="highlight">awesome</span>
|
|
328
|
+
*
|
|
329
|
+
* {{ 'Angular is great' | replace:'great':'awesome':'highlight':false }}
|
|
330
|
+
* // Output: Angular is <span class="highlight">great</span>
|
|
331
|
+
*
|
|
332
|
+
* <div [innerHTML]="'Angular is great' | replace:'great':'awesome':'highlight':false"></div>
|
|
333
|
+
* // Renders: Angular is <span class="highlight">great</span>
|
|
334
|
+
*/
|
|
335
|
+
class ReplacePipe {
|
|
336
|
+
sanitizer = inject(DomSanitizer);
|
|
337
|
+
transform(value, pattern, replacement, highlightClass, isReplace = true) {
|
|
338
|
+
if (!value)
|
|
339
|
+
return '';
|
|
340
|
+
// handles empty string pattern
|
|
341
|
+
if (!pattern || (typeof pattern === 'string' && pattern.trim() === '')) {
|
|
342
|
+
return value;
|
|
343
|
+
}
|
|
344
|
+
const finalPattern = typeof pattern === 'string' ? new RegExp(pattern, 'gi') : pattern;
|
|
345
|
+
if (!highlightClass) {
|
|
346
|
+
return isReplace ? value.replace(finalPattern, replacement) : value;
|
|
347
|
+
}
|
|
348
|
+
// Sanitize the replacement to prevent XSS
|
|
349
|
+
const sanitizedReplacement = replacement.replace(/</g, '<').replace(/>/g, '>');
|
|
350
|
+
if (isReplace) {
|
|
351
|
+
const highlightedReplacement = `<span class="${highlightClass}">${sanitizedReplacement}</span>`;
|
|
352
|
+
const replaced = value.replace(finalPattern, highlightedReplacement);
|
|
353
|
+
return this.sanitizer.bypassSecurityTrustHtml(replaced);
|
|
354
|
+
}
|
|
355
|
+
const highlightedMatch = `<span class="${highlightClass}">$&</span>`;
|
|
356
|
+
const result = value.replace(finalPattern, highlightedMatch);
|
|
357
|
+
return this.sanitizer.bypassSecurityTrustHtml(result);
|
|
358
|
+
}
|
|
359
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ReplacePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
360
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: ReplacePipe, isStandalone: true, name: "replace" });
|
|
361
|
+
}
|
|
362
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ReplacePipe, decorators: [{
|
|
363
|
+
type: Pipe,
|
|
364
|
+
args: [{
|
|
365
|
+
name: 'replace',
|
|
366
|
+
standalone: true
|
|
367
|
+
}]
|
|
368
|
+
}] });
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* SnakeCasePipe: Converts text to snake_case (e.g., "hello world" → "hello_world").
|
|
372
|
+
*
|
|
373
|
+
* @param {string} value - The input string to transform.
|
|
374
|
+
* @returns {string} The string in snake_case, or an empty string if input is invalid.
|
|
375
|
+
*
|
|
376
|
+
* @example
|
|
377
|
+
* ```html
|
|
378
|
+
* {{ 'hello world' | snakeCase }} <!-- Outputs: hello_world -->
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
class SnakeCasePipe {
|
|
382
|
+
transform(value) {
|
|
383
|
+
if (!value || typeof value !== 'string')
|
|
384
|
+
return '';
|
|
385
|
+
return value
|
|
386
|
+
.trim()
|
|
387
|
+
.replace(/([A-Z])/g, '_$1') // Convert camelCase to snake_case (e.g., helloWorld -> hello_World)
|
|
388
|
+
.toLowerCase() // Convert everything to lowercase
|
|
389
|
+
.replace(/[\s-]+/g, '_') // Replace spaces and hyphens with underscores
|
|
390
|
+
.replace(/[^a-z0-9_]+/g, '') // Remove all non-alphanumeric and non-underscore characters
|
|
391
|
+
.replace(/_+/g, '_') // Collapse multiple underscores
|
|
392
|
+
.replace(/^_|_$/g, ''); // Remove leading/trailing underscores
|
|
393
|
+
}
|
|
394
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: SnakeCasePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
395
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: SnakeCasePipe, isStandalone: true, name: "snakeCase" });
|
|
396
|
+
}
|
|
397
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: SnakeCasePipe, decorators: [{
|
|
398
|
+
type: Pipe,
|
|
399
|
+
args: [{
|
|
400
|
+
name: 'snakeCase',
|
|
401
|
+
standalone: true
|
|
402
|
+
}]
|
|
403
|
+
}] });
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* TitleCasePipe: Capitalizes the first letter of each word in a string.
|
|
407
|
+
*
|
|
408
|
+
* @param {string} value - The input string to transform.
|
|
409
|
+
* @returns {string} The string with each word capitalized, or an empty string if input is invalid.
|
|
410
|
+
*
|
|
411
|
+
* @example
|
|
412
|
+
* ```html
|
|
413
|
+
* {{ 'hello world' | titleCase }} <!-- Outputs: Hello World -->
|
|
414
|
+
* ```
|
|
415
|
+
*/
|
|
416
|
+
class TitleCasePipe {
|
|
417
|
+
transform(value) {
|
|
418
|
+
if (!value || typeof value !== 'string')
|
|
419
|
+
return '';
|
|
420
|
+
return value
|
|
421
|
+
.split(' ')
|
|
422
|
+
.filter(word => word.length > 0)
|
|
423
|
+
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
424
|
+
.join(' ');
|
|
425
|
+
}
|
|
426
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: TitleCasePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
427
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: TitleCasePipe, isStandalone: true, name: "titleCase" });
|
|
428
|
+
}
|
|
429
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: TitleCasePipe, decorators: [{
|
|
430
|
+
type: Pipe,
|
|
431
|
+
args: [{
|
|
432
|
+
name: 'titleCase',
|
|
433
|
+
standalone: true
|
|
434
|
+
}]
|
|
435
|
+
}] });
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* TruncatePipe: Truncates a string to a specified maximum length, optionally preserving words.
|
|
439
|
+
*
|
|
440
|
+
* This Angular pipe transforms a string input by truncating it to the given `maxLength`.
|
|
441
|
+
* It provides options to customize the ellipsis and preserve word boundaries.
|
|
442
|
+
*
|
|
443
|
+
* @param {string} value - The input string to be truncated.
|
|
444
|
+
* @param {number} [maxLength=10] - The maximum length of the truncated string. Defaults to 10.
|
|
445
|
+
* @param {string} [ellipsis='...'] - The string to append to the truncated portion. Defaults to '...'.
|
|
446
|
+
* @param {boolean} [preserveWords=false] - If true, truncates at the last space before `maxLength` to avoid cutting words. Defaults to false.
|
|
447
|
+
* @returns {string} - The truncated string. Returns an empty string if the input is null, undefined, or not a string.
|
|
448
|
+
*
|
|
449
|
+
* @example
|
|
450
|
+
* {{ 'This is a long sentence' | truncate }} // Returns 'This is a...'
|
|
451
|
+
* {{ 'This is a long sentence' | truncate: 20 }} // Returns 'This is a long sente...'
|
|
452
|
+
* {{ 'This is a long sentence' | truncate: 15: ' [more]' }} // Returns 'This is a long [more]'
|
|
453
|
+
* {{ 'This is a long sentence' | truncate: 15: '...' : true }} // Returns 'This is a...'
|
|
454
|
+
* {{ 'This is a long sentence' | truncate: 20: '...' : true }} // Returns 'This is a long...'
|
|
455
|
+
* {{ null | truncate }} // Returns ''
|
|
456
|
+
* {{ undefined | truncate }} // Returns ''
|
|
457
|
+
*/
|
|
458
|
+
class TruncatePipe {
|
|
459
|
+
transform(value, maxLength = 10, ellipsis = '...', preserveWords = false) {
|
|
460
|
+
if (!value || typeof value !== 'string') {
|
|
461
|
+
return '';
|
|
462
|
+
}
|
|
463
|
+
if (value.length <= maxLength) {
|
|
464
|
+
return value;
|
|
465
|
+
}
|
|
466
|
+
const charsToKeep = maxLength - ellipsis.length;
|
|
467
|
+
// If maxLength is too small to even include the ellipsis, just return the ellipsis.
|
|
468
|
+
if (charsToKeep < 0) {
|
|
469
|
+
return ellipsis;
|
|
470
|
+
}
|
|
471
|
+
let truncated = value.substring(0, charsToKeep);
|
|
472
|
+
if (preserveWords) {
|
|
473
|
+
const lastSpaceIndex = truncated.lastIndexOf(' ');
|
|
474
|
+
// If a space is found and it's not the very beginning of the string
|
|
475
|
+
if (lastSpaceIndex !== -1 && lastSpaceIndex !== 0) {
|
|
476
|
+
truncated = truncated.substring(0, lastSpaceIndex);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
return truncated.trim() + ellipsis;
|
|
480
|
+
}
|
|
481
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: TruncatePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
482
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: TruncatePipe, isStandalone: true, name: "truncate" });
|
|
483
|
+
}
|
|
484
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: TruncatePipe, decorators: [{
|
|
485
|
+
type: Pipe,
|
|
486
|
+
args: [{
|
|
487
|
+
name: 'truncate',
|
|
488
|
+
standalone: true
|
|
489
|
+
}]
|
|
490
|
+
}] });
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* CreditCardMaskPipe: Masks all but the last four digits of a string, optionally controlled by a boolean flag.
|
|
494
|
+
* By default, masking is applied.
|
|
495
|
+
*
|
|
496
|
+
* @param {string} value - The input string to mask (e.g., credit card number).
|
|
497
|
+
* @param {boolean} shouldMask - (Optional) Determines if masking should be applied. Defaults to true.
|
|
498
|
+
* @returns {string} - The masked string or the original value if `shouldMask` is false or the value is too short.
|
|
499
|
+
*
|
|
500
|
+
* @example
|
|
501
|
+
* {{ '1234567890123456' | creditCardMask }} // Outputs: **** **** **** 3456
|
|
502
|
+
* {{ '1234-5678-9012-3456' | creditCardMask }} // Outputs: **** **** **** 3456
|
|
503
|
+
* {{ '1234567890123456' | creditCardMask: true }} // Outputs: **** **** **** 3456
|
|
504
|
+
* {{ '1234567890123456' | creditCardMask: false }} // Outputs: 1234567890123456
|
|
505
|
+
*/
|
|
506
|
+
class CreditCardMaskPipe {
|
|
507
|
+
transform(value, shouldMask = true) {
|
|
508
|
+
if (!value) {
|
|
509
|
+
return value;
|
|
510
|
+
}
|
|
511
|
+
if (shouldMask) {
|
|
512
|
+
const cleanedValue = value.replace(/[\s-]/g, '');
|
|
513
|
+
const cleanedLength = cleanedValue.length;
|
|
514
|
+
if (cleanedLength < 4) {
|
|
515
|
+
return value;
|
|
516
|
+
}
|
|
517
|
+
const visibleDigits = cleanedValue.slice(-4);
|
|
518
|
+
const maskedSection = '*'.repeat(cleanedLength - 4);
|
|
519
|
+
const groupedMask = maskedSection.match(/.{1,4}/g)?.join(' ') ?? '';
|
|
520
|
+
return `${groupedMask} ${visibleDigits}`.trim();
|
|
521
|
+
}
|
|
522
|
+
return value;
|
|
523
|
+
}
|
|
524
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CreditCardMaskPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
525
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: CreditCardMaskPipe, isStandalone: true, name: "creditCardMask" });
|
|
526
|
+
}
|
|
527
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CreditCardMaskPipe, decorators: [{
|
|
528
|
+
type: Pipe,
|
|
529
|
+
args: [{
|
|
530
|
+
name: 'creditCardMask',
|
|
531
|
+
standalone: true,
|
|
532
|
+
}]
|
|
533
|
+
}] });
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* EmailMaskPipe: Masks the local part of an email address, revealing only the first and last characters.
|
|
537
|
+
*
|
|
538
|
+
* This Angular pipe transforms an email address string by replacing the characters between the first and last characters of the local part (before the '@') with "***".
|
|
539
|
+
* If the local part is 2 characters or less, it masks all characters except the first.
|
|
540
|
+
*
|
|
541
|
+
* @param {string} value - The email address string to be masked.
|
|
542
|
+
* @returns {string} - The masked email address, or the original value if it's not a valid email or falsy.
|
|
543
|
+
*
|
|
544
|
+
* @example
|
|
545
|
+
* {{ 'test@example.com' | emailMask }} // Returns 't***t@example.com'
|
|
546
|
+
* {{ 'te@example.com' | emailMask }} // Returns 't***@example.com'
|
|
547
|
+
* {{ 't@example.com' | emailMask }} // Returns 't***@example.com'
|
|
548
|
+
* {{ 'example.com' | emailMask }} // Returns 'example.com'
|
|
549
|
+
* {{ null | emailMask }} // Returns ''
|
|
550
|
+
* {{ undefined | emailMask }} // Returns ''
|
|
551
|
+
*/
|
|
552
|
+
class EmailMaskPipe {
|
|
553
|
+
transform(value) {
|
|
554
|
+
if (!value || !value.includes('@')) {
|
|
555
|
+
return value || '';
|
|
556
|
+
}
|
|
557
|
+
const [local, domain] = value.split('@');
|
|
558
|
+
if (local.length <= 2) {
|
|
559
|
+
return `${local[0]}***@${domain}`;
|
|
560
|
+
}
|
|
561
|
+
const firstChar = local[0];
|
|
562
|
+
const lastChar = local[local.length - 1];
|
|
563
|
+
return `${firstChar}***${lastChar}@${domain}`;
|
|
564
|
+
}
|
|
565
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: EmailMaskPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
566
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: EmailMaskPipe, isStandalone: true, name: "emailMask" });
|
|
567
|
+
}
|
|
568
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: EmailMaskPipe, decorators: [{
|
|
569
|
+
type: Pipe,
|
|
570
|
+
args: [{
|
|
571
|
+
name: 'emailMask',
|
|
572
|
+
standalone: true
|
|
573
|
+
}]
|
|
574
|
+
}] });
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Converts special HTML characters in a string to their corresponding HTML entities.
|
|
578
|
+
* This prevents the browser from interpreting the input as HTML, rendering it as plain text.
|
|
579
|
+
*
|
|
580
|
+
* @param {string} value - The input string containing HTML to escape.
|
|
581
|
+
* @returns {string} The string with special HTML characters escaped, or an empty string if input is invalid.
|
|
582
|
+
*
|
|
583
|
+
* @example
|
|
584
|
+
* ```html
|
|
585
|
+
* {{ '<p>Hello</p>' | htmlEscape }} <!-- Outputs: <p>Hello</p> -->
|
|
586
|
+
* ```
|
|
587
|
+
*/
|
|
588
|
+
class HtmlEscapePipe {
|
|
589
|
+
transform(value) {
|
|
590
|
+
if (!value || typeof value !== 'string')
|
|
591
|
+
return '';
|
|
592
|
+
const escapeMap = {
|
|
593
|
+
'&': '&',
|
|
594
|
+
'<': '<',
|
|
595
|
+
'>': '>',
|
|
596
|
+
'"': '"',
|
|
597
|
+
"'": '''
|
|
598
|
+
};
|
|
599
|
+
return value.replace(/[&<>"']/g, char => escapeMap[char]);
|
|
600
|
+
}
|
|
601
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: HtmlEscapePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
602
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: HtmlEscapePipe, isStandalone: true, name: "htmlEscape" });
|
|
603
|
+
}
|
|
604
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: HtmlEscapePipe, decorators: [{
|
|
605
|
+
type: Pipe,
|
|
606
|
+
args: [{
|
|
607
|
+
name: 'htmlEscape',
|
|
608
|
+
standalone: true
|
|
609
|
+
}]
|
|
610
|
+
}] });
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Sanitizes HTML input to remove unsafe elements while allowing safe HTML to be rendered.
|
|
614
|
+
* Uses Angular's DomSanitizer to mark the output as trusted for use in [innerHTML].
|
|
615
|
+
*
|
|
616
|
+
* @param {string} value - The input string containing HTML to sanitize.
|
|
617
|
+
* @returns {SafeHtml} The sanitized HTML marked as safe, or an empty string if input is invalid.
|
|
618
|
+
*
|
|
619
|
+
* @remarks
|
|
620
|
+
* WARNING: Use with caution. Only apply to trusted input to avoid XSS risks.
|
|
621
|
+
* Ensure input is pre-validated or sourced from a secure origin (e.g., a controlled rich-text editor).
|
|
622
|
+
*
|
|
623
|
+
* @example
|
|
624
|
+
* ```html
|
|
625
|
+
* <div [innerHTML]="'<p>Hello</p><script>alert(1)</script>' | htmlSanitize"></div>
|
|
626
|
+
* <!-- Renders: <p>Hello</p> (script tag removed) -->
|
|
627
|
+
* ```
|
|
628
|
+
*/
|
|
629
|
+
class HtmlSanitizePipe {
|
|
630
|
+
sanitizer = inject(DomSanitizer);
|
|
631
|
+
transform(value) {
|
|
632
|
+
if (!value || typeof value !== 'string')
|
|
633
|
+
return this.sanitizer.bypassSecurityTrustHtml('');
|
|
634
|
+
return this.sanitizer.sanitize(0, value) || this.sanitizer.bypassSecurityTrustHtml('');
|
|
635
|
+
}
|
|
636
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: HtmlSanitizePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
637
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: HtmlSanitizePipe, isStandalone: true, name: "htmlSanitize" });
|
|
638
|
+
}
|
|
639
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: HtmlSanitizePipe, decorators: [{
|
|
640
|
+
type: Pipe,
|
|
641
|
+
args: [{
|
|
642
|
+
name: 'htmlSanitize',
|
|
643
|
+
standalone: true
|
|
644
|
+
}]
|
|
645
|
+
}] });
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* IpAddressMaskPipe: Masks the last two octets of an IPv4 address.
|
|
649
|
+
*
|
|
650
|
+
* @param {string} value - The IPv4 address (e.g., 192.168.1.1).
|
|
651
|
+
* @param {boolean} shouldMask - (Optional) Determines if masking should be applied. Defaults to true..
|
|
652
|
+
*
|
|
653
|
+
* @returns {string} - The masked IP address (e.g., 192.168.*.*).
|
|
654
|
+
*
|
|
655
|
+
* @example
|
|
656
|
+
* {{ '192.168.1.1' | ipAddressMask }} // Outputs: 192.168.*.*
|
|
657
|
+
* {{ '10.0.0.255' | ipAddressMask }} // Outputs: 10.0.*.*
|
|
658
|
+
*/
|
|
659
|
+
class IpAddressMaskPipe {
|
|
660
|
+
transform(value, shouldMask = true) {
|
|
661
|
+
if (!value || !/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(value)) {
|
|
662
|
+
return value;
|
|
663
|
+
}
|
|
664
|
+
if (shouldMask) {
|
|
665
|
+
const parts = value.split('.');
|
|
666
|
+
return `${parts[0]}.${parts[1]}.*.*`;
|
|
667
|
+
}
|
|
668
|
+
return value;
|
|
669
|
+
}
|
|
670
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: IpAddressMaskPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
671
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: IpAddressMaskPipe, isStandalone: true, name: "ipAddressMask" });
|
|
672
|
+
}
|
|
673
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: IpAddressMaskPipe, decorators: [{
|
|
674
|
+
type: Pipe,
|
|
675
|
+
args: [{
|
|
676
|
+
name: 'ipAddressMask',
|
|
677
|
+
standalone: true
|
|
678
|
+
}]
|
|
679
|
+
}] });
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* BarcodePipe: Generates a barcode from a string value.
|
|
683
|
+
*
|
|
684
|
+
* @param {string} value - The value to encode (e.g., '123456789').
|
|
685
|
+
* @param {BarcodeOptions} [options={}] - Configuration options.
|
|
686
|
+
*
|
|
687
|
+
* @returns {Promise<SafeHtml | SafeResourceUrl>} - SVG markup or image data URL.
|
|
688
|
+
*
|
|
689
|
+
* @example
|
|
690
|
+
* <div [innerHTML]="'123456789' | barcode:{elementType:'svg',format:'CODE128'} | async"></div>
|
|
691
|
+
* <img [src]="'123456789' | barcode:{elementType:'img'} | async" />
|
|
692
|
+
*/
|
|
693
|
+
class BarcodePipe {
|
|
694
|
+
sanitizer = inject(DomSanitizer);
|
|
695
|
+
async transform(value, options = {}) {
|
|
696
|
+
const { elementType = 'svg', format = 'CODE128', lineColor = '#000000', width = 2, height = 100, displayValue = true, } = options;
|
|
697
|
+
if (!value) {
|
|
698
|
+
return '';
|
|
699
|
+
}
|
|
700
|
+
// Sanitize the value to prevent XSS
|
|
701
|
+
const sanitizedValue = value.replace(/</g, '<').replace(/>/g, '>');
|
|
702
|
+
try {
|
|
703
|
+
const config = { format, lineColor, width, height, displayValue };
|
|
704
|
+
if (elementType === 'svg') {
|
|
705
|
+
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
706
|
+
JsBarcode(svg, sanitizedValue, config);
|
|
707
|
+
return this.sanitizer.bypassSecurityTrustHtml(svg.outerHTML);
|
|
708
|
+
}
|
|
709
|
+
else {
|
|
710
|
+
const canvas = document.createElement('canvas');
|
|
711
|
+
JsBarcode(canvas, sanitizedValue, config);
|
|
712
|
+
const dataUrl = canvas.toDataURL('image/png');
|
|
713
|
+
return this.sanitizer.bypassSecurityTrustResourceUrl(dataUrl);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
catch (error) {
|
|
717
|
+
console.error('Barcode generation failed:', error);
|
|
718
|
+
return '';
|
|
719
|
+
}
|
|
201
720
|
}
|
|
202
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
203
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type:
|
|
721
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: BarcodePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
722
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: BarcodePipe, isStandalone: true, name: "barcode" });
|
|
204
723
|
}
|
|
205
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
724
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: BarcodePipe, decorators: [{
|
|
206
725
|
type: Pipe,
|
|
207
726
|
args: [{
|
|
208
|
-
name: '
|
|
209
|
-
standalone: true
|
|
727
|
+
name: 'barcode',
|
|
728
|
+
standalone: true,
|
|
210
729
|
}]
|
|
211
730
|
}] });
|
|
212
731
|
|
|
@@ -361,8 +880,6 @@ function parseColor(value) {
|
|
|
361
880
|
* // Alpha channel support
|
|
362
881
|
* {{ '#FF000080' | colorConvert:'rgba' }} // rgba(255, 0, 0, 0.5)
|
|
363
882
|
* {{ 'rgba(255, 0, 0, 0.5)' | colorConvert:'hex' }} // #FF000080
|
|
364
|
-
*
|
|
365
|
-
* @author Mofiro Jean
|
|
366
883
|
*/
|
|
367
884
|
class ColorConvertPipe {
|
|
368
885
|
transform(value, target) {
|
|
@@ -370,393 +887,149 @@ class ColorConvertPipe {
|
|
|
370
887
|
return '';
|
|
371
888
|
}
|
|
372
889
|
const trimmedValue = value.trim();
|
|
373
|
-
const parsed = parseColor(trimmedValue);
|
|
374
|
-
if (!parsed) {
|
|
375
|
-
return value;
|
|
376
|
-
}
|
|
377
|
-
const { r, g, b, a } = parsed;
|
|
378
|
-
switch (target) {
|
|
379
|
-
case 'hex':
|
|
380
|
-
if (a < 1) {
|
|
381
|
-
return `#${toHex(r)}${toHex(g)}${toHex(b)}${alphaToHex(a)}`;
|
|
382
|
-
}
|
|
383
|
-
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
384
|
-
case 'rgb':
|
|
385
|
-
return `rgb(${clampChannel(r)}, ${clampChannel(g)}, ${clampChannel(b)})`;
|
|
386
|
-
case 'rgba':
|
|
387
|
-
return `rgba(${clampChannel(r)}, ${clampChannel(g)}, ${clampChannel(b)}, ${clampAlpha(a)})`;
|
|
388
|
-
default:
|
|
389
|
-
return value;
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ColorConvertPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
393
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: ColorConvertPipe, isStandalone: true, name: "colorConvert" });
|
|
394
|
-
}
|
|
395
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ColorConvertPipe, decorators: [{
|
|
396
|
-
type: Pipe,
|
|
397
|
-
args: [{
|
|
398
|
-
name: 'colorConvert',
|
|
399
|
-
standalone: true,
|
|
400
|
-
}]
|
|
401
|
-
}] });
|
|
402
|
-
|
|
403
|
-
class CountPipe {
|
|
404
|
-
transform(value) {
|
|
405
|
-
if (value === null || value === undefined) {
|
|
406
|
-
return 0;
|
|
407
|
-
}
|
|
408
|
-
if (Array.isArray(value) || typeof value === 'string') {
|
|
409
|
-
return value.length;
|
|
410
|
-
}
|
|
411
|
-
if (typeof value === 'object') {
|
|
412
|
-
return Object.keys(value).length;
|
|
413
|
-
}
|
|
414
|
-
return 0;
|
|
415
|
-
}
|
|
416
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CountPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
417
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: CountPipe, isStandalone: true, name: "count" });
|
|
418
|
-
}
|
|
419
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CountPipe, decorators: [{
|
|
420
|
-
type: Pipe,
|
|
421
|
-
args: [{
|
|
422
|
-
name: 'count',
|
|
423
|
-
standalone: true
|
|
424
|
-
}]
|
|
425
|
-
}] });
|
|
426
|
-
|
|
427
|
-
/**
|
|
428
|
-
* CreditCardMaskPipe: Masks all but the last four digits of a string, optionally controlled by a boolean flag.
|
|
429
|
-
* By default, masking is applied.
|
|
430
|
-
*
|
|
431
|
-
* @param {string} value - The input string to mask (e.g., credit card number).
|
|
432
|
-
* @param {boolean} shouldMask - (Optional) Determines if masking should be applied. Defaults to true.
|
|
433
|
-
* @returns {string} - The masked string or the original value if `shouldMask` is false or the value is too short.
|
|
434
|
-
*
|
|
435
|
-
* @example
|
|
436
|
-
* {{ '1234567890123456' | creditCardMask }} // Outputs: **** **** **** 3456
|
|
437
|
-
* {{ '1234-5678-9012-3456' | creditCardMask }} // Outputs: **** **** **** 3456
|
|
438
|
-
* {{ '1234567890123456' | creditCardMask: true }} // Outputs: **** **** **** 3456
|
|
439
|
-
* {{ '1234567890123456' | creditCardMask: false }} // Outputs: 1234567890123456
|
|
440
|
-
*
|
|
441
|
-
* @author Mofiro Jean
|
|
442
|
-
*/
|
|
443
|
-
class CreditCardMaskPipe {
|
|
444
|
-
transform(value, shouldMask = true) {
|
|
445
|
-
if (!value) {
|
|
446
|
-
return value;
|
|
447
|
-
}
|
|
448
|
-
if (shouldMask) {
|
|
449
|
-
const cleanedValue = value.replace(/[\s-]/g, '');
|
|
450
|
-
const cleanedLength = cleanedValue.length;
|
|
451
|
-
if (cleanedLength < 4) {
|
|
452
|
-
return value;
|
|
453
|
-
}
|
|
454
|
-
const visibleDigits = cleanedValue.slice(-4);
|
|
455
|
-
const maskedSection = '*'.repeat(cleanedLength - 4);
|
|
456
|
-
const groupedMask = maskedSection.match(/.{1,4}/g)?.join(' ') ?? '';
|
|
457
|
-
return `${groupedMask} ${visibleDigits}`.trim();
|
|
458
|
-
}
|
|
459
|
-
return value;
|
|
460
|
-
}
|
|
461
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CreditCardMaskPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
462
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: CreditCardMaskPipe, isStandalone: true, name: "creditCardMask" });
|
|
463
|
-
}
|
|
464
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CreditCardMaskPipe, decorators: [{
|
|
465
|
-
type: Pipe,
|
|
466
|
-
args: [{
|
|
467
|
-
name: 'creditCardMask',
|
|
468
|
-
standalone: true,
|
|
469
|
-
}]
|
|
470
|
-
}] });
|
|
471
|
-
|
|
472
|
-
/**
|
|
473
|
-
* DeviceTypePipe: Detects the device type based on the user agent string.
|
|
474
|
-
*
|
|
475
|
-
* @param {string} value - The user agent string (defaults to navigator.userAgent).
|
|
476
|
-
*
|
|
477
|
-
* @returns {'mobile' | 'tablet' | 'desktop' | 'unknown'} - The detected device type.
|
|
478
|
-
*
|
|
479
|
-
* @example
|
|
480
|
-
* {{ '' | device }} // Outputs: 'mobile' (on a mobile device)
|
|
481
|
-
* <div *ngIf="'' | device === 'desktop'">Desktop-only content</div>
|
|
482
|
-
*/
|
|
483
|
-
class DeviceTypePipe {
|
|
484
|
-
transform(value = typeof navigator !== 'undefined' ? navigator.userAgent : '') {
|
|
485
|
-
if (!value)
|
|
486
|
-
return 'unknown';
|
|
487
|
-
const userAgent = value.toLowerCase();
|
|
488
|
-
const isMobile = /mobile|android|iphone|ipod|blackberry|opera mini|iemobile|windows phone/i.test(userAgent);
|
|
489
|
-
const isTablet = /ipad|tablet|kindle|playbook|silk|nexus 7|nexus 10|android(?!.*mobile)/i.test(userAgent);
|
|
490
|
-
if (isMobile)
|
|
491
|
-
return 'mobile';
|
|
492
|
-
if (isTablet)
|
|
493
|
-
return 'tablet';
|
|
494
|
-
return 'desktop';
|
|
495
|
-
}
|
|
496
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DeviceTypePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
497
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: DeviceTypePipe, isStandalone: true, name: "device" });
|
|
498
|
-
}
|
|
499
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DeviceTypePipe, decorators: [{
|
|
500
|
-
type: Pipe,
|
|
501
|
-
args: [{
|
|
502
|
-
name: 'device',
|
|
503
|
-
standalone: true
|
|
504
|
-
}]
|
|
505
|
-
}] });
|
|
506
|
-
|
|
507
|
-
/**
|
|
508
|
-
* EmailMaskPipe: Masks the local part of an email address, revealing only the first and last characters.
|
|
509
|
-
*
|
|
510
|
-
* This Angular pipe transforms an email address string by replacing the characters between the first and last characters of the local part (before the '@') with "***".
|
|
511
|
-
* If the local part is 2 characters or less, it masks all characters except the first.
|
|
512
|
-
*
|
|
513
|
-
* @param {string} value - The email address string to be masked.
|
|
514
|
-
* @returns {string} - The masked email address, or the original value if it's not a valid email or falsy.
|
|
515
|
-
*
|
|
516
|
-
* @example
|
|
517
|
-
* {{ 'test@example.com' | emailMask }} // Returns 't***t@example.com'
|
|
518
|
-
* {{ 'te@example.com' | emailMask }} // Returns 't***@example.com'
|
|
519
|
-
* {{ 't@example.com' | emailMask }} // Returns 't***@example.com'
|
|
520
|
-
* {{ 'example.com' | emailMask }} // Returns 'example.com'
|
|
521
|
-
* {{ null | emailMask }} // Returns ''
|
|
522
|
-
* {{ undefined | emailMask }} // Returns ''
|
|
523
|
-
*
|
|
524
|
-
* @author Mofiro Jean
|
|
525
|
-
*/
|
|
526
|
-
class EmailMaskPipe {
|
|
527
|
-
transform(value) {
|
|
528
|
-
if (!value || !value.includes('@')) {
|
|
529
|
-
return value || '';
|
|
530
|
-
}
|
|
531
|
-
const [local, domain] = value.split('@');
|
|
532
|
-
if (local.length <= 2) {
|
|
533
|
-
return `${local[0]}***@${domain}`;
|
|
534
|
-
}
|
|
535
|
-
const firstChar = local[0];
|
|
536
|
-
const lastChar = local[local.length - 1];
|
|
537
|
-
return `${firstChar}***${lastChar}@${domain}`;
|
|
538
|
-
}
|
|
539
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: EmailMaskPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
540
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: EmailMaskPipe, isStandalone: true, name: "emailMask" });
|
|
541
|
-
}
|
|
542
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: EmailMaskPipe, decorators: [{
|
|
543
|
-
type: Pipe,
|
|
544
|
-
args: [{
|
|
545
|
-
name: 'emailMask',
|
|
546
|
-
standalone: true
|
|
547
|
-
}]
|
|
548
|
-
}] });
|
|
549
|
-
|
|
550
|
-
/**
|
|
551
|
-
* GravatarPipe: Generates Gravatar URLs from email addresses.
|
|
552
|
-
*
|
|
553
|
-
* @param {string} value - The email address.
|
|
554
|
-
* @param {number} [size=80] - The avatar size in pixels.
|
|
555
|
-
*
|
|
556
|
-
* @returns {string} - The Gravatar URL.
|
|
557
|
-
*
|
|
558
|
-
* @example
|
|
559
|
-
* <img [src]="'user@example.com' | gravatar:100" />
|
|
560
|
-
*
|
|
561
|
-
* @author Mofiro Jean
|
|
562
|
-
*/
|
|
563
|
-
class GravatarPipe {
|
|
564
|
-
transform(value, size = 80) {
|
|
565
|
-
if (!value)
|
|
566
|
-
return `https://www.gravatar.com/avatar/?s=${size}`;
|
|
567
|
-
const hash = md5(value.trim().toLowerCase());
|
|
568
|
-
return `https://www.gravatar.com/avatar/${hash}?s=${size}`;
|
|
569
|
-
}
|
|
570
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: GravatarPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
571
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: GravatarPipe, isStandalone: true, name: "gravatar" });
|
|
572
|
-
}
|
|
573
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: GravatarPipe, decorators: [{
|
|
574
|
-
type: Pipe,
|
|
575
|
-
args: [{
|
|
576
|
-
name: 'gravatar',
|
|
577
|
-
standalone: true
|
|
578
|
-
}]
|
|
579
|
-
}] });
|
|
580
|
-
|
|
581
|
-
/**
|
|
582
|
-
* HighlightPipe: Highlights occurrences of a search term within a string.
|
|
583
|
-
*
|
|
584
|
-
* This Angular pipe transforms a string input by wrapping all occurrences of a specified
|
|
585
|
-
* search term with a `<span>` element that has the class "highlight".
|
|
586
|
-
* It uses the Angular `DomSanitizer` to bypass security and render the highlighted HTML.
|
|
587
|
-
*
|
|
588
|
-
* @param {string} value - The input string in which to highlight the search term.
|
|
589
|
-
* @param {string} searchTerm - The string to search for and highlight.
|
|
590
|
-
* @returns {SafeHtml} - The input string with the search term highlighted, or an empty string if input or searchTerm are falsy.
|
|
591
|
-
*
|
|
592
|
-
* @example
|
|
593
|
-
* {{ 'This is a test string' | highlight: 'test' }} // Returns 'This is a <span class="highlight">test</span> string'
|
|
594
|
-
* {{ 'This is a test TEST string' | highlight: 'test' }} // Returns 'This is a <span class="highlight">test</span> <span class="highlight">TEST</span> string'
|
|
595
|
-
* {{ 'This is a test string' | highlight: '' }} // Returns 'This is a test string'
|
|
596
|
-
* {{ null | highlight: 'test' }} // Returns ''
|
|
597
|
-
* {{ undefined | highlight: 'test' }} // Returns ''
|
|
598
|
-
*
|
|
599
|
-
* @author Mofiro Jean
|
|
600
|
-
*/
|
|
601
|
-
class HighlightPipe {
|
|
602
|
-
sanitizer = inject(DomSanitizer);
|
|
603
|
-
transform(value, searchTerm) {
|
|
604
|
-
if (!value || !searchTerm) {
|
|
605
|
-
return this.sanitizer.bypassSecurityTrustHtml(value || '');
|
|
890
|
+
const parsed = parseColor(trimmedValue);
|
|
891
|
+
if (!parsed) {
|
|
892
|
+
return value;
|
|
893
|
+
}
|
|
894
|
+
const { r, g, b, a } = parsed;
|
|
895
|
+
switch (target) {
|
|
896
|
+
case 'hex':
|
|
897
|
+
if (a < 1) {
|
|
898
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}${alphaToHex(a)}`;
|
|
899
|
+
}
|
|
900
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
901
|
+
case 'rgb':
|
|
902
|
+
return `rgb(${clampChannel(r)}, ${clampChannel(g)}, ${clampChannel(b)})`;
|
|
903
|
+
case 'rgba':
|
|
904
|
+
return `rgba(${clampChannel(r)}, ${clampChannel(g)}, ${clampChannel(b)}, ${clampAlpha(a)})`;
|
|
905
|
+
default:
|
|
906
|
+
return value;
|
|
606
907
|
}
|
|
607
|
-
const escapedSearch = searchTerm.replace(/[.*+?${}()|[\\]/g, '\\$&');
|
|
608
|
-
const regex = new RegExp(`(${escapedSearch})`, 'gi');
|
|
609
|
-
const highlighed = value.replace(regex, '<span class="highlight">$1</span>');
|
|
610
|
-
return this.sanitizer.bypassSecurityTrustHtml(highlighed);
|
|
611
908
|
}
|
|
612
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
613
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type:
|
|
909
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ColorConvertPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
910
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: ColorConvertPipe, isStandalone: true, name: "colorConvert" });
|
|
614
911
|
}
|
|
615
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
912
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ColorConvertPipe, decorators: [{
|
|
616
913
|
type: Pipe,
|
|
617
914
|
args: [{
|
|
618
|
-
name: '
|
|
619
|
-
standalone: true
|
|
915
|
+
name: 'colorConvert',
|
|
916
|
+
standalone: true,
|
|
620
917
|
}]
|
|
621
918
|
}] });
|
|
622
919
|
|
|
623
920
|
/**
|
|
624
|
-
*
|
|
625
|
-
* This prevents the browser from interpreting the input as HTML, rendering it as plain text.
|
|
921
|
+
* GravatarPipe: Generates Gravatar URLs from email addresses.
|
|
626
922
|
*
|
|
627
|
-
* @param {string} value - The
|
|
628
|
-
* @
|
|
923
|
+
* @param {string} value - The email address.
|
|
924
|
+
* @param {number} [size=80] - The avatar size in pixels.
|
|
925
|
+
*
|
|
926
|
+
* @returns {string} - The Gravatar URL.
|
|
629
927
|
*
|
|
630
928
|
* @example
|
|
631
|
-
*
|
|
632
|
-
* {{ '<p>Hello</p>' | htmlEscape }} <!-- Outputs: <p>Hello</p> -->
|
|
633
|
-
* ```
|
|
929
|
+
* <img [src]="'user@example.com' | gravatar:100" />
|
|
634
930
|
*/
|
|
635
|
-
class
|
|
636
|
-
transform(value) {
|
|
637
|
-
if (!value
|
|
638
|
-
return
|
|
639
|
-
const
|
|
640
|
-
|
|
641
|
-
'<': '<',
|
|
642
|
-
'>': '>',
|
|
643
|
-
'"': '"',
|
|
644
|
-
"'": '''
|
|
645
|
-
};
|
|
646
|
-
return value.replace(/[&<>"']/g, char => escapeMap[char]);
|
|
931
|
+
class GravatarPipe {
|
|
932
|
+
transform(value, size = 80) {
|
|
933
|
+
if (!value)
|
|
934
|
+
return `https://www.gravatar.com/avatar/?s=${size}`;
|
|
935
|
+
const hash = md5(value.trim().toLowerCase());
|
|
936
|
+
return `https://www.gravatar.com/avatar/${hash}?s=${size}`;
|
|
647
937
|
}
|
|
648
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
649
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type:
|
|
938
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: GravatarPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
939
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: GravatarPipe, isStandalone: true, name: "gravatar" });
|
|
650
940
|
}
|
|
651
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
941
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: GravatarPipe, decorators: [{
|
|
652
942
|
type: Pipe,
|
|
653
943
|
args: [{
|
|
654
|
-
name: '
|
|
944
|
+
name: 'gravatar',
|
|
655
945
|
standalone: true
|
|
656
946
|
}]
|
|
657
947
|
}] });
|
|
658
948
|
|
|
659
949
|
/**
|
|
660
|
-
*
|
|
661
|
-
* Uses Angular's DomSanitizer to mark the output as trusted for use in [innerHTML].
|
|
950
|
+
* QrCodePipe: Generates a QR code from a string.
|
|
662
951
|
*
|
|
663
|
-
* @param {string} value - The
|
|
664
|
-
* @
|
|
952
|
+
* @param {string} value - The string to encode.
|
|
953
|
+
* @param {QrCodeOptions} [options] - The QR code options.
|
|
665
954
|
*
|
|
666
|
-
* @
|
|
667
|
-
* WARNING: Use with caution. Only apply to trusted input to avoid XSS risks.
|
|
668
|
-
* Ensure input is pre-validated or sourced from a secure origin (e.g., a controlled rich-text editor).
|
|
955
|
+
* @returns {Promise<string>} - A promise that resolves with the QR code data URL.
|
|
669
956
|
*
|
|
670
957
|
* @example
|
|
671
|
-
*
|
|
672
|
-
* <div [innerHTML]="'<p>Hello</p><script>alert(1)</script>' | htmlSanitize"></div>
|
|
673
|
-
* <!-- Renders: <p>Hello</p> (script tag removed) -->
|
|
674
|
-
* ```
|
|
958
|
+
* <img [src]="'Hello, World!' | qrCode | async" />
|
|
675
959
|
*/
|
|
676
|
-
class
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
return
|
|
960
|
+
class QrCodePipe {
|
|
961
|
+
transform(value, options) {
|
|
962
|
+
if (!value) {
|
|
963
|
+
return Promise.resolve('');
|
|
964
|
+
}
|
|
965
|
+
return QRCode.toDataURL(value, options);
|
|
682
966
|
}
|
|
683
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
684
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type:
|
|
967
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: QrCodePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
968
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: QrCodePipe, isStandalone: true, name: "qrCode" });
|
|
685
969
|
}
|
|
686
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
970
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: QrCodePipe, decorators: [{
|
|
687
971
|
type: Pipe,
|
|
688
972
|
args: [{
|
|
689
|
-
name: '
|
|
973
|
+
name: 'qrCode',
|
|
690
974
|
standalone: true
|
|
691
975
|
}]
|
|
692
976
|
}] });
|
|
693
977
|
|
|
694
|
-
|
|
695
|
-
* InitialsPipe: Extracts initials from a name.
|
|
696
|
-
*
|
|
697
|
-
* @param {string} value - The full name.
|
|
698
|
-
*
|
|
699
|
-
* @returns {string} - The initials (e.g., 'John Doe' → 'JD').
|
|
700
|
-
*
|
|
701
|
-
* @example
|
|
702
|
-
* {{ 'John Doe' | initials }} // Outputs: JD
|
|
703
|
-
* {{ 'Mary Jane Watson' | initials }} // Outputs: MJW
|
|
704
|
-
*
|
|
705
|
-
* @author Mofiro Jean
|
|
706
|
-
*/
|
|
707
|
-
class InitialsPipe {
|
|
978
|
+
class CountPipe {
|
|
708
979
|
transform(value) {
|
|
709
|
-
if (
|
|
710
|
-
return
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
.
|
|
714
|
-
|
|
715
|
-
|
|
980
|
+
if (value === null || value === undefined) {
|
|
981
|
+
return 0;
|
|
982
|
+
}
|
|
983
|
+
if (Array.isArray(value) || typeof value === 'string') {
|
|
984
|
+
return value.length;
|
|
985
|
+
}
|
|
986
|
+
if (typeof value === 'object') {
|
|
987
|
+
return Object.keys(value).length;
|
|
988
|
+
}
|
|
989
|
+
return 0;
|
|
716
990
|
}
|
|
717
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
718
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type:
|
|
991
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CountPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
992
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: CountPipe, isStandalone: true, name: "count" });
|
|
719
993
|
}
|
|
720
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
994
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CountPipe, decorators: [{
|
|
721
995
|
type: Pipe,
|
|
722
996
|
args: [{
|
|
723
|
-
name: '
|
|
997
|
+
name: 'count',
|
|
724
998
|
standalone: true
|
|
725
999
|
}]
|
|
726
1000
|
}] });
|
|
727
1001
|
|
|
728
1002
|
/**
|
|
729
|
-
*
|
|
1003
|
+
* DeviceTypePipe: Detects the device type based on the user agent string.
|
|
730
1004
|
*
|
|
731
|
-
* @param {string} value - The
|
|
732
|
-
* @param {boolean} shouldMask - (Optional) Determines if masking should be applied. Defaults to true..
|
|
1005
|
+
* @param {string} value - The user agent string (defaults to navigator.userAgent).
|
|
733
1006
|
*
|
|
734
|
-
* @returns {
|
|
1007
|
+
* @returns {'mobile' | 'tablet' | 'desktop' | 'unknown'} - The detected device type.
|
|
735
1008
|
*
|
|
736
1009
|
* @example
|
|
737
|
-
* {{ '
|
|
738
|
-
*
|
|
739
|
-
*
|
|
740
|
-
* @author Mofiro Jean
|
|
1010
|
+
* {{ '' | device }} // Outputs: 'mobile' (on a mobile device)
|
|
1011
|
+
* <div *ngIf="'' | device === 'desktop'">Desktop-only content</div>
|
|
741
1012
|
*/
|
|
742
|
-
class
|
|
743
|
-
transform(value
|
|
744
|
-
if (!value
|
|
745
|
-
return
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
1013
|
+
class DeviceTypePipe {
|
|
1014
|
+
transform(value = typeof navigator !== 'undefined' ? navigator.userAgent : '') {
|
|
1015
|
+
if (!value)
|
|
1016
|
+
return 'unknown';
|
|
1017
|
+
const userAgent = value.toLowerCase();
|
|
1018
|
+
const isMobile = /mobile|android|iphone|ipod|blackberry|opera mini|iemobile|windows phone/i.test(userAgent);
|
|
1019
|
+
const isTablet = /ipad|tablet|kindle|playbook|silk|nexus 7|nexus 10|android(?!.*mobile)/i.test(userAgent);
|
|
1020
|
+
if (isMobile)
|
|
1021
|
+
return 'mobile';
|
|
1022
|
+
if (isTablet)
|
|
1023
|
+
return 'tablet';
|
|
1024
|
+
return 'desktop';
|
|
752
1025
|
}
|
|
753
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
754
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1026
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DeviceTypePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1027
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: DeviceTypePipe, isStandalone: true, name: "device" });
|
|
755
1028
|
}
|
|
756
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1029
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DeviceTypePipe, decorators: [{
|
|
757
1030
|
type: Pipe,
|
|
758
1031
|
args: [{
|
|
759
|
-
name: '
|
|
1032
|
+
name: 'device',
|
|
760
1033
|
standalone: true
|
|
761
1034
|
}]
|
|
762
1035
|
}] });
|
|
@@ -772,8 +1045,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
772
1045
|
* @example
|
|
773
1046
|
* {{ '{"name": "John", "age": 30}' | jsonPretty }} // Outputs: Colorful, indented JSON
|
|
774
1047
|
* <pre [innerHTML]="data | jsonPretty:4"></pre> // 4-space indentation
|
|
775
|
-
*
|
|
776
|
-
* @author Mofiro Jean
|
|
777
1048
|
*/
|
|
778
1049
|
class JsonPrettyPipe {
|
|
779
1050
|
sanitizer = inject(DomSanitizer);
|
|
@@ -841,180 +1112,162 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
841
1112
|
}] });
|
|
842
1113
|
|
|
843
1114
|
/**
|
|
844
|
-
*
|
|
845
|
-
*
|
|
846
|
-
* @param {string} value - The input string to transform.
|
|
847
|
-
* @returns {string} The string in kebab-case, or an empty string if input is invalid.
|
|
848
|
-
*
|
|
849
|
-
* @example
|
|
850
|
-
* ```html
|
|
851
|
-
* {{ 'hello world' | kebabCase }} <!-- Outputs: hello-world -->
|
|
852
|
-
* ```
|
|
853
|
-
*
|
|
854
|
-
* @author Mofiro Jean
|
|
855
|
-
*/
|
|
856
|
-
class KebabCasePipe {
|
|
857
|
-
transform(value) {
|
|
858
|
-
if (!value || typeof value !== 'string')
|
|
859
|
-
return '';
|
|
860
|
-
return value
|
|
861
|
-
.trim()
|
|
862
|
-
.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2') // Add hyphen between camelCase words
|
|
863
|
-
.toLowerCase()
|
|
864
|
-
.replace(/[^a-z0-9-]+/g, '-') // Replace non-alphanumeric (except hyphen) with hyphen
|
|
865
|
-
.replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
|
|
866
|
-
}
|
|
867
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: KebabCasePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
868
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: KebabCasePipe, isStandalone: true, name: "kebabCase" });
|
|
869
|
-
}
|
|
870
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: KebabCasePipe, decorators: [{
|
|
871
|
-
type: Pipe,
|
|
872
|
-
args: [{
|
|
873
|
-
name: 'kebabCase',
|
|
874
|
-
standalone: true
|
|
875
|
-
}]
|
|
876
|
-
}] });
|
|
877
|
-
|
|
878
|
-
/**
|
|
879
|
-
* MorseCodePipe: Converts text to Morse code.
|
|
1115
|
+
* TextToSpeechPipe: Converts text to speech using the Web Speech API.
|
|
880
1116
|
*
|
|
881
|
-
* @param {string} value - The text to convert to
|
|
1117
|
+
* @param {string} value - The text to convert to speech.
|
|
1118
|
+
* @param {string} [lang='en-US'] - The language (local) for speech synthesis.
|
|
882
1119
|
*
|
|
883
|
-
* @returns {
|
|
1120
|
+
* @returns {void} - Triggers speech synthesis (no return value).
|
|
884
1121
|
*
|
|
885
1122
|
* @example
|
|
886
|
-
* {{ '
|
|
887
|
-
* {{ '
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.',
|
|
897
|
-
'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-',
|
|
898
|
-
'Y': '-.--', 'Z': '--..', '0': '-----', '1': '.----', '2': '..---',
|
|
899
|
-
'3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...',
|
|
900
|
-
'8': '---..', '9': '----.'
|
|
901
|
-
};
|
|
902
|
-
transform(value) {
|
|
903
|
-
if (!value || typeof value !== 'string') {
|
|
904
|
-
return '';
|
|
905
|
-
}
|
|
906
|
-
return value
|
|
907
|
-
.toUpperCase()
|
|
908
|
-
.split('')
|
|
909
|
-
.map(char => this.morseCodeMap[char] || '')
|
|
910
|
-
.filter(code => code)
|
|
911
|
-
.join(' ');
|
|
1123
|
+
* <div>{{ Hello World' | textToSpeech }}</div>
|
|
1124
|
+
* <div>{{ 'Bonjour' | textToSpeech:'fr-FR' }}h</div>
|
|
1125
|
+
*/
|
|
1126
|
+
class TextToSpeechPipe {
|
|
1127
|
+
transform(value, lang = 'en-US') {
|
|
1128
|
+
if (!value || typeof window === 'undefined' || !window.speechSynthesis)
|
|
1129
|
+
return;
|
|
1130
|
+
const uttrance = new SpeechSynthesisUtterance(value);
|
|
1131
|
+
uttrance.lang = lang;
|
|
1132
|
+
window.speechSynthesis.speak(uttrance);
|
|
912
1133
|
}
|
|
913
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
914
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1134
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: TextToSpeechPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1135
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: TextToSpeechPipe, isStandalone: true, name: "textToSpeech" });
|
|
915
1136
|
}
|
|
916
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1137
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: TextToSpeechPipe, decorators: [{
|
|
917
1138
|
type: Pipe,
|
|
918
1139
|
args: [{
|
|
919
|
-
name: '
|
|
1140
|
+
name: 'textToSpeech',
|
|
920
1141
|
standalone: true
|
|
921
1142
|
}]
|
|
922
1143
|
}] });
|
|
923
1144
|
|
|
924
1145
|
/**
|
|
925
|
-
|
|
1146
|
+
* TimeAgo: Converts a date into a localized time string.
|
|
926
1147
|
*
|
|
927
|
-
*
|
|
928
|
-
*
|
|
1148
|
+
* Use the in-built Intl.RelativeTimeFormat to convert a date into a localized time string.
|
|
1149
|
+
* It was chosen over moment.js because it's more lightweight and supports more locales.
|
|
1150
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat
|
|
929
1151
|
*
|
|
930
|
-
* @
|
|
1152
|
+
* @param {Date | number | string} value - The date to convert.
|
|
1153
|
+
* @param {string} [local='en'] - BCP 47 local code (e.g., 'en', 'fr', 'es').
|
|
931
1154
|
*
|
|
932
|
-
* @
|
|
933
|
-
* <img [src]="'Hello, World!' | qrCode | async" />
|
|
1155
|
+
* @returns {string} - The localized time string.
|
|
934
1156
|
*
|
|
935
|
-
* @
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1157
|
+
* @example
|
|
1158
|
+
* {{ date | timeAgo }} // '5 minutes ago'
|
|
1159
|
+
* {{ date | timeAgo:'fr' }} // 'il y a 5 minutes'
|
|
1160
|
+
*
|
|
1161
|
+
* @note Pure pipe - output won't automatically update as time passes.
|
|
1162
|
+
* Use signals or periodic change detection to re-trigger.
|
|
1163
|
+
* */
|
|
1164
|
+
class TimeAgoPipePipe {
|
|
1165
|
+
static THRESHOLDS = [
|
|
1166
|
+
[60, 1, 'second'],
|
|
1167
|
+
[3600, 60, 'minute'],
|
|
1168
|
+
[86400, 3600, 'hour'],
|
|
1169
|
+
[604800, 86400, 'day'],
|
|
1170
|
+
[2592000, 604800, 'week'],
|
|
1171
|
+
[31536000, 2592000, 'month'],
|
|
1172
|
+
[Infinity, 31536000, 'year'],
|
|
1173
|
+
];
|
|
1174
|
+
cacheLocal = '';
|
|
1175
|
+
rtf;
|
|
1176
|
+
transform(value, local = 'en') {
|
|
1177
|
+
if (value === null || value === undefined || value === "") {
|
|
1178
|
+
return "";
|
|
941
1179
|
}
|
|
942
|
-
|
|
1180
|
+
const date = new Date(value);
|
|
1181
|
+
if (isNaN(date.getTime())) {
|
|
1182
|
+
return "";
|
|
1183
|
+
}
|
|
1184
|
+
if (local !== this.cacheLocal) {
|
|
1185
|
+
this.rtf = new Intl.RelativeTimeFormat(local, { numeric: "auto" });
|
|
1186
|
+
this.cacheLocal = local;
|
|
1187
|
+
}
|
|
1188
|
+
const seconds = Math.floor((date.getTime() - Date.now()) / 1000);
|
|
1189
|
+
for (const [max, divisor, unit] of TimeAgoPipePipe.THRESHOLDS) {
|
|
1190
|
+
if (Math.abs(seconds) < max) {
|
|
1191
|
+
return this.rtf.format(Math.round(seconds / divisor), unit);
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
return "";
|
|
943
1195
|
}
|
|
944
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
945
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1196
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: TimeAgoPipePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1197
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: TimeAgoPipePipe, isStandalone: true, name: "timeAgo" });
|
|
946
1198
|
}
|
|
947
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1199
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: TimeAgoPipePipe, decorators: [{
|
|
948
1200
|
type: Pipe,
|
|
949
1201
|
args: [{
|
|
950
|
-
name: '
|
|
1202
|
+
name: 'timeAgo',
|
|
951
1203
|
standalone: true
|
|
952
1204
|
}]
|
|
953
1205
|
}] });
|
|
954
1206
|
|
|
955
1207
|
/**
|
|
956
|
-
*
|
|
957
|
-
*
|
|
958
|
-
* - If `isReplace` is `false`, it highlights occurrences of the pattern (if `highlightClass` is provided).
|
|
959
|
-
* - If `isReplace` is `true`, it replaces occurrences of the pattern with the replacement string, optionally highlighting the replacement.
|
|
1208
|
+
* FlattenPipe: Flattens nested arrays to a specified depth.
|
|
960
1209
|
*
|
|
961
|
-
* @param {
|
|
962
|
-
* @param {
|
|
963
|
-
* @param {string} replacement - The string to replace matches with.
|
|
964
|
-
* @param {string} [highlightClass] - Optional CSS class for highlighting matched or replaced text (e.g., 'highlight').
|
|
965
|
-
* @param {boolean} [isReplace=true] - Whether to perform replacement (true) or only highlight matches (false).
|
|
1210
|
+
* @param {unknown[]} value - The nested array to flatten.
|
|
1211
|
+
* @param {number} [depth=Infinity] - How many levels of nesting to flatten.
|
|
966
1212
|
*
|
|
967
|
-
* @returns {
|
|
1213
|
+
* @returns {unknown[]} - A new flattened array.
|
|
968
1214
|
*
|
|
969
1215
|
* @example
|
|
970
|
-
* {{
|
|
971
|
-
*
|
|
972
|
-
*
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1216
|
+
* {{ [[1, 2], [3, 4]] | flatten }} // [1, 2, 3, 4]
|
|
1217
|
+
* {{ [[1, [2, [3]]]] | flatten:1 }} // [1, 2, [3]]
|
|
1218
|
+
* {{ [['a', 'b'], ['c']] | flatten }} // ['a', 'b', 'c']
|
|
1219
|
+
*/
|
|
1220
|
+
class Flatten {
|
|
1221
|
+
transform(value, depth = Infinity) {
|
|
1222
|
+
if (!Array.isArray(value)) {
|
|
1223
|
+
return [];
|
|
1224
|
+
}
|
|
1225
|
+
return value.flat(depth);
|
|
1226
|
+
}
|
|
1227
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: Flatten, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1228
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: Flatten, isStandalone: true, name: "flatten" });
|
|
1229
|
+
}
|
|
1230
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: Flatten, decorators: [{
|
|
1231
|
+
type: Pipe,
|
|
1232
|
+
args: [{
|
|
1233
|
+
name: 'flatten',
|
|
1234
|
+
standalone: true
|
|
1235
|
+
}]
|
|
1236
|
+
}] });
|
|
1237
|
+
|
|
1238
|
+
/**
|
|
1239
|
+
* InitialPipe: Returns all elements except the last n.
|
|
978
1240
|
*
|
|
979
|
-
* {
|
|
980
|
-
*
|
|
1241
|
+
* @param {unknown[]} value - The array to slice.
|
|
1242
|
+
* @param {number} [n=1] - Number of elements to exclude from the end.
|
|
981
1243
|
*
|
|
982
|
-
*
|
|
983
|
-
* // Renders: Angular is <span class="highlight">great</span>
|
|
1244
|
+
* @returns {unknown[]} - A new array without the last n elements.
|
|
984
1245
|
*
|
|
985
|
-
* @
|
|
1246
|
+
* @example
|
|
1247
|
+
* {{ [1, 2, 3, 4, 5] | initial }} // [1, 2, 3, 4]
|
|
1248
|
+
* {{ [1, 2, 3, 4, 5] | initial:2 }} // [1, 2, 3]
|
|
1249
|
+
* {{ ['a', 'b', 'c'] | initial }} // ['a', 'b']
|
|
986
1250
|
*/
|
|
987
|
-
class
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
return '';
|
|
992
|
-
// handles empty string pattern
|
|
993
|
-
if (!pattern || (typeof pattern === 'string' && pattern.trim() === '')) {
|
|
994
|
-
return value;
|
|
1251
|
+
class InitialPipe {
|
|
1252
|
+
transform(value, n = 1) {
|
|
1253
|
+
if (!Array.isArray(value)) {
|
|
1254
|
+
return [];
|
|
995
1255
|
}
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
return isReplace ? value.replace(finalPattern, replacement) : value;
|
|
1256
|
+
if (n <= 0) {
|
|
1257
|
+
return [...value];
|
|
999
1258
|
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
if (isReplace) {
|
|
1003
|
-
const highlightedReplacement = `<span class="${highlightClass}">${sanitizedReplacement}</span>`;
|
|
1004
|
-
const replaced = value.replace(finalPattern, highlightedReplacement);
|
|
1005
|
-
return this.sanitizer.bypassSecurityTrustHtml(replaced);
|
|
1259
|
+
if (n >= value.length) {
|
|
1260
|
+
return [];
|
|
1006
1261
|
}
|
|
1007
|
-
|
|
1008
|
-
const result = value.replace(finalPattern, highlightedMatch);
|
|
1009
|
-
return this.sanitizer.bypassSecurityTrustHtml(result);
|
|
1262
|
+
return value.slice(0, -n);
|
|
1010
1263
|
}
|
|
1011
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1012
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1264
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: InitialPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1265
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: InitialPipe, isStandalone: true, name: "initial" });
|
|
1013
1266
|
}
|
|
1014
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1267
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: InitialPipe, decorators: [{
|
|
1015
1268
|
type: Pipe,
|
|
1016
1269
|
args: [{
|
|
1017
|
-
name: '
|
|
1270
|
+
name: 'initial',
|
|
1018
1271
|
standalone: true
|
|
1019
1272
|
}]
|
|
1020
1273
|
}] });
|
|
@@ -1030,15 +1283,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
1030
1283
|
* {{ 'hello' | reverse }} // Outputs: 'olleh'
|
|
1031
1284
|
* {{ '12345' | reverse }} // Outputs: '54321'
|
|
1032
1285
|
* <p>{{ userInput | reverse }}</p>
|
|
1033
|
-
*
|
|
1034
|
-
* @author Mofiro Jean
|
|
1035
1286
|
*/
|
|
1036
1287
|
class ReversePipe {
|
|
1037
1288
|
transform(value) {
|
|
1038
|
-
if (
|
|
1039
|
-
return
|
|
1289
|
+
if (Array.isArray(value)) {
|
|
1290
|
+
return [...value].reverse();
|
|
1040
1291
|
}
|
|
1041
|
-
|
|
1292
|
+
if (typeof value === 'string') {
|
|
1293
|
+
return value.split('').reverse().join('');
|
|
1294
|
+
}
|
|
1295
|
+
return '';
|
|
1042
1296
|
}
|
|
1043
1297
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ReversePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1044
1298
|
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: ReversePipe, isStandalone: true, name: "reverse" });
|
|
@@ -1052,194 +1306,258 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
1052
1306
|
}] });
|
|
1053
1307
|
|
|
1054
1308
|
/**
|
|
1055
|
-
*
|
|
1309
|
+
* SamplePipe: Randomly selects n items from an array.
|
|
1056
1310
|
*
|
|
1057
|
-
*
|
|
1058
|
-
*
|
|
1311
|
+
* Uses Fisher-Yates partial shuffle for unbiased selection.
|
|
1312
|
+
* Returns a single item when n=1 (default), or an array when n>1.
|
|
1313
|
+
*
|
|
1314
|
+
* @param {unknown[]} value - The array to sample from.
|
|
1315
|
+
* @param {number} [n=1] - Number of items to select.
|
|
1316
|
+
*
|
|
1317
|
+
* @returns {unknown | unknown[]} - A single random item (n=1) or array of random items (n>1).
|
|
1059
1318
|
*
|
|
1060
1319
|
* @example
|
|
1061
|
-
*
|
|
1062
|
-
* {{
|
|
1063
|
-
*
|
|
1320
|
+
* {{ [1, 2, 3, 4, 5] | sample }} // 3 (random single)
|
|
1321
|
+
* {{ [1, 2, 3, 4, 5] | sample:3 }} // [5, 1, 3] (random 3)
|
|
1322
|
+
* {{ users | sample:5 }} // 5 random users
|
|
1064
1323
|
*
|
|
1065
|
-
* @
|
|
1324
|
+
* @note Impure pipe — returns different results on each change detection cycle.
|
|
1325
|
+
* Bind the result to a signal to control when it re-samples.
|
|
1066
1326
|
*/
|
|
1067
|
-
class
|
|
1068
|
-
transform(value) {
|
|
1069
|
-
if (!value ||
|
|
1070
|
-
return
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1327
|
+
class SamplePipe {
|
|
1328
|
+
transform(value, n = 1) {
|
|
1329
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
1330
|
+
return n === 1 ? undefined : [];
|
|
1331
|
+
}
|
|
1332
|
+
if (n <= 0) {
|
|
1333
|
+
return [];
|
|
1334
|
+
}
|
|
1335
|
+
// Clamp n to array length
|
|
1336
|
+
const count = Math.min(n, value.length);
|
|
1337
|
+
// Fisher-Yates partial shuffle — only shuffle `count` positions
|
|
1338
|
+
const arr = [...value];
|
|
1339
|
+
for (let i = arr.length - 1; i > arr.length - 1 - count; i--) {
|
|
1340
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
1341
|
+
[arr[i], arr[j]] = [arr[j], arr[i]];
|
|
1342
|
+
}
|
|
1343
|
+
const result = arr.slice(arr.length - count);
|
|
1344
|
+
// Return single item for n=1, array otherwise
|
|
1345
|
+
return n === 1 ? result[0] : result;
|
|
1079
1346
|
}
|
|
1080
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1081
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1347
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: SamplePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1348
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: SamplePipe, isStandalone: true, name: "sample", pure: false });
|
|
1082
1349
|
}
|
|
1083
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1350
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: SamplePipe, decorators: [{
|
|
1084
1351
|
type: Pipe,
|
|
1085
1352
|
args: [{
|
|
1086
|
-
name: '
|
|
1087
|
-
standalone: true
|
|
1353
|
+
name: 'sample',
|
|
1354
|
+
standalone: true,
|
|
1355
|
+
pure: false,
|
|
1088
1356
|
}]
|
|
1089
1357
|
}] });
|
|
1090
1358
|
|
|
1091
1359
|
/**
|
|
1092
|
-
*
|
|
1360
|
+
* ShufflePipe: Randomly reorders elements in an array using the Fisher-Yates
|
|
1361
|
+
algorithm.
|
|
1093
1362
|
*
|
|
1094
|
-
*
|
|
1095
|
-
*
|
|
1363
|
+
* Uses the Fisher-Yates (Knuth) shuffle for unbiased randomization,
|
|
1364
|
+
* guaranteeing every permutation has equal probability.
|
|
1096
1365
|
*
|
|
1097
|
-
* @
|
|
1366
|
+
* @param {unknown[]} value - The array to shuffle.
|
|
1367
|
+
*
|
|
1368
|
+
* @returns {unknown[]} - A new array with elements in random order.
|
|
1098
1369
|
*
|
|
1099
1370
|
* @example
|
|
1100
|
-
*
|
|
1101
|
-
*
|
|
1371
|
+
* {{ [1, 2, 3, 4, 5] | shuffle }} // [3, 1, 5, 2, 4]
|
|
1372
|
+
* {{ ['a', 'b', 'c'] | shuffle }} // ['c', 'a', 'b']
|
|
1102
1373
|
*
|
|
1103
|
-
* @
|
|
1374
|
+
* @note Impure pipe — runs on every change detection cycle.
|
|
1375
|
+
* Avoid using in performance-critical templates or bind the result
|
|
1376
|
+
* to a signal/variable to control when it re-shuffles.
|
|
1104
1377
|
*/
|
|
1105
|
-
class
|
|
1106
|
-
transform(value
|
|
1107
|
-
if (!value
|
|
1108
|
-
return;
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1378
|
+
class ShufflePipe {
|
|
1379
|
+
transform(value) {
|
|
1380
|
+
if (!Array.isArray(value)) {
|
|
1381
|
+
return [];
|
|
1382
|
+
}
|
|
1383
|
+
const arr = [...value];
|
|
1384
|
+
for (let i = arr.length - 1; i >= 0; i--) {
|
|
1385
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
1386
|
+
[arr[i], arr[j]] = [arr[j], arr[i]];
|
|
1387
|
+
}
|
|
1388
|
+
return arr;
|
|
1112
1389
|
}
|
|
1113
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1114
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1390
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ShufflePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1391
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: ShufflePipe, isStandalone: true, name: "shuffle", pure: false });
|
|
1115
1392
|
}
|
|
1116
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1393
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ShufflePipe, decorators: [{
|
|
1117
1394
|
type: Pipe,
|
|
1118
1395
|
args: [{
|
|
1119
|
-
name: '
|
|
1396
|
+
name: 'shuffle',
|
|
1397
|
+
pure: false,
|
|
1120
1398
|
standalone: true
|
|
1121
1399
|
}]
|
|
1122
1400
|
}] });
|
|
1123
1401
|
|
|
1124
1402
|
/**
|
|
1125
|
-
*
|
|
1403
|
+
* TailPipe: Returns all elements except the first n.
|
|
1126
1404
|
*
|
|
1127
|
-
* @param {
|
|
1128
|
-
* @
|
|
1405
|
+
* @param {unknown[]} value - The array to slice.
|
|
1406
|
+
* @param {number} [n=1] - Number of elements to exclude from the start.
|
|
1407
|
+
*
|
|
1408
|
+
* @returns {unknown[]} - A new array without the first n elements.
|
|
1129
1409
|
*
|
|
1130
1410
|
* @example
|
|
1131
|
-
*
|
|
1132
|
-
* {{
|
|
1133
|
-
*
|
|
1411
|
+
* {{ [1, 2, 3, 4, 5] | tail }} // [2, 3, 4, 5]
|
|
1412
|
+
* {{ [1, 2, 3, 4, 5] | tail:2 }} // [3, 4, 5]
|
|
1413
|
+
* {{ ['a', 'b', 'c'] | tail }} // ['b', 'c']
|
|
1134
1414
|
*/
|
|
1135
|
-
class
|
|
1136
|
-
transform(value) {
|
|
1137
|
-
if (!value
|
|
1138
|
-
return
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1415
|
+
class TailPipe {
|
|
1416
|
+
transform(value, n = 1) {
|
|
1417
|
+
if (!Array.isArray(value)) {
|
|
1418
|
+
return [];
|
|
1419
|
+
}
|
|
1420
|
+
// n = 0 means keep everything
|
|
1421
|
+
if (n <= 0)
|
|
1422
|
+
return [...value];
|
|
1423
|
+
// n >= length means remove everything
|
|
1424
|
+
if (n >= value.length)
|
|
1425
|
+
return [];
|
|
1426
|
+
return value.slice(n);
|
|
1144
1427
|
}
|
|
1145
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1146
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1428
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: TailPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1429
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: TailPipe, isStandalone: true, name: "tail" });
|
|
1147
1430
|
}
|
|
1148
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1431
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: TailPipe, decorators: [{
|
|
1149
1432
|
type: Pipe,
|
|
1150
1433
|
args: [{
|
|
1151
|
-
name: '
|
|
1152
|
-
standalone: true
|
|
1434
|
+
name: 'tail',
|
|
1153
1435
|
}]
|
|
1154
1436
|
}] });
|
|
1155
1437
|
|
|
1156
1438
|
/**
|
|
1157
|
-
*
|
|
1439
|
+
* TruthifyPipe: Removes all falsy values from an array.
|
|
1158
1440
|
*
|
|
1159
|
-
*
|
|
1160
|
-
* It provides options to customize the ellipsis and preserve word boundaries.
|
|
1441
|
+
* Falsy values: false, 0, -0, '', null, undefined, NaN
|
|
1161
1442
|
*
|
|
1162
|
-
* @param {
|
|
1163
|
-
* @param {number} [maxLength=10] - The maximum length of the truncated string. Defaults to 10.
|
|
1164
|
-
* @param {string} [ellipsis='...'] - The string to append to the truncated portion. Defaults to '...'.
|
|
1165
|
-
* @param {boolean} [preserveWords=false] - If true, truncates at the last space before `maxLength` to avoid cutting words. Defaults to false.
|
|
1166
|
-
* @returns {string} - The truncated string. Returns an empty string if the input is null, undefined, or not a string.
|
|
1443
|
+
* @param {unknown[]} value - The array to filter.
|
|
1167
1444
|
*
|
|
1168
|
-
* @
|
|
1169
|
-
* {{ 'This is a long sentence' | truncate }} // Returns 'This is a...'
|
|
1170
|
-
* {{ 'This is a long sentence' | truncate: 20 }} // Returns 'This is a long sente...'
|
|
1171
|
-
* {{ 'This is a long sentence' | truncate: 15: ' [more]' }} // Returns 'This is a long [more]'
|
|
1172
|
-
* {{ 'This is a long sentence' | truncate: 15: '...' : true }} // Returns 'This is a...'
|
|
1173
|
-
* {{ 'This is a long sentence' | truncate: 20: '...' : true }} // Returns 'This is a long...'
|
|
1174
|
-
* {{ null | truncate }} // Returns ''
|
|
1175
|
-
* {{ undefined | truncate }} // Returns ''
|
|
1445
|
+
* @returns {unknown[]} - A new array with only truthy values.
|
|
1176
1446
|
*
|
|
1177
|
-
* @
|
|
1447
|
+
* @example
|
|
1448
|
+
* {{ [0, 1, '', 'hello', null, true] | truthify }} // [1, 'hello', true]
|
|
1449
|
+
* {{ ['', 'a', '', 'b'] | truthify }} // ['a', 'b']
|
|
1178
1450
|
*/
|
|
1179
|
-
class
|
|
1180
|
-
transform(value
|
|
1181
|
-
if (!value
|
|
1182
|
-
return
|
|
1183
|
-
}
|
|
1184
|
-
if (value.length <= maxLength) {
|
|
1185
|
-
return value;
|
|
1451
|
+
class TruthifyPipe {
|
|
1452
|
+
transform(value) {
|
|
1453
|
+
if (!Array.isArray(value)) {
|
|
1454
|
+
return [];
|
|
1186
1455
|
}
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1456
|
+
return value.filter(Boolean);
|
|
1457
|
+
}
|
|
1458
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: TruthifyPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1459
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: TruthifyPipe, isStandalone: true, name: "truthify" });
|
|
1460
|
+
}
|
|
1461
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: TruthifyPipe, decorators: [{
|
|
1462
|
+
type: Pipe,
|
|
1463
|
+
args: [{
|
|
1464
|
+
name: 'truthify',
|
|
1465
|
+
standalone: true,
|
|
1466
|
+
}]
|
|
1467
|
+
}] });
|
|
1468
|
+
|
|
1469
|
+
/**
|
|
1470
|
+
* UniquePipe: Removes duplicate values from an array.
|
|
1471
|
+
*
|
|
1472
|
+
* Supports primitives, objects by property key, and deep nested keys via dot notation.
|
|
1473
|
+
*
|
|
1474
|
+
* @param {unknown[]} value - The array to deduplicate.
|
|
1475
|
+
* @param {string} [key] - Optional property path to compare objects by (e.g., 'id', 'user.email').
|
|
1476
|
+
*
|
|
1477
|
+
* @returns {unknown[]} - A new array with duplicates removed, preserving first occurrence.
|
|
1478
|
+
*
|
|
1479
|
+
* @example
|
|
1480
|
+
* {{ [1, 2, 2, 3] | unique }} // [1, 2, 3]
|
|
1481
|
+
* {{ users | unique:'email' }} // unique by email
|
|
1482
|
+
* {{ orders | unique:'customer.email' }} // unique by nested property
|
|
1483
|
+
*/
|
|
1484
|
+
class UniquePipe {
|
|
1485
|
+
transform(value, key) {
|
|
1486
|
+
if (!Array.isArray(value)) {
|
|
1487
|
+
return [];
|
|
1191
1488
|
}
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
const lastSpaceIndex = truncated.lastIndexOf(' ');
|
|
1195
|
-
// If a space is found and it's not the very beginning of the string
|
|
1196
|
-
if (lastSpaceIndex !== -1 && lastSpaceIndex !== 0) {
|
|
1197
|
-
truncated = truncated.substring(0, lastSpaceIndex);
|
|
1198
|
-
}
|
|
1489
|
+
if (!key) {
|
|
1490
|
+
return [...new Set(value)];
|
|
1199
1491
|
}
|
|
1200
|
-
|
|
1492
|
+
const seen = new Set();
|
|
1493
|
+
return value.filter(item => {
|
|
1494
|
+
const val = this.getNestedValue(item, key);
|
|
1495
|
+
if (seen.has(val))
|
|
1496
|
+
return false;
|
|
1497
|
+
seen.add(val);
|
|
1498
|
+
return true;
|
|
1499
|
+
});
|
|
1201
1500
|
}
|
|
1202
|
-
|
|
1203
|
-
|
|
1501
|
+
getNestedValue(obj, path) {
|
|
1502
|
+
return path.split('.').reduce((current, segment) => current?.[segment], obj);
|
|
1503
|
+
}
|
|
1504
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: UniquePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1505
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: UniquePipe, isStandalone: true, name: "unique" });
|
|
1204
1506
|
}
|
|
1205
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type:
|
|
1507
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: UniquePipe, decorators: [{
|
|
1206
1508
|
type: Pipe,
|
|
1207
1509
|
args: [{
|
|
1208
|
-
name: '
|
|
1510
|
+
name: 'unique',
|
|
1209
1511
|
standalone: true
|
|
1210
1512
|
}]
|
|
1211
1513
|
}] });
|
|
1212
1514
|
|
|
1515
|
+
// Text
|
|
1213
1516
|
const ALL_PIPES = [
|
|
1517
|
+
// Text
|
|
1214
1518
|
AsciiArtPipe,
|
|
1215
|
-
BarcodePipe,
|
|
1216
1519
|
CamelCasePipe,
|
|
1217
|
-
ColorConvertPipe,
|
|
1218
|
-
CreditCardMaskPipe,
|
|
1219
|
-
DeviceTypePipe,
|
|
1220
|
-
EmailMaskPipe,
|
|
1221
|
-
GravatarPipe,
|
|
1222
1520
|
HighlightPipe,
|
|
1223
|
-
HtmlEscapePipe,
|
|
1224
|
-
HtmlSanitizePipe,
|
|
1225
1521
|
InitialsPipe,
|
|
1226
|
-
IpAddressMaskPipe,
|
|
1227
|
-
JsonPrettyPipe,
|
|
1228
1522
|
KebabCasePipe,
|
|
1229
1523
|
MorseCodePipe,
|
|
1230
|
-
QrCodePipe,
|
|
1231
1524
|
ReplacePipe,
|
|
1232
|
-
ReversePipe,
|
|
1233
1525
|
SnakeCasePipe,
|
|
1234
|
-
TextToSpeechPipe,
|
|
1235
1526
|
TitleCasePipe,
|
|
1236
1527
|
TruncatePipe,
|
|
1237
|
-
|
|
1528
|
+
// Security & Privacy
|
|
1529
|
+
CreditCardMaskPipe,
|
|
1530
|
+
EmailMaskPipe,
|
|
1531
|
+
HtmlEscapePipe,
|
|
1532
|
+
HtmlSanitizePipe,
|
|
1533
|
+
IpAddressMaskPipe,
|
|
1534
|
+
// Media & Visual
|
|
1535
|
+
BarcodePipe,
|
|
1536
|
+
ColorConvertPipe,
|
|
1537
|
+
GravatarPipe,
|
|
1538
|
+
QrCodePipe,
|
|
1539
|
+
// Data & Utility
|
|
1540
|
+
CountPipe,
|
|
1541
|
+
DeviceTypePipe,
|
|
1542
|
+
JsonPrettyPipe,
|
|
1543
|
+
TextToSpeechPipe,
|
|
1544
|
+
TimeAgoPipePipe,
|
|
1545
|
+
// Array
|
|
1546
|
+
Flatten,
|
|
1547
|
+
InitialPipe,
|
|
1548
|
+
ReversePipe,
|
|
1549
|
+
SamplePipe,
|
|
1550
|
+
ShufflePipe,
|
|
1551
|
+
TailPipe,
|
|
1552
|
+
TruthifyPipe,
|
|
1553
|
+
UniquePipe,
|
|
1238
1554
|
];
|
|
1239
1555
|
|
|
1556
|
+
// Text
|
|
1557
|
+
|
|
1240
1558
|
/**
|
|
1241
1559
|
* Generated bundle index. Do not edit.
|
|
1242
1560
|
*/
|
|
1243
1561
|
|
|
1244
|
-
export { ALL_PIPES, AsciiArtPipe, BarcodePipe, CamelCasePipe, ColorConvertPipe, CountPipe, CreditCardMaskPipe, DeviceTypePipe, EmailMaskPipe, GravatarPipe, HighlightPipe, HtmlEscapePipe, HtmlSanitizePipe, InitialsPipe, IpAddressMaskPipe, JsonPrettyPipe, KebabCasePipe, MorseCodePipe, QrCodePipe, ReplacePipe, ReversePipe, SnakeCasePipe, TextToSpeechPipe, TitleCasePipe, TruncatePipe };
|
|
1562
|
+
export { ALL_PIPES, AsciiArtPipe, BarcodePipe, CamelCasePipe, ColorConvertPipe, CountPipe, CreditCardMaskPipe, DeviceTypePipe, EmailMaskPipe, Flatten, GravatarPipe, HighlightPipe, HtmlEscapePipe, HtmlSanitizePipe, InitialPipe, InitialsPipe, IpAddressMaskPipe, JsonPrettyPipe, KebabCasePipe, MorseCodePipe, QrCodePipe, ReplacePipe, ReversePipe, SamplePipe, ShufflePipe, SnakeCasePipe, TailPipe, TextToSpeechPipe, TimeAgoPipePipe, TitleCasePipe, TruncatePipe, TruthifyPipe, UniquePipe };
|
|
1245
1563
|
//# sourceMappingURL=ngx-transforms.mjs.map
|