@quikturn/logos-angular 1.0.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/README.md +455 -0
- package/dist/index.cjs +206 -0
- package/dist/index.d.cts +316 -0
- package/dist/index.d.ts +316 -0
- package/dist/index.mjs +528 -0
- package/package.json +79 -0
package/README.md
ADDED
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
# @quikturn/logos-angular
|
|
2
|
+
|
|
3
|
+
> Angular components for the [Quikturn Logos API](https://getquikturn.io) -- drop-in logo display, infinite carousel, and responsive grid. Built with standalone components and signal inputs for Angular 17+.
|
|
4
|
+
|
|
5
|
+
**[Get your API key](https://getquikturn.io)** -- free tier available, no credit card required.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **`<quikturn-logo>`** -- single logo image with lazy loading, optional link wrapper
|
|
10
|
+
- **`<quikturn-logo-carousel>`** -- infinite scrolling logo ticker (horizontal or vertical)
|
|
11
|
+
- **`<quikturn-logo-grid>`** -- responsive CSS grid of logos with custom template support
|
|
12
|
+
- **`provideQuikturnLogos()`** -- DI-based configuration for token and base URL
|
|
13
|
+
- **`injectLogoUrl()`** -- signal-based reactive logo URL builder
|
|
14
|
+
- **`logoUrl` pipe** -- template pipe for domain-to-URL conversion
|
|
15
|
+
- **Zero CSS dependencies** -- inline styles only, no Angular Material required
|
|
16
|
+
- **Standalone components** -- no `NgModule` needed, import directly
|
|
17
|
+
- **Signal inputs** -- modern Angular patterns with `input()` and `output()`
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# pnpm (recommended)
|
|
23
|
+
pnpm add @quikturn/logos-angular @quikturn/logos
|
|
24
|
+
|
|
25
|
+
# npm
|
|
26
|
+
npm install @quikturn/logos-angular @quikturn/logos
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Peer dependencies:** Angular `>= 17`, `@quikturn/logos >= 0.1.0`
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
### 1. Provide your token at the application level
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
// app.config.ts
|
|
37
|
+
import { ApplicationConfig } from "@angular/core";
|
|
38
|
+
import { provideQuikturnLogos } from "@quikturn/logos-angular";
|
|
39
|
+
|
|
40
|
+
export const appConfig: ApplicationConfig = {
|
|
41
|
+
providers: [
|
|
42
|
+
provideQuikturnLogos({ token: "qt_your_publishable_key" }),
|
|
43
|
+
],
|
|
44
|
+
};
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. Import and use components
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { Component } from "@angular/core";
|
|
51
|
+
import { QuikturnLogoComponent, QuikturnLogoCarouselComponent } from "@quikturn/logos-angular";
|
|
52
|
+
|
|
53
|
+
@Component({
|
|
54
|
+
selector: "app-example",
|
|
55
|
+
standalone: true,
|
|
56
|
+
imports: [QuikturnLogoComponent, QuikturnLogoCarouselComponent],
|
|
57
|
+
template: `
|
|
58
|
+
<!-- Single logo -->
|
|
59
|
+
<quikturn-logo domain="github.com" [size]="64" />
|
|
60
|
+
|
|
61
|
+
<!-- Infinite scrolling carousel -->
|
|
62
|
+
<quikturn-logo-carousel
|
|
63
|
+
[domains]="['github.com', 'stripe.com', 'vercel.com', 'figma.com']"
|
|
64
|
+
[speed]="120"
|
|
65
|
+
[fadeOut]="true"
|
|
66
|
+
[pauseOnHover]="true"
|
|
67
|
+
/>
|
|
68
|
+
`,
|
|
69
|
+
})
|
|
70
|
+
export class ExampleComponent {}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
All components, pipes, and signal functions automatically inherit the token from `provideQuikturnLogos()`.
|
|
74
|
+
|
|
75
|
+
## API Reference
|
|
76
|
+
|
|
77
|
+
### `provideQuikturnLogos(config)`
|
|
78
|
+
|
|
79
|
+
Provides Quikturn configuration to the Angular DI system. Call this in your `ApplicationConfig` or a component's `providers` array.
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
provideQuikturnLogos({ token: "qt_abc123", baseUrl: "https://custom.api" })
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
| Option | Type | Required | Description |
|
|
86
|
+
|--------|------|----------|-------------|
|
|
87
|
+
| `token` | `string` | yes | Publishable API key (`qt_`/`pk_` prefix) |
|
|
88
|
+
| `baseUrl` | `string` | no | Override the Quikturn API base URL |
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### `<quikturn-logo>`
|
|
93
|
+
|
|
94
|
+
Renders a single logo `<img>`. Optionally wraps in an `<a>` tag when `href` is provided. Validates `href` to reject `javascript:` and `data:` protocols.
|
|
95
|
+
|
|
96
|
+
```html
|
|
97
|
+
<quikturn-logo
|
|
98
|
+
domain="stripe.com"
|
|
99
|
+
[size]="128"
|
|
100
|
+
format="webp"
|
|
101
|
+
[greyscale]="true"
|
|
102
|
+
theme="dark"
|
|
103
|
+
alt="Stripe"
|
|
104
|
+
href="https://stripe.com"
|
|
105
|
+
loading="lazy"
|
|
106
|
+
class="my-logo"
|
|
107
|
+
/>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
#### Inputs
|
|
111
|
+
|
|
112
|
+
| Input | Type | Default | Description |
|
|
113
|
+
|-------|------|---------|-------------|
|
|
114
|
+
| `domain` | `string` | **required** | Domain to fetch logo for |
|
|
115
|
+
| `token` | `string` | from provider | Publishable API key |
|
|
116
|
+
| `baseUrl` | `string` | from provider | API base URL override |
|
|
117
|
+
| `size` | `number` | -- | Logo width in pixels |
|
|
118
|
+
| `format` | `string` | -- | `"png"`, `"jpeg"`, `"webp"`, `"avif"`, or MIME type |
|
|
119
|
+
| `greyscale` | `boolean` | -- | Greyscale transformation |
|
|
120
|
+
| `theme` | `string` | -- | `"light"` or `"dark"` |
|
|
121
|
+
| `alt` | `string` | `"<domain> logo"` | Image alt text |
|
|
122
|
+
| `href` | `string` | -- | Wraps the image in a link |
|
|
123
|
+
| `loading` | `"lazy" \| "eager"` | `"lazy"` | Native image loading strategy |
|
|
124
|
+
| `class` | `string` | -- | CSS class on wrapper element |
|
|
125
|
+
|
|
126
|
+
#### Outputs
|
|
127
|
+
|
|
128
|
+
| Output | Type | Description |
|
|
129
|
+
|--------|------|-------------|
|
|
130
|
+
| `imgError` | `Event` | Emitted when the logo image fails to load |
|
|
131
|
+
| `imgLoad` | `Event` | Emitted when the logo image loads successfully |
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
### `<quikturn-logo-carousel>`
|
|
136
|
+
|
|
137
|
+
Infinite scrolling logo ticker powered by `requestAnimationFrame`. Supports horizontal (left/right) and vertical (up/down) scrolling, hover-based speed changes, fade overlays, and per-logo customization.
|
|
138
|
+
|
|
139
|
+
```html
|
|
140
|
+
<quikturn-logo-carousel
|
|
141
|
+
[domains]="['github.com', 'stripe.com', 'vercel.com', 'figma.com']"
|
|
142
|
+
[speed]="120"
|
|
143
|
+
direction="left"
|
|
144
|
+
[logoHeight]="28"
|
|
145
|
+
[gap]="48"
|
|
146
|
+
[fadeOut]="true"
|
|
147
|
+
fadeOutColor="#f5f5f5"
|
|
148
|
+
[pauseOnHover]="true"
|
|
149
|
+
[scaleOnHover]="true"
|
|
150
|
+
width="100%"
|
|
151
|
+
/>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
#### Using `logos` for per-logo configuration
|
|
155
|
+
|
|
156
|
+
```html
|
|
157
|
+
<quikturn-logo-carousel
|
|
158
|
+
[logos]="[
|
|
159
|
+
{ domain: 'github.com', href: 'https://github.com', alt: 'GitHub' },
|
|
160
|
+
{ domain: 'stripe.com', size: 256, greyscale: true },
|
|
161
|
+
{ domain: 'vercel.com', theme: 'dark' }
|
|
162
|
+
]"
|
|
163
|
+
/>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
#### Inputs
|
|
167
|
+
|
|
168
|
+
| Input | Type | Default | Description |
|
|
169
|
+
|-------|------|---------|-------------|
|
|
170
|
+
| `domains` | `string[]` | -- | Simple list of domains (use this or `logos`) |
|
|
171
|
+
| `logos` | `LogoConfig[]` | -- | Per-logo configuration objects (use this or `domains`) |
|
|
172
|
+
| `token` | `string` | from provider | Publishable API key |
|
|
173
|
+
| `baseUrl` | `string` | from provider | API base URL override |
|
|
174
|
+
| `speed` | `number` | `120` | Scroll speed in pixels per second |
|
|
175
|
+
| `direction` | `"left" \| "right" \| "up" \| "down"` | `"left"` | Scroll direction |
|
|
176
|
+
| `pauseOnHover` | `boolean` | -- | Pause scrolling on mouse hover |
|
|
177
|
+
| `hoverSpeed` | `number` | -- | Custom speed during hover (`0` = pause, overrides `pauseOnHover`) |
|
|
178
|
+
| `logoHeight` | `number` | `28` | Height of each logo image in pixels |
|
|
179
|
+
| `gap` | `number` | `32` | Gap between logos in pixels |
|
|
180
|
+
| `width` | `number \| string` | `"100%"` | Container width (`600`, `"80%"`, etc.) |
|
|
181
|
+
| `fadeOut` | `boolean` | `false` | Show gradient fade overlays at edges |
|
|
182
|
+
| `fadeOutColor` | `string` | `"#ffffff"` | Fade overlay color (match your background) |
|
|
183
|
+
| `scaleOnHover` | `boolean` | `false` | Scale logos on individual hover |
|
|
184
|
+
| `logoSize` | `number` | -- | Default image fetch width for all logos |
|
|
185
|
+
| `logoFormat` | `string` | -- | Default image format for all logos |
|
|
186
|
+
| `logoGreyscale` | `boolean` | -- | Default greyscale setting for all logos |
|
|
187
|
+
| `logoTheme` | `string` | -- | Default theme for all logos |
|
|
188
|
+
| `class` | `string` | -- | CSS class on root container |
|
|
189
|
+
| `ariaLabel` | `string` | `"Company logos"` | Accessible label for the region |
|
|
190
|
+
|
|
191
|
+
#### `LogoConfig`
|
|
192
|
+
|
|
193
|
+
Used in the `logos` array for per-logo customization:
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
interface LogoConfig {
|
|
197
|
+
domain: string; // Required
|
|
198
|
+
href?: string; // Wrap in link
|
|
199
|
+
alt?: string; // Alt text override
|
|
200
|
+
size?: number; // Per-logo image width
|
|
201
|
+
format?: string; // Per-logo format
|
|
202
|
+
greyscale?: boolean; // Per-logo greyscale
|
|
203
|
+
theme?: "light" | "dark";
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
### `<quikturn-logo-grid>`
|
|
210
|
+
|
|
211
|
+
Responsive CSS grid of logos with optional custom templates.
|
|
212
|
+
|
|
213
|
+
```html
|
|
214
|
+
<quikturn-logo-grid
|
|
215
|
+
[domains]="['github.com', 'stripe.com', 'vercel.com', 'figma.com']"
|
|
216
|
+
[columns]="4"
|
|
217
|
+
[gap]="24"
|
|
218
|
+
ariaLabel="Our partners"
|
|
219
|
+
/>
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
#### Custom template
|
|
223
|
+
|
|
224
|
+
```html
|
|
225
|
+
<quikturn-logo-grid [domains]="companies">
|
|
226
|
+
<ng-template #renderItem let-logo let-i="index">
|
|
227
|
+
<div class="custom-card">
|
|
228
|
+
<img [src]="logo.url" [alt]="logo.alt" />
|
|
229
|
+
<span>{{ logo.domain }}</span>
|
|
230
|
+
</div>
|
|
231
|
+
</ng-template>
|
|
232
|
+
</quikturn-logo-grid>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
#### Inputs
|
|
236
|
+
|
|
237
|
+
| Input | Type | Default | Description |
|
|
238
|
+
|-------|------|---------|-------------|
|
|
239
|
+
| `domains` | `string[]` | -- | Simple list of domains (use this or `logos`) |
|
|
240
|
+
| `logos` | `LogoConfig[]` | -- | Per-logo configuration objects |
|
|
241
|
+
| `token` | `string` | from provider | Publishable API key |
|
|
242
|
+
| `baseUrl` | `string` | from provider | API base URL override |
|
|
243
|
+
| `columns` | `number` | `4` | Number of grid columns |
|
|
244
|
+
| `gap` | `number` | `24` | Grid gap in pixels |
|
|
245
|
+
| `logoSize` | `number` | -- | Default image fetch width |
|
|
246
|
+
| `logoFormat` | `string` | -- | Default image format |
|
|
247
|
+
| `logoGreyscale` | `boolean` | -- | Default greyscale |
|
|
248
|
+
| `logoTheme` | `string` | -- | Default theme |
|
|
249
|
+
| `class` | `string` | -- | CSS class on grid container |
|
|
250
|
+
| `ariaLabel` | `string` | `"Company logos"` | Accessible label for the region |
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
### `logoUrl` Pipe
|
|
255
|
+
|
|
256
|
+
Transform a domain string into a logo URL directly in templates.
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
import { Component } from "@angular/core";
|
|
260
|
+
import { LogoUrlPipe } from "@quikturn/logos-angular";
|
|
261
|
+
|
|
262
|
+
@Component({
|
|
263
|
+
selector: "app-pipe-demo",
|
|
264
|
+
standalone: true,
|
|
265
|
+
imports: [LogoUrlPipe],
|
|
266
|
+
template: `
|
|
267
|
+
<img [src]="'github.com' | logoUrl" alt="GitHub logo" />
|
|
268
|
+
<img [src]="'google.com' | logoUrl: { size: 64, format: 'webp' }" alt="Google logo" />
|
|
269
|
+
`,
|
|
270
|
+
})
|
|
271
|
+
export class PipeDemoComponent {}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
The pipe reads the token from the `QUIKTURN_CONFIG` injection token. You can override per-use:
|
|
275
|
+
|
|
276
|
+
```html
|
|
277
|
+
<img [src]="'github.com' | logoUrl: { token: 'qt_other_token' }" alt="GitHub" />
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
### `injectLogoUrl(options)`
|
|
283
|
+
|
|
284
|
+
Signal-based helper that builds a reactive logo URL. Must be called within an Angular injection context. The returned signal recomputes automatically whenever any input signal changes.
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
import { Component, signal } from "@angular/core";
|
|
288
|
+
import { injectLogoUrl } from "@quikturn/logos-angular";
|
|
289
|
+
|
|
290
|
+
@Component({
|
|
291
|
+
selector: "app-signal-demo",
|
|
292
|
+
standalone: true,
|
|
293
|
+
template: `<img [src]="logoSrc()" alt="Logo" />`,
|
|
294
|
+
})
|
|
295
|
+
export class SignalDemoComponent {
|
|
296
|
+
domain = signal("github.com");
|
|
297
|
+
|
|
298
|
+
logoSrc = injectLogoUrl({
|
|
299
|
+
domain: () => this.domain(),
|
|
300
|
+
size: () => 128,
|
|
301
|
+
format: () => "webp",
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
| Option | Type | Description |
|
|
307
|
+
|--------|------|-------------|
|
|
308
|
+
| `domain` | `() => string` | Reactive getter for the domain (required) |
|
|
309
|
+
| `token` | `() => string \| undefined` | Override the provider token |
|
|
310
|
+
| `baseUrl` | `() => string \| undefined` | Override the provider base URL |
|
|
311
|
+
| `size` | `() => number \| undefined` | Logo width in pixels |
|
|
312
|
+
| `format` | `() => string \| undefined` | Output format |
|
|
313
|
+
| `greyscale` | `() => boolean \| undefined` | Greyscale transformation |
|
|
314
|
+
| `theme` | `() => string \| undefined` | Theme optimization |
|
|
315
|
+
|
|
316
|
+
**Returns:** `Signal<string>` -- computed signal with the full logo URL
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## Types
|
|
321
|
+
|
|
322
|
+
All types are exported for use in your application:
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
import type {
|
|
326
|
+
QuikturnConfig,
|
|
327
|
+
LogoOptions,
|
|
328
|
+
LogoConfig,
|
|
329
|
+
ResolvedLogo,
|
|
330
|
+
SupportedOutputFormat,
|
|
331
|
+
FormatShorthand,
|
|
332
|
+
ThemeOption,
|
|
333
|
+
} from "@quikturn/logos-angular";
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
| Type | Description |
|
|
337
|
+
|------|-------------|
|
|
338
|
+
| `QuikturnConfig` | Configuration for `provideQuikturnLogos()` (`token`, optional `baseUrl`) |
|
|
339
|
+
| `LogoOptions` | Options for logo generation (`size`, `format`, `greyscale`, `theme`) |
|
|
340
|
+
| `LogoConfig` | Per-logo config extending `LogoOptions` with `domain`, `href`, `alt` |
|
|
341
|
+
| `ResolvedLogo` | Internal resolved logo with pre-built `url`, `domain`, `alt`, `href` |
|
|
342
|
+
| `SupportedOutputFormat` | Full format strings (re-exported from `@quikturn/logos`) |
|
|
343
|
+
| `FormatShorthand` | Short format aliases (re-exported from `@quikturn/logos`) |
|
|
344
|
+
| `ThemeOption` | `"light" \| "dark"` (re-exported from `@quikturn/logos`) |
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## API Summary
|
|
349
|
+
|
|
350
|
+
| Export | Kind | Description |
|
|
351
|
+
|--------|------|-------------|
|
|
352
|
+
| `provideQuikturnLogos()` | Function | Provide config to Angular DI |
|
|
353
|
+
| `QUIKTURN_CONFIG` | InjectionToken | Access config directly via `inject()` |
|
|
354
|
+
| `injectLogoUrl()` | Function | Signal-based reactive logo URL builder |
|
|
355
|
+
| `LogoUrlPipe` | Pipe | Template pipe for domain-to-URL conversion |
|
|
356
|
+
| `QuikturnLogoComponent` | Component | Single logo image |
|
|
357
|
+
| `QuikturnLogoGridComponent` | Component | Grid layout of logos |
|
|
358
|
+
| `QuikturnLogoCarouselComponent` | Component | Infinite scrolling carousel |
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## Examples
|
|
363
|
+
|
|
364
|
+
### Logo Wall (Marketing Page)
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
@Component({
|
|
368
|
+
selector: "app-logo-wall",
|
|
369
|
+
standalone: true,
|
|
370
|
+
imports: [QuikturnLogoCarouselComponent],
|
|
371
|
+
template: `
|
|
372
|
+
<h2>Trusted by industry leaders</h2>
|
|
373
|
+
<quikturn-logo-carousel
|
|
374
|
+
[domains]="partners"
|
|
375
|
+
[speed]="80"
|
|
376
|
+
[logoHeight]="32"
|
|
377
|
+
[gap]="64"
|
|
378
|
+
[fadeOut]="true"
|
|
379
|
+
[pauseOnHover]="true"
|
|
380
|
+
/>
|
|
381
|
+
`,
|
|
382
|
+
})
|
|
383
|
+
export class LogoWallComponent {
|
|
384
|
+
partners = [
|
|
385
|
+
"github.com", "stripe.com", "vercel.com", "figma.com",
|
|
386
|
+
"linear.app", "notion.so", "slack.com", "discord.com",
|
|
387
|
+
];
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Partner Grid with Links
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
@Component({
|
|
395
|
+
selector: "app-partner-grid",
|
|
396
|
+
standalone: true,
|
|
397
|
+
imports: [QuikturnLogoGridComponent],
|
|
398
|
+
template: `
|
|
399
|
+
<quikturn-logo-grid [logos]="partners" [columns]="2" [gap]="32" />
|
|
400
|
+
`,
|
|
401
|
+
})
|
|
402
|
+
export class PartnerGridComponent {
|
|
403
|
+
partners: LogoConfig[] = [
|
|
404
|
+
{ domain: "github.com", href: "https://github.com", alt: "GitHub" },
|
|
405
|
+
{ domain: "stripe.com", href: "https://stripe.com", alt: "Stripe" },
|
|
406
|
+
{ domain: "vercel.com", href: "https://vercel.com", alt: "Vercel" },
|
|
407
|
+
{ domain: "figma.com", href: "https://figma.com", alt: "Figma" },
|
|
408
|
+
];
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Vertical Carousel
|
|
413
|
+
|
|
414
|
+
```html
|
|
415
|
+
<div style="height: 240px">
|
|
416
|
+
<quikturn-logo-carousel
|
|
417
|
+
[domains]="['github.com', 'stripe.com', 'vercel.com']"
|
|
418
|
+
direction="up"
|
|
419
|
+
[speed]="60"
|
|
420
|
+
[logoHeight]="24"
|
|
421
|
+
/>
|
|
422
|
+
</div>
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### Signal-Based Reactive URL
|
|
426
|
+
|
|
427
|
+
```typescript
|
|
428
|
+
@Component({
|
|
429
|
+
selector: "app-reactive",
|
|
430
|
+
standalone: true,
|
|
431
|
+
template: `
|
|
432
|
+
<input [(ngModel)]="domain" placeholder="Enter a domain" />
|
|
433
|
+
<img [src]="logoSrc()" [alt]="domain() + ' logo'" />
|
|
434
|
+
`,
|
|
435
|
+
})
|
|
436
|
+
export class ReactiveComponent {
|
|
437
|
+
domain = signal("github.com");
|
|
438
|
+
logoSrc = injectLogoUrl({
|
|
439
|
+
domain: () => this.domain(),
|
|
440
|
+
size: () => 256,
|
|
441
|
+
format: () => "webp",
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
## Resources
|
|
447
|
+
|
|
448
|
+
- **[Quikturn website](https://getquikturn.io)** -- sign up, manage keys, explore the API
|
|
449
|
+
- **[Dashboard](https://getquikturn.io/dashboard)** -- usage analytics, key management, plan upgrades
|
|
450
|
+
- **[Pricing](https://getquikturn.io/pricing)** -- free tier, pro, and enterprise plans
|
|
451
|
+
- **[Core SDK docs](https://www.npmjs.com/package/@quikturn/logos)** -- `@quikturn/logos` URL builder, browser client, server client
|
|
452
|
+
|
|
453
|
+
## License
|
|
454
|
+
|
|
455
|
+
MIT -- built by [Quikturn](https://getquikturn.io)
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("@angular/core"),g=require("@quikturn/logos"),O=require("@angular/common"),u=new t.InjectionToken("QUIKTURN_CONFIG");function x(s){return t.makeEnvironmentProviders([{provide:u,useValue:s}])}function w(s){t.assertInInjectionContext(w);const e=t.inject(u,{optional:!0});return t.computed(()=>{var o,r,a,l,c,d;const i=((o=s.token)==null?void 0:o.call(s))??(e==null?void 0:e.token),n=((r=s.baseUrl)==null?void 0:r.call(s))??(e==null?void 0:e.baseUrl);return g.logoUrl(s.domain(),{token:i,baseUrl:n,size:(a=s.size)==null?void 0:a.call(s),format:(l=s.format)==null?void 0:l.call(s),greyscale:(c=s.greyscale)==null?void 0:c.call(s),theme:(d=s.theme)==null?void 0:d.call(s)})})}var U=Object.getOwnPropertyDescriptor,L=(s,e,i,n)=>{for(var o=n>1?void 0:n?U(e,i):e,r=s.length-1,a;r>=0;r--)(a=s[r])&&(o=a(o)||o);return o};exports.LogoUrlPipe=class{constructor(){this.config=t.inject(u,{optional:!0})}transform(e,i){var r,a;const n=(i==null?void 0:i.token)??((r=this.config)==null?void 0:r.token),o=(i==null?void 0:i.baseUrl)??((a=this.config)==null?void 0:a.baseUrl);return g.logoUrl(e,{token:n,baseUrl:o,size:i==null?void 0:i.size,format:i==null?void 0:i.format,greyscale:i==null?void 0:i.greyscale,theme:i==null?void 0:i.theme})}};exports.LogoUrlPipe=L([t.Pipe({name:"logoUrl",standalone:!0})],exports.LogoUrlPipe);const k=new Set;function y(s){if(typeof window>"u"||!s||s.startsWith("sk_")||k.has(s))return;k.add(s);const e=new Image;e.src=`${g.BASE_URL}/_beacon?token=${s}&page=${encodeURIComponent(location.href)}`}function b(s){try{const e=new URL(s,"https://placeholder.invalid");return e.protocol==="https:"||e.protocol==="http:"}catch{return!1}}var z=Object.getOwnPropertyDescriptor,I=(s,e,i,n)=>{for(var o=n>1?void 0:n?z(e,i):e,r=s.length-1,a;r>=0;r--)(a=s[r])&&(o=a(o)||o);return o};exports.QuikturnLogoComponent=class{constructor(){this.config=t.inject(u,{optional:!0}),this.domain=t.input.required(),this.token=t.input(void 0),this.baseUrl=t.input(void 0),this.size=t.input(void 0),this.format=t.input(void 0),this.greyscale=t.input(void 0),this.theme=t.input(void 0),this.alt=t.input(void 0),this.href=t.input(void 0),this.cssClass=t.input(void 0,{alias:"class"}),this.loading=t.input("lazy"),this.imgError=t.output(),this.imgLoad=t.output(),this.effectiveToken=t.computed(()=>{var e;return this.token()??((e=this.config)==null?void 0:e.token)??""}),this.effectiveBaseUrl=t.computed(()=>{var e;return this.baseUrl()??((e=this.config)==null?void 0:e.baseUrl)}),this.safeHref=t.computed(()=>{const e=this.href();return e&&b(e)?e:void 0}),this.src=t.computed(()=>g.logoUrl(this.domain(),{token:this.effectiveToken()||void 0,size:this.size(),format:this.format(),greyscale:this.greyscale(),theme:this.theme(),baseUrl:this.effectiveBaseUrl()})),this.altText=t.computed(()=>this.alt()??`${this.domain()} logo`)}ngOnInit(){const e=this.effectiveToken();e&&y(e)}};exports.QuikturnLogoComponent=I([t.Component({selector:"quikturn-logo",standalone:!0,template:`
|
|
2
|
+
@if (safeHref()) {
|
|
3
|
+
<a [href]="safeHref()" target="_blank" rel="noopener noreferrer" [class]="cssClass()">
|
|
4
|
+
<img [src]="src()" [alt]="altText()" [attr.loading]="loading()" (error)="imgError.emit($event)" (load)="imgLoad.emit($event)" />
|
|
5
|
+
</a>
|
|
6
|
+
} @else if (cssClass()) {
|
|
7
|
+
<span [class]="cssClass()">
|
|
8
|
+
<img [src]="src()" [alt]="altText()" [attr.loading]="loading()" (error)="imgError.emit($event)" (load)="imgLoad.emit($event)" />
|
|
9
|
+
</span>
|
|
10
|
+
} @else {
|
|
11
|
+
<img [src]="src()" [alt]="altText()" [attr.loading]="loading()" (error)="imgError.emit($event)" (load)="imgLoad.emit($event)" />
|
|
12
|
+
}
|
|
13
|
+
`})],exports.QuikturnLogoComponent);var _=Object.getOwnPropertyDescriptor,T=(s,e,i,n)=>{for(var o=n>1?void 0:n?_(e,i):e,r=s.length-1,a;r>=0;r--)(a=s[r])&&(o=a(o)||o);return o};exports.QuikturnLogoGridComponent=class{constructor(){this.config=t.inject(u,{optional:!0}),this.domains=t.input(void 0),this.logos=t.input(void 0),this.token=t.input(void 0),this.baseUrl=t.input(void 0),this.columns=t.input(4),this.gap=t.input(24),this.logoSize=t.input(void 0),this.logoFormat=t.input(void 0),this.logoGreyscale=t.input(void 0),this.logoTheme=t.input(void 0),this.cssClass=t.input(void 0,{alias:"class"}),this.ariaLabel=t.input("Company logos"),this.customTemplate=t.contentChild("renderItem"),this.effectiveToken=t.computed(()=>{var e;return this.token()??((e=this.config)==null?void 0:e.token)??""}),this.effectiveBaseUrl=t.computed(()=>{var e;return this.baseUrl()??((e=this.config)==null?void 0:e.baseUrl)}),this.resolvedLogos=t.computed(()=>(this.logos()??(this.domains()??[]).map(i=>({domain:i}))).map(i=>({domain:i.domain,alt:i.alt??`${i.domain} logo`,href:i.href&&b(i.href)?i.href:void 0,url:g.logoUrl(i.domain,{token:this.effectiveToken()||void 0,size:i.size??this.logoSize(),format:i.format??this.logoFormat(),greyscale:i.greyscale??this.logoGreyscale(),theme:i.theme??this.logoTheme(),baseUrl:this.effectiveBaseUrl()})})))}ngOnInit(){const e=this.effectiveToken();e&&y(e)}};exports.QuikturnLogoGridComponent=T([t.Component({selector:"quikturn-logo-grid",standalone:!0,imports:[O.CommonModule],template:`
|
|
14
|
+
<div
|
|
15
|
+
role="region"
|
|
16
|
+
[attr.aria-label]="ariaLabel()"
|
|
17
|
+
[class]="cssClass()"
|
|
18
|
+
[style.display]="'grid'"
|
|
19
|
+
[style.grid-template-columns]="'repeat(' + columns() + ', 1fr)'"
|
|
20
|
+
[style.gap.px]="gap()"
|
|
21
|
+
[style.align-items]="'center'"
|
|
22
|
+
[style.justify-items]="'center'"
|
|
23
|
+
>
|
|
24
|
+
@for (logo of resolvedLogos(); track logo.domain; let i = $index) {
|
|
25
|
+
@if (customTemplate()) {
|
|
26
|
+
<ng-container
|
|
27
|
+
[ngTemplateOutlet]="customTemplate()!"
|
|
28
|
+
[ngTemplateOutletContext]="{ $implicit: logo, index: i }"
|
|
29
|
+
></ng-container>
|
|
30
|
+
} @else {
|
|
31
|
+
<div style="display: flex; align-items: center; justify-content: center;">
|
|
32
|
+
@if (logo.href) {
|
|
33
|
+
<a
|
|
34
|
+
[href]="logo.href"
|
|
35
|
+
target="_blank"
|
|
36
|
+
rel="noopener noreferrer"
|
|
37
|
+
[attr.aria-label]="logo.alt"
|
|
38
|
+
>
|
|
39
|
+
<img
|
|
40
|
+
[src]="logo.url"
|
|
41
|
+
[alt]="logo.alt"
|
|
42
|
+
loading="lazy"
|
|
43
|
+
style="max-width: 100%; height: auto; display: block;"
|
|
44
|
+
/>
|
|
45
|
+
</a>
|
|
46
|
+
} @else {
|
|
47
|
+
<img
|
|
48
|
+
[src]="logo.url"
|
|
49
|
+
[alt]="logo.alt"
|
|
50
|
+
loading="lazy"
|
|
51
|
+
style="max-width: 100%; height: auto; display: block;"
|
|
52
|
+
/>
|
|
53
|
+
}
|
|
54
|
+
</div>
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
</div>
|
|
58
|
+
`})],exports.QuikturnLogoGridComponent);var E=Object.defineProperty,M=Object.getOwnPropertyDescriptor,C=(s,e,i,n)=>{for(var o=n>1?void 0:n?M(e,i):e,r=s.length-1,a;r>=0;r--)(a=s[r])&&(o=(n?a(e,i,o):a(o))||o);return n&&o&&E(e,i,o),o};const f={SMOOTH_TAU:.25,MIN_COPIES:2,COPY_HEADROOM:2};exports.QuikturnLogoCarouselComponent=class{constructor(){this.config=t.inject(u,{optional:!0}),this.domains=t.input(void 0),this.logos=t.input(void 0),this.token=t.input(void 0),this.baseUrl=t.input(void 0),this.speed=t.input(120),this.direction=t.input("left"),this.pauseOnHover=t.input(void 0),this.hoverSpeed=t.input(void 0),this.logoHeight=t.input(28),this.gap=t.input(32),this.width=t.input("100%"),this.fadeOut=t.input(!1),this.fadeOutColor=t.input("#ffffff"),this.scaleOnHover=t.input(!1),this.logoSize=t.input(void 0),this.logoFormat=t.input(void 0),this.logoGreyscale=t.input(void 0),this.logoTheme=t.input(void 0),this.cssClass=t.input(void 0,{alias:"class"}),this.ariaLabel=t.input("Company logos"),this.seqWidth=t.signal(0),this.seqHeight=t.signal(0),this.copyCount=t.signal(f.MIN_COPIES),this.isHovered=t.signal(!1),this.animationFrameId=null,this.currentVelocity=0,this.offset=0,this.resizeObserver=null,this.handleResize=()=>this.updateDimensions(),this.effectiveToken=t.computed(()=>{var e;return this.token()??((e=this.config)==null?void 0:e.token)??""}),this.effectiveBaseUrl=t.computed(()=>{var e;return this.baseUrl()??((e=this.config)==null?void 0:e.baseUrl)}),this.isVertical=t.computed(()=>this.direction()==="up"||this.direction()==="down"),this.resolvedLogos=t.computed(()=>(this.logos()??(this.domains()??[]).map(i=>({domain:i}))).map(i=>({domain:i.domain,alt:i.alt??`${i.domain} logo`,href:i.href,url:g.logoUrl(i.domain,{token:this.effectiveToken()||void 0,size:i.size??this.logoSize(),format:i.format??this.logoFormat(),greyscale:i.greyscale??this.logoGreyscale(),theme:i.theme??this.logoTheme(),baseUrl:this.effectiveBaseUrl()})}))),this.cssWidth=t.computed(()=>{const e=this.width();return typeof e=="number"?`${e}px`:e??"100%"}),this.copyIndices=t.computed(()=>Array.from({length:this.copyCount()},(e,i)=>i)),this.targetVelocity=t.computed(()=>{const e=Math.abs(this.speed()),i=this.isVertical()?this.direction()==="up"?1:-1:this.direction()==="left"?1:-1,n=this.speed()<0?-1:1;return e*i*n}),this.effectiveHoverSpeed=t.computed(()=>{const e=this.hoverSpeed();if(e!==void 0)return e;if(this.pauseOnHover()===!0)return 0})}ngOnInit(){const e=this.effectiveToken();e&&y(e)}ngAfterViewInit(){var i;this.updateDimensions(),this.trackImageLoads(),this.startAnimation();const e=(i=this.containerRef)==null?void 0:i.nativeElement;e&&typeof window<"u"&&(window.ResizeObserver?(this.resizeObserver=new ResizeObserver(()=>this.updateDimensions()),this.resizeObserver.observe(e)):window.addEventListener("resize",this.handleResize))}ngOnDestroy(){var e;this.stopAnimation(),(e=this.resizeObserver)==null||e.disconnect(),this.resizeObserver=null,typeof window<"u"&&window.removeEventListener("resize",this.handleResize)}handleMouseEnter(){this.effectiveHoverSpeed()!==void 0&&this.isHovered.set(!0)}handleMouseLeave(){this.effectiveHoverSpeed()!==void 0&&this.isHovered.set(!1)}updateDimensions(){var l,c,d;const e=(l=this.containerRef)==null?void 0:l.nativeElement,i=(c=this.trackRef)==null?void 0:c.nativeElement;if(!e||!i)return;const n=i.querySelector("ul");if(!n)return;const o=n.getBoundingClientRect(),r=o.width,a=o.height;if(this.isVertical()){const h=((d=e.parentElement)==null?void 0:d.clientHeight)??0;if(h>0&&(e.style.height=`${Math.ceil(h)}px`),a>0){this.seqHeight.set(Math.ceil(a));const m=e.clientHeight||h||a,v=Math.ceil(m/a)+f.COPY_HEADROOM;this.copyCount.set(Math.max(f.MIN_COPIES,v))}}else if(r>0){this.seqWidth.set(Math.ceil(r));const h=e.clientWidth||0,m=Math.ceil(h/r)+f.COPY_HEADROOM;this.copyCount.set(Math.max(f.MIN_COPIES,m))}}trackImageLoads(){var r;const e=(r=this.trackRef)==null?void 0:r.nativeElement;if(!e)return;const i=e.querySelectorAll("ul:first-child img");if(i.length===0)return;let n=i.length;const o=()=>{n--,n===0&&this.updateDimensions()};i.forEach(a=>{const l=a;l.complete?o():(l.addEventListener("load",o,{once:!0}),l.addEventListener("error",o,{once:!0}))})}startAnimation(){var r,a;const e=(r=this.trackRef)==null?void 0:r.nativeElement;if(!e)return;if(typeof window<"u"&&((a=window.matchMedia)==null?void 0:a.call(window,"(prefers-reduced-motion: reduce)").matches)){e.style.transform="translate3d(0, 0, 0)";return}let n=null;this.currentVelocity=this.targetVelocity();const o=l=>{if(n===null){n=l,this.animationFrameId=requestAnimationFrame(o);return}const c=Math.min(Math.max(0,(l-n)/1e3),.1);n=l;const d=this.effectiveHoverSpeed(),h=this.isHovered()&&d!==void 0?d:this.targetVelocity(),m=f.SMOOTH_TAU,v=1-Math.exp(-c/m);this.currentVelocity+=(h-this.currentVelocity)*v,this.offset+=this.currentVelocity*c;const p=this.isVertical()?this.seqHeight():this.seqWidth();p>0&&(this.offset=(this.offset%p+p)%p),this.isVertical()?e.style.transform=`translate3d(0, ${-this.offset}px, 0)`:e.style.transform=`translate3d(${-this.offset}px, 0, 0)`,this.animationFrameId=requestAnimationFrame(o)};this.animationFrameId=requestAnimationFrame(o)}stopAnimation(){this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null)}};C([t.ViewChild("container")],exports.QuikturnLogoCarouselComponent.prototype,"containerRef",2);C([t.ViewChild("track")],exports.QuikturnLogoCarouselComponent.prototype,"trackRef",2);exports.QuikturnLogoCarouselComponent=C([t.Component({selector:"quikturn-logo-carousel",standalone:!0,imports:[O.CommonModule],template:`
|
|
59
|
+
<div
|
|
60
|
+
#container
|
|
61
|
+
role="region"
|
|
62
|
+
[attr.aria-label]="ariaLabel()"
|
|
63
|
+
[class]="cssClass()"
|
|
64
|
+
[style.position]="'relative'"
|
|
65
|
+
[style.overflow]="'hidden'"
|
|
66
|
+
[style.width]="isVertical() ? undefined : cssWidth()"
|
|
67
|
+
[style.height]="isVertical() ? '100%' : undefined"
|
|
68
|
+
>
|
|
69
|
+
@if (fadeOut()) {
|
|
70
|
+
@if (isVertical()) {
|
|
71
|
+
<div
|
|
72
|
+
aria-hidden="true"
|
|
73
|
+
data-testid="fade-overlay"
|
|
74
|
+
[style.position]="'absolute'"
|
|
75
|
+
[style.pointer-events]="'none'"
|
|
76
|
+
[style.z-index]="1"
|
|
77
|
+
[style.top]="'0'"
|
|
78
|
+
[style.left]="'0'"
|
|
79
|
+
[style.right]="'0'"
|
|
80
|
+
[style.height]="'clamp(24px, 8%, 120px)'"
|
|
81
|
+
[style.background]="
|
|
82
|
+
'linear-gradient(to bottom, ' +
|
|
83
|
+
fadeOutColor() +
|
|
84
|
+
' 0%, transparent 100%)'
|
|
85
|
+
"
|
|
86
|
+
></div>
|
|
87
|
+
<div
|
|
88
|
+
aria-hidden="true"
|
|
89
|
+
data-testid="fade-overlay"
|
|
90
|
+
[style.position]="'absolute'"
|
|
91
|
+
[style.pointer-events]="'none'"
|
|
92
|
+
[style.z-index]="1"
|
|
93
|
+
[style.bottom]="'0'"
|
|
94
|
+
[style.left]="'0'"
|
|
95
|
+
[style.right]="'0'"
|
|
96
|
+
[style.height]="'clamp(24px, 8%, 120px)'"
|
|
97
|
+
[style.background]="
|
|
98
|
+
'linear-gradient(to top, ' +
|
|
99
|
+
fadeOutColor() +
|
|
100
|
+
' 0%, transparent 100%)'
|
|
101
|
+
"
|
|
102
|
+
></div>
|
|
103
|
+
} @else {
|
|
104
|
+
<div
|
|
105
|
+
aria-hidden="true"
|
|
106
|
+
data-testid="fade-overlay"
|
|
107
|
+
[style.position]="'absolute'"
|
|
108
|
+
[style.pointer-events]="'none'"
|
|
109
|
+
[style.z-index]="1"
|
|
110
|
+
[style.top]="'0'"
|
|
111
|
+
[style.bottom]="'0'"
|
|
112
|
+
[style.left]="'0'"
|
|
113
|
+
[style.width]="'clamp(24px, 8%, 120px)'"
|
|
114
|
+
[style.background]="
|
|
115
|
+
'linear-gradient(to right, ' +
|
|
116
|
+
fadeOutColor() +
|
|
117
|
+
' 0%, transparent 100%)'
|
|
118
|
+
"
|
|
119
|
+
></div>
|
|
120
|
+
<div
|
|
121
|
+
aria-hidden="true"
|
|
122
|
+
data-testid="fade-overlay"
|
|
123
|
+
[style.position]="'absolute'"
|
|
124
|
+
[style.pointer-events]="'none'"
|
|
125
|
+
[style.z-index]="1"
|
|
126
|
+
[style.top]="'0'"
|
|
127
|
+
[style.bottom]="'0'"
|
|
128
|
+
[style.right]="'0'"
|
|
129
|
+
[style.width]="'clamp(24px, 8%, 120px)'"
|
|
130
|
+
[style.background]="
|
|
131
|
+
'linear-gradient(to left, ' +
|
|
132
|
+
fadeOutColor() +
|
|
133
|
+
' 0%, transparent 100%)'
|
|
134
|
+
"
|
|
135
|
+
></div>
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
<div
|
|
140
|
+
#track
|
|
141
|
+
[style.display]="'flex'"
|
|
142
|
+
[style.flex-direction]="isVertical() ? 'column' : 'row'"
|
|
143
|
+
[style.width]="isVertical() ? '100%' : 'max-content'"
|
|
144
|
+
[style.will-change]="'transform'"
|
|
145
|
+
[style.user-select]="'none'"
|
|
146
|
+
[style.position]="'relative'"
|
|
147
|
+
[style.z-index]="'0'"
|
|
148
|
+
(mouseenter)="handleMouseEnter()"
|
|
149
|
+
(mouseleave)="handleMouseLeave()"
|
|
150
|
+
>
|
|
151
|
+
@for (ci of copyIndices(); track ci) {
|
|
152
|
+
<ul
|
|
153
|
+
role="list"
|
|
154
|
+
[attr.aria-hidden]="ci > 0 ? 'true' : null"
|
|
155
|
+
[style.display]="'flex'"
|
|
156
|
+
[style.flex-direction]="isVertical() ? 'column' : 'row'"
|
|
157
|
+
[style.align-items]="'center'"
|
|
158
|
+
[style.list-style]="'none'"
|
|
159
|
+
[style.margin]="'0'"
|
|
160
|
+
[style.padding]="'0'"
|
|
161
|
+
>
|
|
162
|
+
@for (logo of resolvedLogos(); track logo.domain + '-' + ci + '-' + $index) {
|
|
163
|
+
<li
|
|
164
|
+
role="listitem"
|
|
165
|
+
[style.flex]="'none'"
|
|
166
|
+
[style.margin-right.px]="isVertical() ? 0 : gap()"
|
|
167
|
+
[style.margin-bottom.px]="isVertical() ? gap() : 0"
|
|
168
|
+
>
|
|
169
|
+
@if (logo.href) {
|
|
170
|
+
<a
|
|
171
|
+
[href]="logo.href"
|
|
172
|
+
target="_blank"
|
|
173
|
+
rel="noopener noreferrer"
|
|
174
|
+
[attr.aria-label]="logo.alt"
|
|
175
|
+
style="display: inline-flex; align-items: center; text-decoration: none"
|
|
176
|
+
>
|
|
177
|
+
<img
|
|
178
|
+
[src]="logo.url"
|
|
179
|
+
[alt]="logo.alt"
|
|
180
|
+
loading="lazy"
|
|
181
|
+
decoding="async"
|
|
182
|
+
[attr.draggable]="false"
|
|
183
|
+
[style.height.px]="logoHeight()"
|
|
184
|
+
style="width: auto; display: block; object-fit: contain"
|
|
185
|
+
/>
|
|
186
|
+
</a>
|
|
187
|
+
} @else {
|
|
188
|
+
<span style="display: inline-flex; align-items: center">
|
|
189
|
+
<img
|
|
190
|
+
[src]="logo.url"
|
|
191
|
+
[alt]="logo.alt"
|
|
192
|
+
loading="lazy"
|
|
193
|
+
decoding="async"
|
|
194
|
+
[attr.draggable]="false"
|
|
195
|
+
[style.height.px]="logoHeight()"
|
|
196
|
+
style="width: auto; display: block; object-fit: contain"
|
|
197
|
+
/>
|
|
198
|
+
</span>
|
|
199
|
+
}
|
|
200
|
+
</li>
|
|
201
|
+
}
|
|
202
|
+
</ul>
|
|
203
|
+
}
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
`})],exports.QuikturnLogoCarouselComponent);exports.QUIKTURN_CONFIG=u;exports.injectLogoUrl=w;exports.isValidHref=b;exports.provideQuikturnLogos=x;
|