1"use strict";(globalThis.webpackChunkorbisid_docs=globalThis.webpackChunkorbisid_docs||[]).push([[8173],{6872(e,t,n){n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>d,default:()=>m,frontMatter:()=>o,metadata:()=>r,toc:()=>u});const r=JSON.parse('{"id":"installation/requirements","title":"Requirements","description":"Software","source":"@site/docs/installation/requirements.md","sourceDirName":"installation","slug":"/installation/requirements","permalink":"/docs/installation/requirements","draft":false,"unlisted":false,"tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"sidebar_position":1,"title":"Requirements"},"sidebar":"mainSidebar","previous":{"title":"Introduction","permalink":"/docs/"},"next":{"title":"Quick Start","permalink":"/docs/installation/quick-start"}}');var s=n(4848),i=n(8453),l=n(5537),a=n(9329);const o={sidebar_position:1,title:"Requirements"},d="System Requirements",c={},u=[{value:"Software",id:"software",level:2},{value:"Hardware",id:"hardware",level:2},{value:"Network",id:"network",level:2},{value:"Inbound Ports",id:"inbound-ports",level:3},{value:"Outbound Ports (from OrbisID to target systems)",id:"outbound-ports-from-orbisid-to-target-systems",level:3},{value:"TLS Certificates",id:"tls-certificates",level:2},{value:"Option A: Let's Encrypt (Certbot)",id:"option-a-lets-encrypt-certbot",level:3},{value:"Option B: Self-Signed Certificate",id:"option-b-self-signed-certificate",level:3},{value:"Option C: Corporate CA Certificate",id:"option-c-corporate-ca-certificate",level:3},{value:"Browser Support",id:"browser-support",level:2},{value:"Database",id:"database",level:2}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"system-requirements",children:"System Requirements"})}),"\n",(0,s.jsx)(t.h2,{id:"software",children:"Software"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Software"}),(0,s.jsx)(t.th,{children:"Minimum Version"}),(0,s.jsx)(t.th,{children:"Notes"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Docker"}),(0,s.jsx)(t.td,{children:"24.0+"}),(0,s.jsx)(t.td,{children:"Required for every deployment mode except the Windows Installer below"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Docker Compose"}),(0,s.jsx)(t.td,{children:"2.20+"}),(0,s.jsxs)(t.td,{children:["V2 plugin (",(0,s.jsx)(t.code,{children:"docker compose"}),") recommended; not needed for the Windows Installer"]})]})]})]}),"\n",(0,s.jsxs)(t.p,{children:["OrbisID is distributed as Docker images for every deployment mode on this page except one: on Windows, the ",(0,s.jsx)(t.a,{href:"./quick-start#option-a-windows-installer",children:"Windows Installer"})," installs OrbisID as native Windows services instead, with no Docker requirement \u2014 it bundles its own Java runtime, Node.js runtime, and (optionally) PostgreSQL binaries. It doesn't include the AI/Intelligence Layer (Ollama) \u2014 see that option's Known Limitations."]}),"\n",(0,s.jsx)(t.h2,{id:"hardware",children:"Hardware"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Resource"}),(0,s.jsx)(t.th,{children:"Minimum"}),(0,s.jsx)(t.th,{children:"Recommended"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"CPU"}),(0,s.jsx)(t.td,{children:"2 cores"}),(0,s.jsx)(t.td,{children:"4+ cores"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"RAM"}),(0,s.jsx)(t.td,{children:"8 GB"}),(0,s.jsx)(t.td,{children:"16+ GB"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Disk"}),(0,s.jsx)(t.td,{children:"20 GB"}),(0,s.jsx)(t.td,{children:"60+ GB"})]})]})]}),"\n",(0,s.jsxs)(t.p,{children:["Both release packages start a local AI runtime (",(0,s.jsx)(t.a,{href:"https://ollama.com",children:"Ollama"}),") automatically, which raises the baseline versus a database-and-app-only deployment \u2014 CPU-only LLM inference is memory-hungry even for the small default model. If you don't plan to use ",(0,s.jsx)(t.a,{href:"../user-guide/ai-assistant",children:"AI features"})," and are resource-constrained, stop the bundled container (",(0,s.jsx)(t.code,{children:"docker
1compose stop ollama ollama-init"}),") and the minimums drop back to roughly 4 GB RAM / 10 GB disk."]}),"\n",(0,s.jsx)(t.p,{children:"Disk usage otherwise grows with the number of systems scanned, how long you retain audit logs and scan history, and the Ollama runtime \u2014 the Ollama container image (a few GB; not included in the release download itself) and the two default chat/embedding models (~2 GB) are both pulled from the internet the first time you start the stack."}),"\n",(0,s.jsx)(t.h2,{id:"network",children:"Network"}),"\n",(0,s.jsx)(t.h3,{id:"inbound-ports",children:"Inbound Ports"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Port"}),(0,s.jsx)(t.th,{children:"Protocol"}),(0,s.jsx)(t.th,{children:"Purpose"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"80"}),(0,s.jsx)(t.td,{children:"TCP"}),(0,s.jsx)(t.td,{children:"HTTP (redirect to HTTPS in production)"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"443"}),(0,s.jsx)(t.td,{children:"TCP"}),(0,s.jsx)(t.td,{children:"HTTPS (recommended for production)"})]})]})]}),"\n",(0,s.jsx)(t.h3,{id:"outbound-ports-from-orbisid-to-target-systems",children:"Outbound Ports (from OrbisID to target systems)"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Target System Type"}),(0,s.jsx)(t.th,{children:"Protocol"}),(0,s.jsx)(t.th,{children:"Port(s)"}),(0,s.jsx)(t.th,{children:"Notes"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Active Directory"}),(0,s.jsx)(t.td,{children:"LDAP"}),(0,s.jsx)(t.td,{children:"389 TCP"}),(0,s.jsx)(t.td,{children:"Unencrypted (not recommended for production)"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Active Directory"}),(0,s.jsx)(t.td,{children:"LDAPS"}),(0,s.jsx)(t.td,{children:"636 TCP"}),(0,s.jsx)(t.td,{children:"Recommended \u2014 encrypted"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Linux"}),(0,s.jsx)(t.td,{children:"SSH"}),(0,s.jsx)(t.td,{children:"22 TCP"}),(0,s.jsx)(t.td,{children:"Configurable"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Windows"}),(0,s.jsx)(t.td,{children:"WinRM HTTP"}),(0,s.jsx)(t.td,{children:"5985 TCP"}),(0,s.jsx)(t.td,{children:"Unencrypted"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Windows"}),(0,s.jsx)(t.td,{children:"WinRM HTTPS"}),(0,s.jsx)(t.td,{children:"5986 TCP"}),(0,s.jsx)(t.td,{children:"Recommended \u2014 encrypted"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"SQL Server"}),(0,s.jsx)(t.td,{children:"JDBC"}),(0,s.jsx)(t.td,{children:"1433 TCP"}),(0,s.jsx)(t.td,{children:"Configurable"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"On-Premise Agent"}),(0,s.jsx)(t.td,{children:"HTTPS"}),(0,s.jsx)(t.td,{children:"443 TCP"}),(0,s.jsx)(t.td,{children:"OrbisID polls agents for job completion"})]})]})]}),"\n",(0,s.jsxs)(t.p,{children:["See ",(0,s.jsx)(t.a,{href:"../target-systems",children:"Target Systems"})," for full per-system connection requirements."]}),"\n",(0,s.jsxs)(t.p,{children:["If target systems are in segmented networks not directly reachable from OrbisID, deploy an ",(0,s.jsx)(t.a,{href:"../api/on-premise-agent",children:"On-Premise Agent"})," in those network segments instead."]}),"\n",(0,s.jsx)(t.h2,{id:"tls-certificates",children:"TLS Certificates"}),"\n",(0,s.jsxs)(t.p,{children:["Production deployments should use HTTPS. OrbisID uses Nginx as a reverse proxy, so certificates are configured at the Nginx layer. See ",(0,s.jsx)(t.a,{href:"./deployment#enabling-https",children:"Deployment \u2014 Enabling HTTPS"})," for how to configure Nginx with your certificate files."]}),"\n",(0,s.jsx)(t.h3,{id:"option-a-lets-encrypt-certbot",children:"Option A: Let's Encrypt (Certbot)"}),"\n",(0,s.jsx)(t.p,{children:"Use this when the OrbisID host has a public DNS name and internet access:"}),"\n",(0,s.jsxs)(l.A,{groupId:"operating-systems",children:[(0,s.jsx)(a.A,{value:"linux",label:"Linux",children:(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"# Install Certbot\nsudo apt install certbot # Debian/Ubuntu\n# or\nsudo yum install certbot # RHEL/CentOS\n\n# Obtain a certificate (standalone mode \u2014 stop Nginx first if running on port 80)\nsudo certbot certonly --standalone -d your.orbisid.domain.com\n\n# Certificate files are written to:\n# /etc/letsencrypt/live/your.orbisid.domain.com/fullchain.pem\n# /etc/letsencrypt/live/your.orbisid.domain.com/privke
1y.pem\n"})})}),(0,s.jsx)(a.A,{value:"macos",label:"macOS",children:(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"# Install Certbot\nbrew install certbot\n\n# Obtain a certificate (standalone mode \u2014 stop Nginx first if running on port 80)\nsudo certbot certonly --standalone -d your.orbisid.domain.com\n\n# Certificate files are written to:\n# /etc/letsencrypt/live/your.orbisid.domain.com/fullchain.pem\n# /etc/letsencrypt/live/your.orbisid.domain.com/privkey.pem\n"})})}),(0,s.jsx)(a.A,{value:"windows",label:"Windows",children:(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-powershell",children:"# Install Certbot \u2014 download and run the official Windows installer from\n# https://certbot.eff.org/instructions?ws=other&os=windows (a separate .exe,\n# not available via apt/yum). It installs a `certbot` command on your PATH.\n\n# Obtain a certificate (standalone mode \u2014 stop Nginx first if running on port 80)\ncertbot certonly --standalone -d your.orbisid.domain.com\n\n# Certificate files are written to:\n# C:\\Certbot\\live\\your.orbisid.domain.com\\fullchain.pem\n# C:\\Certbot\\live\\your.orbisid.domain.com\\privkey.pem\n"})})})]}),"\n",(0,s.jsxs)(t.p,{children:["Copy the certificate files to the OrbisID ",(0,s.jsx)(t.code,{children:"ssl/"})," directory, then configure Nginx as described in the deployment guide."]}),"\n",(0,s.jsx)(t.h3,{id:"option-b-self-signed-certificate",children:"Option B: Self-Signed Certificate"}),"\n",(0,s.jsx)(t.p,{children:"Use this for internal deployments without a public domain:"}),"\n",(0,s.jsxs)(l.A,{groupId:"operating-systems",children:[(0,s.jsx)(a.A,{value:"linux",label:"Linux",children:(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'# Generate a self-signed certificate valid for 10 years\nmkdir -p ssl\nopenssl req -x509 -nodes -days 3650 -newkey rsa:4096 \\\n -keyout ssl/privkey.pem \\\n -out ssl/fullchain.pem \\\n -subj "/CN=orbisid.internal" \\\n -addext "subjectAltName=DNS:orbisid.internal,IP:192.168.1.100"\n'})})}),(0,s.jsx)(a.A,{value:"macos",label:"macOS",children:(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'# Generate a self-signed certificate valid for 10 years\nmkdir -p ssl\nopenssl req -x509 -nodes -days 3650 -newkey rsa:4096 \\\n -keyout ssl/privkey.pem \\\n -out ssl/fullchain.pem \\\n -subj "/CN=orbisid.internal" \\\n -addext "subjectAltName=DNS:orbisid.internal,IP:192.168.1.100"\n'})})}),(0,s.jsx)(a.A,{value:"windows",label:"Windows",children:(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-powershell",children:'# OpenSSL isn\'t built into Windows. Install it first \u2014 e.g. via Git for\n# Windows (https://git-scm.com/download/win), which bundles an `openssl.exe`\n# on its PATH \u2014 then run the same command used on Linux/macOS:\nNew-Item -ItemType Directory -Force -Path ssl | Out-Null\nopenssl req -x509 -nodes -days 3650 -newkey rsa:4096 `\n -keyout ssl/privkey.pem `\n -out ssl/fullchain.pem `\n -subj "/CN=orbisid.internal" `\n -addext "subjectAltName=DNS:orbisid.internal,IP:192.168.1.100"\n'})})})]}),"\n",(0,s.jsxs)(t.p,{children:["Replace ",(0,s.jsx)(t.code,{children:"orbisid.internal"})," and the IP address with your actual hostname and IP. Users will need to trust the certificate in their browser or via a corporate CA."]}),"\n",(0,s.jsx)(t.h3,{id:"option-c-corporate-ca-certificate",children:"Option C: Corporate CA Certificate"}),"\n",(0,s.jsxs)(t.p,{children:["If your organisation issues certificates internally, request a certificate for the OrbisID hostname and place the resulting ",(0,s.jsx)(t.code,{children:"fullchain.pem"})," and ",(0,s.jsx)(t.code,{children:"privkey.pem"})," files in the ",(0,s.jsx)(t.code,{children:"ssl/"})," directory before starting the stack."]}),"\n",(0,s.jsx)(t.h2,{id:"browser-support",children:"Browser Support"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Browser"}),(0,s.jsx)(t.th,{children:"Minimum Version"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Chrome / Chromium"}),(0,s.jsx)(t.td,{children:"100+"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Firefox"}),(0,s.jsx)(t.td,{children:"100+"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Safari"}),(0,s.jsx)(t.td,{children:"15+"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Microsoft Edge"}),(0,s.jsx)(t.td,{children:"100+"})]})]})]}),"\n",(0,s.jsx)(t.h2,{id:"database",children:"Database"}),"\n",(0,s.jsx)(t.p,{children:"OrbisID uses PostgreSQL 16. Two deployment options are available:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"All-in-One"})," - PostgreSQL runs as a container alongside OrbisID (simplest setup)"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Exter
1nal Database"})," - connect to your own managed PostgreSQL instance (on-premise, AWS RDS, Azure Database, etc.)"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"For external databases, the minimum supported version is PostgreSQL 15."})]})}function m(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},9329(e,t,n){n.d(t,{A:()=>l});n(6540);var r=n(4164);const s="tabItem_Ymn6";var i=n(4848);function l({children:e,hidden:t,className:n}){return(0,i.jsx)("div",{role:"tabpanel",className:(0,r.A)(s,n),hidden:t,children:e})}},5537(e,t,n){n.d(t,{A:()=>S});var r=n(6540),s=n(4164),i=n(5627),l=n(6347),a=n(372),o=n(604),d=n(1861),c=n(8749);function u(e){return r.Children.toArray(e).filter(e=>"\n"!==e).map(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)})?.filter(Boolean)??[]}function h(e){const{values:t,children:n}=e;return(0,r.useMemo)(()=>{const e=t??function(e){return u(e).map(({props:{value:e,label:t,attributes:n,default:r}})=>({value:e,label:t,attributes:n,default:r}))}(n);return function(e){const t=(0,d.XI)(e,(e,t)=>e.value===t.value);if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map(e=>e.value).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e},[t,n])}function m({value:e,tabValues:t}){return t.some(t=>t.value===e)}function p({queryString:e=!1,groupId:t}){const n=(0,l.W6)(),s=function({queryString:e=!1,groupId:t}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!t)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:e,groupId:t});return[(0,o.aZ)(s),(0,r.useCallback)(e=>{if(!s)return;const t=new URLSearchParams(n.location.search);t.set(s,e),n.replace({...n.location,search:t.toString()})},[s,n])]}function x(e){const{defaultValue:t,queryString:n=!1,groupId:s}=e,i=h(e),[l,o]=(0,r.useState)(()=>function({defaultValue:e,tabValues:t}){if(0===t.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!m({value:e,tabValues:t}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${t.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}const n=t.find(e=>e.default)??t[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:i})),[d,u]=p({queryString:n,groupId:s}),[x,j]=function({groupId:e}){const t=function(e){return e?`docusaurus.tab.${e}`:null}(e),[n,s]=(0,c.Dv)(t);return[n,(0,r.useCallback)(e=>{t&&s.set(e)},[t,s])]}({groupId:s}),b=(()=>{const e=d??x;return m({value:e,tabValues:i})?e:null})();(0,a.A)(()=>{b&&o(b)},[b]);return{selectedValue:l,selectValue:(0,r.useCallback)(e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);o(e),u(e),j(e)},[u,j,i]),tabValues:i}}var j=n(9136);const b="tabList__CuJ",f="tabItem_LNqP";var y=n(4848);function g({className:e,block:t,selectedValue:n,selectValue:r,tabValues:l}){const a=[],{blockElementScrollPositionUntilNextRender:o}=(0,i.a_)(),d=e=>{const t=e.currentTarget,s=a.indexOf(t),i=l[s].value;i!==n&&(o(t),r(i))},c=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=a.indexOf(e.currentTarget)+1;t=a[n]??a[0];break}case"ArrowLeft":{const n=a.indexOf(e.currentTarget)-1;t=a[n]??a[a.length-1];break}}t?.focus()};return(0,y.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.A)("tabs",{"tabs--block":t},e),children:l.map(({value:e,label:t,attributes:r})=>(0,y.jsx)("li",{role:"tab",tabIndex:n===e?0:-1,"aria-selected":n===e,ref:e=>{a.push(e)},onKeyDown:c,onClick:d,...r,className:(0,s.A)("tabs__item",f,r?.className,{"tabs__item--active":n===e}),children:t??e},e))})}function v({lazy:e,children:t,selectedValue:n}
1){const i=(Array.isArray(t)?t:[t]).filter(Boolean);if(e){const e=i.find(e=>e.props.value===n);return e?(0,r.cloneElement)(e,{className:(0,s.A)("margin-top--md",e.props.className)}):null}return(0,y.jsx)("div",{className:"margin-top--md",children:i.map((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==n}))})}function w(e){const t=x(e);return(0,y.jsxs)("div",{className:(0,s.A)("tabs-container",b),children:[(0,y.jsx)(g,{...t,...e}),(0,y.jsx)(v,{...t,...e})]})}function S(e){const t=(0,j.A)();return(0,y.jsx)(w,{...e,children:u(e.children)},String(t))}},8453(e,t,n){n.d(t,{R:()=>l,x:()=>a});var r=n(6540);const s={},i=r.createContext(s);function l(e){const t=r.useContext(i);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),r.createElement(i.Provider,{value:t},e.children)}}}]);
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.