linkedin-api-voyager 1.1.0 → 1.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/lib/company.js +4 -1
- package/lib/config.js +3 -9
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/posts.d.ts +11 -1
- package/lib/posts.js +83 -6
- package/lib/search.d.ts +3 -26
- package/lib/search.js +163 -112
- package/lib/teste.d.ts +1 -0
- package/lib/teste.js +10 -0
- package/lib/types.d.ts +794 -0
- package/lib/types.js +2 -0
- package/lib/user.d.ts +38 -0
- package/lib/user.js +172 -0
- package/lib/utils.d.ts +35 -0
- package/lib/utils.js +440 -27
- package/package.json +4 -3
- package/lib/account.d.ts +0 -18
- package/lib/account.js +0 -98
- package/lib/linkedin.d.ts +0 -0
- package/lib/linkedin.js +0 -1
package/lib/types.js
ADDED
package/lib/user.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export interface MiniUserProfileLinkedin {
|
|
2
|
+
id_urn: string;
|
|
3
|
+
publicIdentifier: string;
|
|
4
|
+
firstName: string;
|
|
5
|
+
lastName: string;
|
|
6
|
+
fullName: string;
|
|
7
|
+
headline: string;
|
|
8
|
+
about: string;
|
|
9
|
+
birthDate: {
|
|
10
|
+
month: number;
|
|
11
|
+
day: number;
|
|
12
|
+
};
|
|
13
|
+
profilePicture: string;
|
|
14
|
+
backgroundPicture: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const getUserMiniProfile: (identifier: string) => Promise<MiniUserProfileLinkedin>;
|
|
17
|
+
export declare const extractProfileIdLinkedin: (profileUrl: string) => Promise<any>;
|
|
18
|
+
export declare const getProfileSectionAbout: (identifier: string) => Promise<any>;
|
|
19
|
+
export declare const getProfissionalExperiences: (identifier: string) => Promise<{
|
|
20
|
+
company: any;
|
|
21
|
+
role: string | null;
|
|
22
|
+
idCompany: string | null;
|
|
23
|
+
time_duration?: string | null;
|
|
24
|
+
location?: string | null;
|
|
25
|
+
description?: string | null;
|
|
26
|
+
time_period?: string | null;
|
|
27
|
+
duration?: string | null;
|
|
28
|
+
}[]>;
|
|
29
|
+
export declare const getContactInfo: (identifier: string) => Promise<never[] | {
|
|
30
|
+
address: any;
|
|
31
|
+
weChatContactInfo: any;
|
|
32
|
+
phoneNumbers: any;
|
|
33
|
+
emailAddress: any;
|
|
34
|
+
websites: any;
|
|
35
|
+
}>;
|
|
36
|
+
export declare const getLinkedinSkills: (identifier: string) => Promise<any>;
|
|
37
|
+
export declare const getLinkedinEducation: (identifier: string) => Promise<any>;
|
|
38
|
+
export declare const getLinkedinCertifications: (identifier: string) => Promise<any>;
|
package/lib/user.js
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getLinkedinCertifications = exports.getLinkedinEducation = exports.getLinkedinSkills = exports.getContactInfo = exports.getProfissionalExperiences = exports.getProfileSectionAbout = exports.extractProfileIdLinkedin = exports.getUserMiniProfile = void 0;
|
|
13
|
+
const company_1 = require("./company");
|
|
14
|
+
const config_1 = require("./config");
|
|
15
|
+
const utils_1 = require("./utils");
|
|
16
|
+
const getUserMiniProfile = (identifier) => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
|
+
var _a, _b, _c, _d, _e, _f;
|
|
18
|
+
const response = yield (0, config_1.fetchData)(`graphql?variables=(vanityName:${identifier})&queryId=voyagerIdentityDashProfiles.34ead06db82a2cc9a778fac97f69ad6a`);
|
|
19
|
+
if ("included" in response) {
|
|
20
|
+
const profileData = response.included.find((item) => (item === null || item === void 0 ? void 0 : item.publicIdentifier) === `${identifier}`);
|
|
21
|
+
const profile = {
|
|
22
|
+
id_urn: profileData === null || profileData === void 0 ? void 0 : profileData.entityUrn.replace("urn:li:fsd_profile:", ""),
|
|
23
|
+
publicIdentifier: profileData === null || profileData === void 0 ? void 0 : profileData.publicIdentifier,
|
|
24
|
+
firstName: profileData === null || profileData === void 0 ? void 0 : profileData.firstName,
|
|
25
|
+
lastName: profileData === null || profileData === void 0 ? void 0 : profileData.lastName,
|
|
26
|
+
fullName: `${(profileData === null || profileData === void 0 ? void 0 : profileData.firstName) || ""} ${(profileData === null || profileData === void 0 ? void 0 : profileData.lastName) || ""}`,
|
|
27
|
+
headline: (0, utils_1.getNestedValue)(profileData, "headline"),
|
|
28
|
+
about: (yield (0, exports.getProfileSectionAbout)(identifier)) || "N/A",
|
|
29
|
+
birthDate: {
|
|
30
|
+
month: ((_a = profileData === null || profileData === void 0 ? void 0 : profileData.birthDateOn) === null || _a === void 0 ? void 0 : _a.month) || null,
|
|
31
|
+
day: ((_b = profileData === null || profileData === void 0 ? void 0 : profileData.birthDateOn) === null || _b === void 0 ? void 0 : _b.day) || null,
|
|
32
|
+
},
|
|
33
|
+
profilePicture: `${(0, utils_1.getNestedValue)(profileData, "profilePicture.displayImageReferenceResolutionResult.vectorImage.rootUrl")}${((_d = (_c = (0, utils_1.getNestedValue)(profileData, "profilePicture.displayImageReferenceResolutionResult.vectorImage.artifacts")) === null || _c === void 0 ? void 0 : _c.at(-1)) === null || _d === void 0 ? void 0 : _d.fileIdentifyingUrlPathSegment) || null}`,
|
|
34
|
+
backgroundPicture: `${(0, utils_1.getNestedValue)(profileData, "backgroundPicture.displayImageReferenceResolutionResult.vectorImage.rootUrl")}${((_f = (_e = (0, utils_1.getNestedValue)(profileData, "backgroundPicture.displayImageReferenceResolutionResult.vectorImage.artifacts")) === null || _e === void 0 ? void 0 : _e.at(-1)) === null || _f === void 0 ? void 0 : _f.fileIdentifyingUrlPathSegment) || null}`,
|
|
35
|
+
};
|
|
36
|
+
return profile;
|
|
37
|
+
}
|
|
38
|
+
throw new Error("Profile not found");
|
|
39
|
+
});
|
|
40
|
+
exports.getUserMiniProfile = getUserMiniProfile;
|
|
41
|
+
const extractProfileIdLinkedin = (profileUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
42
|
+
const match = profileUrl.match(/linkedin\.com\/in\/([a-zA-Z0-9-]+)/);
|
|
43
|
+
const profileId = match ? match[1] : profileUrl;
|
|
44
|
+
if (profileId) {
|
|
45
|
+
const response = yield (0, config_1.fetchData)(`graphql?variables=(vanityName:${profileId})&queryId=voyagerIdentityDashProfiles.34ead06db82a2cc9a778fac97f69ad6a`);
|
|
46
|
+
if ("included" in response) {
|
|
47
|
+
const profileData = response.included.find((item) => (item === null || item === void 0 ? void 0 : item.publicIdentifier) === `${profileId}`);
|
|
48
|
+
return (profileData === null || profileData === void 0 ? void 0 : profileData.entityUrn.replace("urn:li:fsd_profile:", "")) || null;
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
});
|
|
54
|
+
exports.extractProfileIdLinkedin = extractProfileIdLinkedin;
|
|
55
|
+
const getProfileSectionAbout = (identifier) => __awaiter(void 0, void 0, void 0, function* () {
|
|
56
|
+
var _a, _b, _c;
|
|
57
|
+
const profileId = yield (0, exports.extractProfileIdLinkedin)(identifier);
|
|
58
|
+
const response = yield (0, config_1.fetchData)(`graphql?variables=(profileUrn:urn%3Ali%3Afsd_profile%3A${profileId})&queryId=voyagerIdentityDashProfileCards.55af784c21dc8640b500ab5b45937064`);
|
|
59
|
+
const aboutData = (0, utils_1.getDataIncludedForEntity)(response, `about`);
|
|
60
|
+
const about = aboutData === null || aboutData === void 0 ? void 0 : aboutData.topComponents.find((item) => { var _a; return ((_a = item.components) === null || _a === void 0 ? void 0 : _a.textComponent) !== null; });
|
|
61
|
+
const aboutText = ((_c = (_b = (_a = about === null || about === void 0 ? void 0 : about.components) === null || _a === void 0 ? void 0 : _a.textComponent) === null || _b === void 0 ? void 0 : _b.text) === null || _c === void 0 ? void 0 : _c.text) || null;
|
|
62
|
+
return aboutText;
|
|
63
|
+
});
|
|
64
|
+
exports.getProfileSectionAbout = getProfileSectionAbout;
|
|
65
|
+
const getProfissionalExperiences = (identifier) => __awaiter(void 0, void 0, void 0, function* () {
|
|
66
|
+
const profileId = yield (0, exports.extractProfileIdLinkedin)(identifier);
|
|
67
|
+
if (!profileId) {
|
|
68
|
+
throw new Error("Profile not found");
|
|
69
|
+
}
|
|
70
|
+
const response = yield (0, config_1.fetchData)(`graphql?variables=(profileUrn:urn%3Ali%3Afsd_profile%3A${profileId},sectionType:experience,locale:en_US)&queryId=voyagerIdentityDashProfileComponents.c5d4db426a0f8247b8ab7bc1d660775a`);
|
|
71
|
+
const experiencesData = Promise.all((0, utils_1.extractExperiences)(response).map((item) => __awaiter(void 0, void 0, void 0, function* () {
|
|
72
|
+
const company = yield (0, company_1.getCompany)(item.idCompany || "");
|
|
73
|
+
if (item.idCompany) {
|
|
74
|
+
delete item.idCompany;
|
|
75
|
+
}
|
|
76
|
+
return Object.assign(Object.assign({}, item), { company });
|
|
77
|
+
})));
|
|
78
|
+
return experiencesData;
|
|
79
|
+
});
|
|
80
|
+
exports.getProfissionalExperiences = getProfissionalExperiences;
|
|
81
|
+
const getContactInfo = (identifier) => __awaiter(void 0, void 0, void 0, function* () {
|
|
82
|
+
var _a, _b, _c;
|
|
83
|
+
const profileId = yield (0, exports.extractProfileIdLinkedin)(identifier);
|
|
84
|
+
if (!profileId) {
|
|
85
|
+
throw new Error("Profile not found");
|
|
86
|
+
}
|
|
87
|
+
const response = yield (0, config_1.fetchData)(`graphql?includeWebMetadata=true&variables=(memberIdentity:${identifier})&queryId=voyagerIdentityDashProfiles.c7452e58fa37646d09dae4920fc5b4b9`);
|
|
88
|
+
const included = (response === null || response === void 0 ? void 0 : response.included) || [];
|
|
89
|
+
if (!included.length) {
|
|
90
|
+
console.warn("[PROFILE] No 'included' array found");
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
const dataProfile = included.find((item) => (item === null || item === void 0 ? void 0 : item.entityUrn) === `urn:li:fsd_profile:${profileId}`);
|
|
94
|
+
const contactInfo = {
|
|
95
|
+
address: (dataProfile === null || dataProfile === void 0 ? void 0 : dataProfile.address) || null,
|
|
96
|
+
weChatContactInfo: (dataProfile === null || dataProfile === void 0 ? void 0 : dataProfile.weChatContactInfo) || null,
|
|
97
|
+
phoneNumbers: ((_a = dataProfile === null || dataProfile === void 0 ? void 0 : dataProfile.phoneNumbers) === null || _a === void 0 ? void 0 : _a.map((item) => { var _a; return (_a = item === null || item === void 0 ? void 0 : item.phoneNumber) === null || _a === void 0 ? void 0 : _a.number; })) || null,
|
|
98
|
+
emailAddress: ((_b = dataProfile === null || dataProfile === void 0 ? void 0 : dataProfile.emailAddress) === null || _b === void 0 ? void 0 : _b.emailAddress) || null,
|
|
99
|
+
websites: ((_c = dataProfile === null || dataProfile === void 0 ? void 0 : dataProfile.websites) === null || _c === void 0 ? void 0 : _c.map((item) => ({
|
|
100
|
+
label: item === null || item === void 0 ? void 0 : item.label,
|
|
101
|
+
url: item === null || item === void 0 ? void 0 : item.url,
|
|
102
|
+
}))) || null,
|
|
103
|
+
};
|
|
104
|
+
return contactInfo;
|
|
105
|
+
});
|
|
106
|
+
exports.getContactInfo = getContactInfo;
|
|
107
|
+
const getLinkedinSkills = (identifier) => __awaiter(void 0, void 0, void 0, function* () {
|
|
108
|
+
const profileId = yield (0, exports.extractProfileIdLinkedin)(identifier);
|
|
109
|
+
if (!profileId) {
|
|
110
|
+
throw new Error("Profile not found");
|
|
111
|
+
}
|
|
112
|
+
const response = yield (0, config_1.fetchData)(`graphql?includeWebMetadata=true&variables=(profileUrn:urn%3Ali%3Afsd_profile%3A${profileId},sectionType:skills,locale:pt_BR)&queryId=voyagerIdentityDashProfileComponents.c5d4db426a0f8247b8ab7bc1d660775a`);
|
|
113
|
+
const included = (response === null || response === void 0 ? void 0 : response.included) || [];
|
|
114
|
+
const componentsSkills = included
|
|
115
|
+
.filter((item) => (item === null || item === void 0 ? void 0 : item.$type) ===
|
|
116
|
+
"com.linkedin.voyager.dash.identity.profile.tetris.PagedListComponent")
|
|
117
|
+
.map((item) => item === null || item === void 0 ? void 0 : item.components.elements.map((item) => (item === null || item === void 0 ? void 0 : item.components.entityComponent.titleV2.text.text) || null))
|
|
118
|
+
.filter((item) => item !== null)
|
|
119
|
+
.flat();
|
|
120
|
+
return componentsSkills;
|
|
121
|
+
});
|
|
122
|
+
exports.getLinkedinSkills = getLinkedinSkills;
|
|
123
|
+
const getLinkedinEducation = (identifier) => __awaiter(void 0, void 0, void 0, function* () {
|
|
124
|
+
const profileId = yield (0, exports.extractProfileIdLinkedin)(identifier);
|
|
125
|
+
if (!profileId) {
|
|
126
|
+
throw new Error("Profile not found");
|
|
127
|
+
}
|
|
128
|
+
const response = yield (0, config_1.fetchData)(`graphql?includeWebMetadata=true&variables=(profileUrn:urn%3Ali%3Afsd_profile%3A${profileId},sectionType:education,locale:pt_BR)&queryId=voyagerIdentityDashProfileComponents.c5d4db426a0f8247b8ab7bc1d660775a`);
|
|
129
|
+
const included = (response === null || response === void 0 ? void 0 : response.included) || [];
|
|
130
|
+
const componentsEducation = included
|
|
131
|
+
.filter((item) => (item === null || item === void 0 ? void 0 : item.$type) ===
|
|
132
|
+
"com.linkedin.voyager.dash.identity.profile.tetris.PagedListComponent")
|
|
133
|
+
.map((item) => item === null || item === void 0 ? void 0 : item.components.elements.map((item) => (item === null || item === void 0 ? void 0 : item.components.entityComponent) || null))
|
|
134
|
+
.filter((item) => item !== null);
|
|
135
|
+
const parseData = (componentsEducation === null || componentsEducation === void 0 ? void 0 : componentsEducation[0]) || [];
|
|
136
|
+
const educationData = parseData.map((item) => {
|
|
137
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
138
|
+
const isStudying = (item === null || item === void 0 ? void 0 : item.caption) === null;
|
|
139
|
+
const skillsData = item === null || item === void 0 ? void 0 : item.subComponents.components.find((item) => { var _a; return ((_a = item === null || item === void 0 ? void 0 : item.components) === null || _a === void 0 ? void 0 : _a.insightComponent) === null; });
|
|
140
|
+
return {
|
|
141
|
+
schoolName: ((_b = (_a = item === null || item === void 0 ? void 0 : item.titleV2) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.text) || null,
|
|
142
|
+
linkedinUrlSchool: (item === null || item === void 0 ? void 0 : item.textActionTarget) || null,
|
|
143
|
+
degreeName: (item === null || item === void 0 ? void 0 : item.subtitle.text) || null,
|
|
144
|
+
startDate: !isStudying
|
|
145
|
+
? Number((_d = (_c = item === null || item === void 0 ? void 0 : item.caption) === null || _c === void 0 ? void 0 : _c.text) === null || _d === void 0 ? void 0 : _d.split(" - ")[0]) || null
|
|
146
|
+
: null,
|
|
147
|
+
endDate: !isStudying
|
|
148
|
+
? Number((_f = (_e = item === null || item === void 0 ? void 0 : item.caption) === null || _e === void 0 ? void 0 : _e.text) === null || _f === void 0 ? void 0 : _f.split(" - ")[1]) || null
|
|
149
|
+
: null,
|
|
150
|
+
isStudying,
|
|
151
|
+
skills: ((_l = (_k = (_j = (_h = (_g = skillsData === null || skillsData === void 0 ? void 0 : skillsData.components) === null || _g === void 0 ? void 0 : _g.fixedListComponent) === null || _h === void 0 ? void 0 : _h.components[0]) === null || _j === void 0 ? void 0 : _j.components) === null || _k === void 0 ? void 0 : _k.textComponent) === null || _l === void 0 ? void 0 : _l.text.text) || null,
|
|
152
|
+
};
|
|
153
|
+
});
|
|
154
|
+
return educationData;
|
|
155
|
+
});
|
|
156
|
+
exports.getLinkedinEducation = getLinkedinEducation;
|
|
157
|
+
const getLinkedinCertifications = (identifier) => __awaiter(void 0, void 0, void 0, function* () {
|
|
158
|
+
const profileId = yield (0, exports.extractProfileIdLinkedin)(identifier);
|
|
159
|
+
if (!profileId) {
|
|
160
|
+
throw new Error("Profile not found");
|
|
161
|
+
}
|
|
162
|
+
const response = yield (0, config_1.fetchData)(`graphql?includeWebMetadata=true&variables=(profileUrn:urn%3Ali%3Afsd_profile%3A${profileId},sectionType:certifications,locale:pt_BR)&queryId=voyagerIdentityDashProfileComponents.c5d4db426a0f8247b8ab7bc1d660775a`);
|
|
163
|
+
const included = (response === null || response === void 0 ? void 0 : response.included) || [];
|
|
164
|
+
const componentsCertifications = included
|
|
165
|
+
.filter((item) => (item === null || item === void 0 ? void 0 : item.$type) ===
|
|
166
|
+
"com.linkedin.voyager.dash.identity.profile.tetris.PagedListComponent")
|
|
167
|
+
.map((item) => item === null || item === void 0 ? void 0 : item.components.elements.map((item) => (item === null || item === void 0 ? void 0 : item.components.entityComponent) || null))
|
|
168
|
+
.filter((item) => item !== null);
|
|
169
|
+
const parseData = (componentsCertifications === null || componentsCertifications === void 0 ? void 0 : componentsCertifications[0]) || [];
|
|
170
|
+
return parseData;
|
|
171
|
+
});
|
|
172
|
+
exports.getLinkedinCertifications = getLinkedinCertifications;
|
package/lib/utils.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ExperienceItem, LIDate, LinkedVectorImage, Organization, RawOrganization, VectorImage } from "./types";
|
|
1
2
|
export declare function filterKeys(obj: any, keysToKeep: string[]): any;
|
|
2
3
|
export declare function filterOutKeys(obj: any, keysToIgnore: string[]): any;
|
|
3
4
|
export declare function getNestedValue(obj: any, path: string): any;
|
|
@@ -8,3 +9,37 @@ export declare function extractDataWithReferences(elements: string[], included:
|
|
|
8
9
|
export declare function debugResolvedStructure(elements: string[], included: any[], maxDepth?: number): void;
|
|
9
10
|
export declare function extractFieldsFromIncluded(included: any[], fields: string[]): Record<string, any>[];
|
|
10
11
|
export declare function mergeExtraFields(mainData: any[], extraData: Record<string, any>[], matchKey?: string): any[];
|
|
12
|
+
type AnyObject = Record<string, any>;
|
|
13
|
+
interface Experience {
|
|
14
|
+
role: string | null;
|
|
15
|
+
idCompany: string | null;
|
|
16
|
+
company: string | null;
|
|
17
|
+
time_duration?: string | null;
|
|
18
|
+
location?: string | null;
|
|
19
|
+
description?: string | null;
|
|
20
|
+
time_period?: string | null;
|
|
21
|
+
duration?: string | null;
|
|
22
|
+
}
|
|
23
|
+
export declare const getDataIncludedForEntity: (jsonData: AnyObject, entityUrn: string) => any;
|
|
24
|
+
export declare function extractExperiences(jsonData: AnyObject): Experience[];
|
|
25
|
+
export declare function assert(value: unknown, message?: string | Error): asserts value;
|
|
26
|
+
export declare function getIdFromUrn(urn?: string): string | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Return the URN of a raw group update
|
|
29
|
+
*
|
|
30
|
+
* Example: urn:li:fs_miniProfile:<id>
|
|
31
|
+
* Example: urn:li:fs_updateV2:(<urn>,GROUP_FEED,EMPTY,DEFAULT,false)
|
|
32
|
+
*/
|
|
33
|
+
export declare function getUrnFromRawUpdate(update?: string): string | undefined;
|
|
34
|
+
export declare function isLinkedInUrn(urn?: string): boolean | undefined;
|
|
35
|
+
export declare function parseExperienceItem(item: any, { isGroupItem, included }: {
|
|
36
|
+
isGroupItem?: boolean;
|
|
37
|
+
included: any[];
|
|
38
|
+
}): ExperienceItem;
|
|
39
|
+
export declare function getGroupedItemId(item: any): string | undefined;
|
|
40
|
+
export declare const omit: <T extends Record<string, unknown> | object, K extends keyof any>(inputObj: T, ...keys: K[]) => Omit<T, K>;
|
|
41
|
+
export declare function resolveImageUrl(vectorImage?: VectorImage): string | undefined;
|
|
42
|
+
export declare function resolveLinkedVectorImageUrl(linkedVectorImage?: LinkedVectorImage): string | undefined;
|
|
43
|
+
export declare function stringifyLinkedInDate(date?: LIDate): string | undefined;
|
|
44
|
+
export declare function normalizeRawOrganization(o?: RawOrganization): Organization;
|
|
45
|
+
export {};
|