superdesk-ui-framework 3.0.1-beta.1 → 3.0.1-beta.2

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.
Files changed (168) hide show
  1. package/app/fonts/sd_big-icons.eot +0 -0
  2. package/app/fonts/sd_big-icons.svg +55 -53
  3. package/app/fonts/sd_big-icons.ttf +0 -0
  4. package/app/fonts/sd_big-icons.woff +0 -0
  5. package/app/fonts/sd_icons.eot +0 -0
  6. package/app/fonts/sd_icons.svg +1 -0
  7. package/app/fonts/sd_icons.ttf +0 -0
  8. package/app/fonts/sd_icons.woff +0 -0
  9. package/app/img/dots.svg +3 -0
  10. package/app/styles/_accessibility.scss +3 -3
  11. package/app/styles/_big-icon-font.scss +60 -23
  12. package/app/styles/_boxed-list.scss +26 -3
  13. package/app/styles/_buttons.scss +4 -0
  14. package/app/styles/_helpers.scss +4 -3
  15. package/app/styles/_icon-font.scss +341 -307
  16. package/app/styles/_icon-labels.scss +66 -10
  17. package/app/styles/_table-list.scss +244 -0
  18. package/app/styles/app.scss +1 -0
  19. package/app/styles/components/_list-item.scss +24 -20
  20. package/app/styles/components/_sd-dropzone.scss +52 -16
  21. package/app/styles/components/_subnav.scss +87 -80
  22. package/app/styles/design-tokens/_design-tokens-general.scss +7 -0
  23. package/app/styles/design-tokens/_new-colors.scss +4 -2
  24. package/app/styles/form-elements/_inputs.scss +4 -0
  25. package/app/styles/grids/_grid-layout.scss +21 -7
  26. package/app/styles/layout/_container.scss +3 -0
  27. package/app/styles/layout/_editor.scss +108 -16
  28. package/app/styles/menus/_sd-sidebar-menu.scss +6 -0
  29. package/app/styles/primereact/_pr-dialog.scss +39 -7
  30. package/app-typescript/components/CreateButton.tsx +38 -0
  31. package/app-typescript/components/DropZone.tsx +4 -4
  32. package/app-typescript/components/Icon.tsx +3 -1
  33. package/app-typescript/components/IconLabel.tsx +8 -1
  34. package/app-typescript/components/Input.tsx +2 -0
  35. package/app-typescript/components/Layouts/AuthoringContainer.tsx +27 -0
  36. package/app-typescript/components/Layouts/AuthoringInnerHeader.tsx +2 -0
  37. package/app-typescript/components/Layouts/AuthoringMain.tsx +11 -7
  38. package/app-typescript/components/Layouts/AuthoringMainToolBar.tsx +7 -1
  39. package/app-typescript/components/Layouts/Container.tsx +1 -1
  40. package/app-typescript/components/Layouts/ContentSplitter.tsx +23 -0
  41. package/app-typescript/components/Layouts/Layout.tsx +33 -0
  42. package/app-typescript/components/Layouts/LayoutContainer.tsx +1 -4
  43. package/app-typescript/components/Layouts/MainPanel.tsx +10 -5
  44. package/app-typescript/components/Layouts/OverlayPanel.tsx +19 -0
  45. package/app-typescript/components/Layouts/Panel.tsx +1 -0
  46. package/app-typescript/components/Layouts/index.tsx +8 -2
  47. package/app-typescript/components/Lists/BoxedList.tsx +6 -2
  48. package/app-typescript/components/Lists/ContentList.tsx +100 -0
  49. package/app-typescript/components/Lists/TableList.tsx +208 -0
  50. package/app-typescript/components/Modal.tsx +27 -17
  51. package/app-typescript/components/Navigation/SideBarTabs.tsx +10 -0
  52. package/app-typescript/components/SearchBar.tsx +79 -0
  53. package/app-typescript/components/Select.tsx +2 -0
  54. package/app-typescript/components/SidebarMenu.tsx +68 -0
  55. package/app-typescript/components/Spinner.tsx +1 -1
  56. package/app-typescript/components/SwitchGroup.tsx +2 -1
  57. package/app-typescript/index.ts +3 -0
  58. package/dist/dots.svg +3 -0
  59. package/dist/examples.bundle.css +7871 -379
  60. package/dist/examples.bundle.js +29461 -15740
  61. package/dist/playgrounds/react-playgrounds/EditorTest.tsx +9 -4
  62. package/dist/playgrounds/react-playgrounds/Index.tsx +3 -1
  63. package/dist/playgrounds/react-playgrounds/PersonalProfile.tsx +13 -0
  64. package/dist/playgrounds/react-playgrounds/RundownEditor.tsx +466 -0
  65. package/dist/playgrounds/react-playgrounds/Rundowns.tsx +1002 -0
  66. package/dist/playgrounds/react-playgrounds/TestGround.tsx +190 -182
  67. package/dist/playgrounds/react-playgrounds/UiPlayground.tsx +4 -0
  68. package/dist/playgrounds/react-playgrounds/components/AuthoringContainer.tsx +26 -0
  69. package/dist/playgrounds/react-playgrounds/components/ContentSplitter.tsx +22 -0
  70. package/dist/playgrounds/react-playgrounds/components/Index.tsx +6 -1
  71. package/dist/playgrounds/react-playgrounds/components/MainPanel.tsx +11 -1
  72. package/dist/playgrounds/react-playgrounds/components/SearchBar.tsx +51 -9
  73. package/dist/react/Container.tsx +1 -1
  74. package/dist/react/ContentList.tsx +280 -0
  75. package/dist/react/CreateButton.tsx +71 -0
  76. package/dist/react/DropZone.tsx +14 -6
  77. package/dist/react/IconButtons.tsx +6 -6
  78. package/dist/react/IconLabels.tsx +24 -2
  79. package/dist/react/Index.tsx +15 -0
  80. package/dist/react/Inputs.tsx +32 -3
  81. package/dist/react/Modal.tsx +1 -0
  82. package/dist/react/TableList.tsx +268 -0
  83. package/dist/sd_big-icons.eot +0 -0
  84. package/dist/sd_big-icons.svg +55 -53
  85. package/dist/sd_big-icons.ttf +0 -0
  86. package/dist/sd_big-icons.woff +0 -0
  87. package/dist/sd_icons.eot +0 -0
  88. package/dist/sd_icons.svg +1 -0
  89. package/dist/sd_icons.ttf +0 -0
  90. package/dist/sd_icons.woff +0 -0
  91. package/dist/superdesk-ui.bundle.css +44994 -24931
  92. package/dist/superdesk-ui.bundle.js +2437 -1949
  93. package/dist/vendor.bundle.js +27 -27
  94. package/examples/css/docs-page.css +2 -3
  95. package/examples/index.js +8 -0
  96. package/examples/pages/playgrounds/react-playgrounds/EditorTest.tsx +9 -4
  97. package/examples/pages/playgrounds/react-playgrounds/Index.tsx +3 -1
  98. package/examples/pages/playgrounds/react-playgrounds/PersonalProfile.tsx +13 -0
  99. package/examples/pages/playgrounds/react-playgrounds/RundownEditor.tsx +466 -0
  100. package/examples/pages/playgrounds/react-playgrounds/Rundowns.tsx +1002 -0
  101. package/examples/pages/playgrounds/react-playgrounds/TestGround.tsx +190 -182
  102. package/examples/pages/playgrounds/react-playgrounds/UiPlayground.tsx +4 -0
  103. package/examples/pages/playgrounds/react-playgrounds/components/AuthoringContainer.tsx +26 -0
  104. package/examples/pages/playgrounds/react-playgrounds/components/ContentSplitter.tsx +22 -0
  105. package/examples/pages/playgrounds/react-playgrounds/components/Index.tsx +6 -1
  106. package/examples/pages/playgrounds/react-playgrounds/components/MainPanel.tsx +11 -1
  107. package/examples/pages/playgrounds/react-playgrounds/components/SearchBar.tsx +51 -9
  108. package/examples/pages/react/Container.tsx +1 -1
  109. package/examples/pages/react/ContentList.tsx +280 -0
  110. package/examples/pages/react/CreateButton.tsx +71 -0
  111. package/examples/pages/react/DropZone.tsx +14 -6
  112. package/examples/pages/react/IconButtons.tsx +6 -6
  113. package/examples/pages/react/IconLabels.tsx +24 -2
  114. package/examples/pages/react/Index.tsx +15 -0
  115. package/examples/pages/react/Inputs.tsx +32 -3
  116. package/examples/pages/react/Modal.tsx +1 -0
  117. package/examples/pages/react/TableList.tsx +268 -0
  118. package/package.json +2 -1
  119. package/react/components/CreateButton.d.ts +17 -0
  120. package/react/components/CreateButton.js +66 -0
  121. package/react/components/DropZone.d.ts +2 -2
  122. package/react/components/DropZone.js +2 -2
  123. package/react/components/Icon.d.ts +1 -0
  124. package/react/components/Icon.js +2 -1
  125. package/react/components/IconLabel.d.ts +2 -0
  126. package/react/components/IconLabel.js +6 -3
  127. package/react/components/Input.d.ts +1 -0
  128. package/react/components/Input.js +1 -0
  129. package/react/components/Layouts/AuthoringContainer.d.ts +11 -0
  130. package/react/components/Layouts/AuthoringContainer.js +58 -0
  131. package/react/components/Layouts/AuthoringInnerHeader.d.ts +1 -0
  132. package/react/components/Layouts/AuthoringInnerHeader.js +6 -3
  133. package/react/components/Layouts/AuthoringMain.d.ts +3 -1
  134. package/react/components/Layouts/AuthoringMain.js +2 -2
  135. package/react/components/Layouts/AuthoringMainToolBar.d.ts +1 -0
  136. package/react/components/Layouts/AuthoringMainToolBar.js +8 -1
  137. package/react/components/Layouts/Container.d.ts +1 -1
  138. package/react/components/Layouts/ContentSplitter.d.ts +10 -0
  139. package/react/components/Layouts/ContentSplitter.js +56 -0
  140. package/react/components/Layouts/Layout.d.ts +8 -0
  141. package/react/components/Layouts/Layout.js +35 -0
  142. package/react/components/Layouts/LayoutContainer.js +1 -1
  143. package/react/components/Layouts/MainPanel.d.ts +1 -0
  144. package/react/components/Layouts/MainPanel.js +11 -4
  145. package/react/components/Layouts/OverlayPanel.d.ts +8 -0
  146. package/react/components/Layouts/OverlayPanel.js +49 -0
  147. package/react/components/Layouts/Panel.d.ts +1 -0
  148. package/react/components/Layouts/index.d.ts +6 -2
  149. package/react/components/Layouts/index.js +12 -4
  150. package/react/components/Lists/BoxedList.d.ts +2 -0
  151. package/react/components/Lists/BoxedList.js +6 -4
  152. package/react/components/Modal.d.ts +2 -0
  153. package/react/components/Modal.js +11 -3
  154. package/react/components/Navigation/SideBarTabs.d.ts +1 -0
  155. package/react/components/Navigation/SideBarTabs.js +4 -0
  156. package/react/components/SearchBar.d.ts +23 -0
  157. package/react/components/SearchBar.js +87 -0
  158. package/react/components/Select.d.ts +1 -0
  159. package/react/components/Select.js +1 -0
  160. package/react/components/Spinner.js +1 -1
  161. package/react/components/SwitchGroup.d.ts +1 -0
  162. package/react/components/SwitchGroup.js +1 -1
  163. package/react/index.d.ts +2 -0
  164. package/react/index.js +5 -0
  165. package/sd_icons.eot +0 -0
  166. package/sd_icons.svg +189 -0
  167. package/sd_icons.ttf +0 -0
  168. package/sd_icons.woff +0 -0
