hunter-mate 0.1.24 → 0.1.26
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/dist/assets/extension/background/{service-worker.20261017012007.js → service-worker.20261019161523.js} +56 -4
- package/dist/assets/extension/background/service-worker.js +56 -4
- package/dist/assets/extension/build-info.json +1 -1
- package/dist/assets/extension/manifest.json +3 -3
- package/dist/assets/server/chunks/{chunk-SAJB6JRK.mjs → chunk-VL7WHUEV.mjs} +556 -8
- package/dist/assets/server/chunks/{script-rule-ZJN6CEYX.mjs → script-rule-4RZQ2PQE.mjs} +1 -2
- package/dist/assets/server/main.mjs +1038 -870
- package/dist/index.js +178 -24
- package/dist/watchdog.js +14 -3
- package/dist/web/dist/404.html +1 -1
- package/dist/web/dist/_next/static/chunks/187-f067914dcd1330c2.js +32 -0
- package/dist/web/dist/_next/static/chunks/253-9278ce6c4d446329.js +1 -0
- package/dist/web/dist/_next/static/chunks/{589-f984bff035a1cb85.js → 589-cc56950ae4117cdd.js} +1 -1
- package/dist/web/dist/_next/static/chunks/659-122057f46f941df7.js +1 -0
- package/dist/web/dist/_next/static/chunks/{686-9f419b70feea9470.js → 686-05b99d3674f45bf7.js} +1 -1
- package/dist/web/dist/_next/static/chunks/728-cffab7e836020551.js +12 -0
- package/dist/web/dist/_next/static/chunks/{865-0ed23dd43c0832a2.js → 865-8e1d8c34192526ed.js} +1 -1
- package/dist/web/dist/_next/static/chunks/{935-7be3e60dd8bc29d2.js → 935-efb30b9f6f558e3f.js} +1 -1
- package/dist/web/dist/_next/static/chunks/{a7067448-e416655baf443992.js → a7067448-3f2b194cfadb91fb.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/_not-found/{page-5b7249eb3c9a6cb9.js → page-d939b40bb8878d26.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/admin/data/{page-14698e9c4ddaa6d9.js → page-df1d84c14e85f294.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/auth/verify/{page-05304d5803008d61.js → page-cfeb844e1b72ccaa.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/companies/{page-e8d02fe997579315.js → page-57b1ef0b12134ce0.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/company/admin/{page-c2584183bc4b34d1.js → page-010928306f8df0ed.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/entity/{page-08755f96102f0565.js → page-fa96319650d38e78.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/jobs/page-5ba0bdc881b98d42.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/{layout-af39afc7866e74db.js → layout-bd9a7e5e4474b692.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/logs/{page-be50a4e10b1a0024.js → page-bcdbb3885abda5a2.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/matching/jobs/[id]/talents/{page-cf445b0cb8c2cb0a.js → page-8aca89db1e666a49.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/matching/portraits/[id]/jobs/{page-c7ff0d79b6a75915.js → page-7086f1b773e57511.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/{page-bd282e1e5f0965f1.js → page-49fe1e8630d2237e.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/parselog/{page-9814e75d6900a743.js → page-fcdfdd41cf1f86f7.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/recordings/{page-441016638b43c4f8.js → page-7ba5d89391c9dace.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/resource-usage/{page-f6fa06bfe21bcd32.js → page-7b939cf673d764e6.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/shared/[token]/{page-c9c5042a2d07c0bc.js → page-df87328c52f862f1.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/snapshots/[id]/agent-prompt/{page-f54cf2f0058035ca.js → page-7d4d25de2c6704e9.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/talents/{page-0edef6d07b3cf69d.js → page-5a2caa7a503ee041.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/team/insights/{page-8b3934df3e292368.js → page-f097b4b8578a6e5d.js} +1 -1
- package/dist/web/dist/_next/static/css/a8f0a381a2372781.css +3 -0
- package/dist/web/dist/admin/data.html +1 -1
- package/dist/web/dist/admin/data.txt +5 -5
- package/dist/web/dist/auth/verify.html +1 -1
- package/dist/web/dist/auth/verify.txt +5 -5
- package/dist/web/dist/companies.html +1 -1
- package/dist/web/dist/companies.txt +5 -5
- package/dist/web/dist/company/admin.html +1 -1
- package/dist/web/dist/company/admin.txt +5 -5
- package/dist/web/dist/entity.html +1 -1
- package/dist/web/dist/entity.txt +5 -5
- package/dist/web/dist/index.html +1 -1
- package/dist/web/dist/index.txt +5 -5
- package/dist/web/dist/jobs.html +1 -1
- package/dist/web/dist/jobs.txt +5 -5
- package/dist/web/dist/logs.html +1 -1
- package/dist/web/dist/logs.txt +5 -5
- package/dist/web/dist/matching/jobs/placeholder/talents.html +1 -1
- package/dist/web/dist/matching/jobs/placeholder/talents.txt +5 -5
- package/dist/web/dist/matching/portraits/placeholder/jobs.html +1 -1
- package/dist/web/dist/matching/portraits/placeholder/jobs.txt +5 -5
- package/dist/web/dist/parselog.html +1 -1
- package/dist/web/dist/parselog.txt +5 -5
- package/dist/web/dist/recordings.html +1 -1
- package/dist/web/dist/recordings.txt +5 -5
- package/dist/web/dist/resource-usage.html +1 -1
- package/dist/web/dist/resource-usage.txt +5 -5
- package/dist/web/dist/shared/placeholder.html +1 -1
- package/dist/web/dist/shared/placeholder.txt +5 -5
- package/dist/web/dist/snapshots/placeholder/agent-prompt.html +1 -1
- package/dist/web/dist/snapshots/placeholder/agent-prompt.txt +5 -5
- package/dist/web/dist/talents.html +1 -1
- package/dist/web/dist/talents.txt +5 -5
- package/dist/web/dist/team/insights.html +1 -1
- package/dist/web/dist/team/insights.txt +5 -5
- package/package.json +1 -1
- package/dist/assets/server/chunks/chunk-BLXHCSZD.mjs +0 -565
- package/dist/assets/server/chunks/esm-4U746B76.mjs +0 -29
- package/dist/web/dist/_next/static/chunks/105-dcd8f6d5867c8995.js +0 -32
- package/dist/web/dist/_next/static/chunks/253-a05d05b94bfbd7a4.js +0 -1
- package/dist/web/dist/_next/static/chunks/555-e2a871b9d2eccb03.js +0 -12
- package/dist/web/dist/_next/static/chunks/852-ad19b97821a4cf9e.js +0 -1
- package/dist/web/dist/_next/static/chunks/app/jobs/page-4827a9ef286b6483.js +0 -1
- package/dist/web/dist/_next/static/css/10ba1fa1d6ce23a7.css +0 -3
- /package/dist/web/dist/_next/static/{hBLezfvVOMiGqm4V9F15i → m0UGHVTGvtvb9mn4-uzJJ}/_buildManifest.js +0 -0
- /package/dist/web/dist/_next/static/{hBLezfvVOMiGqm4V9F15i → m0UGHVTGvtvb9mn4-uzJJ}/_ssgManifest.js +0 -0
|
@@ -14408,14 +14408,562 @@ var { merge: merge2 } = static_exports;
|
|
|
14408
14408
|
var { parseHTML: parseHTML2 } = static_exports;
|
|
14409
14409
|
var { root: root2 } = static_exports;
|
|
14410
14410
|
|
|
14411
|
+
// dist/.server-tsc/extraction/linkedin-extractor.js
|
|
14412
|
+
var SECTION_KEYWORDS = /* @__PURE__ */ new Set([
|
|
14413
|
+
"About",
|
|
14414
|
+
"Experience",
|
|
14415
|
+
"Education",
|
|
14416
|
+
"Skills",
|
|
14417
|
+
"Projects",
|
|
14418
|
+
"Featured",
|
|
14419
|
+
"Activity",
|
|
14420
|
+
"People you may know",
|
|
14421
|
+
"You might like",
|
|
14422
|
+
"Ad Options",
|
|
14423
|
+
"Don\u2019t want to see this",
|
|
14424
|
+
"Explore Premium profiles",
|
|
14425
|
+
"People who follow"
|
|
14426
|
+
]);
|
|
14427
|
+
function isSectionLike(text3) {
|
|
14428
|
+
const t = text3.trim();
|
|
14429
|
+
if (!t)
|
|
14430
|
+
return true;
|
|
14431
|
+
for (const kw of SECTION_KEYWORDS) {
|
|
14432
|
+
if (t.includes(kw))
|
|
14433
|
+
return true;
|
|
14434
|
+
}
|
|
14435
|
+
return false;
|
|
14436
|
+
}
|
|
14437
|
+
var NON_NAME_KEYWORDS = /notifications|messages|jobs|network|home|search/i;
|
|
14438
|
+
function looksLikeName(text3) {
|
|
14439
|
+
const t = text3.trim();
|
|
14440
|
+
return t.length > 0 && t.length <= 80 && !isSectionLike(t) && !NON_NAME_KEYWORDS.test(t);
|
|
14441
|
+
}
|
|
14442
|
+
function isPunctuationOnly(text3) {
|
|
14443
|
+
return /^[^\p{L}\p{N}]*$/u.test(text3.trim());
|
|
14444
|
+
}
|
|
14445
|
+
function looksLikeLocation(text3) {
|
|
14446
|
+
const t = text3.trim();
|
|
14447
|
+
const parts = t.split(",").map((s) => s.trim()).filter(Boolean);
|
|
14448
|
+
if (parts.length === 0 || parts.length > 3)
|
|
14449
|
+
return false;
|
|
14450
|
+
return parts.every((p) => /^[A-Za-zÀ-ſ\s'-]{2,40}$/.test(p) && !/\d/.test(p));
|
|
14451
|
+
}
|
|
14452
|
+
function looksLikeUrl(text3) {
|
|
14453
|
+
return /^https?:\/\//.test(text3.trim());
|
|
14454
|
+
}
|
|
14455
|
+
function looksLikeFollowers(text3) {
|
|
14456
|
+
const t = text3.trim();
|
|
14457
|
+
return /followers|connections/i.test(t) || /^[\d,]+\+?\s*$/.test(t);
|
|
14458
|
+
}
|
|
14459
|
+
function looksLikeExperienceLocation(text3) {
|
|
14460
|
+
const t = text3.trim();
|
|
14461
|
+
if (t.length > 60)
|
|
14462
|
+
return false;
|
|
14463
|
+
if (/\b(Area|Region|City|Metropolitan)\b/i.test(t))
|
|
14464
|
+
return true;
|
|
14465
|
+
if (/^[A-Z][a-z]+(?:\s+[A-Z][a-z]+){0,5}(?:\s+(Area|Region|City|Metropolitan))?$/i.test(t))
|
|
14466
|
+
return true;
|
|
14467
|
+
return false;
|
|
14468
|
+
}
|
|
14469
|
+
function looksLikeDateRange(text3) {
|
|
14470
|
+
const t = text3.trim();
|
|
14471
|
+
const hasYear = /\b(19|20)\d{2}\b/.test(t);
|
|
14472
|
+
const hasMonthOrPresent = /\b(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec|Present|present|至今)\b/.test(t);
|
|
14473
|
+
const yearRange = /\b(19|20)\d{2}\b\s*[-–—]\s*\b(19|20)\d{2}\b/.test(t);
|
|
14474
|
+
return hasYear && (hasMonthOrPresent || yearRange);
|
|
14475
|
+
}
|
|
14476
|
+
function firstText($2, container) {
|
|
14477
|
+
return $2(container).text().replace(/\s+/g, " ").trim();
|
|
14478
|
+
}
|
|
14479
|
+
function extractLinkedInProfile(html3) {
|
|
14480
|
+
const $2 = typeof html3 === "string" ? load(html3) : html3;
|
|
14481
|
+
const out = {};
|
|
14482
|
+
const h2s = $2("h2");
|
|
14483
|
+
let name = null;
|
|
14484
|
+
let nameEl = null;
|
|
14485
|
+
h2s.each((_i, el) => {
|
|
14486
|
+
if (name)
|
|
14487
|
+
return;
|
|
14488
|
+
const $el = $2(el);
|
|
14489
|
+
const cls = $el.attr("class") || "";
|
|
14490
|
+
const parentCls = $el.parent().attr("class") || "";
|
|
14491
|
+
const t = $el.text().replace(/\s+/g, " ").trim().replace(/\s*\|\s*$/, "");
|
|
14492
|
+
if (looksLikeName(t) && (cls.includes("_1f667e81") || parentCls.includes("a8841267"))) {
|
|
14493
|
+
name = t;
|
|
14494
|
+
nameEl = $el;
|
|
14495
|
+
}
|
|
14496
|
+
});
|
|
14497
|
+
if (!name) {
|
|
14498
|
+
h2s.each((_i, el) => {
|
|
14499
|
+
if (name)
|
|
14500
|
+
return;
|
|
14501
|
+
const t = $2(el).text().replace(/\s+/g, " ").trim().replace(/\s*\|\s*$/, "");
|
|
14502
|
+
if (looksLikeName(t)) {
|
|
14503
|
+
name = t;
|
|
14504
|
+
nameEl = $2(el);
|
|
14505
|
+
}
|
|
14506
|
+
});
|
|
14507
|
+
}
|
|
14508
|
+
if (name)
|
|
14509
|
+
out.name = name;
|
|
14510
|
+
const topCard = nameEl ? nameEl.closest("section").first() : h2s.first().closest("section").first();
|
|
14511
|
+
const topTexts = [];
|
|
14512
|
+
topCard.find("p").each((_i, el) => {
|
|
14513
|
+
const t = $2(el).text().replace(/\s+/g, " ").trim();
|
|
14514
|
+
if (t && !topTexts.includes(t))
|
|
14515
|
+
topTexts.push(t);
|
|
14516
|
+
});
|
|
14517
|
+
const meaningfulTop = topTexts.filter((t) => !/^·\s*\d+(?:rd|th|nd|st)?$/.test(t));
|
|
14518
|
+
if (meaningfulTop[0] && !isSectionLike(meaningfulTop[0])) {
|
|
14519
|
+
out.headline = meaningfulTop[0];
|
|
14520
|
+
}
|
|
14521
|
+
if (meaningfulTop[1] && !isSectionLike(meaningfulTop[1]) && !isPunctuationOnly(meaningfulTop[1])) {
|
|
14522
|
+
out.currentCompany = meaningfulTop[1];
|
|
14523
|
+
}
|
|
14524
|
+
for (let i = 0; i < meaningfulTop.length; i++) {
|
|
14525
|
+
const t = meaningfulTop[i];
|
|
14526
|
+
if (t === out.headline || t === out.currentCompany)
|
|
14527
|
+
continue;
|
|
14528
|
+
if (!out.location && looksLikeLocation(t))
|
|
14529
|
+
out.location = t;
|
|
14530
|
+
if (looksLikeUrl(t))
|
|
14531
|
+
out.website = t;
|
|
14532
|
+
if (looksLikeFollowers(t)) {
|
|
14533
|
+
const next2 = meaningfulTop[i + 1];
|
|
14534
|
+
out.followers = next2 && /connections|followers/i.test(next2) ? `${t} ${next2}` : t;
|
|
14535
|
+
if (next2 && /connections|followers/i.test(next2))
|
|
14536
|
+
i++;
|
|
14537
|
+
}
|
|
14538
|
+
}
|
|
14539
|
+
const aboutH2 = h2s.filter((_i, el) => $2(el).text().includes("About")).first();
|
|
14540
|
+
if (aboutH2.length) {
|
|
14541
|
+
let cursor = aboutH2.parent().next();
|
|
14542
|
+
const summaryParts = [];
|
|
14543
|
+
for (let i = 0; i < 6 && cursor.length; i++) {
|
|
14544
|
+
const tag = cursor.prop("tagName")?.toLowerCase();
|
|
14545
|
+
if (tag === "h2")
|
|
14546
|
+
break;
|
|
14547
|
+
const t = firstText($2, cursor);
|
|
14548
|
+
if (t.length > 20 && !isSectionLike(t))
|
|
14549
|
+
summaryParts.push(t);
|
|
14550
|
+
cursor = cursor.next();
|
|
14551
|
+
}
|
|
14552
|
+
if (summaryParts.length)
|
|
14553
|
+
out.summary = summaryParts.join(" ");
|
|
14554
|
+
}
|
|
14555
|
+
const expH2 = h2s.filter((_i, el) => $2(el).text().includes("Experience")).first();
|
|
14556
|
+
if (expH2.length) {
|
|
14557
|
+
const section = expH2.closest("section").first();
|
|
14558
|
+
const pTexts = [];
|
|
14559
|
+
section.find("p").each((_i, el) => {
|
|
14560
|
+
const t = firstText($2, el);
|
|
14561
|
+
if (t && !isSectionLike(t))
|
|
14562
|
+
pTexts.push(t);
|
|
14563
|
+
});
|
|
14564
|
+
const experiences = [];
|
|
14565
|
+
let lastDateIdx = -1;
|
|
14566
|
+
for (let i = 0; i < pTexts.length; i++) {
|
|
14567
|
+
if (looksLikeDateRange(pTexts[i])) {
|
|
14568
|
+
const item = { duration: pTexts[i] };
|
|
14569
|
+
if (pTexts[i - 1])
|
|
14570
|
+
item.company = pTexts[i - 1];
|
|
14571
|
+
if (pTexts[i - 2])
|
|
14572
|
+
item.title = pTexts[i - 2];
|
|
14573
|
+
if (experiences.length > 0 && lastDateIdx >= 0) {
|
|
14574
|
+
const desc = pTexts.slice(lastDateIdx + 1, i - 2);
|
|
14575
|
+
if (desc.length) {
|
|
14576
|
+
const first2 = desc[0];
|
|
14577
|
+
if (looksLikeExperienceLocation(first2)) {
|
|
14578
|
+
experiences[experiences.length - 1].location = first2;
|
|
14579
|
+
if (desc.length > 1) {
|
|
14580
|
+
experiences[experiences.length - 1].description = desc.slice(1).join(" ");
|
|
14581
|
+
}
|
|
14582
|
+
} else {
|
|
14583
|
+
experiences[experiences.length - 1].description = desc.join(" ");
|
|
14584
|
+
}
|
|
14585
|
+
}
|
|
14586
|
+
}
|
|
14587
|
+
if (Object.keys(item).length > 1)
|
|
14588
|
+
experiences.push(item);
|
|
14589
|
+
lastDateIdx = i;
|
|
14590
|
+
}
|
|
14591
|
+
}
|
|
14592
|
+
if (experiences.length)
|
|
14593
|
+
out.experiences = experiences;
|
|
14594
|
+
}
|
|
14595
|
+
const eduH2 = h2s.filter((_i, el) => $2(el).text().includes("Education")).first();
|
|
14596
|
+
if (eduH2.length) {
|
|
14597
|
+
const section = eduH2.closest("section").first();
|
|
14598
|
+
const pTexts = [];
|
|
14599
|
+
section.find("p").each((_i, el) => {
|
|
14600
|
+
const t = firstText($2, el);
|
|
14601
|
+
if (t && !isSectionLike(t))
|
|
14602
|
+
pTexts.push(t);
|
|
14603
|
+
});
|
|
14604
|
+
const education = [];
|
|
14605
|
+
let lastDateIdx = -1;
|
|
14606
|
+
for (let i = 0; i < pTexts.length; i++) {
|
|
14607
|
+
if (looksLikeDateRange(pTexts[i])) {
|
|
14608
|
+
const item = { years: pTexts[i] };
|
|
14609
|
+
if (pTexts[i - 2]) {
|
|
14610
|
+
item.school = pTexts[i - 2];
|
|
14611
|
+
item.degree = pTexts[i - 1];
|
|
14612
|
+
} else if (pTexts[i - 1]) {
|
|
14613
|
+
item.school = pTexts[i - 1];
|
|
14614
|
+
}
|
|
14615
|
+
if (Object.keys(item).length > 1)
|
|
14616
|
+
education.push(item);
|
|
14617
|
+
lastDateIdx = i;
|
|
14618
|
+
}
|
|
14619
|
+
}
|
|
14620
|
+
if (lastDateIdx >= 0 && lastDateIdx < pTexts.length - 1) {
|
|
14621
|
+
const tail = pTexts.slice(lastDateIdx + 1);
|
|
14622
|
+
if (tail.length >= 2) {
|
|
14623
|
+
education.push({ school: tail[0], degree: tail[1] });
|
|
14624
|
+
} else if (tail.length === 1) {
|
|
14625
|
+
education.push({ school: tail[0] });
|
|
14626
|
+
}
|
|
14627
|
+
}
|
|
14628
|
+
if (education.length)
|
|
14629
|
+
out.education = education;
|
|
14630
|
+
}
|
|
14631
|
+
const skillH2 = h2s.filter((_i, el) => $2(el).text().includes("Skills")).first();
|
|
14632
|
+
if (skillH2.length) {
|
|
14633
|
+
const section = skillH2.closest("section, div").first();
|
|
14634
|
+
const skills = /* @__PURE__ */ new Set();
|
|
14635
|
+
section.find('span, button, a, li, div[role="listitem"]').each((_i, el) => {
|
|
14636
|
+
const t = firstText($2, el);
|
|
14637
|
+
if (t && t.length <= 50 && t.length >= 2 && !isSectionLike(t) && !looksLikeDateRange(t) && !looksLikeFollowers(t) && !looksLikeUrl(t)) {
|
|
14638
|
+
skills.add(t);
|
|
14639
|
+
}
|
|
14640
|
+
});
|
|
14641
|
+
if (skills.size)
|
|
14642
|
+
out.skills = Array.from(skills).slice(0, 50);
|
|
14643
|
+
}
|
|
14644
|
+
return out;
|
|
14645
|
+
}
|
|
14646
|
+
|
|
14647
|
+
// dist/.server-tsc/extraction/talent-entity.js
|
|
14648
|
+
var LIEPIN_CONSUMED_SECTION_KEYS = /* @__PURE__ */ new Set([
|
|
14649
|
+
"single",
|
|
14650
|
+
"basic-info",
|
|
14651
|
+
"job-exp-info",
|
|
14652
|
+
"job-expectancy-info-wrap",
|
|
14653
|
+
"work-info",
|
|
14654
|
+
"project-info",
|
|
14655
|
+
"edu-info",
|
|
14656
|
+
"lang-info",
|
|
14657
|
+
"skill-info",
|
|
14658
|
+
"self-eva-info",
|
|
14659
|
+
"self-evaluation-info",
|
|
14660
|
+
"operation-wrap"
|
|
14661
|
+
]);
|
|
14662
|
+
var LIEPIN_WORK_KNOWN_COLS = /* @__PURE__ */ new Set([
|
|
14663
|
+
"\u6240\u5728\u90E8\u95E8",
|
|
14664
|
+
"\u5DE5\u4F5C\u5730\u70B9",
|
|
14665
|
+
"\u4E0B\u5C5E\u4EBA\u6570",
|
|
14666
|
+
"\u6C47\u62A5\u5BF9\u8C61",
|
|
14667
|
+
"\u804C\u8D23\u4E1A\u7EE9"
|
|
14668
|
+
]);
|
|
14669
|
+
var LIEPIN_PROJECT_KNOWN_COLS = /* @__PURE__ */ new Set(["\u9879\u76EE\u804C\u52A1", "\u6240\u5728\u516C\u53F8", "\u9879\u76EE\u63CF\u8FF0", "\u9879\u76EE\u804C\u8D23"]);
|
|
14670
|
+
function pickUnmappedCols(cols, known) {
|
|
14671
|
+
const out = {};
|
|
14672
|
+
for (const [k, v] of Object.entries(cols)) {
|
|
14673
|
+
if (!known.has(k))
|
|
14674
|
+
out[k] = v;
|
|
14675
|
+
}
|
|
14676
|
+
return Object.keys(out).length ? out : void 0;
|
|
14677
|
+
}
|
|
14678
|
+
|
|
14679
|
+
// dist/.server-tsc/extraction/liepin-extractor.js
|
|
14680
|
+
var clean = (s) => {
|
|
14681
|
+
if (s == null)
|
|
14682
|
+
return null;
|
|
14683
|
+
const t = s.replace(/\s+/g, " ").trim();
|
|
14684
|
+
return t || null;
|
|
14685
|
+
};
|
|
14686
|
+
function splitByI($2, el) {
|
|
14687
|
+
const html3 = $2(el).html() || "";
|
|
14688
|
+
return html3.replace(/<i[^>]*>\s*<\/i>/g, "|").split("|").map((s) => clean($2(s).text?.() ?? s) ?? clean(s.replace(/<[^>]+>/g, ""))).map((s) => s || "").filter(Boolean);
|
|
14689
|
+
}
|
|
14690
|
+
function parsePeriod(text3) {
|
|
14691
|
+
const m = text3.match(/[((]\s*([^))]*?)\s*[))]/);
|
|
14692
|
+
if (!m)
|
|
14693
|
+
return { start: null, end: null, duration: null };
|
|
14694
|
+
const parts = m[1].split(",").map((s) => clean(s)).filter(Boolean);
|
|
14695
|
+
const range = (parts[0] || "").split("-").map((s) => clean(s));
|
|
14696
|
+
return {
|
|
14697
|
+
start: range[0] || null,
|
|
14698
|
+
end: range[1] || null,
|
|
14699
|
+
duration: parts[1] || null
|
|
14700
|
+
};
|
|
14701
|
+
}
|
|
14702
|
+
function readInfoCols($2, root3) {
|
|
14703
|
+
const out = {};
|
|
14704
|
+
root3.find(".rd-info-col").each((_i, col) => {
|
|
14705
|
+
const title = clean($2(col).find(".rd-info-col-title").first().text());
|
|
14706
|
+
const cont = clean($2(col).find(".rd-info-col-cont").first().text());
|
|
14707
|
+
if (title && cont)
|
|
14708
|
+
out[title.replace(/[::]\s*$/, "")] = cont;
|
|
14709
|
+
});
|
|
14710
|
+
return out;
|
|
14711
|
+
}
|
|
14712
|
+
function extractBasic($2) {
|
|
14713
|
+
const root3 = $2("#resume-detail-basic-info, .resume-detail-basic-info").first();
|
|
14714
|
+
if (!root3.length)
|
|
14715
|
+
return {};
|
|
14716
|
+
const name = clean(root3.find(".name-box .name").first().text());
|
|
14717
|
+
const sepInfos = root3.find(".basic-cont .sep-info, .sep-info").toArray();
|
|
14718
|
+
const sepParts = sepInfos.map((el) => splitByI($2, el));
|
|
14719
|
+
const contactIdx = sepParts.findIndex((p) => /方便联系时间/.test(p.join(" ")));
|
|
14720
|
+
const personalIdx = sepParts.findIndex((p) => /岁|工作\s*\d+\s*年/.test(p.join(" ")));
|
|
14721
|
+
const partsP = personalIdx >= 0 ? sepParts[personalIdx] : sepParts[0] ?? [];
|
|
14722
|
+
const companyIdx = sepParts.findIndex((p, i) => i !== personalIdx && i !== contactIdx && p.join(" ").trim().length > 0);
|
|
14723
|
+
const partsC = companyIdx >= 0 ? sepParts[companyIdx] : [];
|
|
14724
|
+
const joined0 = partsP.join(" ");
|
|
14725
|
+
const age = joined0.match(/(\d+)\s*岁/)?.[1] ?? null;
|
|
14726
|
+
const workYears = joined0.match(/工作\s*(\d+)\s*年/)?.[1] ?? null;
|
|
14727
|
+
const gender = partsP.find((p) => /^(男|女)$/.test(p)) ?? null;
|
|
14728
|
+
const currentPosition = partsC.length ? partsC[0] : null;
|
|
14729
|
+
const personalLast = partsP.length ? partsP[partsP.length - 1] ?? null : null;
|
|
14730
|
+
const companyFromLine = partsC.length > 1 ? partsC.slice(1).join(" ") : null;
|
|
14731
|
+
const currentCompany = personalLast === "\u4FDD\u5BC6" ? "\u4FDD\u5BC6" : companyFromLine ?? personalLast;
|
|
14732
|
+
const companyMasked = currentCompany === "\u4FDD\u5BC6" ? true : partsP.includes("\u4FDD\u5BC6") || (currentCompany ? /保密/.test(currentCompany) : false) ? true : void 0;
|
|
14733
|
+
const contactTimeRaw = clean(root3.find(".res-status-box").first().text());
|
|
14734
|
+
return {
|
|
14735
|
+
name,
|
|
14736
|
+
nameMasked: name ? /\*/.test(name) : void 0,
|
|
14737
|
+
statusTag: clean(root3.find(".user-status-tag").first().text()),
|
|
14738
|
+
gender,
|
|
14739
|
+
age: age ? Number(age) : null,
|
|
14740
|
+
city: partsP.find((p) => /^(北京|上海|广州|深圳|天津|重庆|杭州|南京|苏州|成都|武汉|西安)$/.test(p)) ?? partsP.find((p) => /^[一-鿿]{2,6}$/.test(p) && !/^(男|女|保密)$/.test(p) && !/岁|年/.test(p) && !/(博士|硕士|MBA|本科|大专|专科|高中|中专|初中)/.test(p)) ?? null,
|
|
14741
|
+
degree: partsP.find((p) => /(博士|硕士|MBA|本科|大专|专科|高中|中专|初中)/.test(p)) ?? null,
|
|
14742
|
+
workYears: workYears ? Number(workYears) : null,
|
|
14743
|
+
workYearsText: joined0.match(/工作[^|]*/) ? joined0.match(/工作\s*\d+\s*年/)?.[0] ?? null : null,
|
|
14744
|
+
currentCompany: currentCompany ?? null,
|
|
14745
|
+
currentCompanyMasked: companyMasked,
|
|
14746
|
+
currentPosition,
|
|
14747
|
+
contactTime: contactTimeRaw ? contactTimeRaw.replace(/^方便联系时间[::]\s*/, "") : null,
|
|
14748
|
+
photoUrl: root3.find(".logo-box img").first().attr("src") ?? null
|
|
14749
|
+
};
|
|
14750
|
+
}
|
|
14751
|
+
function extractIntent($2) {
|
|
14752
|
+
const root3 = $2("#resume-detail-job-exp-info, .resume-detail-job-expectancy-info-wrap").first();
|
|
14753
|
+
if (!root3.length)
|
|
14754
|
+
return {};
|
|
14755
|
+
const labels = root3.find(".lebels-wrap span").toArray().map((el) => clean($2(el).text())).filter(Boolean);
|
|
14756
|
+
return {
|
|
14757
|
+
position: clean(root3.find(".tabs .title").first().attr("title")) ?? clean(root3.find(".tabs .title").first().text()),
|
|
14758
|
+
salary: clean(root3.find(".tabs .salary").first().text()),
|
|
14759
|
+
city: clean(root3.find(".dqname-wrap").first().text()),
|
|
14760
|
+
industries: labels
|
|
14761
|
+
};
|
|
14762
|
+
}
|
|
14763
|
+
function extractWorkExperiences($2) {
|
|
14764
|
+
const out = [];
|
|
14765
|
+
$2("#resume-detail-work-info .rd-work-item-cont, .resume-detail-work-info .rd-info-tpl-item").each((_i, el) => {
|
|
14766
|
+
const item = $2(el);
|
|
14767
|
+
const periodText = clean(item.find(".rd-work-time").first().text()) ?? "";
|
|
14768
|
+
const cols = readInfoCols($2, item);
|
|
14769
|
+
const extra = pickUnmappedCols(cols, LIEPIN_WORK_KNOWN_COLS);
|
|
14770
|
+
out.push({
|
|
14771
|
+
company: clean(item.find(".rd-work-comp h5").first().attr("title")) ?? clean(item.find(".rd-work-comp h5").first().text()),
|
|
14772
|
+
...parsePeriod(periodText),
|
|
14773
|
+
position: clean(item.find(".job-name").first().text()),
|
|
14774
|
+
department: cols["\u6240\u5728\u90E8\u95E8"] ?? null,
|
|
14775
|
+
location: cols["\u5DE5\u4F5C\u5730\u70B9"] ?? null,
|
|
14776
|
+
subordinates: cols["\u4E0B\u5C5E\u4EBA\u6570"] != null ? Number(cols["\u4E0B\u5C5E\u4EBA\u6570"]) : null,
|
|
14777
|
+
reportsTo: cols["\u6C47\u62A5\u5BF9\u8C61"] ?? null,
|
|
14778
|
+
responsibilities: cols["\u804C\u8D23\u4E1A\u7EE9"] ?? null,
|
|
14779
|
+
...extra ? { extra } : {}
|
|
14780
|
+
});
|
|
14781
|
+
});
|
|
14782
|
+
return out;
|
|
14783
|
+
}
|
|
14784
|
+
function extractProjects($2) {
|
|
14785
|
+
const out = [];
|
|
14786
|
+
$2("#resume-detail-project-info .rd-project-item-cont, .resume-detail-project-info .rd-project-item-cont, .resume-detail-project-info .rd-info-tpl-item").each((_i, el) => {
|
|
14787
|
+
const item = $2(el);
|
|
14788
|
+
const periodText = clean(item.find(".rd-project-time").first().text()) ?? "";
|
|
14789
|
+
const cols = readInfoCols($2, item);
|
|
14790
|
+
const extra = pickUnmappedCols(cols, LIEPIN_PROJECT_KNOWN_COLS);
|
|
14791
|
+
out.push({
|
|
14792
|
+
name: clean(item.find(".rd-project-name h5").first().attr("title")) ?? clean(item.find(".rd-project-name h5").first().text()),
|
|
14793
|
+
...parsePeriod(periodText),
|
|
14794
|
+
role: cols["\u9879\u76EE\u804C\u52A1"] ?? null,
|
|
14795
|
+
company: cols["\u6240\u5728\u516C\u53F8"] ?? null,
|
|
14796
|
+
description: cols["\u9879\u76EE\u63CF\u8FF0"] ?? null,
|
|
14797
|
+
duties: cols["\u9879\u76EE\u804C\u8D23"] ?? null,
|
|
14798
|
+
...extra ? { extra } : {}
|
|
14799
|
+
});
|
|
14800
|
+
});
|
|
14801
|
+
return out;
|
|
14802
|
+
}
|
|
14803
|
+
function extractEducation($2) {
|
|
14804
|
+
const out = [];
|
|
14805
|
+
$2("#resume-detail-edu-info .rd-edu-info-item, .resume-detail-edu-info .rd-edu-info-item").each((_i, el) => {
|
|
14806
|
+
const item = $2(el);
|
|
14807
|
+
const raw = clean(item.text()) ?? "";
|
|
14808
|
+
const segs = raw.split("\xB7").map((s) => clean(s)).filter(Boolean);
|
|
14809
|
+
const periodM = raw.match(/\d{4}\.\d{2}\s*-\s*(?:\d{4}\.\d{2}|至今)/);
|
|
14810
|
+
const segEdu = (segs.length > 2 ? segs[2] : segs.length > 1 ? segs[1] : "").match(/(博士|硕士|MBA|本科|大专|专科|高中|中专|初中)/);
|
|
14811
|
+
out.push({
|
|
14812
|
+
school: clean(item.find(".school-name").first().attr("title")) ?? clean(item.find(".school-name").first().text()),
|
|
14813
|
+
major: clean(item.find(".school-special").first().attr("title")) ?? clean(item.find(".school-special").first().text()) ?? (segs.length > 1 ? /^(博士|硕士|MBA|本科|大专|专科|高中|中专|初中)/.test(segs[1]) ? null : segs[1] : null),
|
|
14814
|
+
degree: clean(item.find(".school-degree").first().attr("title")) ?? clean(item.find(".school-degree").first().text()) ?? (segEdu ? segEdu[0] : null),
|
|
14815
|
+
period: clean(item.find(".school-time").first().text()) ?? (periodM ? periodM[0] : null),
|
|
14816
|
+
tags: item.find(".edu-school-tags .tag-item, .tag-item").toArray().map((t) => clean($2(t).text())).filter(Boolean)
|
|
14817
|
+
});
|
|
14818
|
+
});
|
|
14819
|
+
return out;
|
|
14820
|
+
}
|
|
14821
|
+
function extractResId($2) {
|
|
14822
|
+
const scm = $2("[data-tlg-scm]").first().attr("data-tlg-scm") || "";
|
|
14823
|
+
const m = scm.match(/cid=([^&]+)/);
|
|
14824
|
+
return m?.[1] ?? null;
|
|
14825
|
+
}
|
|
14826
|
+
function sweepExtraSections($2) {
|
|
14827
|
+
const sections = [];
|
|
14828
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14829
|
+
$2('[id^="resume-detail-"], [class*="resume-detail-"]').each((_i, el) => {
|
|
14830
|
+
const $el = $2(el);
|
|
14831
|
+
const id = $el.attr("id") || "";
|
|
14832
|
+
const cls = ($el.attr("class") || "").split(/\s+/).find((c) => c.startsWith("resume-detail-") && c !== "resume-detail-template" && c !== "resume-detail-template-cont") || "";
|
|
14833
|
+
const key = (id || cls).replace(/^resume-detail-/, "");
|
|
14834
|
+
if (!key || seen.has(key))
|
|
14835
|
+
return;
|
|
14836
|
+
const isSection = $el.find(".resume-detail-template-cont").length > 0 || $el.parents('[id^="resume-detail-"], [class*="resume-detail-"]').length === 0;
|
|
14837
|
+
if (!isSection)
|
|
14838
|
+
return;
|
|
14839
|
+
seen.add(key);
|
|
14840
|
+
if (LIEPIN_CONSUMED_SECTION_KEYS.has(key))
|
|
14841
|
+
return;
|
|
14842
|
+
const text3 = clean($el.text());
|
|
14843
|
+
if (!text3)
|
|
14844
|
+
return;
|
|
14845
|
+
const title = clean($el.find(".resume-detail-template-title, .template-title").first().text()) ?? clean($el.find("h3, h4").first().text());
|
|
14846
|
+
sections.push({ key, title, text: text3.length > 2e3 ? `${text3.slice(0, 2e3)}\u2026` : text3 });
|
|
14847
|
+
});
|
|
14848
|
+
return sections;
|
|
14849
|
+
}
|
|
14850
|
+
function extractLiepinTalent(html3) {
|
|
14851
|
+
const $2 = typeof html3 === "string" ? load(html3) : html3;
|
|
14852
|
+
const isTalentPage = $2("#resume-detail-basic-info, .resume-detail-basic-info").length > 0;
|
|
14853
|
+
if (!isTalentPage)
|
|
14854
|
+
return { platform: "liepin", pageType: "unknown" };
|
|
14855
|
+
const languages = $2("#resume-detail-lang-info .rd-lang-item .lang-name, .resume-detail-lang-info .rd-lang-item .lang-name").toArray().map((el) => clean($2(el).text())).filter(Boolean);
|
|
14856
|
+
const skills = $2("#resume-detail-skill-info .skill-tag, .resume-detail-skill-info .skill-tag").toArray().map((el) => clean($2(el).text())).filter(Boolean);
|
|
14857
|
+
const basic = extractBasic($2);
|
|
14858
|
+
const workExperiences = extractWorkExperiences($2);
|
|
14859
|
+
const projects = extractProjects($2);
|
|
14860
|
+
const education = extractEducation($2);
|
|
14861
|
+
const extraSections = sweepExtraSections($2);
|
|
14862
|
+
return {
|
|
14863
|
+
platform: "liepin",
|
|
14864
|
+
pageType: "talent",
|
|
14865
|
+
resId: extractResId($2),
|
|
14866
|
+
...basic,
|
|
14867
|
+
intent: extractIntent($2),
|
|
14868
|
+
workExperiences,
|
|
14869
|
+
projects,
|
|
14870
|
+
education,
|
|
14871
|
+
languages,
|
|
14872
|
+
skills,
|
|
14873
|
+
selfEvaluation: clean($2("#resume-detail-self-eva-info .resume-detail-template-cont").first().text()) ?? clean($2(".resume-detail-self-evaluation-info").first().text()),
|
|
14874
|
+
statement: clean($2(".c-detail-statement").first().text()),
|
|
14875
|
+
hasAntiScrapeWatermark: $2(".cozue").length > 0,
|
|
14876
|
+
...extraSections.length ? { extra: { sections: extraSections } } : {},
|
|
14877
|
+
_counts: {
|
|
14878
|
+
workExperiences: workExperiences.length,
|
|
14879
|
+
projects: projects.length,
|
|
14880
|
+
education: education.length,
|
|
14881
|
+
languages: languages.length,
|
|
14882
|
+
skills: skills.length,
|
|
14883
|
+
extraSections: extraSections.length
|
|
14884
|
+
}
|
|
14885
|
+
};
|
|
14886
|
+
}
|
|
14887
|
+
|
|
14888
|
+
// dist/.server-tsc/extraction/script-rule.js
|
|
14889
|
+
function readField($2, root3, rule) {
|
|
14890
|
+
const el = rule.self ? root3.first() : root3.find(rule.selector).first();
|
|
14891
|
+
if (!el.length)
|
|
14892
|
+
return null;
|
|
14893
|
+
let value;
|
|
14894
|
+
if (!rule.attr || rule.attr === "text")
|
|
14895
|
+
value = el.text().trim();
|
|
14896
|
+
else if (rule.attr === "html")
|
|
14897
|
+
value = el.html();
|
|
14898
|
+
else
|
|
14899
|
+
value = el.attr(rule.attr) ?? null;
|
|
14900
|
+
if (value == null)
|
|
14901
|
+
return null;
|
|
14902
|
+
if (rule.regex) {
|
|
14903
|
+
const m = value.match(new RegExp(rule.regex, "s"));
|
|
14904
|
+
value = m?.[1]?.trim() ?? null;
|
|
14905
|
+
}
|
|
14906
|
+
return value || null;
|
|
14907
|
+
}
|
|
14908
|
+
function toCheerio(html3) {
|
|
14909
|
+
return typeof html3 === "string" ? load(html3) : html3;
|
|
14910
|
+
}
|
|
14911
|
+
function applyScriptRule(html3, payload) {
|
|
14912
|
+
if (payload.engine === "linkedin-profile") {
|
|
14913
|
+
return extractLinkedInProfile(html3);
|
|
14914
|
+
}
|
|
14915
|
+
if (payload.engine === "liepin-talent") {
|
|
14916
|
+
return extractLiepinTalent(html3);
|
|
14917
|
+
}
|
|
14918
|
+
const $2 = toCheerio(html3);
|
|
14919
|
+
const out = {};
|
|
14920
|
+
for (const [field, rule] of Object.entries(payload.fields || {})) {
|
|
14921
|
+
out[field] = readField($2, $2("body").length ? $2("body") : $2.root(), rule);
|
|
14922
|
+
}
|
|
14923
|
+
for (const [listName, listRule] of Object.entries(payload.lists || {})) {
|
|
14924
|
+
const items = [];
|
|
14925
|
+
$2(listRule.selector).each((_i, el) => {
|
|
14926
|
+
const item = {};
|
|
14927
|
+
for (const [field, rule] of Object.entries(listRule.fields)) {
|
|
14928
|
+
item[field] = readField($2, $2(el), rule);
|
|
14929
|
+
}
|
|
14930
|
+
if (Object.values(item).some((v) => v != null))
|
|
14931
|
+
items.push(item);
|
|
14932
|
+
});
|
|
14933
|
+
if (items.length) {
|
|
14934
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14935
|
+
out[listName] = items.filter((item) => {
|
|
14936
|
+
const key = JSON.stringify(item, Object.keys(item).sort());
|
|
14937
|
+
if (seen.has(key))
|
|
14938
|
+
return false;
|
|
14939
|
+
seen.add(key);
|
|
14940
|
+
return true;
|
|
14941
|
+
});
|
|
14942
|
+
}
|
|
14943
|
+
}
|
|
14944
|
+
if (payload.entityList) {
|
|
14945
|
+
const items = [];
|
|
14946
|
+
$2(payload.entityList.selector).each((_i, el) => {
|
|
14947
|
+
const item = {};
|
|
14948
|
+
for (const [field, rule] of Object.entries(payload.entityList.fields)) {
|
|
14949
|
+
item[field] = readField($2, $2(el), rule);
|
|
14950
|
+
}
|
|
14951
|
+
if (Object.values(item).some((v) => v != null))
|
|
14952
|
+
items.push(item);
|
|
14953
|
+
});
|
|
14954
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14955
|
+
out.__entityList = items.filter((item) => {
|
|
14956
|
+
const key = JSON.stringify(item, Object.keys(item).sort());
|
|
14957
|
+
if (seen.has(key))
|
|
14958
|
+
return false;
|
|
14959
|
+
seen.add(key);
|
|
14960
|
+
return true;
|
|
14961
|
+
});
|
|
14962
|
+
}
|
|
14963
|
+
return out;
|
|
14964
|
+
}
|
|
14965
|
+
|
|
14411
14966
|
export {
|
|
14412
|
-
html,
|
|
14413
|
-
xml,
|
|
14414
|
-
text,
|
|
14415
14967
|
load,
|
|
14416
|
-
|
|
14417
|
-
contains2 as contains,
|
|
14418
|
-
merge2 as merge,
|
|
14419
|
-
parseHTML2 as parseHTML,
|
|
14420
|
-
root2 as root
|
|
14968
|
+
applyScriptRule
|
|
14421
14969
|
};
|
|
@@ -6,8 +6,7 @@ const __filename = __f2p(import.meta.url);
|
|
|
6
6
|
const __dirname = __dirnameFn(__filename);
|
|
7
7
|
import {
|
|
8
8
|
applyScriptRule
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-SAJB6JRK.mjs";
|
|
9
|
+
} from "./chunk-VL7WHUEV.mjs";
|
|
11
10
|
import "./chunk-GNM26E3H.mjs";
|
|
12
11
|
export {
|
|
13
12
|
applyScriptRule
|