From 6a083b045f871e6cce7b715dad0d7b00d9c88e16 Mon Sep 17 00:00:00 2001 From: bengarvey Date: Sun, 20 Oct 2024 22:39:16 -0400 Subject: [PATCH] updated linter settings --- .eslintrc.json | 1 + .github/workflows/eslint.yml | 2 +- package.json | 4 +- scripts/famgen.js | 255 ++++++++++++++++++----------------- 4 files changed, 132 insertions(+), 130 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index f5add18..3a0162b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -9,6 +9,7 @@ "sourceType": "module" }, "plugins": ["html"], + "extends": ["airbnb"], "rules": { "no-unused-expressions": ["error", { "allowTernary": true }], "no-use-before-define": ["error", { "functions": false, "classes": true, "variables": true }], diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml index ce0c03f..1027a25 100644 --- a/.github/workflows/eslint.yml +++ b/.github/workflows/eslint.yml @@ -13,4 +13,4 @@ jobs: run: npm install - name: Run ESLint - run: npx eslint js/lineage.js index.html \ No newline at end of file + run: npx eslint js/lineage.js index.html scripts/famgen.js diff --git a/package.json b/package.json index ed1ba35..4890e5e 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,6 @@ "eslint-plugin-airbnb-base": "^0.0.1-security", "eslint-plugin-html": "^8.1.2", "eslint-plugin-import": "^2.31.0", - "eslint-plugin-jsx-a11y": "^6.10.0", - "eslint-plugin-react": "^7.37.1", - "eslint-plugin-react-hooks": "^4.6.2" + "eslint-plugin-jsx-a11y": "^6.10.0" } } diff --git a/scripts/famgen.js b/scripts/famgen.js index 1f35132..8f80046 100644 --- a/scripts/famgen.js +++ b/scripts/famgen.js @@ -1,11 +1,12 @@ const Chance = require('chance'); + const chance = new Chance(); // Constants const TOTAL_NODES = 10; // This is the number we start with, but we'll end up with more when we add spouses/kids const MAX_CHILDREN = 5; // Max children per family const MIN_CHILDREN = 0; // Min children per family -const GENDER_NEUTRAL_NAMES = [ +const GENDER_NEUTRAL_NAMES = [ 'Alex', 'Jordan', 'Taylor', 'Casey', 'Morgan', 'Riley', 'Avery', 'Quinn', 'Cameron', 'Peyton', 'Rowan', 'Sawyer', 'Charlie', 'Skyler', 'Dakota', 'Emerson', 'Finley', 'Harper', 'Phoenix', 'River', 'Bailey', 'Ellis', 'Hayden', 'Jesse', 'Marlowe', 'Shawn', 'Tatum', 'Addison', 'Ash', 'Blake', @@ -50,73 +51,73 @@ const GENDER_NEUTRAL_NAMES = [ 'Otto', 'Pace', 'Paxton', 'Rafe', 'Raleigh', 'Ranger', 'Ren', 'Rio', 'Roux', 'Ryker', 'Sequoia', 'Shai', 'Shane', 'Sonny', 'Sorren', 'Stone', 'Taj', 'Tanis', 'Taran', 'Tesla', 'Tobiah', 'Tobin', 'Torren', 'Trace', 'Trey', 'Tully', 'Wade', 'Wayne', 'Weston', 'Xander', - 'York', 'Zeppelin', 'Zion', 'Ziv' + 'York', 'Zeppelin', 'Zion', 'Ziv', ]; const NON_BINARY_PERCENTAGE = 0.03; // 3% const SAME_SEX_PERCENTAGE = 0.05; // 5% -let nodes = []; -let links = []; +const nodes = []; +const links = []; let currentId = 0; // Keep track of sibling groups to prevent sibling marriages -let siblingGroups = []; +const siblingGroups = []; // Helper Functions const getRandomBirthDeathDates = () => { - const birthYear = parseInt(chance.year({ min: 1900, max: 2000 }), 10); - const minDeathYear = birthYear + 20; - const maxDeathYear = Math.min(minDeathYear + 80, 2100); + const birthYear = parseInt(chance.year({ min: 1900, max: 2000 }), 10); + const minDeathYear = birthYear + 20; + const maxDeathYear = Math.min(minDeathYear + 80, 2100); - const deathYear = parseInt(chance.year({ min: minDeathYear, max: maxDeathYear }), 10); + const deathYear = parseInt(chance.year({ min: minDeathYear, max: maxDeathYear }), 10); - const birthMonth = chance.integer({ min: 0, max: 11 }); - const birthDay = chance.integer({ min: 1, max: 28 }); - const deathMonth = chance.integer({ min: 0, max: 11 }); - const deathDay = chance.integer({ min: 1, max: 28 }); + const birthMonth = chance.integer({ min: 0, max: 11 }); + const birthDay = chance.integer({ min: 1, max: 28 }); + const deathMonth = chance.integer({ min: 0, max: 11 }); + const deathDay = chance.integer({ min: 1, max: 28 }); - const birthDate = new Date(birthYear, birthMonth, birthDay); - const deathDate = new Date(deathYear, deathMonth, deathDay); + const birthDate = new Date(birthYear, birthMonth, birthDay); + const deathDate = new Date(deathYear, deathMonth, deathDay); - if (isNaN(birthDate.getTime()) || isNaN(deathDate.getTime())) { - throw new Error('Invalid date generated'); - } + if (Number.isNaN(birthDate.getTime()) || Number.isNaN(deathDate.getTime())) { + throw new Error('Invalid date generated'); + } - return { birthDate, deathDate }; + return { birthDate, deathDate }; }; const createNode = (gender) => { - const isNonBinary = Math.random() < NON_BINARY_PERCENTAGE; - let name; - - if (isNonBinary || gender === 'non-binary') { - name = chance.pickone(GENDER_NEUTRAL_NAMES); - } else { - name = chance.first({ gender: gender.toLowerCase() }); - } - - const { birthDate, deathDate } = getRandomBirthDeathDates(); - - const node = { - id: currentId++, - name, - gender: isNonBinary ? 'non-binary' : gender, - lastName: chance.last(), - birthDate: birthDate.toISOString(), - deathDate: deathDate.toISOString() - }; - - nodes.push(node); - return node; + const isNonBinary = Math.random() < NON_BINARY_PERCENTAGE; + let name; + + if (isNonBinary || gender === 'non-binary') { + name = chance.pickone(GENDER_NEUTRAL_NAMES); + } else { + name = chance.first({ gender: gender.toLowerCase() }); + } + + const { birthDate, deathDate } = getRandomBirthDeathDates(); + currentId += 1; + const node = { + id: currentId, + name, + gender: isNonBinary ? 'non-binary' : gender, + lastName: chance.last(), + birthDate: birthDate.toISOString(), + deathDate: deathDate.toISOString(), + }; + + nodes.push(node); + return node; }; const createLink = (sourceId, targetId, relation, color) => { - links.push({ - source: sourceId, - target: targetId, - relation, - color - }); + links.push({ + source: sourceId, + target: targetId, + relation, + color, + }); }; const getParentType = (gender) => { @@ -126,76 +127,59 @@ const getParentType = (gender) => { }; const createFamilyTree = (parent1, parent2, generation = 1) => { - const numChildren = chance.integer({ min: MIN_CHILDREN, max: MAX_CHILDREN }); - const siblingGroup = []; + const numChildren = chance.integer({ min: MIN_CHILDREN, max: MAX_CHILDREN }); + const siblingGroup = []; - for (let i = 0; i < numChildren; i++) { - const childGender = chance.gender(); - const child = createNode(childGender); + for (let i = 0; i < numChildren; i += 1) { + const childGender = chance.gender(); + const child = createNode(childGender); - // Inherit last name - child.lastName = chance.pickone([parent1.lastName, parent2.lastName]); + // Inherit last name + child.lastName = chance.pickone([parent1.lastName, parent2.lastName]); - // Add child to sibling group - siblingGroup.push(child.id); + // Add child to sibling group + siblingGroup.push(child.id); - // Color parent-child links based on gender of the parent - let parent1Color = parent1.gender === 'Male' ? '#0000FF' : (parent1.gender === 'Female' ? '#FFC0CB' : '#800080'); - let parent2Color = parent2.gender === 'Male' ? '#0000FF' : (parent2.gender === 'Female' ? '#FFC0CB' : '#800080'); + // Color parent-child links based on gender of the parent + // eslint-disable-next-line no-nested-ternary + const parent1Color = parent1.gender === 'Male' ? '#0000FF' : (parent1.gender === 'Female' ? '#FFC0CB' : '#800080'); + // eslint-disable-next-line no-nested-ternary + const parent2Color = parent2.gender === 'Male' ? '#0000FF' : (parent2.gender === 'Female' ? '#FFC0CB' : '#800080'); - // Create parent-child links with appropriate colors - createLink(parent1.id, child.id, getParentType(parent1.gender), parent1Color); - createLink(parent2.id, child.id, getParentType(parent2.gender), parent2Color); + // Create parent-child links with appropriate colors + createLink(parent1.id, child.id, getParentType(parent1.gender), parent1Color); + createLink(parent2.id, child.id, getParentType(parent2.gender), parent2Color); - // Recursively generate more families - if (generation < 3) { - let spouseGender = chance.gender(); - let isSameSexCouple = Math.random() < SAME_SEX_PERCENTAGE; + // Recursively generate more families + if (generation < 3) { + let spouseGender = chance.gender(); + const isSameSexCouple = Math.random() < SAME_SEX_PERCENTAGE; - // For same-sex couple, spouse gender matches the child gender - if (isSameSexCouple) spouseGender = child.gender; + // For same-sex couple, spouse gender matches the child gender + if (isSameSexCouple) spouseGender = child.gender; - const spouse = createNode(spouseGender); - createLink(child.id, spouse.id, 'spouse', '#cc0'); + const spouse = createNode(spouseGender); + createLink(child.id, spouse.id, 'spouse', '#cc0'); - createFamilyTree(child, spouse, generation + 1); - } + createFamilyTree(child, spouse, generation + 1); } + } - // Add sibling group to the siblingGroups list - if (siblingGroup.length > 1) { - siblingGroups.push(siblingGroup); - } + // Add sibling group to the siblingGroups list + if (siblingGroup.length > 1) { + siblingGroups.push(siblingGroup); + } }; // Ensure no siblings marry by checking against sibling groups const isValidMarriage = (person1Id, person2Id) => { - for (const group of siblingGroups) { - if (group.includes(person1Id) && group.includes(person2Id)) { - return false; // They are siblings - } - } - return true; // Not siblings -}; - -const linkUnlinkedDescendants = () => { - const unlinked = findUnlinkedDescendants(); - - chance.shuffle(unlinked); - - // Pair up unlinked descendants and create spouse relationships - for (let i = 0; i < unlinked.length - 1; i += 2) { - const descendant1 = unlinked[i]; - const descendant2 = unlinked[i + 1]; - - if (isValidMarriage(descendant1.id, descendant2.id)) { - // Create a spousal link between them - createLink(descendant1.id, descendant2.id, 'spouse', '#cc0'); - - // Generate children for the newly formed couple - createFamilyTree(descendant1, descendant2); - } + // eslint-disable-next-line no-restricted-syntax + for (const group of siblingGroups) { + if (group.includes(person1Id) && group.includes(person2Id)) { + return false; // They are siblings } + } + return true; // Not siblings }; const findUnlinkedDescendants = () => { @@ -203,44 +187,63 @@ const findUnlinkedDescendants = () => { const linked = new Set(); // Traverse through all links and mark linked individuals as 'spouses' - links.forEach(link => { - if (link.relation === 'spouse') { - linked.add(link.source); - linked.add(link.target); - } + links.forEach((link) => { + if (link.relation === 'spouse') { + linked.add(link.source); + linked.add(link.target); + } }); // Find nodes that are not linked as a spouse - nodes.forEach(node => { - if (!linked.has(node.id)) { - unlinked.push(node); - } + nodes.forEach((node) => { + if (!linked.has(node.id)) { + unlinked.push(node); + } }); return unlinked; }; +const linkUnlinkedDescendants = () => { + const unlinked = findUnlinkedDescendants(); + + chance.shuffle(unlinked); + + // Pair up unlinked descendants and create spouse relationships + for (let i = 0; i < unlinked.length - 1; i += 2) { + const descendant1 = unlinked[i]; + const descendant2 = unlinked[i + 1]; + + if (isValidMarriage(descendant1.id, descendant2.id)) { + // Create a spousal link between them + createLink(descendant1.id, descendant2.id, 'spouse', '#cc0'); + + // Generate children for the newly formed couple + createFamilyTree(descendant1, descendant2); + } + } +}; // Create initial family const createInitialFamilies = () => { - const numFamilies = TOTAL_NODES / (MAX_CHILDREN + 2); // Estimate - for (let i = 0; i < numFamilies; i++) { - const parent1Gender = chance.gender(); - let parent2Gender = chance.gender(); + const numFamilies = TOTAL_NODES / (MAX_CHILDREN + 2); // Estimate + for (let i = 0; i < numFamilies; i += 1) { + const parent1Gender = chance.gender(); + let parent2Gender = chance.gender(); - // Same-sex couple logic - let isSameSexCouple = Math.random() < SAME_SEX_PERCENTAGE; - if (isSameSexCouple) parent2Gender = parent1Gender; + // Same-sex couple logic + const isSameSexCouple = Math.random() < SAME_SEX_PERCENTAGE; + if (isSameSexCouple) parent2Gender = parent1Gender; - const parent1 = createNode(parent1Gender); - const parent2 = createNode(parent2Gender); + const parent1 = createNode(parent1Gender); + const parent2 = createNode(parent2Gender); - // Link parents as spouses - createLink(parent1.id, parent2.id, 'spouse', '#cc0'); + // Link parents as spouses + createLink(parent1.id, parent2.id, 'spouse', '#cc0'); - // Create their family - createFamilyTree(parent1, parent2); - } + // Create their family + createFamilyTree(parent1, parent2); + } }; // Run the generator @@ -248,8 +251,8 @@ createInitialFamilies(); linkUnlinkedDescendants(); const dataset = { - nodes, - links + nodes, + links, }; // Output the dataset (or write to a file)