@@ -1,11 +1,14 @@
1
1
  import React from 'react';
2
2
  import { Dialog as PrimeDialog } from '@superdesk/primereact/dialog';
3
+ import classNames from 'classnames';
3
4
 
4
5
  interface IProps {
5
6
  id?: string;
6
7
  className?: string;
7
8
  theme?: string;
8
9
  visible?: boolean;
10
+ contentBg?: 'default' | 'medium' | 'dark';
11
+ contentPadding?: 'none' | 'small' | 'medium' | 'large';
9
12
  size?: 'small' | 'medium' | 'large' | 'x-large';
10
13
  maximized?: boolean;
11
14
  headerTemplate?: JSX.Element | string;
@@ -17,22 +20,29 @@ interface IProps {
17
20
 
18
21
  export class Modal extends React.Component<IProps, {}> {
19
22
  render() {
20
- return <div style={{display: 'content'}}
21
- data-theme={this.props.theme !== 'dark' ? null : 'dark-ui' }
22
- className={this.props.className}>
23
- <PrimeDialog
24
- id={this.props.id}
25
- visible={this.props.visible}
26
- header={this.props.headerTemplate}
27
- footer={this.props.footerTemplate}
28
- closeOnEscape={this.props.closeOnEscape}
29
- maximized={this.props.maximized}
30
- contentClassName={this.props.size ?
31
- ('p-dialog-content--' + this.props.size) : undefined}
32
- onShow={this.props.onShow}
33
- onHide={this.props.onHide}>
34
- {this.props.children}
35
- </PrimeDialog>
36
- </div>;
23
+ let classes = classNames({
24
+ [`p-dialog-content--${this.props.size}`]: this.props.size,
25
+ 'p-dialog-content--default': this.props.contentBg === undefined,
26
+ [`p-dialog-content--${this.props.contentBg}`]: this.props.contentBg,
27
+ 'p-dialog-content--s-padding': this.props.contentPadding === undefined,
28
+ [`p-dialog-content--${this.props.contentPadding}`]: this.props.contentPadding,
29
+ }, this.props.className);
30
+ return (
31
+ <div style={{display: 'content'}}
32
+ data-theme={this.props.theme !== 'dark' ? null : 'dark-ui' }>
33
+ <PrimeDialog
34
+ id={this.props.id}
35
+ visible={this.props.visible}
36
+ header={this.props.headerTemplate}
37
+ footer={this.props.footerTemplate}
38
+ closeOnEscape={this.props.closeOnEscape}
39
+ maximized={this.props.maximized}
40
+ contentClassName={classes}
41
+ onShow={this.props.onShow}
42
+ onHide={this.props.onHide}>
43
+ {this.props.children}
44
+ </PrimeDialog>
45
+ </div>
46
+ );
37
47
  }
38
48
  }
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { Icon } from '../Icon';
3
+ import { Badge } from '../Badge';
3
4
 
4
5
  interface IProps {
5
6
  items: Array<ISideBarTab | 'divider'>;
@@ -11,6 +12,7 @@ export interface ISideBarTab {
11
12
  size: 'small' | 'big'; // defaults to 'small'
12
13
  tooltip?: string;
13
14
  active?: boolean;
15
+ badgeValue?: string;
14
16
  onClick(event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void;
15
17
  }
16
18
 
@@ -61,6 +63,14 @@ export class SideBarTabs extends React.PureComponent<IProps, IState> {
61
63
  ' sd-sidetab-menu__btn--active' :
62
64
  (index === this.state.index ? ' sd-sidetab-menu__btn--active' : ''))}
63
65
  onClick={() => this.handleClick(item, index, event)}>
66
+ {
67
+ item['badgeValue'] != null
68
+ ? (
69
+ <Badge text={item['badgeValue']} type='primary' />
70
+ )
71
+ : null
72
+ }
73
+
64
74
  <span className='sd-sidetab-menu__main-icon '>
65
75
  <Icon size={item['size']} name={item['icon']} />
66
76
  </span>
@@ -0,0 +1,79 @@
1
+ import * as React from 'react';
2
+ import classNames from 'classnames';
3
+ import {Icon} from './Icon';
4
+
5
+ interface IProps {
6
+ value?: string | number;
7
+ type?: 'expanded' | 'collapsed' | 'boxed';
8
+ placeholder: string;
9
+ focused?: boolean;
10
+ boxed?: boolean;
11
+ onSubmit?(): void;
12
+ }
13
+
14
+ interface IState {
15
+ inputValue: any;
16
+ type: string;
17
+ focused: boolean;
18
+ boxed?: boolean;
19
+ }
20
+
21
+ export class SearchBar extends React.PureComponent<IProps, IState> {
22
+ private inputRef: any;
23
+ constructor(props: IProps) {
24
+ super(props);
25
+ this.state = {
26
+ inputValue: this.props.value ? this.props.value : '',
27
+ focused: this.props.focused ? this.props.focused : false,
28
+ type: this.props.type ? this.props.type : 'expanded',
29
+ boxed: this.props.boxed ? this.props.boxed : false,
30
+ };
31
+ this.inputRef = React.createRef();
32
+ }
33
+
34
+ componentDidUpdate(prevProps: any) {
35
+ if (prevProps.value !== this.props.value) {
36
+ this.setState({inputValue: this.props.value});
37
+ }
38
+ }
39
+
40
+ componentDidMount = () => {
41
+ document.addEventListener("mousedown", (event) => {
42
+ if (this.inputRef.current && !this.inputRef.current.contains(event.target)) {
43
+ this.setState({focused: false});
44
+ }
45
+ });
46
+ }
47
+
48
+ render() {
49
+ let classes = classNames('sd-searchbar', {
50
+ [`sd-searchbar--${this.state.type}`] : this.props.type,
51
+ 'sd-searchbar--expanded': this.state.type === 'expanded' || this.props.type === undefined,
52
+ 'sd-searchbar--focused' : this.state.focused,
53
+ 'sd-searchbar--boxed': this.state.boxed,
54
+ });
55
+ return (
56
+ <div className={classes} ref={this.inputRef}>
57
+ <label className="sd-searchbar__icon"></label>
58
+ <input id="search-input"
59
+ ref={(input: any) => (input && this.props.focused) && input.focus()}
60
+ className="sd-searchbar__input"
61
+ type="text"
62
+ placeholder={this.props.placeholder}
63
+ value={this.state.inputValue}
64
+ onChange={(e) => this.setState({inputValue: e.target.value})}
65
+ onFocus={() => this.setState({focused: true})} />
66
+ {this.state.inputValue &&
67
+ <button className="sd-searchbar__cancel" onClick={() => this.setState({inputValue: ''})}>
68
+ <Icon name='remove-sign' />
69
+ </button>}
70
+ <button
71
+ id="sd-searchbar__search-btn"
72
+ className="sd-searchbar__search-btn"
73
+ onSubmit={() => this.props.onSubmit}>
74
+ <Icon name='chevron-right-thin' />
75
+ </button>
76
+ </div>
77
+ );
78
+ }
79
+ }
@@ -13,6 +13,7 @@ interface ISelect {
13
13
  inlineLabel?: boolean;
14
14
  labelHidden?: boolean;
15
15
  tabindex?: number;
16
+ fullWidth?: boolean;
16
17
  onChange(newValue: string): void;
17
18
  }
18
19
 
@@ -45,6 +46,7 @@ class Select extends React.Component<ISelect, IState> {
45
46
  'sd-input--inline-label': this.props.inlineLabel,
46
47
  'sd-input--required': this.props.required,
47
48
  'sd-input--disabled': this.props.disabled,
49
+ 'sd-input--full-width': this.props.fullWidth,
48
50
  'sd-input--invalid': this.props.invalid || this.state.invalid,
49
51
  });
50
52
  const labelClasses = classNames('sd-input__label', {
@@ -0,0 +1,68 @@
1
+ import * as React from 'react';
2
+ import { Icon } from './Icon';
3
+
4
+ interface IProps {
5
+ items: Array<IItem | 'divider'>;
6
+ }
7
+
8
+ interface IItem {
9
+ icon: string;
10
+ size: 'small' | 'big'; // defaults to 'small'
11
+ tooltip?: string;
12
+ active?: boolean;
13
+ }
14
+
15
+ interface IState {
16
+ index: number;
17
+ closeIndex: number;
18
+ }
19
+
20
+ export class SidebarMenu extends React.PureComponent<IProps, IState> {
21
+ constructor(props: IProps) {
22
+ super(props);
23
+ this.state = {
24
+ index: -1,
25
+ closeIndex: -1,
26
+ };
27
+ this.handleClick = this.handleClick.bind(this);
28
+ }
29
+
30
+ handleClick(indexNumber: number) {
31
+ this.setState({
32
+ index: indexNumber,
33
+ });
34
+ if (this.state.index === indexNumber) {
35
+ this.setState({
36
+ closeIndex: indexNumber,
37
+ });
38
+ }
39
+ }
40
+
41
+ render() {
42
+ return (
43
+ <div className='sd-sidebar-menu sd-content-wrapper__left-tabs'>
44
+ <ul className='authoring-active'>
45
+ {this.props.items.map((item, index) => {
46
+ if (item === 'divider') {
47
+ return (
48
+ <li key={index} className='sd-sidebar-menu__spacer'></li>
49
+ );
50
+ } else {
51
+ return (
52
+ <li key={index} data-sd-tooltip={item['tooltip']} data-flow='right'>
53
+ <a className={'sd-sidebar-menu__btn' + (index === this.state.closeIndex ? ' sd-sidebar-menu__btn--closed ' : '') + (item['active'] ? ' sd-sidebar-menu__btn--active' : (index === this.state.index ? ' sd-sidebar-menu__btn--active' : ''))}
54
+ onClick={() => this.handleClick(index)}>
55
+ <span className='sd-sidebar-menu__main-icon '>
56
+ <Icon size={item['size']} name={item['icon']} />
57
+ </span>
58
+ <i className='sd-sidebar-menu__helper-icon big-icon--chevron-left'></i>
59
+ </a>
60
+ </li>
61
+ );
62
+ }
63
+ })}
64
+ </ul>
65
+ </div>
66
+ );
67
+ }
68
+ }
@@ -23,7 +23,7 @@ class Spinner extends React.PureComponent<IProps> {
23
23
  });
24
24
  return (
25
25
  <svg role="progressbar" className={classes} viewBox="0 0 50 50">
26
- <circle className="sd-spinner__path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
26
+ <circle className="sd-spinner__path" cx="25" cy="25" r="20" fill="none" strokeWidth="5"></circle>
27
27
  </svg>
28
28
  );
29
29
  }
@@ -5,6 +5,7 @@ interface IProps {
5
5
  orientation?: 'vertical' | 'horizontal'; // defaults to 'vertical'
6
6
  align?: 'left' | 'right'; // defaults to 'left'
7
7
  children: React.ReactNode;
8
+ className?: string;
8
9
  }
9
10
 
10
11
  export class SwitchGroup extends React.PureComponent<IProps> {
@@ -13,7 +14,7 @@ export class SwitchGroup extends React.PureComponent<IProps> {
13
14
  [`sd-switch__group--vertical`]: this.props.orientation !== 'horizontal',
14
15
  [`sd-switch__group--horizontal`]: this.props.orientation === 'horizontal',
15
16
  [`sd-switch__group--right`]: this.props.align === 'right',
16
- });
17
+ }, this.props.className);
17
18
 
