@chem-po/react-native 0.0.52 → 0.0.53

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 (98) hide show
  1. package/package.json +5 -20
  2. package/src/components/box/Center.tsx +0 -19
  3. package/src/components/box/CollapseHorizontal.tsx +0 -44
  4. package/src/components/box/ContentBox.tsx +0 -24
  5. package/src/components/box/DropShadow.tsx +0 -28
  6. package/src/components/box/ExpandOnMount.tsx +0 -74
  7. package/src/components/box/Expandable.tsx +0 -143
  8. package/src/components/box/FullSizeContainer.tsx +0 -64
  9. package/src/components/box/index.ts +0 -7
  10. package/src/components/button/ActionButton.tsx +0 -196
  11. package/src/components/button/ButtonText.tsx +0 -60
  12. package/src/components/button/DeleteButton.tsx +0 -288
  13. package/src/components/button/LoadingButton.tsx +0 -41
  14. package/src/components/button/Toggle.tsx +0 -109
  15. package/src/components/button/hooks.ts +0 -66
  16. package/src/components/button/index.ts +0 -5
  17. package/src/components/feed/FeedContentPane.tsx +0 -97
  18. package/src/components/feed/MediaFeed.tsx +0 -199
  19. package/src/components/feed/MediaFeedBackground.tsx +0 -136
  20. package/src/components/feed/MediaFeedRefresh.tsx +0 -113
  21. package/src/components/feed/constants.ts +0 -2
  22. package/src/components/feed/context.tsx +0 -19
  23. package/src/components/feed/hooks.ts +0 -279
  24. package/src/components/feed/index.ts +0 -2
  25. package/src/components/form/Condition.tsx +0 -27
  26. package/src/components/form/Field.tsx +0 -44
  27. package/src/components/form/Form.tsx +0 -452
  28. package/src/components/form/FormFooter.tsx +0 -164
  29. package/src/components/form/UploadProgress/index.tsx +0 -50
  30. package/src/components/form/index.ts +0 -3
  31. package/src/components/form/input/Editable.tsx +0 -206
  32. package/src/components/form/input/InputSlider.tsx +0 -71
  33. package/src/components/form/input/OptionalTag.tsx +0 -43
  34. package/src/components/form/input/StandaloneInput.tsx +0 -49
  35. package/src/components/form/input/boolean/index.tsx +0 -53
  36. package/src/components/form/input/color/index.tsx +0 -145
  37. package/src/components/form/input/common/InputClearButton.tsx +0 -57
  38. package/src/components/form/input/date/index.tsx +0 -125
  39. package/src/components/form/input/datetime/index.tsx +0 -176
  40. package/src/components/form/input/file/index.tsx +0 -310
  41. package/src/components/form/input/hooks/index.ts +0 -2
  42. package/src/components/form/input/hooks/useInputColor.ts +0 -7
  43. package/src/components/form/input/hooks/useInputImperativeHandle.ts +0 -22
  44. package/src/components/form/input/hooks/useInputStyles.ts +0 -114
  45. package/src/components/form/input/index.ts +0 -4
  46. package/src/components/form/input/input.tsx +0 -218
  47. package/src/components/form/input/multipleSelect/index.tsx +0 -221
  48. package/src/components/form/input/number/index.tsx +0 -108
  49. package/src/components/form/input/select/index.tsx +0 -152
  50. package/src/components/form/input/socialMedia/index.tsx +0 -235
  51. package/src/components/form/input/text/AutoResizeTextarea.tsx +0 -41
  52. package/src/components/form/input/text/index.tsx +0 -99
  53. package/src/components/form/input/text/textarea.tsx +0 -32
  54. package/src/components/form/input/text/useWebAutoResize.tsx +0 -73
  55. package/src/components/form/input/time/index.tsx +0 -125
  56. package/src/components/form/types.ts +0 -8
  57. package/src/components/form/view/file.tsx +0 -80
  58. package/src/components/form/view/index.tsx +0 -125
  59. package/src/components/form/view/multipleSelect.tsx +0 -85
  60. package/src/components/form/view/select.tsx +0 -83
  61. package/src/components/form/view/styles.ts +0 -12
  62. package/src/components/icons/index.tsx +0 -28
  63. package/src/components/image/ImageViewModal.tsx +0 -319
  64. package/src/components/image/index.ts +0 -1
  65. package/src/components/index.ts +0 -8
  66. package/src/components/layout/CollapseHorizontal.tsx +0 -92
  67. package/src/components/loading/CircularProgress.tsx +0 -56
  68. package/src/components/loading/Loading.tsx +0 -146
  69. package/src/components/loading/LoadingImage.tsx +0 -163
  70. package/src/components/loading/LoadingOverlay.tsx +0 -74
  71. package/src/components/loading/LoadingSwitch.tsx +0 -110
  72. package/src/components/loading/ProgressBar.tsx +0 -75
  73. package/src/components/loading/index.ts +0 -6
  74. package/src/components/text/AnimatedText.tsx +0 -68
  75. package/src/components/text/Txt.tsx +0 -12
  76. package/src/components/text/index.ts +0 -1
  77. package/src/components/theme/colorMode/DarkModeToggle.tsx +0 -47
  78. package/src/components/theme/colorMode/index.ts +0 -1
  79. package/src/components/theme/index.ts +0 -1
  80. package/src/constants/index.ts +0 -1
  81. package/src/constants/toast.ts +0 -24
  82. package/src/contexts/fonts.tsx +0 -23
  83. package/src/contexts/index.ts +0 -1
  84. package/src/contexts/root.tsx +0 -190
  85. package/src/hooks/index.ts +0 -3
  86. package/src/hooks/useFadeIn.ts +0 -48
  87. package/src/hooks/useFont.ts +0 -25
  88. package/src/hooks/useRefreshFontScale.ts +0 -39
  89. package/src/hooks/useThemeState.ts +0 -43
  90. package/src/index.ts +0 -6
  91. package/src/store/index.ts +0 -2
  92. package/src/store/useFontScale.ts +0 -8
  93. package/src/store/useScreen.ts +0 -25
  94. package/src/styles/fill.ts +0 -19
  95. package/src/types/forms.ts +0 -14
  96. package/src/types/index.ts +0 -1
  97. package/src/utils/downloadFile.ts +0 -61
  98. package/src/utils/downloadFileLegacy.ts +0 -66
