PageSourceSearch

https://revcycleai.com/js/company-directory-intelligence.js

js revcycleai.com collected 2026-10-07 13:17:42 UTC 7,270 bytes, 54 lines download raw bytes

1(function(){
2'use strict';
3if(!location.pathname.startsWith('/company-intelligence'))return;
4if(window.matchMedia('(min-width:921px)').matches)return;
5const isPro=()=>['true','1'].includes(String(localStorage.getItem('rcai_pro_unlocked')||''));
6const esc=s=>String(s??'').replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
7const arr=v=>Array.isArray(v)?v.filter(Boolean):v?[v]:[];
8const money=n=>n?new Intl.NumberFormat('en-US',{style:'currency',currency:'USD',notation:'compact',maximumFractionDigits:1}).format(n):'—';
9const wait=async(sel,tries=80)=>{while(tries--){const el=document.querySelector(sel);if(el)return el;await new Promise(r=>setTimeout(r,75));}return null};
10(async()=>{
11 const rows=await wait('#rows'); if(!rows)return;
12 const [db,scoresDb,matrixDb,txDb,ownDb,auditDb]=await Promise.all([
13  fetch('/data/company-intelligence.json',{cache:'no-store'}).then(r=>r.json()).catch(()=>({companies:[]})),
14  fetch('/data/company-scores.json',{cache:'no-store'}).then(r=>r.json()).catch(()=>({companies:[]})),
15  fetch('/data/rcm-market-matrix.json',{cache:'no-store'}).then(r=>r.json()).catch(()=>({companies:[]})),
16  fetch('/data/rcm-transactions.json',{cache:'no-store'}).then(r=>r.json()).catch(()=>({transactions:[]})),
17  fetch('/data/ownership-history.json',{cache:'no-store'}).then(r=>r.json()).catch(()=>({companies:{}})),
18  fetch('/data/funding-completeness.json',{cache:'no-store'}).then(r=>r.json()).catch(()=>({companies:[]}))
19 ]);
20 const companies=db.companies||[];
21 const scoreMap=new Map((scoresDb.companies||[]).map(x=>[x.slug,x]));
22 const matrixMap=new Map((matrixDb.companies||[]).map(x=>[x.slug,x]));
23 const auditMap=new Map((auditDb.companies||[]).map(x=>[x.slug,x]));
24 const txBy=new Map();for(const t of txDb.transactions||[]){const a=txBy.get(t.target_slug)||[];a.push(t);txBy.set(t.target_slug,a)}
25 const own=ownDb.companies||{};
26 const table=document.querySelector('.table');
27 if(!table)return;
28 table.style.minWidth=isPro()?'1420px':'980px';
29 const head=table.querySelector('thead tr');
30 head.innerHTML=`<th>Company</th><th>Category</th><th>Ownership</th><th>Founded / HQ</th><th>Confidence</th><th class="pro-col">Funding</th><th class="pro-col">Market Matrix</th><th class="pro-col">Momentum</th><th class="pro-col">Buyer fit</th><th class="pro-col">Integrations</th><th class="pro-col">Pricing</th><th class="pro-col">Competitive set</th><th></th>`;
31 const toolbar=document.querySelector('.toolbar');
32 const addSelect=(id,label)=>{if(!toolbar||document.getElementById(id))return null;const s=document.createElement('select');s.className='field';s.id=id;s.innerHTML=`<option value="">${label}</option>`;toolbar.appendChild(s);return s};
33 const stageSel=addSelect('fundingStage','All funding stages');
34 const tierSel=addSelect('matrixTier','All Matrix tiers');
35 if(stageSel){[...new Set(companies.map(c=>c.funding_stage).filter(Boolean))].sort().forEach(v=>stageSel.insertAdjacentHTML('beforeend',`<option>${esc(v)}</option>`));}
36 if(tierSel){['Leader','Major Contender','Emerging'].forEach(v=>tierSel.insertAdjacentHTML('beforeend',`<option>${v}</option>`));}
37 const search=document.getElementById('search'),cat=document.getElementById('category'),ownership=document.getElementById('ownership');
38 const initials=n=>String(n||'').split(/\s+/).slice(0,2).map(x=>x[0]||'').join('').toUpperCase();
39 const currentOwner=c=>{if(c.ownership)return c.ownership;const ev=arr(own[c.slug]).slice().reverse().find(x=>x.owner);return ev?.owner||'—'};
40 const latestTx=c=>arr(txBy.get(c.slug)).sort((a,b)=>String(b.date_announced||'').localeCompare(String(a.date_announced||'')))[0];
41 const fundingLabel=c=>{const a=auditMap.get(c.slug),t=latestTx(c);const bits=[];if(c.funding_stage)bits.push(c.funding_stage);if(t?.amount_usd||t?.amount_display)bits.push(t.amount_display||money(t.amount_usd));else if(c.funding_total)bits.push(c.funding_total);if(a?.status&&a.status!=='unknown')bits.push(a.status);return bits.join(' · ')||'—'};
42 const render=()=>{
43  const q=(search?.value||'').trim().toLowerCase(),cv=cat?.value||'',ov=ownership?.value||'',sv=stageSel?.value||'',tv=tierSel?.value||'';
44  const filtered=companies.filter(c=>{const m=matrixMap.get(c.slug);const hay=[c.name,c.category,c.subcategory,c.description,c.ownership,c.hq,c.funding_stage,...arr(c.capabilities),...arr(c.aliases),...arr(c.competitors),...arr(c.integrations),...arr(c.buyer_segments)].filter(
44Boolean).join(' ').toLowerCase();return(!q||hay.includes(q))&&(!cv||c.category===cv)&&(!ov||currentOwner(c)===ov)&&(!sv||c.funding_stage===sv)&&(!tv||m?.tier===tv)}).sort((a,b)=>a.name.localeCompare(b.name));
45  const count=document.getElementById('resultCount');if(count)count.textContent=`${filtered.length} of ${companies.length} companies`;
46  rows.innerHTML=filtered.length?filtered.map(c=>{const s=scoreMap.get(c.slug),m=matrixMap.get(c.slug);const buyer=arr(c.buyer_segments).join(', ')||arr(c.organization_size_fit).join(', ')||'—';const pricing=c.pricing_model||c.pricing_details||'—';const comps=arr(c.competitors).slice(0,3).join(', ')||'—';const integrations=arr(c.integrations).slice(0,3).join(', ')||'—';const founded=[c.founded_year,c.hq].filter(Boolean).join(' · ')||'—';const owner=currentOwner(c);const profile=`/companies/${encodeURIComponent(c.slug)}/`;return `<tr data-slug="${esc(c.slug)}"><td><div class="co"><div class="mark">${esc(initials(c.name))}</div><div><strong>${esc(c.name)}</strong><small>${esc(c.subcategory||'')}</small></div></div></td><td><span class="pill">${esc(c.category||'—')}</span></td><td>${esc(owner)}</td><td>${esc(founded)}</td><td><span class="confidence ${esc(c.data_confidence||'low')}">${esc(c.data_confidence||'low')}</span></td><td class="pro-col">${esc(fundingLabel(c))}</td><td class="pro-col">${m?`<a href="/methodology/#market-matrix"><b>${esc(m.tier)}</b> · Impact ${m.market_impact_score} · Vision ${m.vision_capability_score}</a>`:'—'}</td><td class="pro-col">${s?`<a href="/methodology/#momentum"><b>${s.momentum_score}</b></a>`:'—'}</td><td class="pro-col">${esc(buyer)}</td><td class="pro-col">${esc(integrations)}</td><td class="pro-col">${esc(pricing)}</td><td class="pro-col">${esc(comps)}</td><td><a class="open" href="${profile}">Profile →</a></td></tr>`}).join(''):`<tr><td colspan="13" class="empty">No companies match these filters.</td></tr>`;
47  document.querySelectorAll('#rows tr[data-slug]').forEach(tr=>{tr.style.cursor='pointer';tr.onclick=e=>{if(e.target.closest('a,button,input,select'))return;location.href=`/companies/${encodeURIComponent(tr.dataset.slug)}/`}});
48 };
49 const syncMode=()=>{document.body.classList.toggle('pro-mode',isPro());if(stageSel)stageSel.style.display=isPro()?'':'none';if(tierSel)tierSel.style.display=isPro()?'':'none';table.style.minWidth=isPro()?'1420px':'980px';render();};
50 [search,cat,ownership,stageSel,tierSel].filter(Boolean).forEach(el=>['input','change'].forEach(ev=>el.addEventListener(ev,()=>setTimeout(render,0))));
51 const modeBtns=document.querySelectorAll('.mode button');modeBtns.forEach(b=>b.addEventListener('click',e=>{if(!isPro()&&b.dataset.mode==='pro'){e.preventDefault();e.stopImmediatePropagation();location.href='/pro/';return;}setTimeout(syncMode,0)},true));
52 syncMode();
53})();
54})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.