@wger-project/react-components 25.11.17 → 25.11.22
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/build/main.js +126 -126
- package/build/main.js.map +1 -1
- package/package.json +2 -2
- package/src/components/Exercises/Add/Step1Basics.test.tsx +4 -1
- package/src/components/Exercises/Detail/ExerciseDetailEdit.tsx +43 -27
- package/src/components/Exercises/Detail/ExerciseDetailView.tsx +57 -17
- package/src/components/Exercises/Detail/OverviewCard.test.tsx +7 -11
- package/src/components/Exercises/ExerciseOverview.tsx +6 -6
- package/src/components/Exercises/Overview/ExerciseGrid.tsx +1 -2
- package/src/components/Exercises/forms/ExerciseAliases.tsx +78 -21
- package/src/components/Exercises/forms/yupValidators.ts +7 -4
- package/src/components/Exercises/models/exercise.ts +55 -43
- package/src/services/measurements.ts +15 -2
- package/src/tests/exerciseTestdata.ts +61 -55
- package/src/tests/exercises/searchResponse.ts +31 -29
- package/src/tests/responseApi.ts +25 -14
|
@@ -8,42 +8,53 @@ import { ExerciseVideo, ExerciseVideoAdapter } from "components/Exercises/models
|
|
|
8
8
|
import { Adapter } from "utils/Adapter";
|
|
9
9
|
import { ENGLISH_LANGUAGE_ID } from "utils/consts";
|
|
10
10
|
|
|
11
|
+
export type ExerciseConstructorParams = {
|
|
12
|
+
id: number | null;
|
|
13
|
+
uuid: string | null;
|
|
14
|
+
category: Category;
|
|
15
|
+
equipment?: Equipment[];
|
|
16
|
+
muscles?: Muscle[];
|
|
17
|
+
musclesSecondary?: Muscle[];
|
|
18
|
+
images?: ExerciseImage[];
|
|
19
|
+
variationId?: number | null;
|
|
20
|
+
lastUpdateGlobal?: Date;
|
|
21
|
+
translations?: Translation[];
|
|
22
|
+
videos?: ExerciseVideo[];
|
|
23
|
+
authors?: string[];
|
|
24
|
+
};
|
|
25
|
+
|
|
11
26
|
export class Exercise {
|
|
12
|
-
|
|
27
|
+
id: number | null;
|
|
28
|
+
uuid: string | null;
|
|
29
|
+
variationId: number | null;
|
|
30
|
+
category: Category;
|
|
31
|
+
lastUpdateGlobal: Date;
|
|
32
|
+
|
|
33
|
+
muscles: Muscle[] = [];
|
|
34
|
+
musclesSecondary: Muscle[] = [];
|
|
35
|
+
images: ExerciseImage[] = [];
|
|
13
36
|
videos: ExerciseVideo[] = [];
|
|
37
|
+
equipment: Equipment[] = [];
|
|
14
38
|
authors: string[] = [];
|
|
39
|
+
translations: Translation[] = [];
|
|
15
40
|
|
|
16
|
-
constructor(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
videos
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
licenseAuthorS: string[],
|
|
31
|
-
*/
|
|
32
|
-
) {
|
|
33
|
-
if (translations) {
|
|
34
|
-
this.translations = translations;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (videos) {
|
|
38
|
-
this.videos = videos;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (authors) {
|
|
42
|
-
this.authors = authors;
|
|
43
|
-
}
|
|
41
|
+
constructor(init: ExerciseConstructorParams) {
|
|
42
|
+
this.id = init.id;
|
|
43
|
+
this.uuid = init.uuid;
|
|
44
|
+
this.category = init.category;
|
|
45
|
+
this.variationId = init.variationId ?? null;
|
|
46
|
+
this.lastUpdateGlobal = init.lastUpdateGlobal ?? new Date();
|
|
47
|
+
|
|
48
|
+
this.muscles = init.muscles ?? [];
|
|
49
|
+
this.musclesSecondary = init.musclesSecondary ?? [];
|
|
50
|
+
this.images = init.images ?? [];
|
|
51
|
+
this.videos = init.videos ?? [];
|
|
52
|
+
this.equipment = init.equipment ?? [];
|
|
53
|
+
this.authors = init.authors ?? [];
|
|
54
|
+
this.translations = init.translations ?? [];
|
|
44
55
|
}
|
|
45
56
|
|
|
46
|
-
// Returns the users translation or
|
|
57
|
+
// Returns the users' translation or English as a fallback
|
|
47
58
|
//
|
|
48
59
|
// Note that we still check for the case that no english translation can be
|
|
49
60
|
// found. While this can't happen for the "regular" wger server, other local
|
|
@@ -97,25 +108,26 @@ export class ExerciseAdapter implements Adapter<Exercise> {
|
|
|
97
108
|
const translationAdapter = new TranslationAdapter();
|
|
98
109
|
const videoAdapter = new ExerciseVideoAdapter();
|
|
99
110
|
|
|
100
|
-
const exercise = new Exercise(
|
|
101
|
-
item.id,
|
|
102
|
-
item.uuid,
|
|
103
|
-
categoryAdapter.fromJson(item.category),
|
|
111
|
+
const exercise = new Exercise({
|
|
112
|
+
id: item.id,
|
|
113
|
+
uuid: item.uuid,
|
|
114
|
+
category: categoryAdapter.fromJson(item.category),
|
|
104
115
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
105
|
-
item.equipment.map((e: any) =>
|
|
116
|
+
equipment: item.equipment.map((e: any) => equipmentAdapter.fromJson(e)),
|
|
106
117
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
107
|
-
item.muscles.map((m: any) =>
|
|
118
|
+
muscles: item.muscles.map((m: any) => muscleAdapter.fromJson(m)),
|
|
108
119
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
109
|
-
item.muscles_secondary.map((m: any) =>
|
|
120
|
+
musclesSecondary: item.muscles_secondary.map((m: any) => muscleAdapter.fromJson(m)),
|
|
110
121
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
111
|
-
item.images.map((i: any) =>
|
|
112
|
-
item.variations,
|
|
122
|
+
images: item.images.map((i: any) => imageAdapter.fromJson(i)),
|
|
123
|
+
variationId: item.variations,
|
|
113
124
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
114
|
-
item.translations.map((t: any) => translationAdapter.fromJson(t)),
|
|
125
|
+
translations: item.translations.map((t: any) => translationAdapter.fromJson(t)),
|
|
115
126
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
116
|
-
item.videos.map((t: any) => videoAdapter.fromJson(t)),
|
|
117
|
-
item.
|
|
118
|
-
|
|
127
|
+
videos: item.videos.map((t: any) => videoAdapter.fromJson(t)),
|
|
128
|
+
authors: item.total_authors_history,
|
|
129
|
+
lastUpdateGlobal: new Date(item.last_update_global),
|
|
130
|
+
});
|
|
119
131
|
|
|
120
132
|
if (!exercise.translations.some(t => t.language === ENGLISH_LANGUAGE_ID)) {
|
|
121
133
|
console.info(`No english translation found for exercise base ${exercise.uuid}!`);
|
|
@@ -2,6 +2,7 @@ import axios from 'axios';
|
|
|
2
2
|
import { MeasurementCategory, MeasurementCategoryAdapter } from "components/Measurements/models/Category";
|
|
3
3
|
import { MeasurementEntry, MeasurementEntryAdapter } from "components/Measurements/models/Entry";
|
|
4
4
|
import { ApiMeasurementCategoryType } from 'types';
|
|
5
|
+
import { API_MAX_PAGE_SIZE } from "utils/consts";
|
|
5
6
|
import { dateToYYYYMMDD } from "utils/date";
|
|
6
7
|
import { fetchPaginated } from 'utils/requests';
|
|
7
8
|
import { makeHeader, makeUrl } from "utils/url";
|
|
@@ -20,8 +21,14 @@ export const getMeasurementCategories = async (options?: MeasurementQueryOptions
|
|
|
20
21
|
const adapter = new MeasurementCategoryAdapter();
|
|
21
22
|
const entryAdapter = new MeasurementEntryAdapter();
|
|
22
23
|
const categories: MeasurementCategory[] = [];
|
|
24
|
+
const categoryUrl = makeUrl(API_MEASUREMENTS_CATEGORY_PATH, {
|
|
25
|
+
query: {
|
|
26
|
+
limit: API_MAX_PAGE_SIZE,
|
|
27
|
+
...filtersetQueryCategories
|
|
28
|
+
}
|
|
29
|
+
});
|
|
23
30
|
|
|
24
|
-
for await (const page of fetchPaginated(
|
|
31
|
+
for await (const page of fetchPaginated(categoryUrl, makeHeader())) {
|
|
25
32
|
for (const catData of page) {
|
|
26
33
|
categories.push(adapter.fromJson(catData));
|
|
27
34
|
}
|
|
@@ -30,7 +37,13 @@ export const getMeasurementCategories = async (options?: MeasurementQueryOptions
|
|
|
30
37
|
// Load entries for each category
|
|
31
38
|
const entryResponses = categories.map(async (category) => {
|
|
32
39
|
const out: MeasurementEntry[] = [];
|
|
33
|
-
const url = makeUrl(API_MEASUREMENTS_ENTRY_PATH, {
|
|
40
|
+
const url = makeUrl(API_MEASUREMENTS_ENTRY_PATH, {
|
|
41
|
+
query: {
|
|
42
|
+
category: category.id,
|
|
43
|
+
limit: API_MAX_PAGE_SIZE,
|
|
44
|
+
...filtersetQueryEntries,
|
|
45
|
+
}
|
|
46
|
+
});
|
|
34
47
|
|
|
35
48
|
// Collect all pages of entries
|
|
36
49
|
for await (const page of fetchPaginated(url, makeHeader())) {
|
|
@@ -46,16 +46,16 @@ export const testEquipment = [
|
|
|
46
46
|
testEquipmentRocks,
|
|
47
47
|
];
|
|
48
48
|
|
|
49
|
-
export const testExerciseSquats = new Exercise(
|
|
50
|
-
345,
|
|
51
|
-
"c788d643-150a-4ac7-97ef-84643c6419bf",
|
|
52
|
-
testCategoryLegs,
|
|
53
|
-
[testEquipmentBarbell, testEquipmentRocks],
|
|
54
|
-
[testMuscleBiggus, testMuscleRectusAbdominis],
|
|
55
|
-
[],
|
|
56
|
-
[],
|
|
57
|
-
null,
|
|
58
|
-
[
|
|
49
|
+
export const testExerciseSquats = new Exercise({
|
|
50
|
+
id: 345,
|
|
51
|
+
uuid: "c788d643-150a-4ac7-97ef-84643c6419bf",
|
|
52
|
+
category: testCategoryLegs,
|
|
53
|
+
equipment: [testEquipmentBarbell, testEquipmentRocks],
|
|
54
|
+
muscles: [testMuscleBiggus, testMuscleRectusAbdominis],
|
|
55
|
+
musclesSecondary: [],
|
|
56
|
+
images: [],
|
|
57
|
+
variationId: null,
|
|
58
|
+
translations: [
|
|
59
59
|
new Translation(111,
|
|
60
60
|
'583281c7-2362-48e7-95d5-8fd6c455e0fb',
|
|
61
61
|
'Squats',
|
|
@@ -74,18 +74,18 @@ export const testExerciseSquats = new Exercise(
|
|
|
74
74
|
]
|
|
75
75
|
)
|
|
76
76
|
]
|
|
77
|
-
);
|
|
77
|
+
});
|
|
78
78
|
|
|
79
|
-
export const testExerciseBenchPress = new Exercise(
|
|
80
|
-
2,
|
|
81
|
-
"abcdef-150a-4ac7-97ef-84643c6419bf",
|
|
82
|
-
testCategoryLegs,
|
|
83
|
-
[testEquipmentBarbell, testEquipmentRocks],
|
|
84
|
-
[testMuscleDacttilaris, testMuscleDeltoid],
|
|
85
|
-
[],
|
|
86
|
-
[],
|
|
87
|
-
1,
|
|
88
|
-
[
|
|
79
|
+
export const testExerciseBenchPress = new Exercise({
|
|
80
|
+
id: 2,
|
|
81
|
+
uuid: "abcdef-150a-4ac7-97ef-84643c6419bf",
|
|
82
|
+
category: testCategoryLegs,
|
|
83
|
+
equipment: [testEquipmentBarbell, testEquipmentRocks],
|
|
84
|
+
muscles: [testMuscleDacttilaris, testMuscleDeltoid],
|
|
85
|
+
musclesSecondary: [],
|
|
86
|
+
images: [],
|
|
87
|
+
variationId: 1,
|
|
88
|
+
translations: [
|
|
89
89
|
new Translation(111,
|
|
90
90
|
'583281c7-2362-48e7-95d5-8fd6c455e0fb',
|
|
91
91
|
'Benchpress',
|
|
@@ -93,17 +93,19 @@ export const testExerciseBenchPress = new Exercise(
|
|
|
93
93
|
2
|
|
94
94
|
),
|
|
95
95
|
]
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
[],
|
|
104
|
-
[],
|
|
105
|
-
|
|
106
|
-
[
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
export const testExerciseCurls = new Exercise({
|
|
99
|
+
id: 3,
|
|
100
|
+
uuid: "abcdef-150a-4ac7-97ef-84643c6419bf",
|
|
101
|
+
lastUpdateGlobal: new Date(),
|
|
102
|
+
category: testCategoryArms,
|
|
103
|
+
equipment: [testEquipmentDumbbell],
|
|
104
|
+
muscles: [testMuscleBiggus, testMuscleDacttilaris],
|
|
105
|
+
musclesSecondary: [],
|
|
106
|
+
images: [],
|
|
107
|
+
variationId: 1,
|
|
108
|
+
translations: [
|
|
107
109
|
new Translation(111,
|
|
108
110
|
'583281c7-2362-48e7-95d5-8fd6c455e0fb',
|
|
109
111
|
'Curls',
|
|
@@ -111,17 +113,19 @@ export const testExerciseCurls = new Exercise(
|
|
|
111
113
|
2
|
|
112
114
|
),
|
|
113
115
|
]
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
[],
|
|
122
|
-
[],
|
|
123
|
-
|
|
124
|
-
[
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
export const testExerciseCrunches = new Exercise({
|
|
119
|
+
id: 4,
|
|
120
|
+
uuid: "abcdef-150a-4ac7-97ef-84643c6419bf",
|
|
121
|
+
lastUpdateGlobal: new Date(),
|
|
122
|
+
category: testCategoryChest,
|
|
123
|
+
equipment: [testEquipmentRocks],
|
|
124
|
+
muscles: [testMuscleDeltoid],
|
|
125
|
+
musclesSecondary: [],
|
|
126
|
+
images: [],
|
|
127
|
+
variationId: null,
|
|
128
|
+
translations: [
|
|
125
129
|
new Translation(111,
|
|
126
130
|
'583281c7-2362-48e7-95d5-8fd6c455e0fb',
|
|
127
131
|
'Crunches',
|
|
@@ -129,17 +133,19 @@ export const testExerciseCrunches = new Exercise(
|
|
|
129
133
|
2
|
|
130
134
|
),
|
|
131
135
|
]
|
|
132
|
-
);
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
[],
|
|
140
|
-
[],
|
|
141
|
-
|
|
142
|
-
[
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
export const testExerciseSkullCrusher = new Exercise({
|
|
139
|
+
id: 5,
|
|
140
|
+
uuid: "abcdef-150a-4ac7-97ef-84643c6419bf",
|
|
141
|
+
lastUpdateGlobal: new Date(),
|
|
142
|
+
category: testCategoryArms,
|
|
143
|
+
equipment: [testEquipmentBarbell],
|
|
144
|
+
muscles: [testMuscleRectusAbdominis],
|
|
145
|
+
musclesSecondary: [],
|
|
146
|
+
images: [],
|
|
147
|
+
variationId: 2,
|
|
148
|
+
translations: [
|
|
143
149
|
new Translation(111,
|
|
144
150
|
'583281c7-2362-48e7-95d5-8fd6c455e0fb',
|
|
145
151
|
'Skull crusher',
|
|
@@ -147,7 +153,7 @@ export const testExerciseSkullCrusher = new Exercise(
|
|
|
147
153
|
2
|
|
148
154
|
),
|
|
149
155
|
]
|
|
150
|
-
);
|
|
156
|
+
});
|
|
151
157
|
|
|
152
158
|
export const testExercises = [
|
|
153
159
|
testExerciseSquats,
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import { Exercise } from "components/Exercises/models/exercise";
|
|
2
1
|
import { Category } from "components/Exercises/models/category";
|
|
2
|
+
import { Exercise } from "components/Exercises/models/exercise";
|
|
3
3
|
import { Translation } from "components/Exercises/models/translation";
|
|
4
4
|
|
|
5
5
|
export const searchResponse: Exercise[] = [
|
|
6
|
-
new Exercise(
|
|
7
|
-
998,
|
|
8
|
-
"uuid-998",
|
|
9
|
-
new
|
|
10
|
-
|
|
11
|
-
[],
|
|
12
|
-
[],
|
|
13
|
-
[],
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
new Exercise({
|
|
7
|
+
id: 998,
|
|
8
|
+
uuid: "uuid-998",
|
|
9
|
+
lastUpdateGlobal: new Date(),
|
|
10
|
+
category: new Category(8, "Bauch"),
|
|
11
|
+
equipment: [],
|
|
12
|
+
muscles: [],
|
|
13
|
+
musclesSecondary: [],
|
|
14
|
+
images: [],
|
|
15
|
+
variationId: null,
|
|
16
|
+
translations: [
|
|
16
17
|
new Translation(
|
|
17
18
|
1149, // id
|
|
18
19
|
"uuid-1149", // uuid
|
|
@@ -20,20 +21,21 @@ export const searchResponse: Exercise[] = [
|
|
|
20
21
|
"", // description
|
|
21
22
|
1 // language (German)
|
|
22
23
|
)
|
|
23
|
-
],
|
|
24
|
-
[],
|
|
25
|
-
[]
|
|
26
|
-
),
|
|
27
|
-
new Exercise(
|
|
28
|
-
979,
|
|
29
|
-
"uuid-979",
|
|
30
|
-
new
|
|
31
|
-
|
|
32
|
-
[],
|
|
33
|
-
[],
|
|
34
|
-
[],
|
|
35
|
-
|
|
36
|
-
|
|
24
|
+
],
|
|
25
|
+
videos: [],
|
|
26
|
+
authors: []
|
|
27
|
+
}),
|
|
28
|
+
new Exercise({
|
|
29
|
+
id: 979,
|
|
30
|
+
uuid: "uuid-979",
|
|
31
|
+
lastUpdateGlobal: new Date(),
|
|
32
|
+
category: new Category(11, "Brust"),
|
|
33
|
+
equipment: [],
|
|
34
|
+
muscles: [],
|
|
35
|
+
musclesSecondary: [],
|
|
36
|
+
images: [],
|
|
37
|
+
variationId: null,
|
|
38
|
+
translations: [
|
|
37
39
|
new Translation(
|
|
38
40
|
1213, // id
|
|
39
41
|
"uuid-1213", // uuid
|
|
@@ -41,8 +43,8 @@ export const searchResponse: Exercise[] = [
|
|
|
41
43
|
"", // description
|
|
42
44
|
1 // language (German)
|
|
43
45
|
)
|
|
44
|
-
],
|
|
45
|
-
[],
|
|
46
|
-
[]
|
|
47
|
-
)
|
|
46
|
+
],
|
|
47
|
+
videos: [],
|
|
48
|
+
authors: []
|
|
49
|
+
})
|
|
48
50
|
];
|
package/src/tests/responseApi.ts
CHANGED
|
@@ -41,20 +41,21 @@ const image = new ExerciseImage(
|
|
|
41
41
|
true
|
|
42
42
|
);
|
|
43
43
|
|
|
44
|
-
export const testApiExercise1 = new Exercise(
|
|
45
|
-
345,
|
|
46
|
-
"c788d643-150a-4ac7-97ef-84643c6419bf",
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
[
|
|
50
|
-
[
|
|
51
|
-
[
|
|
52
|
-
|
|
53
|
-
|
|
44
|
+
export const testApiExercise1 = new Exercise({
|
|
45
|
+
id: 345,
|
|
46
|
+
uuid: "c788d643-150a-4ac7-97ef-84643c6419bf",
|
|
47
|
+
lastUpdateGlobal: new Date("2025-11-22T19:32:02.590941+01:00"),
|
|
48
|
+
category: category,
|
|
49
|
+
equipment: [equipment1, equipment2],
|
|
50
|
+
muscles: [muscle1],
|
|
51
|
+
musclesSecondary: [muscle2],
|
|
52
|
+
images: [image],
|
|
53
|
+
variationId: 228,
|
|
54
|
+
translations: [
|
|
54
55
|
testExerciseTranslation1,
|
|
55
56
|
testExerciseTranslation2
|
|
56
57
|
],
|
|
57
|
-
[
|
|
58
|
+
videos: [
|
|
58
59
|
new ExerciseVideo(
|
|
59
60
|
1,
|
|
60
61
|
"b1c934fa-c4f8-4d84-8cb4-7802be0d284c",
|
|
@@ -62,12 +63,13 @@ export const testApiExercise1 = new Exercise(
|
|
|
62
63
|
false
|
|
63
64
|
)
|
|
64
65
|
],
|
|
65
|
-
[
|
|
66
|
+
authors: [
|
|
66
67
|
"wger.de",
|
|
67
68
|
"author 1",
|
|
68
|
-
"somebody else"
|
|
69
|
+
"somebody else",
|
|
70
|
+
"Mr. T"
|
|
69
71
|
]
|
|
70
|
-
);
|
|
72
|
+
});
|
|
71
73
|
|
|
72
74
|
|
|
73
75
|
export const responseApiExerciseInfo = {
|
|
@@ -77,6 +79,9 @@ export const responseApiExerciseInfo = {
|
|
|
77
79
|
"results": [{
|
|
78
80
|
"id": 345,
|
|
79
81
|
"uuid": "c788d643-150a-4ac7-97ef-84643c6419bf",
|
|
82
|
+
"created": "2023-08-06T10:17:17.422900+02:00",
|
|
83
|
+
"last_update": "2025-11-22T14:17:20.119332+01:00",
|
|
84
|
+
"last_update_global": "2025-11-22T19:32:02.590941+01:00",
|
|
80
85
|
"category": {
|
|
81
86
|
"id": 10,
|
|
82
87
|
"name": "Abs"
|
|
@@ -192,6 +197,12 @@ export const responseApiExerciseInfo = {
|
|
|
192
197
|
"wger.de",
|
|
193
198
|
"author 1",
|
|
194
199
|
"somebody else"
|
|
200
|
+
],
|
|
201
|
+
"total_authors_history": [
|
|
202
|
+
"wger.de",
|
|
203
|
+
"author 1",
|
|
204
|
+
"somebody else",
|
|
205
|
+
"Mr. T"
|
|
195
206
|
]
|
|
196
207
|
}]
|
|
197
208
|
};
|