<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Adom Basic Parts Library</title>
<style>
  :root {
    --bg: #0d1117;
    --surface: #161b22;
    --border: #30363d;
    --text: #e6edf3;
    --text-muted: #8b949e;
    --accent: #58a6ff;
    --accent-dim: #1f6feb33;
    --green: #3fb950;
    --orange: #d29922;
    --red: #f85149;
    --row-hover: #1c2128;
  }
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
    background: var(--bg);
    color: var(--text);
    font-size: 13px;
    line-height: 1.5;
  }
  .header {
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 16px 24px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: sticky;
    top: 0;
    z-index: 100;
  }
  .header h1 {
    font-size: 18px;
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 10px;
  }
  .header h1 .count {
    font-size: 12px;
    font-weight: 400;
    color: var(--text-muted);
    background: var(--border);
    padding: 2px 8px;
    border-radius: 10px;
  }
  .toolbar {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
  }
  .search-box {
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 6px 12px;
    border-radius: 6px;
    font-size: 13px;
    width: 240px;
    outline: none;
  }
  .search-box:focus { border-color: var(--accent); }
  .filter-btn {
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text-muted);
    padding: 6px 12px;
    border-radius: 6px;
    font-size: 12px;
    cursor: pointer;
    transition: all 0.15s;
  }
  .filter-btn:hover { border-color: var(--accent); color: var(--text); }
  .filter-btn.active {
    background: var(--accent-dim);
    border-color: var(--accent);
    color: var(--accent);
  }
  .action-btn {
    background: var(--accent);
    border: none;
    color: #fff;
    padding: 6px 14px;
    border-radius: 6px;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    transition: opacity 0.15s;
  }
  .action-btn:hover { opacity: 0.85; }
  .action-btn.secondary {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-muted);
  }
  .action-btn.secondary:hover { border-color: var(--accent); color: var(--text); }
  .action-btn.danger { background: var(--red); }

  .container { padding: 0; }

  table {
    width: 100%;
    border-collapse: collapse;
    table-layout: auto;
  }
  thead {
    position: sticky;
    top: 57px;
    z-index: 50;
  }
  th {
    background: var(--surface);
    border-bottom: 2px solid var(--border);
    padding: 8px 10px;
    text-align: left;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted);
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
  }
  th:hover { color: var(--text); }
  th .sort-arrow { font-size: 10px; margin-left: 3px; }
  td {
    padding: 6px 10px;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
    max-width: 200px;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  tr:hover td { background: var(--row-hover); }
  tr.editing td { background: var(--accent-dim); }

  .type-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 500;
  }
  .type-resistor { background: #1a3a2a; color: #3fb950; }
  .type-capacitor { background: #2a2a1a; color: #d29922; }
  .type-inductor { background: #1a2a3a; color: #58a6ff; }
  .type-led { background: #3a1a2a; color: #f778ba; }
  .type-ferrite { background: #2a1a3a; color: #bc8cff; }

  .pkg-badge {
    display: inline-block;
    padding: 1px 6px;
    border-radius: 4px;
    font-size: 11px;
    background: var(--border);
    color: var(--text-muted);
  }

  .editable {
    cursor: text;
    border-radius: 3px;
    padding: 1px 4px;
    margin: -1px -4px;
  }
  .editable:hover { background: rgba(255,255,255,0.05); }
  .editable:focus {
    outline: 2px solid var(--accent);
    background: var(--bg);
  }

  .mouser-link {
    color: var(--accent);
    text-decoration: none;
  }
  .mouser-link:hover { text-decoration: underline; }

  .notes-cell {
    color: var(--orange);
    font-style: italic;
    font-size: 11px;
  }

  .section-sep td {
    background: var(--surface);
    padding: 4px 10px;
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
  }
  .section-sep:hover td { background: var(--surface); }

  .empty-state {
    text-align: center;
    padding: 60px 20px;
    color: var(--text-muted);
  }

  /* Modal */
  .modal-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.6);
    z-index: 200;
    justify-content: center;
    align-items: center;
  }
  .modal-overlay.open { display: flex; }
  .modal {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 24px;
    width: 600px;
    max-height: 80vh;
    overflow-y: auto;
  }
  .modal h2 { font-size: 16px; margin-bottom: 16px; }
  .modal label {
    display: block;
    font-size: 12px;
    color: var(--text-muted);
    margin-bottom: 4px;
    margin-top: 12px;
  }
  .modal input, .modal select {
    width: 100%;
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 8px 12px;
    border-radius: 6px;
    font-size: 13px;
    outline: none;
  }
  .modal input:focus, .modal select:focus { border-color: var(--accent); }
  .modal .btn-row {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    margin-top: 20px;
  }

  .toast {
    position: fixed;
    bottom: 20px;
    right: 20px;
    background: var(--green);
    color: #fff;
    padding: 10px 20px;
    border-radius: 8px;
    font-size: 13px;
    font-weight: 500;
    opacity: 0;
    transform: translateY(10px);
    transition: all 0.3s;
    z-index: 300;
  }
  .toast.show { opacity: 1; transform: translateY(0); }

  .stats-bar {
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 8px 24px;
    display: flex;
    gap: 24px;
    font-size: 12px;
    color: var(--text-muted);
  }
  .stats-bar span strong { color: var(--text); }
</style>
</head>
<body>

<div class="header">
  <h1>Adom Basic Parts Library <span class="count" id="partCount">0 parts</span></h1>
  <div class="toolbar">
    <input type="text" class="search-box" id="searchBox" placeholder="Search parts...">
    <div id="filterBtns"></div>
    <button class="action-btn secondary" onclick="exportJSON()">Export JSON</button>
    <button class="action-btn secondary" onclick="exportCSV()">Export CSV</button>
    <button class="action-btn" onclick="openAddModal()">+ Add Part</button>
  </div>
</div>

<div class="stats-bar" id="statsBar"></div>

<div class="container">
  <table>
    <thead>
      <tr>
        <th data-col="type">Type <span class="sort-arrow"></span></th>
        <th data-col="value">Value <span class="sort-arrow"></span></th>
        <th data-col="package">Package <span class="sort-arrow"></span></th>
        <th data-col="tolerance">Tol. <span class="sort-arrow"></span></th>
        <th data-col="material">Material <span class="sort-arrow"></span></th>
        <th data-col="manufacturer">Mfr <span class="sort-arrow"></span></th>
        <th data-col="description">Description <span class="sort-arrow"></span></th>
        <th data-col="mouserPN">Mouser PN</th>
        <th data-col="mfrPN">Mfr PN <span class="sort-arrow"></span></th>
        <th data-col="price">Price/Reel <span class="sort-arrow"></span></th>
        <th data-col="notes">Notes</th>
        <th>Actions</th>
      </tr>
    </thead>
    <tbody id="partsBody"></tbody>
  </table>
  <div class="empty-state" id="emptyState" style="display:none">No parts match your search.</div>
</div>

<!-- Add/Edit Modal -->
<div class="modal-overlay" id="modalOverlay" onclick="if(event.target===this)closeModal()">
  <div class="modal">
    <h2 id="modalTitle">Add Part</h2>
    <input type="hidden" id="editId">
    <label>Type</label>
    <select id="fType">
      <option>Resistor</option>
      <option>Multilayer Ceramic Capacitors</option>
      <option>Inductor</option>
      <option>LED</option>
      <option>Ferrite Bead</option>
    </select>
    <div style="display:grid;grid-template-columns:1fr 1fr;gap:0 16px;">
      <div><label>Value</label><input id="fValue" placeholder="e.g. 10kOhm"></div>
      <div><label>Package</label><input id="fPackage" placeholder="e.g. 0402"></div>
      <div><label>Tolerance</label><input id="fTolerance" placeholder="e.g. 0.01"></div>
      <div><label>Material</label><input id="fMaterial" placeholder="e.g. C0G, X7R"></div>
      <div><label>Manufacturer</label><input id="fManufacturer" placeholder="e.g. Bourns"></div>
      <div><label>Description</label><input id="fDescription" placeholder="e.g. 50V; 62.5mW"></div>
      <div><label>Mouser Part #</label><input id="fMouserPN" placeholder="e.g. 652-CR0402FX-1002GLF"></div>
      <div><label>Manufacturer Part #</label><input id="fMfrPN" placeholder="e.g. CR0402-FX-1002GLF"></div>
      <div><label>Price Per Reel</label><input id="fPrice" placeholder="e.g. $10/10,000"></div>
      <div><label>Notes</label><input id="fNotes" placeholder="Optional notes"></div>
    </div>
    <div class="btn-row">
      <button class="action-btn secondary" onclick="closeModal()">Cancel</button>
      <button class="action-btn danger" id="deleteBtn" onclick="deletePart()" style="display:none">Delete</button>
      <button class="action-btn" onclick="savePart()">Save</button>
    </div>
  </div>
</div>

<div class="toast" id="toast"></div>

<script>
// --- Data ---
let parts = [];
let sortCol = 'type';
let sortDir = 1;
let activeFilter = null;
let searchTerm = '';

const DATA_URL = 'basic-parts-data.json';

async function loadData() {
  parts = [{"id": 1, "type": "Resistor", "value": "0\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "50V; 62.5mW; 200PPM/C", "mouserPN": "303-CQ02WGF0000TCE", "mfrPN": "CQ02WGF0000TCE", "price": "$10/10,000", "notes": ""}, {"id": 2, "type": "Resistor", "value": "1\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "50V; 62.5mW; 200PPM/C", "mouserPN": "303-CQ02WGF100KTCE", "mfrPN": "CQ02WGF100KTCE", "price": "$10/10,000", "notes": ""}, {"id": 3, "type": "Resistor", "value": "1.5\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "50V; 62.5mW; 200PPM/C", "mouserPN": "303-CQ02WGF150KTCE", "mfrPN": "CQ02WGF150KTCE", "price": "$10/10,000", "notes": ""}, {"id": 4, "type": "Resistor", "value": "2.2\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "50V; 62.5mW; 200PPM/C", "mouserPN": "303-CQ02WGF220KTCE", "mfrPN": "CQ02WGF220KTCE", "price": "$10/10,000", "notes": ""}, {"id": 5, "type": "Resistor", "value": "3.3\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "50V; 62.5mW; 200PPM/C", "mouserPN": "303-CQ02WGF330KTCE", "mfrPN": "CQ02WGF330KTCE", "price": "$10/10,000", "notes": ""}, {"id": 6, "type": "Resistor", "value": "4.7\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "50V; 62.5mW; 200PPM/C", "mouserPN": "303-CQ02WGF470KTCE", "mfrPN": "CQ02WGF470KTCE", "price": "$10/10,000", "notes": ""}, {"id": 7, "type": "Resistor", "value": "6.8\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "50V; 62.5mW; 200PPM/C", "mouserPN": "303-CQ02WGF680KTCE", "mfrPN": "CQ02WGF680KTCE", "price": "$10/10,000", "notes": ""}, {"id": 8, "type": "Resistor", "value": "10\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-10R0GLF", "mfrPN": "CR0402-FX-10R0GLF", "price": "$20/10,000", "notes": ""}, {"id": 9, "type": "Resistor", "value": "15\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-15R0GLF", "mfrPN": "CR0402-FX-15R0GLF", "price": "$10/10,000", "notes": ""}, {"id": 10, "type": "Resistor", "value": "22\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-22R0GLF", "mfrPN": "CR0402-FX-22R0GLF", "price": "$10/10,000", "notes": ""}, {"id": 11, "type": "Resistor", "value": "33\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-33R0GLF", "mfrPN": "CR0402-FX-33R0GLF", "price": "$10/10,000", "notes": "ON ORDER"}, {"id": 12, "type": "Resistor", "value": "47\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-47R0GLF", "mfrPN": "CR0402-FX-47R0GLF", "price": "$10/10,000", "notes": ""}, {"id": 13, "type": "Resistor", "value": "68\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-68R0GLF", "mfrPN": "CR0402-FX-68R0GLF", "price": "$10/10,000", "notes": ""}, {"id": 14, "type": "Resistor", "value": "100\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-1000GLF", "mfrPN": "CR0402-FX-1000GLF", "price": "$10/10,000", "notes": ""}, {"id": 15, "type": "Resistor", "value": "150\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-1500GLF", "mfrPN": "CR0402-FX-1500GLF", "price": "$10/10,000", "notes": ""}, {"id": 16, "type": "Resistor", "value": "220\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-2200GLF", "mfrPN": "CR0402-FX-2200GLF", "price": "$10/10,000", "notes": ""}, {"id": 17, "type": "Resistor", "value": "330\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-3300GLF", "mfrPN": "CR0402-FX-3300GLF", "price": "$10/10,000", "notes": ""}, {"id": 18, "type": "Resistor", "value": "470\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-4700GLF", "mfrPN": "CR0402-FX-4700GLF", "price": "$10/10,000", "notes": ""}, {"id": 19, "type": "Resistor", "value": "680\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-6800GLF", "mfrPN": "CR0402-FX-6800GLF", "price": "$10/10,000", "notes": ""}, {"id": 20, "type": "Resistor", "value": "1k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-1001GLF", "mfrPN": "CR0402-FX-1001GLF", "price": "$10/10,000", "notes": ""}, {"id": 21, "type": "Resistor", "value": "1.5k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-1501GLF", "mfrPN": "CR0402-FX-1501GLF", "price": "$10/10,000", "notes": ""}, {"id": 22, "type": "Resistor", "value": "2.2k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-2201GLF", "mfrPN": "CR0402-FX-2201GLF", "price": "$10/10,000", "notes": ""}, {"id": 23, "type": "Resistor", "value": "3.3k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-3301GLF", "mfrPN": "CR0402-FX-3301GLF", "price": "$10/10,000", "notes": ""}, {"id": 24, "type": "Resistor", "value": "4.7k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-4701GLF", "mfrPN": "CR0402-FX-4701GLF", "price": "$10/10,000", "notes": ""}, {"id": 25, "type": "Resistor", "value": "6.8k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-6801GLF", "mfrPN": "CR0402-FX-6801GLF", "price": "$20/10,000", "notes": ""}, {"id": 26, "type": "Resistor", "value": "10k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-1002GLF", "mfrPN": "CR0402-FX-1002GLF", "price": "$10/10,000", "notes": ""}, {"id": 27, "type": "Resistor", "value": "15k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-1502GLF", "mfrPN": "CR0402-FX-1502GLF", "price": "$10/10,000", "notes": ""}, {"id": 28, "type": "Resistor", "value": "22k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-2202GLF", "mfrPN": "CR0402-FX-2202GLF", "price": "$10/10,000", "notes": ""}, {"id": 29, "type": "Resistor", "value": "33k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-3302GLF", "mfrPN": "CR0402-FX-3302GLF", "price": "$10/10,000", "notes": ""}, {"id": 30, "type": "Resistor", "value": "47k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-4702GLF", "mfrPN": "CR0402-FX-4702GLF", "price": "$10/10,000", "notes": ""}, {"id": 31, "type": "Resistor", "value": "68k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-6802GLF", "mfrPN": "CR0402-FX-6802GLF", "price": "$10/10,000", "notes": ""}, {"id": 32, "type": "Resistor", "value": "100k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-1003GLF", "mfrPN": "CR0402-FX-1003GLF", "price": "$10/10,000", "notes": ""}, {"id": 33, "type": "Resistor", "value": "150k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-1503GLF", "mfrPN": "CR0402-FX-1503GLF", "price": "$10/10,000", "notes": ""}, {"id": 34, "type": "Resistor", "value": "220k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-2203GLF", "mfrPN": "CR0402-FX-2203GLF", "price": "$10/10,000", "notes": ""}, {"id": 35, "type": "Resistor", "value": "330k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-3303GLF", "mfrPN": "CR0402-FX-3303GLF", "price": "$20/10,000", "notes": ""}, {"id": 36, "type": "Resistor", "value": "470k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-4703GLF", "mfrPN": "CR0402-FX-4703GLF", "price": "$20/10,000", "notes": ""}, {"id": 37, "type": "Resistor", "value": "680k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-6803GLF", "mfrPN": "CR0402-FX-6803GLF", "price": "$20/10,000", "notes": ""}, {"id": 38, "type": "Resistor", "value": "1M\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-1004GLF", "mfrPN": "CR0402-FX-1004GLF", "price": "$10/10,000", "notes": ""}, {"id": 39, "type": "Resistor", "value": "0\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 200PPM/C", "mouserPN": "303-CQ03WAF0000T5E", "mfrPN": "CQ03WAF0000T5E", "price": "$5/5,000", "notes": ""}, {"id": 40, "type": "Resistor", "value": "1\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 200PPM/C", "mouserPN": "303-0603WAF100KT5E", "mfrPN": "0603WAF100KT5E", "price": "$5/5,000", "notes": ""}, {"id": 41, "type": "Resistor", "value": "1.5\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "SEI Stackpole", "description": "75V; 100mW; 200PPM/C", "mouserPN": "708-RMCF0603FT1R50", "mfrPN": "RMCF0603FT1R50", "price": "$30/10,000", "notes": ""}, {"id": 42, "type": "Resistor", "value": "2.2\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 200PPM/C", "mouserPN": "303-0603WAF220KT5E", "mfrPN": "0603WAF220KT5E", "price": "$5/5,000", "notes": ""}, {"id": 43, "type": "Resistor", "value": "3.3\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 200PPM/C", "mouserPN": "303-0603WAF330KT5E", "mfrPN": "0603WAF330KT5E", "price": "$5/5,000", "notes": ""}, {"id": 44, "type": "Resistor", "value": "4.7\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 200PPM/C", "mouserPN": "303-0603WAF470KT5E", "mfrPN": "0603WAF470KT5E", "price": "$5/5,000", "notes": ""}, {"id": 45, "type": "Resistor", "value": "6.8\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "SEI Stackpole", "description": "75V; 100mW; 200PPM/C", "mouserPN": "708-RMCF0603FT6R80", "mfrPN": "RMCF0603FT6R80", "price": "$20/10,000", "notes": ""}, {"id": 46, "type": "Resistor", "value": "10\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 200PPM/C", "mouserPN": "303-0603WAF100JT5E", "mfrPN": "0603WAF100JT5E", "price": "$5/5,000", "notes": ""}, {"id": 47, "type": "Resistor", "value": "15\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 200PPM/C", "mouserPN": "303-0603WAF150JT5E", "mfrPN": "0603WAF150JT5E", "price": "$5/5,000", "notes": ""}, {"id": 48, "type": "Resistor", "value": "22\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603WAF220JT5E", "mfrPN": "0603WAF220JT5E", "price": "$5/5,000", "notes": ""}, {"id": 49, "type": "Resistor", "value": "33\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603WAF330JT5E", "mfrPN": "0603WAF330JT5E", "price": "$5/5,000", "notes": ""}, {"id": 50, "type": "Resistor", "value": "47\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603WAF470JT5E", "mfrPN": "0603WAF470JT5E", "price": "$5/5,000", "notes": ""}, {"id": 51, "type": "Resistor", "value": "68\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603WAF680JT5E", "mfrPN": "0603WAF680JT5E", "price": "$5/5,000", "notes": ""}, {"id": 52, "type": "Resistor", "value": "100\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-CQ03WAF1000T5E", "mfrPN": "CQ03WAF1000T5E", "price": "$5/5,000", "notes": ""}, {"id": 53, "type": "Resistor", "value": "150\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603SAF1500T5E", "mfrPN": "0603SAF1500T5E", "price": "$5/5,000", "notes": ""}, {"id": 54, "type": "Resistor", "value": "220\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-CQ03WAF2200T5E", "mfrPN": "CQ03WAF2200T5E", "price": "$5/5,000", "notes": ""}, {"id": 55, "type": "Resistor", "value": "330\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603WAF3300T5E", "mfrPN": "0603WAF3300T5E", "price": "$5/5,000", "notes": ""}, {"id": 56, "type": "Resistor", "value": "470\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603WAF4700T5E", "mfrPN": "0603WAF4700T5E", "price": "$5/5,000", "notes": ""}, {"id": 57, "type": "Resistor", "value": "680\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603WAF6800T5E", "mfrPN": "0603WAF6800T5E", "price": "$5/5,000", "notes": ""}, {"id": 58, "type": "Resistor", "value": "1k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-CQ03WAF1001T5E", "mfrPN": "CQ03WAF1001T5E", "price": "$5/5,000", "notes": ""}, {"id": 59, "type": "Resistor", "value": "1.5k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603SAF1501T5E", "mfrPN": "0603SAF1501T5E", "price": "$5/5,000", "notes": ""}, {"id": 60, "type": "Resistor", "value": "2.2k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-CQ03SAF2201T5E", "mfrPN": "CQ03SAF2201T5E", "price": "$5/5,000", "notes": ""}, {"id": 61, "type": "Resistor", "value": "3.3k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-CQ03SAF3301T5E", "mfrPN": "CQ03SAF3301T5E", "price": "$5/5,000", "notes": ""}, {"id": 62, "type": "Resistor", "value": "4.7k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-CQ03SAF4701T5E", "mfrPN": "CQ03SAF4701T5E", "price": "$5/5,000", "notes": ""}, {"id": 63, "type": "Resistor", "value": "6.8k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603WAF6801T5E", "mfrPN": "0603WAF6801T5E", "price": "$5/5,000", "notes": ""}, {"id": 64, "type": "Resistor", "value": "10k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-CQ03WAF1002T5E", "mfrPN": "CQ03WAF1002T5E", "price": "$5/5,000", "notes": ""}, {"id": 65, "type": "Resistor", "value": "15k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603SAF1502T5E", "mfrPN": "0603SAF1502T5E", "price": "$5/5,000", "notes": ""}, {"id": 66, "type": "Resistor", "value": "22k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603WAF2202T5E", "mfrPN": "0603WAF2202T5E", "price": "$5/5,000", "notes": ""}, {"id": 67, "type": "Resistor", "value": "33k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-CQ03SAF3302T5E", "mfrPN": "CQ03SAF3302T5E", "price": "$5/5,000", "notes": ""}, {"id": 68, "type": "Resistor", "value": "47k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-CQ03SAF4702T5E", "mfrPN": "CQ03SAF4702T5E", "price": "$5/5,000", "notes": ""}, {"id": 69, "type": "Resistor", "value": "68k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603WAF6802T5E", "mfrPN": "0603WAF6802T5E", "price": "$5/5,000", "notes": ""}, {"id": 70, "type": "Resistor", "value": "100k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-CQ03WAF1003T5E", "mfrPN": "CQ03WAF1003T5E", "price": "$5/5,000", "notes": ""}, {"id": 71, "type": "Resistor", "value": "150k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603SAF1503T5E", "mfrPN": "0603SAF1503T5E", "price": "$5/5,000", "notes": ""}, {"id": 72, "type": "Resistor", "value": "220k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603WAF2203T5E", "mfrPN": "0603WAF2203T5E", "price": "$5/5,000", "notes": ""}, {"id": 73, "type": "Resistor", "value": "330k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603WAF3303T5E", "mfrPN": "0603WAF3303T5E", "price": "$5/5,000", "notes": ""}, {"id": 74, "type": "Resistor", "value": "470k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-CQ03WAF4703T5E", "mfrPN": "CQ03WAF4703T5E", "price": "$5/5,000", "notes": ""}, {"id": 75, "type": "Resistor", "value": "680k\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-0603WAF6803T5E", "mfrPN": "0603WAF6803T5E", "price": "$5/5,000", "notes": ""}, {"id": 76, "type": "Resistor", "value": "1M\u03a9", "package": "0603", "tolerance": "0.01", "material": "", "manufacturer": "Royalohm", "description": "75V; 100mW; 100PPM/C", "mouserPN": "303-CQ03SAF1004T5E", "mfrPN": "CQ03SAF1004T5E", "price": "$5/5,000", "notes": ""}, {"id": 77, "type": "Multilayer Ceramic Capacitors", "value": "10pF", "package": "0402", "tolerance": "0.05", "material": "C0G", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-MT15N100J500CT", "mfrPN": "MT15N100J500CT", "price": "$20/10,000", "notes": ""}, {"id": 78, "type": "Multilayer Ceramic Capacitors", "value": "22pF", "package": "0402", "tolerance": "0.05", "material": "C0G", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0402N220J500CT", "mfrPN": "0402N220J500CT", "price": "$10/10,000", "notes": ""}, {"id": 79, "type": "Multilayer Ceramic Capacitors", "value": "33pF", "package": "0402", "tolerance": "0.05", "material": "C0G", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0402N330J500CT", "mfrPN": "0402N330J500CT", "price": "$10/10,000", "notes": ""}, {"id": 80, "type": "Multilayer Ceramic Capacitors", "value": "47pF", "package": "0402", "tolerance": "0.05", "material": "C0G", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0402N470G500CT", "mfrPN": "0402N470G500CT", "price": "$20/10,000", "notes": ""}, {"id": 81, "type": "Multilayer Ceramic Capacitors", "value": "100pF", "package": "0402", "tolerance": "0.05", "material": "C0G", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0402N101J500CT", "mfrPN": "0402N101J500CT", "price": "$10/10,000", "notes": ""}, {"id": 82, "type": "Multilayer Ceramic Capacitors", "value": "220pF", "package": "0402", "tolerance": "0.05", "material": "C0G", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0402N221J500CT", "mfrPN": "0402N221J500CT", "price": "$20/10,000", "notes": ""}, {"id": 83, "type": "Multilayer Ceramic Capacitors", "value": "1nF", "package": "0402", "tolerance": "0.05", "material": "X7R", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0402B102J500CT", "mfrPN": "0402B102J500CT", "price": "$20/10,000", "notes": ""}, {"id": 84, "type": "Multilayer Ceramic Capacitors", "value": "4.7nF", "package": "0402", "tolerance": "0.05", "material": "X7R", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0402B472J500CT", "mfrPN": "0402B472J500CT", "price": "$20/10,000", "notes": ""}, {"id": 85, "type": "Multilayer Ceramic Capacitors", "value": "10nF", "package": "0402", "tolerance": "0.05", "material": "X7R", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0402B103J500CT", "mfrPN": "0402B103J500CT", "price": "$20/10,000", "notes": ""}, {"id": 86, "type": "Multilayer Ceramic Capacitors", "value": "22nF", "package": "0402", "tolerance": "0.1", "material": "X7R", "manufacturer": "Walsin", "description": "25V", "mouserPN": "791-0402B223K250CT", "mfrPN": "0402B223K250CT", "price": "$20/10,000", "notes": ""}, {"id": 87, "type": "Multilayer Ceramic Capacitors", "value": "47nF", "package": "0402", "tolerance": "0.05", "material": "X7R", "manufacturer": "Walsin", "description": "25V", "mouserPN": "791-0402B473J250CT", "mfrPN": "0402B473J250CT", "price": "$30/10,000", "notes": ""}, {"id": 88, "type": "Multilayer Ceramic Capacitors", "value": "100nF", "package": "0402", "tolerance": "0.05", "material": "X7R", "manufacturer": "Walsin", "description": "16V", "mouserPN": "791-0402B104J160CT", "mfrPN": "0402B104J160CT", "price": "$20/10,000", "notes": ""}, {"id": 89, "type": "Multilayer Ceramic Capacitors", "value": "220nF", "package": "0402", "tolerance": "0.1", "material": "X7R", "manufacturer": "Walsin", "description": "16V", "mouserPN": "791-0402B224K160CT", "mfrPN": "0402B224K160CT", "price": "$40/10,000", "notes": ""}, {"id": 90, "type": "Multilayer Ceramic Capacitors", "value": "1uF", "package": "0402", "tolerance": "0.1", "material": "X7R", "manufacturer": "Walsin", "description": "25V", "mouserPN": "791-0402X105K250CT", "mfrPN": "0402X105K250CT", "price": "$30/10,000", "notes": ""}, {"id": 91, "type": "Multilayer Ceramic Capacitors", "value": "100pF", "package": "0603", "tolerance": "0.05", "material": "C0G", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0603N101J500CT", "mfrPN": "0603N101J500CT", "price": "$12/4,000", "notes": ""}, {"id": 92, "type": "Multilayer Ceramic Capacitors", "value": "220pF", "package": "0603", "tolerance": "0.05", "material": "C0G", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0603N221J500CT", "mfrPN": "0603N221J500CT", "price": "$24/4,000", "notes": ""}, {"id": 93, "type": "Multilayer Ceramic Capacitors", "value": "470pF", "package": "0603", "tolerance": "0.05", "material": "C0G", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0603N471J500CT", "mfrPN": "0603N471J500CT", "price": "$24/4,000", "notes": ""}, {"id": 94, "type": "Multilayer Ceramic Capacitors", "value": "1nF", "package": "0603", "tolerance": "0.05", "material": "C0G", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0603N102J500CT", "mfrPN": "0603N102J500CT", "price": "$20/4,000", "notes": ""}, {"id": 95, "type": "Multilayer Ceramic Capacitors", "value": "4.7nF", "package": "0603", "tolerance": "0.05", "material": "X7R", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0603B472J500CT", "mfrPN": "0603B472J500CT", "price": "$12/4,000", "notes": ""}, {"id": 96, "type": "Multilayer Ceramic Capacitors", "value": "10nF", "package": "0603", "tolerance": "0.05", "material": "X7R", "manufacturer": "Walsin", "description": "25V", "mouserPN": "791-0603B103J250CT", "mfrPN": "0603B103J250CT", "price": "$24/4,000", "notes": ""}, {"id": 97, "type": "Multilayer Ceramic Capacitors", "value": "47nF", "package": "0603", "tolerance": "0.05", "material": "X7R", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0603B473J500CT", "mfrPN": "0603B473J500CT", "price": "$28/4,000", "notes": ""}, {"id": 98, "type": "Multilayer Ceramic Capacitors", "value": "100nF", "package": "0603", "tolerance": "0.05", "material": "X7R", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0603B104J500CT", "mfrPN": "0603B104J500CT", "price": "$24/4,000", "notes": ""}, {"id": 99, "type": "Multilayer Ceramic Capacitors", "value": "220nF", "package": "0603", "tolerance": "0.1", "material": "X7R", "manufacturer": "Walsin", "description": "25V", "mouserPN": "791-0603B224K250CT", "mfrPN": "0603B224K250CT", "price": "$24/4,000", "notes": ""}, {"id": 100, "type": "Multilayer Ceramic Capacitors", "value": "470nF", "package": "0603", "tolerance": "0.2", "material": "X7R", "manufacturer": "Walsin", "description": "10V", "mouserPN": "791-0603B474M100CT", "mfrPN": "0603B474M100CT", "price": "$32/4,000", "notes": ""}, {"id": 101, "type": "Multilayer Ceramic Capacitors", "value": "1uF", "package": "0603", "tolerance": "0.1", "material": "X7R", "manufacturer": "Walsin", "description": "16V", "mouserPN": "791-0603B105K160CT", "mfrPN": "0603B105K160CT", "price": "$28/4,000", "notes": ""}, {"id": 102, "type": "Multilayer Ceramic Capacitors", "value": "2.2uF", "package": "0603", "tolerance": "0.1", "material": "X5R", "manufacturer": "Walsin", "description": "16V", "mouserPN": "791-0603X225K160CT", "mfrPN": "0603X225K160CT", "price": "$32/4,000", "notes": ""}, {"id": 103, "type": "Multilayer Ceramic Capacitors", "value": "4.7uF", "package": "0603", "tolerance": "0.1", "material": "X5R", "manufacturer": "Walsin", "description": "10V", "mouserPN": "791-0603X475K100CT", "mfrPN": "0603X475K100CT", "price": "$36/4,000", "notes": ""}, {"id": 104, "type": "Multilayer Ceramic Capacitors", "value": "10uF", "package": "0603", "tolerance": "0.1", "material": "X5R", "manufacturer": "Walsin", "description": "10V", "mouserPN": "791-0603X106K100CT", "mfrPN": "0603X106K100CT", "price": "$48/4,000", "notes": ""}, {"id": 105, "type": "Multilayer Ceramic Capacitors", "value": "100nF", "package": "0805", "tolerance": "0.1", "material": "X7R", "manufacturer": "Samsung Electro-Mechanics", "description": "50V", "mouserPN": "187-CL21B104KBCNFNC", "mfrPN": "CL21B104KBCNFNC", "price": "$32/4,000", "notes": ""}, {"id": 106, "type": "Multilayer Ceramic Capacitors", "value": "470nF", "package": "0805", "tolerance": "0.1", "material": "X7R", "manufacturer": "Samsung Electro-Mechanics", "description": "50V", "mouserPN": "187-CL21B474KBFNNNG", "mfrPN": "CL21B474KBFNNNG", "price": "$36/3,000", "notes": ""}, {"id": 107, "type": "Multilayer Ceramic Capacitors", "value": "1uF", "package": "0805", "tolerance": "0.1", "material": "X7R", "manufacturer": "Samsung Electro-Mechanics", "description": "50V", "mouserPN": "187-CL21B105KBFNNNE", "mfrPN": "CL21B105KBFNNNE", "price": "$22/2,000", "notes": ""}, {"id": 108, "type": "Multilayer Ceramic Capacitors", "value": "2.2uF", "package": "0805", "tolerance": "0.1", "material": "X5R", "manufacturer": "Samsung Electro-Mechanics", "description": "25V", "mouserPN": "187-CL21A225KAFNNNG", "mfrPN": "CL21A225KAFNNNG", "price": "$45/3,000", "notes": ""}, {"id": 109, "type": "Multilayer Ceramic Capacitors", "value": "4.7uF", "package": "0805", "tolerance": "0.1", "material": "X5R", "manufacturer": "Samsung Electro-Mechanics", "description": "25V", "mouserPN": "187-CL21A475KAQNNNG", "mfrPN": "CL21A475KAQNNNG", "price": "$42/3,000", "notes": ""}, {"id": 110, "type": "Multilayer Ceramic Capacitors", "value": "10uF", "package": "0805", "tolerance": "0.1", "material": "X5R", "manufacturer": "Samsung Electro-Mechanics", "description": "16V", "mouserPN": "187-CL21A106KOQNNNG", "mfrPN": "CL21A106KOQNNNG", "price": "$36/3,000", "notes": ""}, {"id": 111, "type": "Multilayer Ceramic Capacitors", "value": "22uF", "package": "0805", "tolerance": "0.2", "material": "X5R", "manufacturer": "Samsung Electro-Mechanics", "description": "10V", "mouserPN": "187-CL21A226MPQNNNE", "mfrPN": "CL21A226MPQNNNE", "price": "$54/2,000", "notes": ""}, {"id": 112, "type": "Multilayer Ceramic Capacitors", "value": "47uF", "package": "0805", "tolerance": "0.2", "material": "X5R", "manufacturer": "Samsung Electro-Mechanics", "description": "6.3V", "mouserPN": "187-CL21A476MQYNNNE", "mfrPN": "CL21A476MQYNNNE", "price": "$98/2,000", "notes": ""}, {"id": 113, "type": "Inductor", "value": "470nH", "package": "", "tolerance": "", "material": "", "manufacturer": "", "description": "", "mouserPN": "", "mfrPN": "", "price": "", "notes": ""}, {"id": 114, "type": "Inductor", "value": "100nH", "package": "", "tolerance": "", "material": "", "manufacturer": "", "description": "", "mouserPN": "", "mfrPN": "", "price": "", "notes": ""}, {"id": 115, "type": "Inductor", "value": "1uH", "package": "", "tolerance": "", "material": "", "manufacturer": "", "description": "", "mouserPN": "", "mfrPN": "", "price": "", "notes": ""}, {"id": 116, "type": "Inductor", "value": "10uH", "package": "", "tolerance": "", "material": "", "manufacturer": "", "description": "", "mouserPN": "", "mfrPN": "", "price": "", "notes": ""}, {"id": 117, "type": "Inductor", "value": "2.2uH", "package": "", "tolerance": "", "material": "", "manufacturer": "", "description": "", "mouserPN": "", "mfrPN": "", "price": "", "notes": ""}, {"id": 118, "type": "Inductor", "value": "4.7uH", "package": "", "tolerance": "", "material": "", "manufacturer": "", "description": "", "mouserPN": "", "mfrPN": "", "price": "", "notes": ""}, {"id": 119, "type": "LED", "value": "white", "package": "0402", "tolerance": "", "material": "", "manufacturer": "Inolux", "description": "", "mouserPN": "=\"743-\"&I122", "mfrPN": "IN-S42ATUW", "price": "$485 / 5,000", "notes": ""}, {"id": 120, "type": "LED", "value": "red", "package": "0402", "tolerance": "", "material": "", "manufacturer": "Inolux", "description": "", "mouserPN": "=\"743-\"&I123", "mfrPN": "IN-S42ATR", "price": "$325 / 5,000", "notes": ""}, {"id": 121, "type": "LED", "value": "blue", "package": "0402", "tolerance": "", "material": "", "manufacturer": "Inolux", "description": "", "mouserPN": "=\"743-\"&I124", "mfrPN": "IN-S42ATB", "price": "$480 / 5,000", "notes": ""}, {"id": 122, "type": "LED", "value": "green", "package": "0402", "tolerance": "", "material": "", "manufacturer": "Inolux", "description": "", "mouserPN": "=\"743-\"&I125", "mfrPN": "IN-S42ATG", "price": "$465 / 5,000", "notes": ""}, {"id": 123, "type": "LED", "value": "amber", "package": "0402", "tolerance": "", "material": "", "manufacturer": "Inolux", "description": "", "mouserPN": "=\"743-\"&I126", "mfrPN": "IN-S42ATA", "price": "$340 / 5,000", "notes": ""}, {"id": 124, "type": "LED", "value": "white", "package": "0603", "tolerance": "", "material": "", "manufacturer": "Inolux", "description": "", "mouserPN": "=\"743-\"&I127", "mfrPN": "IN-S63BT5UW", "price": "$253 / 4,000", "notes": ""}, {"id": 125, "type": "LED", "value": "red", "package": "0603", "tolerance": "", "material": "", "manufacturer": "Inolux", "description": "", "mouserPN": "=\"743-\"&I128", "mfrPN": "IN-S63BTR", "price": "$200 / 4,000", "notes": ""}, {"id": 126, "type": "LED", "value": "blue", "package": "0603", "tolerance": "", "material": "", "manufacturer": "Inolux", "description": "", "mouserPN": "=\"743-\"&I129", "mfrPN": "IN-S63BT5B", "price": "$200 / 4,000", "notes": ""}, {"id": 127, "type": "LED", "value": "green", "package": "0603", "tolerance": "", "material": "", "manufacturer": "Inolux", "description": "", "mouserPN": "=\"743-\"&I130", "mfrPN": "IN-S63BTG", "price": "$216 / 4,000", "notes": ""}, {"id": 128, "type": "LED", "value": "amber", "package": "0603", "tolerance": "", "material": "", "manufacturer": "Inolux", "description": "", "mouserPN": "=\"743-\"&I131", "mfrPN": "IN-S63BTA", "price": "$140 / 4,000", "notes": ""}, {"id": 129, "type": "LED", "value": "WS2812", "package": "2020-metric", "tolerance": "", "material": "", "manufacturer": "World Semi", "description": "LCSC = C965555", "mouserPN": "n/a", "mfrPN": "WS2812B-2020", "price": "$176 / 4,500", "notes": "need to bake? (ray: strongly recommended yes bake, thus cannot be loaded on feeder constantly, suggest this should not be a basic part)"}, {"id": 130, "type": "Ferrite Bead", "value": "47 \u03a9 @ 100 MHz", "package": "0402", "tolerance": "\u00b125 %", "material": "Ferrite", "manufacturer": "Murata", "description": "200 mA, 600mOhm DC resistance", "mouserPN": "81-BLM15BA470SN1D", "mfrPN": "BLM15BA470SN1D", "price": "$130/10,000", "notes": ""}, {"id": 131, "type": "Ferrite Bead", "value": "600 \u03a9 @ 100 MHz", "package": "0402", "tolerance": "\u00b125 %", "material": "Ferrite", "manufacturer": "Murata", "description": "500 mA, 340mOhm DC resistance", "mouserPN": "81-BLM15AX601SN1D", "mfrPN": "BLM15AX601SN1D", "price": "$150/10,000", "notes": ""}, {"id": 132, "type": "Resistor", "value": "2k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-2001GLF", "mfrPN": "CR0402-FX-2001GLF", "price": "$10/10,000", "notes": ""}, {"id": 133, "type": "Resistor", "value": "120\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-1200GLF", "mfrPN": "CR0402-FX-1200GLF", "price": "$10/10,000", "notes": ""}, {"id": 134, "type": "Resistor", "value": "5.6k\u03a9", "package": "0402", "tolerance": "0.01", "material": "", "manufacturer": "Bourns", "description": "50V; 62.5mW; 100PPM/C", "mouserPN": "652-CR0402FX-5601GLF", "mfrPN": "CR0402-FX-5601GLF", "price": "$10/10,000", "notes": ""}, {"id": 135, "type": "Multilayer Ceramic Capacitors", "value": "68pF", "package": "0402", "tolerance": "0.05", "material": "C0G", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0402N680J500CT", "mfrPN": "0402N680J500CT", "price": "$10/10,000", "notes": ""}, {"id": 136, "type": "Multilayer Ceramic Capacitors", "value": "330pF", "package": "0402", "tolerance": "0.05", "material": "C0G", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0402N331J500CT", "mfrPN": "0402N331J500CT", "price": "$20/10,000", "notes": ""}, {"id": 137, "type": "Multilayer Ceramic Capacitors", "value": "470pF", "package": "0402", "tolerance": "0.05", "material": "X7R", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0402B471J500CT", "mfrPN": "0402B471J500CT", "price": "$20/10,000", "notes": ""}, {"id": 138, "type": "Multilayer Ceramic Capacitors", "value": "3.3nF", "package": "0402", "tolerance": "0.05", "material": "X7R", "manufacturer": "Walsin", "description": "50V", "mouserPN": "791-0402B332J500CT", "mfrPN": "0402B332J500CT", "price": "$20/10,000", "notes": ""}];
  render();
}

function getTypeClass(type) {
  if (type.includes('Resistor')) return 'type-resistor';
  if (type.includes('Capacitor')) return 'type-capacitor';
  if (type.includes('Inductor')) return 'type-inductor';
  if (type.includes('LED')) return 'type-led';
  if (type.includes('Ferrite')) return 'type-ferrite';
  return '';
}

function getTypeShort(type) {
  if (type.includes('Multilayer')) return 'MLCC';
  if (type.includes('Ferrite')) return 'Ferrite';
  return type;
}

function getTypes() {
  const types = [...new Set(parts.map(p => p.type))];
  return types.sort();
}

function filteredParts() {
  let result = parts;
  if (activeFilter) {
    result = result.filter(p => p.type === activeFilter);
  }
  if (searchTerm) {
    const q = searchTerm.toLowerCase();
    result = result.filter(p =>
      Object.values(p).some(v => String(v).toLowerCase().includes(q))
    );
  }
  result.sort((a, b) => {
    let va = a[sortCol] || '', vb = b[sortCol] || '';
    // Numeric sort for tolerance and value-like fields
    if (sortCol === 'tolerance') {
      va = parseFloat(va) || 0;
      vb = parseFloat(vb) || 0;
      return (va - vb) * sortDir;
    }
    return String(va).localeCompare(String(vb), undefined, { numeric: true }) * sortDir;
  });
  return result;
}

function render() {
  const fp = filteredParts();
  const tbody = document.getElementById('partsBody');
  const empty = document.getElementById('emptyState');

  // Update count
  document.getElementById('partCount').textContent = `${fp.length} of ${parts.length} parts`;

  // Stats
  const stats = getTypes().map(t => {
    const c = parts.filter(p => p.type === t).length;
    return `<span><strong>${c}</strong> ${getTypeShort(t)}${c !== 1 ? 's' : ''}</span>`;
  }).join('');
  document.getElementById('statsBar').innerHTML = stats;

  // Filter buttons
  const filterDiv = document.getElementById('filterBtns');
  filterDiv.innerHTML = getTypes().map(t =>
    `<button class="filter-btn ${activeFilter === t ? 'active' : ''}" onclick="toggleFilter('${t}')">${getTypeShort(t)}</button>`
  ).join('');

  if (fp.length === 0) {
    tbody.innerHTML = '';
    empty.style.display = 'block';
    return;
  }
  empty.style.display = 'none';

  // Sort arrows
  document.querySelectorAll('th[data-col]').forEach(th => {
    const arrow = th.querySelector('.sort-arrow');
    if (arrow) arrow.textContent = th.dataset.col === sortCol ? (sortDir === 1 ? '\u25B2' : '\u25BC') : '';
  });

  // Group by type+package
  let html = '';
  let lastGroup = '';
  for (const p of fp) {
    const group = `${p.type} - ${p.package}`;
    if (group !== lastGroup && !activeFilter) {
      lastGroup = group;
      html += `<tr class="section-sep"><td colspan="12">${getTypeShort(p.type)} ${p.package}</td></tr>`;
    }
    const mouserLink = p.mouserPN
      ? `<a class="mouser-link" href="https://www.mouser.com/ProductDetail/${p.mouserPN}" target="_blank" rel="noopener">${p.mouserPN}</a>`
      : '';
    html += `<tr ondblclick="openEditModal(${p.id})">
      <td><span class="type-badge ${getTypeClass(p.type)}">${getTypeShort(p.type)}</span></td>
      <td><strong>${esc(p.value)}</strong></td>
      <td><span class="pkg-badge">${esc(p.package)}</span></td>
      <td>${esc(p.tolerance)}</td>
      <td>${esc(p.material)}</td>
      <td>${esc(p.manufacturer)}</td>
      <td title="${esc(p.description)}">${esc(p.description)}</td>
      <td>${mouserLink}</td>
      <td>${esc(p.mfrPN)}</td>
      <td>${esc(p.price)}</td>
      <td class="notes-cell" title="${esc(p.notes)}">${esc(p.notes)}</td>
      <td><button class="action-btn secondary" style="padding:2px 8px;font-size:11px" onclick="openEditModal(${p.id})">Edit</button></td>
    </tr>`;
  }
  tbody.innerHTML = html;
}

function esc(s) {
  if (!s) return '';
  return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}

// --- Filters & Search ---
function toggleFilter(type) {
  activeFilter = activeFilter === type ? null : type;
  render();
}

document.getElementById('searchBox').addEventListener('input', e => {
  searchTerm = e.target.value;
  render();
});

// --- Sorting ---
document.querySelectorAll('th[data-col]').forEach(th => {
  th.addEventListener('click', () => {
    const col = th.dataset.col;
    if (sortCol === col) sortDir *= -1;
    else { sortCol = col; sortDir = 1; }
    render();
  });
});

// --- Modal ---
function openAddModal() {
  document.getElementById('modalTitle').textContent = 'Add Part';
  document.getElementById('editId').value = '';
  document.getElementById('deleteBtn').style.display = 'none';
  ['fType','fValue','fPackage','fTolerance','fMaterial','fManufacturer','fDescription','fMouserPN','fMfrPN','fPrice','fNotes']
    .forEach(id => document.getElementById(id).value = '');
  document.getElementById('modalOverlay').classList.add('open');
}

function openEditModal(id) {
  const p = parts.find(x => x.id === id);
  if (!p) return;
  document.getElementById('modalTitle').textContent = 'Edit Part';
  document.getElementById('editId').value = id;
  document.getElementById('deleteBtn').style.display = 'inline-block';
  document.getElementById('fType').value = p.type;
  document.getElementById('fValue').value = p.value;
  document.getElementById('fPackage').value = p.package;
  document.getElementById('fTolerance').value = p.tolerance;
  document.getElementById('fMaterial').value = p.material;
  document.getElementById('fManufacturer').value = p.manufacturer;
  document.getElementById('fDescription').value = p.description;
  document.getElementById('fMouserPN').value = p.mouserPN;
  document.getElementById('fMfrPN').value = p.mfrPN;
  document.getElementById('fPrice').value = p.price;
  document.getElementById('fNotes').value = p.notes;
  document.getElementById('modalOverlay').classList.add('open');
}

function closeModal() {
  document.getElementById('modalOverlay').classList.remove('open');
}

function savePart() {
  const id = document.getElementById('editId').value;
  const data = {
    type: document.getElementById('fType').value,
    value: document.getElementById('fValue').value.trim(),
    package: document.getElementById('fPackage').value.trim(),
    tolerance: document.getElementById('fTolerance').value.trim(),
    material: document.getElementById('fMaterial').value.trim(),
    manufacturer: document.getElementById('fManufacturer').value.trim(),
    description: document.getElementById('fDescription').value.trim(),
    mouserPN: document.getElementById('fMouserPN').value.trim(),
    mfrPN: document.getElementById('fMfrPN').value.trim(),
    price: document.getElementById('fPrice').value.trim(),
    notes: document.getElementById('fNotes').value.trim(),
  };

  if (!data.value) { alert('Value is required'); return; }

  if (id) {
    const idx = parts.findIndex(p => p.id === parseInt(id));
    if (idx >= 0) Object.assign(parts[idx], data);
    showToast('Part updated');
  } else {
    const maxId = parts.reduce((m, p) => Math.max(m, p.id), 0);
    parts.push({ id: maxId + 1, ...data });
    showToast('Part added');
  }
  closeModal();
  render();
  markDirty();
}

function deletePart() {
  const id = parseInt(document.getElementById('editId').value);
  if (!confirm('Delete this part?')) return;
  parts = parts.filter(p => p.id !== id);
  closeModal();
  render();
  showToast('Part deleted');
  markDirty();
}

// --- Export ---
function exportJSON() {
  const blob = new Blob([JSON.stringify(parts, null, 2)], { type: 'application/json' });
  download(blob, 'basic-parts-data.json');
  showToast('JSON exported');
}

function exportCSV() {
  const cols = ['type','value','package','tolerance','material','manufacturer','description','mouserPN','mfrPN','price','notes'];
  const header = cols.join(',');
  const rows = parts.map(p => cols.map(c => `"${String(p[c] || '').replace(/"/g, '""')}"`).join(','));
  const blob = new Blob([header + '\n' + rows.join('\n')], { type: 'text/csv' });
  download(blob, 'basic-parts-library.csv');
  showToast('CSV exported');
}

function download(blob, name) {
  const a = document.createElement('a');
  a.href = URL.createObjectURL(blob);
  a.download = name;
  a.click();
  URL.revokeObjectURL(a.href);
}

// --- Dirty state ---
let dirty = false;
function markDirty() { dirty = true; }
window.addEventListener('beforeunload', e => {
  if (dirty) { e.preventDefault(); e.returnValue = ''; }
});

// --- Toast ---
function showToast(msg) {
  const t = document.getElementById('toast');
  t.textContent = msg;
  t.classList.add('show');
  setTimeout(() => t.classList.remove('show'), 2000);
}

// --- Keyboard ---
document.addEventListener('keydown', e => {
  if (e.key === 'Escape') closeModal();
  if (e.key === '/' && !e.ctrlKey && document.activeElement.tagName !== 'INPUT') {
    e.preventDefault();
    document.getElementById('searchBox').focus();
  }
});

// --- Init ---
loadData();
</script>
</body>
</html>