@repobuddy/storybook 0.2.0 → 0.3.1
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/esm/decorators/show_doc_source.d.ts +2 -0
- package/esm/decorators/show_doc_source.js +10 -0
- package/esm/index.d.ts +2 -0
- package/esm/index.js +2 -0
- package/esm/manager/brand_title.d.ts +4 -4
- package/esm/manager/brand_title.js +3 -3
- package/esm/parameters/define_actions_param.d.ts +2 -0
- package/esm/parameters/define_backgrounds_param.d.ts +39 -0
- package/esm/parameters/define_backgrounds_param.js +3 -0
- package/esm/parameters/define_parameters.d.ts +4 -2
- package/esm/parameters/define_story_sort.d.ts +1 -0
- package/esm/parameters/define_test_param.d.ts +2 -0
- package/esm/parameters/define_viewport_param.d.ts +3 -2
- package/package.json +7 -1
- package/readme.md +22 -8
- package/src/decorators/show_doc_source.tsx +21 -0
- package/src/index.ts +2 -0
- package/src/manager/brand_title.ts +5 -5
- package/src/overview.mdx +7 -0
- package/src/parameters/define_actions_param.ts +1 -0
- package/src/parameters/define_backgrounds_param.ts +48 -0
- package/src/parameters/define_parameters.ts +9 -1
- package/src/parameters/define_story_sort.ts +1 -0
- package/src/parameters/define_test_param.ts +1 -0
- package/src/parameters/define_viewport_param.ts +5 -2
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function showDocSource() {
|
|
3
|
+
return (Story, { parameters }) => {
|
|
4
|
+
return (_jsxs("section", { style: {
|
|
5
|
+
display: 'flex',
|
|
6
|
+
flexDirection: 'column',
|
|
7
|
+
gap: '1rem'
|
|
8
|
+
}, children: [_jsx("pre", { children: parameters.docs?.source?.code }), _jsx(Story, {})] }));
|
|
9
|
+
};
|
|
10
|
+
}
|
package/esm/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
export * from './decorators/show_doc_source.tsx';
|
|
1
2
|
export * from './parameters/define_actions_param.ts';
|
|
3
|
+
export * from './parameters/define_backgrounds_param.ts';
|
|
2
4
|
export * from './parameters/define_docs_param.ts';
|
|
3
5
|
export * from './parameters/define_layout_param.ts';
|
|
4
6
|
export * from './parameters/define_parameters.ts';
|
package/esm/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
export * from "./decorators/show_doc_source.js";
|
|
1
2
|
export * from "./parameters/define_actions_param.js";
|
|
3
|
+
export * from "./parameters/define_backgrounds_param.js";
|
|
2
4
|
export * from "./parameters/define_docs_param.js";
|
|
3
5
|
export * from "./parameters/define_layout_param.js";
|
|
4
6
|
export * from "./parameters/define_parameters.js";
|
|
@@ -5,17 +5,17 @@ export interface BrandTitleOptions {
|
|
|
5
5
|
*/
|
|
6
6
|
title: string;
|
|
7
7
|
/**
|
|
8
|
-
* The
|
|
8
|
+
* The logo to display in the brand title.
|
|
9
9
|
* It can be a simple string or raw HTML (e.g. `<svg>`).
|
|
10
10
|
*/
|
|
11
|
-
|
|
11
|
+
logo?: string | undefined;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* Creates a brand title element for the Storybook manager UI.
|
|
15
15
|
*
|
|
16
16
|
* @param options - The options for customizing the brand title
|
|
17
17
|
* @param options.title - The title text or HTML to display
|
|
18
|
-
* @param options.
|
|
18
|
+
* @param options.logo - Optional logo HTML to display before the title
|
|
19
19
|
* @returns An HTML string containing the brand title element
|
|
20
20
|
*
|
|
21
21
|
* @example
|
|
@@ -27,7 +27,7 @@ export interface BrandTitleOptions {
|
|
|
27
27
|
* addons.setConfig({
|
|
28
28
|
* brandTitle: brandTitle({
|
|
29
29
|
* title: 'My Storybook',
|
|
30
|
-
*
|
|
30
|
+
* logo: '<img src="logo.png" alt="Logo" width="24" height="24">'
|
|
31
31
|
* })
|
|
32
32
|
* })
|
|
33
33
|
* ```
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @param options - The options for customizing the brand title
|
|
5
5
|
* @param options.title - The title text or HTML to display
|
|
6
|
-
* @param options.
|
|
6
|
+
* @param options.logo - Optional logo HTML to display before the title
|
|
7
7
|
* @returns An HTML string containing the brand title element
|
|
8
8
|
*
|
|
9
9
|
* @example
|
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
* addons.setConfig({
|
|
16
16
|
* brandTitle: brandTitle({
|
|
17
17
|
* title: 'My Storybook',
|
|
18
|
-
*
|
|
18
|
+
* logo: '<img src="logo.png" alt="Logo" width="24" height="24">'
|
|
19
19
|
* })
|
|
20
20
|
* })
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
23
|
export function brandTitle(options) {
|
|
24
24
|
return `<span style="display: flex; align-items: center; gap: 2px;">
|
|
25
|
-
${options.
|
|
25
|
+
${options.logo ?? ''}
|
|
26
26
|
${options.title}
|
|
27
27
|
</span>`;
|
|
28
28
|
}
|
|
@@ -3,6 +3,7 @@ export interface ActionsParam {
|
|
|
3
3
|
argTypesRegex?: string | undefined;
|
|
4
4
|
disable?: boolean | undefined;
|
|
5
5
|
handles?: string[] | undefined;
|
|
6
|
+
[k: string]: unknown;
|
|
6
7
|
};
|
|
7
8
|
}
|
|
8
9
|
/**
|
|
@@ -15,6 +16,7 @@ export interface ActionsParam {
|
|
|
15
16
|
*/
|
|
16
17
|
export declare function defineActionsParam(actions: ActionsParam['actions']): {
|
|
17
18
|
actions: {
|
|
19
|
+
[k: string]: unknown;
|
|
18
20
|
argTypesRegex?: string | undefined;
|
|
19
21
|
disable?: boolean | undefined;
|
|
20
22
|
handles?: string[] | undefined;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface BackgroundsParam {
|
|
2
|
+
backgrounds: {
|
|
3
|
+
default?: string | undefined;
|
|
4
|
+
values?: Array<{
|
|
5
|
+
name: string;
|
|
6
|
+
value: string;
|
|
7
|
+
}>;
|
|
8
|
+
disable?: boolean | undefined;
|
|
9
|
+
grid?: {
|
|
10
|
+
cellAmount?: number | undefined;
|
|
11
|
+
cellSize?: number | undefined;
|
|
12
|
+
disable?: boolean | undefined;
|
|
13
|
+
offsetX?: number | undefined;
|
|
14
|
+
offsetY?: number | undefined;
|
|
15
|
+
opacity?: number | undefined;
|
|
16
|
+
} | undefined;
|
|
17
|
+
[k: string]: unknown;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface GlobalApiBackgroundsParam {
|
|
21
|
+
backgrounds: {
|
|
22
|
+
default?: string | undefined;
|
|
23
|
+
options?: Array<{
|
|
24
|
+
name: string;
|
|
25
|
+
value: string;
|
|
26
|
+
}>;
|
|
27
|
+
disabled?: boolean | undefined;
|
|
28
|
+
grid?: {
|
|
29
|
+
cellAmount?: number | undefined;
|
|
30
|
+
cellSize?: number | undefined;
|
|
31
|
+
disable?: boolean | undefined;
|
|
32
|
+
offsetX?: number | undefined;
|
|
33
|
+
offsetY?: number | undefined;
|
|
34
|
+
opacity?: number | undefined;
|
|
35
|
+
} | undefined;
|
|
36
|
+
[k: string]: unknown;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export declare const defineBackgroundsParam: (backgrounds: BackgroundsParam["backgrounds"] | GlobalApiBackgroundsParam["backgrounds"]) => BackgroundsParam;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { BackgroundsParam, GlobalApiBackgroundsParam } from './define_backgrounds_param.ts';
|
|
2
|
+
import type { DocsParam } from './define_docs_param.ts';
|
|
1
3
|
import type { LayoutParam } from './define_layout_param.ts';
|
|
2
4
|
import type { StorySortParam } from './define_story_sort.ts';
|
|
3
5
|
import type { TestParam } from './define_test_param.ts';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
+
import type { ViewportParam } from './define_viewport_param.ts';
|
|
7
|
+
export type StorybookBuiltInParams = Partial<BackgroundsParam | GlobalApiBackgroundsParam> & Partial<DocsParam> & Partial<LayoutParam> & Partial<StorySortParam> & Partial<TestParam> & Partial<ViewportParam>;
|
|
6
8
|
export declare function defineParameters<P extends Record<string, any>>(parameters: P & StorybookBuiltInParams): P & StorybookBuiltInParams;
|
|
@@ -4,6 +4,7 @@ export interface TestParam {
|
|
|
4
4
|
mockReset?: boolean | undefined;
|
|
5
5
|
restoreMocks?: boolean | undefined;
|
|
6
6
|
dangerouslyIgnoreUnhandledErrors?: boolean | undefined;
|
|
7
|
+
[k: string]: unknown;
|
|
7
8
|
};
|
|
8
9
|
}
|
|
9
10
|
/**
|
|
@@ -24,6 +25,7 @@ export interface TestParam {
|
|
|
24
25
|
*/
|
|
25
26
|
export declare function defineTestParam(test: TestParam['test']): {
|
|
26
27
|
test: {
|
|
28
|
+
[k: string]: unknown;
|
|
27
29
|
clearMocks?: boolean | undefined;
|
|
28
30
|
mockReset?: boolean | undefined;
|
|
29
31
|
restoreMocks?: boolean | undefined;
|
|
@@ -17,6 +17,7 @@ export interface ViewportParam {
|
|
|
17
17
|
* @deprecated Use `disabled` instead.
|
|
18
18
|
*/
|
|
19
19
|
disable?: boolean | undefined;
|
|
20
|
+
[k: string]: unknown;
|
|
20
21
|
};
|
|
21
22
|
}
|
|
22
23
|
export interface Viewport {
|
|
@@ -27,7 +28,7 @@ export interface Viewport {
|
|
|
27
28
|
};
|
|
28
29
|
type: 'mobile' | 'tablet' | 'desktop';
|
|
29
30
|
}
|
|
30
|
-
export interface
|
|
31
|
+
export interface GlobalApiViewportParam {
|
|
31
32
|
viewport: {
|
|
32
33
|
/**
|
|
33
34
|
* @see https://storybook.js.org/docs/essentials/viewport#viewports
|
|
@@ -47,4 +48,4 @@ export interface ViewportParamV9 {
|
|
|
47
48
|
disabled?: boolean | undefined;
|
|
48
49
|
};
|
|
49
50
|
}
|
|
50
|
-
export declare function defineViewportParam(viewport: ViewportParam['viewport'] |
|
|
51
|
+
export declare function defineViewportParam(viewport: ViewportParam['viewport'] | GlobalApiViewportParam['viewport']): ViewportParam;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@repobuddy/storybook",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Storybook repo buddy",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"storybook",
|
|
@@ -38,14 +38,20 @@
|
|
|
38
38
|
"@storybook/react-vite": "^8.6.12",
|
|
39
39
|
"@storybook/test": "^8.6.12",
|
|
40
40
|
"@storybook/theming": "^8.6.12",
|
|
41
|
+
"@tailwindcss/cli": "^4.1.5",
|
|
42
|
+
"@tailwindcss/vite": "^4.1.5",
|
|
41
43
|
"@vitest/browser": "^3.1.2",
|
|
42
44
|
"@vitest/coverage-v8": "^3.1.2",
|
|
45
|
+
"dedent": "^1.6.0",
|
|
43
46
|
"react": "^19.1.0",
|
|
44
47
|
"react-dom": "^19.1.0",
|
|
45
48
|
"rimraf": "^6.0.1",
|
|
46
49
|
"storybook": "^8.6.12",
|
|
47
50
|
"storybook-addon-tag-badges": "^1.4.0",
|
|
48
51
|
"storybook-addon-vis": "^0.19.4",
|
|
52
|
+
"storybook-dark-mode": "^4.0.2",
|
|
53
|
+
"tailwindcss": "^4.1.5",
|
|
54
|
+
"vite": "^6.3.4",
|
|
49
55
|
"vitest": "^3.1.2"
|
|
50
56
|
},
|
|
51
57
|
"scripts": {
|
package/readme.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# @repobuddy/storybook
|
|
2
2
|
|
|
3
|
-
Your
|
|
3
|
+
Your repository buddy for Storybook.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
|
-
```
|
|
7
|
+
```sh
|
|
8
8
|
pnpm add -D @repobuddy/storybook
|
|
9
9
|
```
|
|
10
10
|
|
|
@@ -12,9 +12,10 @@ pnpm add -D @repobuddy/storybook
|
|
|
12
12
|
|
|
13
13
|
### Typed Parameters
|
|
14
14
|
|
|
15
|
-
Storybook supports some built-in parameters,
|
|
15
|
+
Storybook supports some built-in parameters,
|
|
16
|
+
but the `parameters` props in the `StoryObj` type is typed as `Record<string, any>`.
|
|
16
17
|
|
|
17
|
-
[`@repobuddy/storybook`] adds these types as well as their corresponding define-functions so that you can use them in your stories.
|
|
18
|
+
[`@repobuddy/storybook`][`@repobuddy/storybook`] adds these types as well as their corresponding define-functions so that you can use them in your stories.
|
|
18
19
|
|
|
19
20
|
For example:
|
|
20
21
|
|
|
@@ -43,12 +44,25 @@ export const MyStory: StoryObj = {
|
|
|
43
44
|
}
|
|
44
45
|
```
|
|
45
46
|
|
|
46
|
-
###
|
|
47
|
+
### Brand Title
|
|
47
48
|
|
|
48
|
-
|
|
49
|
+
[`@repobuddy/storybook`][`@repobuddy/storybook`] also provides a `brandTitle` parameter that allows you to set the brand title of your Storybook.
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
```ts
|
|
52
|
+
import { brandTitle } from '@repobuddy/storybook/manager'
|
|
53
|
+
|
|
54
|
+
addons.setConfig({
|
|
55
|
+
brandTitle: brandTitle({
|
|
56
|
+
title:'My Brand',
|
|
57
|
+
logo: `<svg.../>`
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Tag Badges
|
|
63
|
+
|
|
64
|
+
If you use [`storybook-addon-tag-badges`][`storybook-addon-tag-badges`],
|
|
65
|
+
we provide a different set of badges that uses emojis:
|
|
52
66
|
|
|
53
67
|
- 🆕 New components/features
|
|
54
68
|
- 🅱️ Beta status
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Args, DecoratorFunction, Renderer } from 'storybook/internal/csf'
|
|
2
|
+
|
|
3
|
+
export function showDocSource<TRenderer extends Renderer = Renderer, TArgs = Args>(): DecoratorFunction<
|
|
4
|
+
TRenderer,
|
|
5
|
+
TArgs
|
|
6
|
+
> {
|
|
7
|
+
return (Story, { parameters }) => {
|
|
8
|
+
return (
|
|
9
|
+
<section
|
|
10
|
+
style={{
|
|
11
|
+
display: 'flex',
|
|
12
|
+
flexDirection: 'column',
|
|
13
|
+
gap: '1rem'
|
|
14
|
+
}}
|
|
15
|
+
>
|
|
16
|
+
<pre>{parameters.docs?.source?.code}</pre>
|
|
17
|
+
<Story />
|
|
18
|
+
</section>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
export * from './decorators/show_doc_source.tsx'
|
|
1
2
|
export * from './parameters/define_actions_param.ts'
|
|
3
|
+
export * from './parameters/define_backgrounds_param.ts'
|
|
2
4
|
export * from './parameters/define_docs_param.ts'
|
|
3
5
|
export * from './parameters/define_layout_param.ts'
|
|
4
6
|
export * from './parameters/define_parameters.ts'
|
|
@@ -5,10 +5,10 @@ export interface BrandTitleOptions {
|
|
|
5
5
|
*/
|
|
6
6
|
title: string
|
|
7
7
|
/**
|
|
8
|
-
* The
|
|
8
|
+
* The logo to display in the brand title.
|
|
9
9
|
* It can be a simple string or raw HTML (e.g. `<svg>`).
|
|
10
10
|
*/
|
|
11
|
-
|
|
11
|
+
logo?: string | undefined
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -16,7 +16,7 @@ export interface BrandTitleOptions {
|
|
|
16
16
|
*
|
|
17
17
|
* @param options - The options for customizing the brand title
|
|
18
18
|
* @param options.title - The title text or HTML to display
|
|
19
|
-
* @param options.
|
|
19
|
+
* @param options.logo - Optional logo HTML to display before the title
|
|
20
20
|
* @returns An HTML string containing the brand title element
|
|
21
21
|
*
|
|
22
22
|
* @example
|
|
@@ -28,14 +28,14 @@ export interface BrandTitleOptions {
|
|
|
28
28
|
* addons.setConfig({
|
|
29
29
|
* brandTitle: brandTitle({
|
|
30
30
|
* title: 'My Storybook',
|
|
31
|
-
*
|
|
31
|
+
* logo: '<img src="logo.png" alt="Logo" width="24" height="24">'
|
|
32
32
|
* })
|
|
33
33
|
* })
|
|
34
34
|
* ```
|
|
35
35
|
*/
|
|
36
36
|
export function brandTitle(options: BrandTitleOptions) {
|
|
37
37
|
return `<span style="display: flex; align-items: center; gap: 2px;">
|
|
38
|
-
${options.
|
|
38
|
+
${options.logo ?? ''}
|
|
39
39
|
${options.title}
|
|
40
40
|
</span>`
|
|
41
41
|
}
|
package/src/overview.mdx
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export interface BackgroundsParam {
|
|
2
|
+
backgrounds: {
|
|
3
|
+
default?: string | undefined
|
|
4
|
+
values?: Array<{
|
|
5
|
+
name: string
|
|
6
|
+
value: string
|
|
7
|
+
}>
|
|
8
|
+
disable?: boolean | undefined
|
|
9
|
+
grid?:
|
|
10
|
+
| {
|
|
11
|
+
cellAmount?: number | undefined
|
|
12
|
+
cellSize?: number | undefined
|
|
13
|
+
disable?: boolean | undefined
|
|
14
|
+
offsetX?: number | undefined
|
|
15
|
+
offsetY?: number | undefined
|
|
16
|
+
opacity?: number | undefined
|
|
17
|
+
}
|
|
18
|
+
| undefined
|
|
19
|
+
[k: string]: unknown
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export interface GlobalApiBackgroundsParam {
|
|
23
|
+
backgrounds: {
|
|
24
|
+
default?: string | undefined
|
|
25
|
+
options?: Array<{
|
|
26
|
+
name: string
|
|
27
|
+
value: string
|
|
28
|
+
}>
|
|
29
|
+
disabled?: boolean | undefined
|
|
30
|
+
grid?:
|
|
31
|
+
| {
|
|
32
|
+
cellAmount?: number | undefined
|
|
33
|
+
cellSize?: number | undefined
|
|
34
|
+
disable?: boolean | undefined
|
|
35
|
+
offsetX?: number | undefined
|
|
36
|
+
offsetY?: number | undefined
|
|
37
|
+
opacity?: number | undefined
|
|
38
|
+
}
|
|
39
|
+
| undefined
|
|
40
|
+
[k: string]: unknown
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const defineBackgroundsParam = (
|
|
45
|
+
backgrounds: BackgroundsParam['backgrounds'] | GlobalApiBackgroundsParam['backgrounds']
|
|
46
|
+
): BackgroundsParam => ({
|
|
47
|
+
backgrounds
|
|
48
|
+
})
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
import type { BackgroundsParam, GlobalApiBackgroundsParam } from './define_backgrounds_param.ts'
|
|
2
|
+
import type { DocsParam } from './define_docs_param.ts'
|
|
1
3
|
import type { LayoutParam } from './define_layout_param.ts'
|
|
2
4
|
import type { StorySortParam } from './define_story_sort.ts'
|
|
3
5
|
import type { TestParam } from './define_test_param.ts'
|
|
6
|
+
import type { ViewportParam } from './define_viewport_param.ts'
|
|
4
7
|
|
|
5
|
-
export
|
|
8
|
+
export type StorybookBuiltInParams = Partial<BackgroundsParam | GlobalApiBackgroundsParam> &
|
|
9
|
+
Partial<DocsParam> &
|
|
10
|
+
Partial<LayoutParam> &
|
|
11
|
+
Partial<StorySortParam> &
|
|
12
|
+
Partial<TestParam> &
|
|
13
|
+
Partial<ViewportParam>
|
|
6
14
|
|
|
7
15
|
export function defineParameters<P extends Record<string, any>>(parameters: P & StorybookBuiltInParams) {
|
|
8
16
|
return parameters
|
|
@@ -17,6 +17,7 @@ export interface ViewportParam {
|
|
|
17
17
|
* @deprecated Use `disabled` instead.
|
|
18
18
|
*/
|
|
19
19
|
disable?: boolean | undefined
|
|
20
|
+
[k: string]: unknown
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
|
|
@@ -29,7 +30,7 @@ export interface Viewport {
|
|
|
29
30
|
type: 'mobile' | 'tablet' | 'desktop'
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
export interface
|
|
33
|
+
export interface GlobalApiViewportParam {
|
|
33
34
|
viewport: {
|
|
34
35
|
/**
|
|
35
36
|
* @see https://storybook.js.org/docs/essentials/viewport#viewports
|
|
@@ -50,6 +51,8 @@ export interface ViewportParamV9 {
|
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
export function defineViewportParam(
|
|
54
|
+
export function defineViewportParam(
|
|
55
|
+
viewport: ViewportParam['viewport'] | GlobalApiViewportParam['viewport']
|
|
56
|
+
): ViewportParam {
|
|
54
57
|
return { viewport }
|
|
55
58
|
}
|