@@ -1,125 +0,0 @@
1
- import { InputRef, padZeros } from '@chem-po/core'
2
- import { TimeField, useIconColor } from '@chem-po/react'
3
- import { Ionicons } from '@expo/vector-icons'
4
- import React, { forwardRef, useImperativeHandle, useMemo, useState } from 'react'
5
- import { StyleSheet, Text, View } from 'react-native'
6
- import { Pressable } from 'react-native-gesture-handler'
7
- import { Portal } from 'react-native-paper'
8
- import { TimePickerModal } from 'react-native-paper-dates'
9
- import { FieldProps } from '../../types'
10
- import { DateInputClearButton } from '../common/InputClearButton'
11
- import { useInputColor } from '../hooks/useInputColor'
12
- import { useInputStyles } from '../hooks/useInputStyles'
13
-
14
- export const TimeInput = forwardRef<InputRef, FieldProps<TimeField>>(
15
- (
16
- {
17
- input: { onChange, value, onFocus, onBlur },
18
- field: { placeholder, optional, size },
19
- formSize,
20
- inEditable,
21
- },
22
- ref,
23
- ) => {
24
- const [visible, setVisible] = useState(false)
25
-
26
- const {
27
- container: inputStyles,
28
- iconSize,
29
- text,
30
- clearButtonSize,
31
- buttonContainer,
32
- } = useInputStyles(inEditable, size, formSize)
33
- useImperativeHandle(ref, () => ({
34
- focus: () => {
35
- setVisible(true)
36
- onFocus()
37
- },
38
- blur: () => {
39
- setVisible(false)
40
- onBlur()
41
- },
42
- }))
43
-
44
- const handleTimeChange = ({ hours, minutes }: { hours: number; minutes: number }) => {
45
- setVisible(false)
46
- const timeString = `${padZeros(hours)}:${padZeros(minutes)}`
47
- onChange(timeString)
48
- onBlur()
49
- }
50
-
51
- const handleDismiss = () => {
52
- setVisible(false)
53
- onBlur()
54
- }
55
-
56
- const formattedValue = useMemo(() => {
57
- if (!value) return null
58
- const [hours, minutes] = value.split(':').map(Number)
59
- const amPm = hours >= 12 ? 'PM' : 'AM'
60
- const formattedHours = hours % 12 === 0 ? 12 : hours % 12
61
- return `${formattedHours}:${padZeros(minutes)} ${amPm}`
62
- }, [value])
63
-
64
- const { hours, minutes } = useMemo(() => {
65
- if (!value) return { hours: 0, minutes: 0 }
66
- const [h, m] = value.split(':').map(Number)
67
- return { hours: h, minutes: m }
68
- }, [value])
69
-
70
- const iconColor = useIconColor()
71
- const inputColor = useInputColor(value)
72
-
73
- return (
74
- <View style={styles.container}>
75
- <Pressable
76
- style={[styles.button, inputStyles]}
77
- onPress={() => {
78
- setVisible(true)
79
- onFocus()
80
- }}>
81
- <Text style={[styles.text, text, { color: inputColor }]}>
82
- {formattedValue ?? placeholder}
83
- </Text>
84
- <View style={buttonContainer}>
85
- <Ionicons name="time" size={iconSize} color={iconColor} />
86
- {optional && value ? (
87
- <DateInputClearButton
88
- size={clearButtonSize}
89
- onPress={() => onChange(null)}
90
- isActive={!!value}
91
- />
92
- ) : null}
93
- </View>
94
- </Pressable>
95
- <Portal>
96
- <TimePickerModal
97
- visible={visible}
98
- onDismiss={handleDismiss}
99
- onConfirm={handleTimeChange}
100
- hours={hours}
101
- minutes={minutes}
102
- />
103
- </Portal>
104
- </View>
105
- )
106
- },
107
- )
108
-
109
- TimeInput.displayName = 'TimeInput'
110
-
111
- const styles = StyleSheet.create({
112
- container: {
113
- width: '100%',
114
- },
115
- button: {
116
- flexDirection: 'row',
117
- alignItems: 'center',
118
- justifyContent: 'space-between',
119
- width: '100%',
120
- },
121
- text: {
122
- fontSize: 16,
123
- flex: 1,
124
- },
125
- })
@@ -1,8 +0,0 @@
1
- import { BaseFieldProps, Field } from '@chem-po/react'
2
- import { StyleProp, TextStyle, ViewStyle } from 'react-native'
3
-
4
- export type FieldProps<
5
- T extends Field,
6
- ContainerStyle extends ViewStyle = ViewStyle,
7
- InputStyle extends TextStyle = TextStyle,
8
- > = BaseFieldProps<StyleProp<ContainerStyle>, StyleProp<InputStyle>, T>
@@ -1,80 +0,0 @@
1
- import { ImageViewOptions, InputSize } from '@chem-po/core'
2
- import { FileField, usePlaceholderColor } from '@chem-po/react'
3
- import React, { useMemo } from 'react'
4
- import { StyleProp, StyleSheet, Text, TextStyle, View, ViewStyle } from 'react-native'
5
- import { Txt } from '../../text/Txt'
6
- import { FileView } from '../input/file'
7
- import { useInputStyles } from '../input/hooks/useInputStyles'
8
-
9
- const styles = StyleSheet.create({
10
- container: {
11
- flexDirection: 'column',
12
- },
13
- rowContainer: {
14
- flexDirection: 'row',
15
- },
16
- label: {
17
- paddingRight: 8,
18
- opacity: 0.7,
19
- fontWeight: '600',
20
- },
21
- fileContainer: {
22
- padding: 4,
23
- },
24
- })
25
-
26
- const getFileSizeHeight = (size: InputSize) => {
27
- switch (size) {
28
- case 'sm':
29
- return 80
30
- case 'md':
31
- return 120
32
- case 'lg':
33
- return 150
34
- default:
35
- return 120
36
- }
37
- }
38
-
39
- export const FileFieldView = ({
40
- field,
41
- value,
42
- noLabel,
43
- style,
44
- size: sizeProp,
45
- textStyle,
46
- }: {
47
- field: FileField
48
- value: any
49
- noLabel?: boolean
50
- style?: ViewStyle
51
- textStyle?: StyleProp<TextStyle>
52
- size?: InputSize
53
- }) => {
54
- const { imageOptions, placeholder, size } = field
55
- const options = useMemo<ImageViewOptions>(
56
- () => ({
57
- height: getFileSizeHeight(size ?? sizeProp ?? 'md'),
58
- ...imageOptions,
59
- }),
60
- [imageOptions, size, sizeProp],
61
- )
62
-
63
- const { text, container } = useInputStyles(false, field.size, sizeProp)
64
- const placeholderColor = usePlaceholderColor()
65
-
66
- return (
67
- <View style={[value ? styles.container : styles.rowContainer, style]}>
68
- {!noLabel && <Text style={styles.label}>{placeholder}</Text>}
69
- {value ? (
70
- <View style={styles.fileContainer}>
71
- <FileView textStyle={textStyle} imageOptions={options} value={value} />
72
- </View>
73
- ) : (
74
- <View style={container}>
75
- <Txt style={[text, { color: placeholderColor }, textStyle]}>None</Txt>
76
- </View>
77
- )}
78
- </View>
79
- )
80
- }
@@ -1,125 +0,0 @@
1
- import { displayField, InputSize } from '@chem-po/core'
2
- import { Field, FormatField, usePlaceholderColor } from '@chem-po/react'
3
- import React, { useMemo } from 'react'
4
- import { StyleProp, StyleSheet, TextStyle, View, ViewStyle } from 'react-native'
5
- import { Txt } from '../../text'
6
- import { useInputStyles } from '../input/hooks/useInputStyles'
7
- import { FileFieldView } from './file'
8
- import { MultipleSelectFieldView } from './multipleSelect'
9
- import { SelectFieldView } from './select'
10
- import { inputViewStyles } from './styles'
11
-
12
- const styles = StyleSheet.create({
13
- container: {
14
- flexDirection: 'row',
15
- alignItems: 'center',
16
- },
17
- })
18
-
19
- const DefaultFieldView = ({
20
- field,
21
- value,
22
- noLabel,
23
- style,
24
- size: sizeProp,
25
- inEditable,
26
- textStyle,
27
- }: {
28
- field: Field
29
- value: any
30
- noLabel?: boolean
31
- style?: ViewStyle
32
- textStyle?: StyleProp<TextStyle>
33
- size?: InputSize
34
- inEditable?: boolean
35
- }) => {
36
- const { placeholder } = field
37
-
38
- const { text, container: containerStyles } = useInputStyles(inEditable, field.size, sizeProp)
39
- const formatted = useMemo(() => {
40
- const format = displayField[field._type] as FormatField<Field>
41
- if (!format) return value
42
- return format(field, value)
43
- }, [value, field])
44
-
45
- const placeholderColor = usePlaceholderColor()
46
- const hasValue = useMemo(() => {
47
- return value !== null && value !== undefined && value !== ''
48
- }, [value])
49
-
50
- return (
51
- <View style={[styles.container, containerStyles, { backgroundColor: 'transparent' }, style]}>
52
- {!noLabel && <Txt style={[inputViewStyles.label, text]}>{placeholder}</Txt>}
53
- <Txt style={[text, { color: hasValue ? text.color : placeholderColor }, textStyle]}>
54
- {hasValue ? formatted : 'None'}
55
- </Txt>
56
- </View>
57
- )
58
- }
59
-
60
- export const FieldView = ({
61
- field,
62
- value,
63
- noLabel,
64
- style,
65
- textStyle,
66
- size,
67
- inEditable,
68
- }: {
69
- field: Field
70
- value?: any
71
- noLabel?: boolean
72
- style?: ViewStyle
73
- textStyle?: StyleProp<TextStyle>
74
- size?: InputSize
75
- inEditable?: boolean
76
- }) => {
77
- switch (field._type) {
78
- case 'select':
79
- return (
80
- <SelectFieldView
81
- style={style}
82
- textStyle={textStyle}
83
- field={field}
84
- value={value}
85
- noLabel={noLabel}
86
- size={size}
87
- inEditable={inEditable}
88
- />
89
- )
90
- case 'multipleSelect':
91
- return (
92
- <MultipleSelectFieldView
93
- style={style}
94
- field={field}
95
- value={value}
96
- textStyle={textStyle}
97
- noLabel={noLabel}
98
- size={size}
99
- />
100
- )
101
- case 'file':
102
- return (
103
- <FileFieldView
104
- textStyle={textStyle}
105
- style={style}
106
- field={field}
107
- value={value}
108
- noLabel={noLabel}
109
- size={size}
110
- />
111
- )
112
- default:
113
- return (
114
- <DefaultFieldView
115
- style={style}
116
- field={field}
117
- value={value}
118
- textStyle={textStyle}
119
- noLabel={noLabel}
120
- size={size}
121
- inEditable={inEditable}
122
- />
123
- )
124
- }
125
- }
@@ -1,85 +0,0 @@
1
- import { BaseSelectOption, InputSize } from '@chem-po/core'
2
- import { MultipleSelectField, useColorMode, usePlaceholderColor } from '@chem-po/react'
3
- import { useMemo } from 'react'
4
- import React, { StyleProp, StyleSheet, Text, TextStyle, View, ViewStyle } from 'react-native'
5
- import { Txt } from '../../text/Txt'
6
- import { useInputStyles } from '../input/hooks/useInputStyles'
7
- import { SelectedOptionContainer } from '../input/multipleSelect'
8
- import { DefaultRenderOption } from './select'
9
-
10
- const styles = StyleSheet.create({
11
- container: {
12
- flexDirection: 'row',
13
- flexWrap: 'wrap',
14
- alignItems: 'center',
15
- maxWidth: '100%',
16
- backgroundColor: 'transparent',
17
- },
18
- label: {
19
- paddingRight: 8,
20
- opacity: 0.7,
21
- fontWeight: '600',
22
- },
23
- optionsContainer: {
24
- padding: 2,
25
- flexDirection: 'row',
26
- flexWrap: 'wrap',
27
- },
28
- optionContainer: {
29
- marginTop: 2,
30
- marginHorizontal: 2,
31
- },
32
- })
33
-
34
- type NativeMultipleSelectField<
35
- Value extends any[] = string[],
36
- Option extends BaseSelectOption<Value[number]> = BaseSelectOption<Value[number]>,
37
- > = MultipleSelectField<Value, Option>
38
-
39
- export const MultipleSelectFieldView = <F extends NativeMultipleSelectField>({
40
- field,
41
- value,
42
- noLabel,
43
- size: sizeProp,
44
- style,
45
- textStyle,
46
- }: {
47
- field: F
48
- value?: F['defaultValue']
49
- noLabel?: boolean
50
- textStyle?: StyleProp<TextStyle>
51
- size?: InputSize
52
- style?: ViewStyle
53
- }) => {
54
- const { placeholder, renderOption: customRender, options } = field
55
- const selectedOptions = options.filter(o => value?.includes(o.value))
56
- const colorMode = useColorMode()
57
- const { size, text, container } = useInputStyles(true, field.size, sizeProp)
58
- const placeholderColor = usePlaceholderColor()
59
- const RenderOption = useMemo(() => customRender ?? DefaultRenderOption, [customRender])
60
- return (
61
- <View style={[styles.container, style]}>
62
- {!noLabel && <Text style={styles.label}>{placeholder}</Text>}
63
- {value?.length ? (
64
- <View style={styles.optionsContainer}>
65
- {selectedOptions.map(o => (
66
- <SelectedOptionContainer key={o.value} style={[container, { width: 'auto' }]}>
67
- <RenderOption
68
- option={o}
69
- value={o.value}
70
- textStyle={[text, textStyle]}
71
- colorMode={colorMode}
72
- isSelected
73
- size={size}
74
- />
75
- </SelectedOptionContainer>
76
- ))}
77
- </View>
78
- ) : (
79
- <View style={container}>
80
- <Txt style={[text, { color: placeholderColor }, textStyle]}>None</Txt>
81
- </View>
82
- )}
83
- </View>
84
- )
85
- }
@@ -1,83 +0,0 @@
1
- import { InputSize, RenderSelectOptionProps } from '@chem-po/core'
2
- import { SelectField, useColorMode, usePlaceholderColor } from '@chem-po/react'
3
- import React, { useMemo } from 'react'
4
- import { StyleProp, StyleSheet, Text, TextStyle, View, ViewStyle } from 'react-native'
5
- import { Txt } from '../../text'
6
- import { useInputStyles } from '../input/hooks/useInputStyles'
7
- import { inputViewStyles } from './styles'
8
-
9
- const styles = StyleSheet.create({
10
- container: {
11
- flexDirection: 'row',
12
- alignItems: 'center',
13
- backgroundColor: 'transparent',
14
- },
15
- label: {
16
- paddingRight: 10,
17
- fontWeight: '600',
18
- },
19
- })
20
-
21
- export const DefaultRenderOption = ({
22
- option,
23
- containerStyle,
24
- textStyle,
25
- }: RenderSelectOptionProps & {
26
- containerStyle?: StyleProp<ViewStyle>
27
- textStyle?: StyleProp<TextStyle>
28
- }) => {
29
- return (
30
- <View style={containerStyle}>
31
- <Txt style={[inputViewStyles.value, textStyle]}>{option.label}</Txt>
32
- </View>
33
- )
34
- }
35
-
36
- export const SelectFieldView = <F extends SelectField>({
37
- field,
38
- value,
39
- noLabel,
40
- style,
41
- size: sizeProp,
42
- inEditable,
43
- textStyle,
44
- }: {
45
- field: F
46
- value: F['defaultValue']
47
- noLabel?: boolean
48
- style?: ViewStyle
49
- textStyle?: StyleProp<TextStyle>
50
- size?: InputSize
51
- inEditable?: boolean
52
- }) => {
53
- const { placeholder, renderOption: customRender } = field
54
- const colorMode = useColorMode()
55
- const placeholderColor = usePlaceholderColor()
56
- const { size, text, container } = useInputStyles(inEditable, field.size, sizeProp)
57
- const selectedOption = field.options.find(o => o.value === value)
58
- const RenderOption = useMemo(() => customRender ?? DefaultRenderOption, [customRender])
59
- return (
60
- <View style={[styles.container, style]}>
61
- {!noLabel && (
62
- <Text style={[styles.label, text, { color: placeholderColor }, textStyle]}>
63
- {placeholder}
64
- </Text>
65
- )}
66
- {selectedOption ? (
67
- <RenderOption
68
- value={selectedOption.value}
69
- option={selectedOption}
70
- containerStyle={container}
71
- textStyle={[text, textStyle]}
72
- colorMode={colorMode}
73
- isSelected={true}
74
- size={size}
75
- />
76
- ) : (
77
- <View style={container}>
78
- <Txt style={[text, { color: placeholderColor }, textStyle]}>None</Txt>
79
- </View>
80
- )}
81
- </View>
82
- )
83
- }
@@ -1,12 +0,0 @@
1
- import { StyleSheet } from 'react-native'
2
-
3
- export const inputViewStyles = StyleSheet.create({
4
- label: {
5
- paddingRight: 8,
6
- opacity: 0.7,
7
- fontWeight: '600',
8
- },
9
- value: {
10
- opacity: 1,
11
- },
12
- })
@@ -1,28 +0,0 @@
1
- import React, { FC } from 'react'
2
- import { Path, Svg } from 'react-native-svg'
3
-
4
- interface IconProps {
5
- size?: number
6
- color?: string
7
- }
8
-
9
- export const ChevronDownIcon: FC<IconProps> = ({ size = 24, color = '#000' }) => (
10
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
11
- <Path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" fill={color} />
12
- </Svg>
13
- )
14
-
15
- export const ChevronUpIcon: FC<IconProps> = ({ size = 24, color = '#000' }) => (
16
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
17
- <Path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6 1.41 1.41z" fill={color} />
18
- </Svg>
19
- )
20
-
21
- export const TrashIcon: FC<IconProps> = ({ size = 24, color = '#000' }) => (
22
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
23
- <Path
24
- d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
25
- fill={color}
26
- />
27
- </Svg>
28
- )