# 🗂 NPC Influence Dashboard

> Scale: −10 … 0 … +10 (0 = Neutral; positive = more influential, negative = less)

---

## 😡 Hostile (−10 to −7)
```dataview
TABLE link(file.name) AS NPC, Faction, Level_of_Influence
FROM "NPCs"
WHERE Level_of_Influence <= -7
SORT Level_of_Influence ASC
```

## 😕 Unfriendly (-6 to -1)
```dataview
TABLE link(file.name) AS NPC, Faction, Level_of_Influence
FROM "NPCs"
WHERE Level_of_Influence >= -6 AND Level_of_Influence <= -1
SORT Level_of_Influence ASC
```

## 😐 Neutral (0)
```dataview
TABLE link(file.name) AS NPC, Faction, Level_of_Influence
FROM "NPCs"
WHERE Level_of_Influence = 0
SORT file.name ASC
```

## 🙂 Friendly (+1 to +6)
```dataview
TABLE link(file.name) AS NPC, Faction, Level_of_Influence
FROM "NPCs"
WHERE Level_of_Influence >= 1 AND Level_of_Influence <= 6
SORT Level_of_Influence DESC
```

## 🛡 Allied (+7 to +10)
```dataview
TABLE link(file.name) AS NPC, Faction, Level_of_Influence
FROM "NPCs"
WHERE Level_of_Influence >= 7
SORT Level_of_Influence DESC
```

## 📊 Visual Bands (Emoji + Bipolar Progress Bars)
```dataview
// ===== Settings =====
const FOLDER = "NPCs";
const MAX = 10; // absolute max in either direction

// ===== Helpers =====
const tier = s =>
  s === 0 ? "Neutral" :
  s < 0   ? (s <= -7 ? "Hostile" : "Unfriendly") :
            (s >= 7  ? "Allied"  : "Friendly");

const face = s =>
  s === 0 ? "😐" :
  s < 0   ? (s <= -7 ? "😡" : "😕") :
            (s >= 7  ? "🛡️" : "🙂");

// Bipolar bar: [LLLLL|RRRRR]
function bipolarBar(score) {
  const leftFilled  = Math.min(MAX, Math.max(0, -score));
  const rightFilled = Math.min(MAX, Math.max(0,  score));
  const leftEmpty   = MAX - leftFilled;
  const rightEmpty  = MAX - rightFilled;
  const L = "█".repeat(leftFilled) + "░".repeat(leftEmpty);
  const R = "█".repeat(rightFilled) + "░".repeat(rightEmpty);
  return `[${L}|${R}]`;
}

// ===== Fetch =====
const pages = dv.pages(`"${FOLDER}"`)
  .where(p => Number.isFinite(+p.Level_of_Influence))
  .map(p => ({
    name: p.file.link,
    faction: p.Faction ?? "",
    score: +p.Level_of_Influence
  }));

const groups = {
  "😡 Hostile (−10 to −7)":   pages.filter(p => p.score <= -7).sort((a,b)=>a.score-b.score),
  "😕 Unfriendly (−6 to −1)": pages.filter(p => p.score >= -6 && p.score <= -1).sort((a,b)=>a.score-b.score),
  "😐 Neutral (0)":           pages.filter(p => p.score === 0).sort((a,b)=>String(a.name).localeCompare(String(b.name))),
  "🙂 Friendly (+1 to +6)":   pages.filter(p => p.score >= 1 && p.score <= 6).sort((a,b)=>b.score-a.score),
  "🛡 Allied (+7 to +10)":    pages.filter(p => p.score >= 7).sort((a,b)=>b.score-a.score),
};

for (const [title, rows] of Object.entries(groups)) {
  dv.header(2, title);
  if (!rows.length) { dv.paragraph("_None yet._"); continue; }
  dv.table(
    ["NPC", "Faction", "Score", "Bar", "Tier"],
    rows.map(r => [r.name, r.faction, r.score, bipolarBar(r.score), `${face(r.score)} ${tier(r.score)}`])
  );
}
```