18
19
  return (
19
20
  <div className={classes}>
@@ -69,6 +69,9 @@ export { SelectGrid } from './components/SelectGrid';
69
69
  export { IconPicker } from './components/IconPicker';
70
70
  export { ThemeSelector } from './components/ThemeSelector';
71
71
  export { DropZone } from './components/DropZone';
72
+ export { CreateButton } from './components/CreateButton';
73
+ // export { TreeSelect } from './components/TreeSelect';
74
+ export { SearchBar } from './components/SearchBar';
72
75
 
73
76
  export * from './components/Layouts';
74
77
  export * from './components/Form';
package/dist/dots.svg ADDED
@@ -0,0 +1,3 @@
1
+ <svg width="6" height="30" viewBox="0 0 6 30" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M1 2C1.55228 2 2 1.55228 2 1C2 0.447715 1.55228 0 1 0C0.447715 0 0 0.447715 0 1C0 1.55228 0.447715 2 1 2ZM5 2C5.55228 2 6 1.55228 6 1C6 0.447715 5.55228 0 5 0C4.44772 0 4 0.447715 4 1C4 1.55228 4.44772 2 5 2ZM6 5C6 5.55228 5.55228 6 5 6C4.44772 6 4 5.55228 4 5C4 4.44772 4.44772 4 5 4C5.55228 4 6 4.44772 6 5ZM1 6C1.55228 6 2 5.55228 2 5C2 4.44772 1.55228 4 1 4C0.447715 4 0 4.44772 0 5C0 5.55228 0.447715 6 1 6ZM6 9C6 9.55229 5.55228 10 5 10C4.44772 10 4 9.55229 4 9C4 8.44771 4.44772 8 5 8C5.55228 8 6 8.44771 6 9ZM1 10C1.55228 10 2 9.55229 2 9C2 8.44771 1.55228 8 1 8C0.447715 8 0 8.44771 0 9C0 9.55229 0.447715 10 1 10ZM6 13C6 13.5523 5.55228 14 5 14C4.44772 14 4 13.5523 4 13C4 12.4477 4.44772 12 5 12C5.55228 12 6 12.4477 6 13ZM1 14C1.55228 14 2 13.5523 2 13C2 12.4477 1.55228 12 1 12C0.447715 12 0 12.4477 0 13C0 13.5523 0.447715 14 1 14ZM6 17C6 17.5523 5.55228 18 5 18C4.44772 18 4 17.5523 4 17C4 16.4477 4.44772 16 5 16C5.55228 16 6 16.4477 6 17ZM1 18C1.55228 18 2 17.5523 2 17C2 16.4477 1.55228 16 1 16C0.447715 16 0 16.4477 0 17C0 17.5523 0.447715 18 1 18ZM6 21C6 21.5523 5.55228 22 5 22C4.44772 22 4 21.5523 4 21C4 20.4477 4.44772 20 5 20C5.55228 20 6 20.4477 6 21ZM1 22C1.55228 22 2 21.5523 2 21C2 20.4477 1.55228 20 1 20C0.447715 20 0 20.4477 0 21C0 21.5523 0.447715 22 1 22ZM6 25C6 25.5523 5.55228 26 5 26C4.44772 26 4 25.5523 4 25C4 24.4477 4.44772 24 5 24C5.55228 24 6 24.4477 6 25ZM1 26C1.55228 26 2 25.5523 2 25C2 24.4477 1.55228 24 1 24C0.447715 24 0 24.4477 0 25C0 25.5523 0.447715 26 1 26ZM6 29C6 29.5523 5.55228 30 5 30C4.44772 30 4 29.5523 4 29C4 28.4477 4.44772 28 5 28C5.55228 28 6 28.4477 6 29ZM1 30C1.55228 30 2 29.5523 2 29C2 28.4477 1.55228 28 1 28C0.447715 28 0 28.4477 0 29C0 29.5523 0.447715 30 1 30Z" fill="#ffffff"/>
3
+ </svg>