PageSourceSearch

https://ikalogic.com/assets/js/1b8e4779.aa02e7fa.js

js ikalogic.com collected 2026-10-02 10:30:23 UTC 20,734 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkdocutest=globalThis.webpackChunkdocutest||[]).push([[1756],{57537(e,n,t){t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>h});const s=JSON.parse('{"id":"kb/la-api/la_home","title":"Logic Analyzer API","description":"This API talks to the device directly and is kept for the projects that already use it. It gains","source":"@site/docs/kb/la-api/000index.md","sourceDirName":"kb/la-api","slug":"/kb/la-api/la_home","permalink":"/kb/la-api/la_home","draft":false,"unlisted":false,"tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"id":"la_home","title":"Logic Analyzer API","sidebar_position":1},"sidebar":"docs_la_api","next":{"title":"Common error codes","permalink":"/kb/la-api/common-code/common_err"}}');var i=t(74848),r=t(28453),a=t(4865),l=t(19365);const o={id:"la_home",title:"Logic Analyzer API",sidebar_position:1},c=void 0,d={},h=[{value:"Overview",id:"overview",level:2},{value:"API Workflow",id:"api-workflow",level:2},{value:"Retrieving Captured Samples",id:"retrieving-captured-samples",level:2},{value:"Processing Transitions",id:"processing-transitions",level:3},{value:"Example: Retrieving Captured Samples",id:"example-retrieving-captured-samples",level:3},{value:"Header Files",id:"header-files",level:2},{value:"Thread Safety",id:"thread-safety",level:2}];function p(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(n.admonition,{title:"Superseded by the ScanaStudio SDK",type:"caution",children:[(0,i.jsx)(n.p,{children:"This API talks to the device directly and is kept for the projects that already use it. It gains\nno new features, and it does not support ScanaStudio V6's server, workspaces, decoders or\nmeasurements."}),(0,i.jsxs)(n.p,{children:["New work should use the ",(0,i.jsx)(n.a,{href:"/kb/scanastudio-sdk/scanastudio_sdk_home/",children:"ScanaStudio SDK"}),", which\ncovers Python, NodeJS, Rust and C. The\n",(0,i.jsx)(n.a,{href:"/kb/scanastudio-sdk/migrating/",children:"migration guide"})," maps this API call by call."]})]}),"\n",(0,i.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.strong,{children:"Logic Analyzer API"})," (also referred to as ",(0,i.jsx)(n.strong,{children:"IHWAPI"}),", which is a - legacy - short term for ",(0,i.jsx)(n.strong,{children:"Ikalogic Hardware API"}),") is a collection of libraries (",(0,i.jsx)(n.strong,{children:"DLLs for Windows, SO files for Linux/macOS"}),") that allows users to interface with Ikalogic's logic analyzer devices programmatically."]}),"\n",(0,i.jsx)(n.admonition,{title:"Note",type:"note",children:(0,i.jsxs)(n.p,{children:["This API is designed for seamless integration with various programming languages and environments, including ",(0,i.jsx)(n.strong,{children:"C, C++, C#, and Visual Basic"}),", thanks to its ABI compatibility. However, official support is currently provided only through C header files. If additional language bindings are required, we welcome feedback on possible expansions."]})}),"\n",(0,i.jsx)(n.p,{children:"The API maintains a consistent structure across different devices to ensure a unified experience. However, due to inherent hardware differences, some variations in functionality may exist."}),"\n",(0,i.jsx)(n.admonition,{title:"Known limitations",type:"caution",children:(0,i.jsxs)(n.p,{children:["Ikalogic logic analyzer devices are designed to operate using ",(0,i.jsx)(n.strong,{children:"ScanaStudio"})," software. While it's possible to achieve equivalent signal capture results using the API, the signal generation features as well as advanced trigger features are only available via ScanaStudio for the time being."]})}),"\n",(0,i.jsx)(n.h2,{id:"api-workflow",children:"API Workflow"}),"\n",(0,i.jsx)(n.p,{children:"The typical workflow for interacting with a logic analyzer using the API follows these steps:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Detect available devices"})," \u2013 List all connected devices on the USB bus."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Open a device"})," \u2013 Select and open a device from the available list."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Configure and start a capture"})," \u2013 Set up the analyzer and begin data acquisition."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Retrieve captured samples"})," \u2013 Access and process the recorded signal data."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Close the device"})," \u2013 (Optional) Close the device when finished."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Closing the device after retrieving data is not mandatory. If multiple captures are needed, the device can remain open for extended use. Additionally, the API provides functions to poll the connection status, ensuring the device remains available before initiating new captures."}),"\n",(0,i.jsx)(n.h2,{id:"retrieving-captured-samples",children:"Retrieving Captured Samples"}),"\n",(0,i.jsxs)(n.p,{children:["As of ",(0,i.jsx)(n.strong,{children:"API version 2.0"}),", the sample retrieval mechanism has been redesigned to align with the ",(0,i.jsx)(n.strong,{children:"ScanaStudio scripting API"}),". Captured signals are stored in a ",(0,i.jsx)(n.strong,{children:"compressed format"}),", significantly optimizing memory usage."]}),"\n",(0,i.jsxs)(n.p,{children:["Instead of storing every individual sample, only ",(0,i.jsx)(n.strong,{children:"logic transitions"})," are recorded. Each transition consists of:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Transition value"})," (logic level change)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Sample index"})," (position in the timeline)"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(50395).A+"",width:"823",height:"285"})}),"\n",(0,i.jsx)(n.h3,{id:"processing-transitions",children:"Processing Transitions"}),"\n",(0,i.jsxs)(n.p,{children:["Internally, each logic channel maintains an ",(0,i.jsx)(n.strong,{children:"iterator"}
1)," that retrieves stored transitions efficiently. Before reading transitions, the iterator must be reset using the appropriate API function:"]}),"\n","\n",(0,i.jsxs)(a.A,{groupId:"la-device",children:[(0,i.jsx)(l.A,{value:"sp259",label:"SP259 series",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-cpp",children:"sp259api_trs_reset(); // Resets iterator to the first transition\n"})})}),(0,i.jsx)(l.A,{value:"sp1000",label:"SP1000G series",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-cpp",children:"sp1000gapi_trs_reset(); // Resets iterator to the first transition\n"})})}),(0,i.jsx)(l.A,{value:"sp209",label:"SP209 series",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-cpp",children:"sp209api_trs_reset(); // Resets iterator to the first transition\n"})})})]}),"\n",(0,i.jsx)(n.p,{children:"Subsequently, the transitions are retrieved sequentially using:"}),"\n",(0,i.jsxs)(a.A,{groupId:"la-device",children:[(0,i.jsx)(l.A,{value:"sp259",label:"SP259 series",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-cpp",children:"sp259api_trs_get_next(); // Resets iterator to the first transition\n"})})}),(0,i.jsx)(l.A,{value:"sp1000",label:"SP1000G series",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-cpp",children:"sp1000gapi_trs_get_next(); // Resets iterator to the first transition\n"})})}),(0,i.jsx)(l.A,{value:"sp209",label:"SP209 series",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-cpp",children:"sp209api_trs_get_next(); // Resets iterator to the first transition\n"})})})]}),"\n",(0,i.jsx)(n.p,{children:"until the last transition is reached."}),"\n",(0,i.jsxs)(n.admonition,{title:"More about iterators",type:"info",children:[(0,i.jsxs)(n.p,{children:["Under the hood, the API have an iterator attached to each logic channel. The job of the iterator is to fetch the logic transitions (i.e. logic change) from the compressed storage, and provide it the user of the API, in the most efficient way (offering very fast fetching with minimal memory and processor impact). As with the scripting API, the iterator for each channel needs to be reset, before it can be used to navigate to the first transition. (using the function ",(0,i.jsx)(n.code,{children:"DEVICEAPI_trs_reset()"})," or ",(0,i.jsx)(n.code,{children:"DEVICEAPI_trs_before()"}),", where ",(0,i.jsx)(n.code,{children:"DEVICEAPI_"})," is to be replaced with your actual device api name like in the examples above)."]}),(0,i.jsxs)(n.p,{children:["Then, the proper way to retrieve captured samples is to call ",(0,i.jsx)(n.code,{children:"DEVICEAPI_trs_next()"})," until the very last transition is reached for a specific channel."]})]}),"\n",(0,i.jsx)(n.h3,{id:"example-retrieving-captured-samples",children:"Example: Retrieving Captured Samples"}),"\n",(0,i.jsx)(n.p,{children:"The following is a example showing how to open a device, launch a capture and retrieve captured samples (C++ Code). Please note that this code is rather a simplistic minimal example than a recommended way of interfacing to the device. Please refer to the dedicated chapter of each device for detailed API reference."}),"\n",(0,i.jsxs)(a.A,{groupId:"la-device",children:[(0,i.jsx)(l.A,{value:"sp259",label:"SP259 series",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-cpp",children:'int main()\n{\n    sp259api_handle h;\n    sp259api_create_new_handle(&h, sp259api_model_t::sp259_industrial);\n    sp259api_create_device_list(h);\n    sp259api_device_open_first(h);\n    sp259api_free_device_list(h); \n\n    sp259api_settings_t settings = {};\n    settings.sampling_depth = 10e6;                           \n    settings.post_trig_depth = settings.sampling_depth * 0.9; \n    settings.s_clk = 250e6;\n\n    sp259api_trigger_description_t trig_a, trig_b;\n    trig_a.type = sp259api_trigger_type_t::SP259API_TRG_NOTRIG;\n    trig_a.channel = -1;\n    trig_b.type = sp259api_trigger_type_t::SP259API_TRG_NOTRIG;\n    trig_b.channel = -1;\n\n    sp259api_launch_new_capture_simple_trigger(h, trig_a, trig_b, settings);\n\n\n    int64_t total = 0; //total samples\n    int64_t pre = 0; //pre trigger samples\n    int64_t post = 0; //post trigger samples\n\n    while (post < settings.post_trig_depth)\n    {\n        e = sp259api_get_available_samples(h, &total, &post);\n        pre = total - post;\n        msleep(100);\n\n        std::cout << "retrieved transitions, pre-trig: " << pre / 1000 << +" K, post-trig:" << post / 1000 << " K" << std::endl;\n    }\n\n    const uint8_t ch = 1;\n    sp259api_trs_t trs;\n    sp259api_trs_reset(h, ch);\n    trs.sampple_index = 0;\n    bool is_not_last = true;\n    int trs_count = 0;\n\n    while (is_not_last && trs_count < 10)\n    {\n        sp259api_trs_get_next(h, ch, &trs);\n        printf("TRS @ %lld [%d]\\n", trs.sampple_index, trs.value);\n        sp259api_trs_is_not_last(h, ch, &is_not_last);\n        trs_count++;\n    }\n    \n    sp259api_free(h);\n    return 0;\n}\n\n'})})}),(0,i.jsx)(l.A,{value:"sp1000",label:"SP1000G series",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-cpp",children:'int main() \n{\n    sp1000gapi_handle h;\n    sp1000gapi_create_new_handle(&h, sp1000gapi_model_t::sp1054g);\n    \n    sp1000gapi_create_device_list(h);\n    sp1000gapi_device_open_first(h);\n    \n    sp1000gapi_settings_t settings = {};\n    settings.s_clk = 250e6;\n    settings.sampling_depth = 10e6;\n    settings.post_trig_depth = settings.sampling_depth * 0.9;\n    settings.thresh_capture_mv[0] = 1000;\n    settings.ext_trig_out_polarity = true;\n\n    for (int ch = 0; ch < SP1000G_CHANNELS_COUNT;
1 ch++) {\n        settings.io_type[ch] = SP1000GAPI_IO_IN;\n        settings.io_pull[ch] = SP1000GAPI_PULL_DOWN;\n    }\n\n    sp1000gapi_trigger_description_t trig_a = {SP1000GAPI_TRG_NOTRIG, -1};\n    sp1000gapi_trigger_description_t trig_b = {SP1000GAPI_TRG_NOTRIG, -1};\n\n    sp1000gapi_launch_new_capture_simple_trigger(h, trig_a, trig_b, settings);\n    \n    int64_t total_samples = 0, post_trig_samples = 0;\n    while (post_trig_samples < settings.post_trig_depth) {\n        sp1000gapi_get_available_samples(h, &total_samples, &post_trig_samples);\n        msleep(100);\n    }\n\n    const uint8_t ch = 1;\n    sp1000gapi_trs_t trs;\n    sp1000gapi_trs_reset(h, ch);\n    trs.sampple_index = 0;\n    bool is_not_last = true;\n    int trs_count = 0;\n\n    while (is_not_last && trs_count < 10)\n    {\n        sp1000gapi_trs_get_next(h, ch, &trs);\n        printf("TRS @ %lld [%d]\\n", trs.sampple_index, trs.value);\n        sp1000gapi_trs_is_not_last(h, ch, &is_not_last);\n        trs_count++;\n    }\n\n    sp1000gapi_free(h);\n    return 0;\n}\n'})})})]}),"\n",(0,i.jsx)(n.h2,{id:"header-files",children:"Header Files"}),"\n",(0,i.jsx)(n.p,{children:"To use the API, the following header files must be included in the project:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"ihwapi_common_types.h"})})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Shared across all logic analyzer devices."}),"\n",(0,i.jsx)(n.li,{children:"Defines core types and structures used throughout the API."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"*DEVICE*_types.h"})})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Contains ",(0,i.jsx)(n.strong,{children:"device-specific"})," type definitions and structures."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"*DEVICE*"})," should be replaced with the actual device name (e.g., ",(0,i.jsx)(n.code,{children:"sp209_types.h"}),")."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"*DEVICE*api.h"})})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Declares all API functions for the specific logic analyzer model."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"thread-safety",children:"Thread Safety"}),"\n",(0,i.jsxs)(n.p,{children:["Unless explicitly stated otherwise, all API functions are ",(0,i.jsx)(n.strong,{children:"thread-safe"}),", ensuring safe execution in ",(0,i.jsx)(n.strong,{children:"multi-threaded"})," environments."]}),"\n",(0,i.jsx)(n.admonition,{title:"Disclaimer",type:"info",children:(0,i.jsx)(n.p,{children:"This document assumes you have some general programming knowledge, specially in C / C++"})})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(p,{...e})}):p(e)}},19365(e,n,t){t.d(n,{A:()=>o});t(96540);var s=t(34164),i=t(47751);const r="tabItem_Ymn6";var a=t(74848);function l({children:e,className:n,hidden:t}){return(0,a.jsx)("div",{role:"tabpanel",className:(0,s.A)(r,n),hidden:t,children:e})}function o({children:e,className:n,value:t}){const{selectedValue:s,lazy:r}=(0,i.uc)(),o=t===s;return!o&&r?null:(0,a.jsx)(l,{className:n,hidden:!o,children:e})}},4865(e,n,t){t.d(n,{A:()=>g});t(96540);var s=t(34164),i=t(17559),r=t(47751),a=t(23104),l=t(92303);const o="tabList__CuJ",c="tabItem_LNqP";var d=t(74848);function h({className:e}){const{selectedValue:n,selectValue:t,tabValues:i,block:l}=(0,r.uc)(),o=[],{blockElementScrollPositionUntilNextRender:h}=(0,a.a_)(),p=e=>{const s=e.currentTarget,r=o.indexOf(s),a=i[r].value;a!==n&&(h(s),t(a))},u=e=>{let n=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const t=o.indexOf(e.currentTarget)+1;n=o[t]??o[0];break}case"ArrowLeft":{const t=o.indexOf(e.currentTarget)-1;n=o[t]??o[o.length-1];break}}n?.focus()};return(0,d.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.A)("tabs",{"tabs--block":l}
1,e),children:i.map(({value:e,label:t,attributes:i})=>(0,d.jsx)("li",{role:"tab",tabIndex:n===e?0:-1,"aria-selected":n===e,ref:e=>{o.push(e)},onKeyDown:u,onClick:p,...i,className:(0,s.A)("tabs__item",c,i?.className,{"tabs__item--active":n===e}),children:t??e},e))})}function p({children:e}){return(0,d.jsx)("div",{className:"margin-top--md",children:e})}function u({className:e,children:n}){return(0,d.jsxs)("div",{className:(0,s.A)(i.G.tabs.container,"tabs-container",o),children:[(0,d.jsx)(h,{className:e}),(0,d.jsx)(p,{children:n})]})}function g(e){const n=(0,l.A)(),t=(0,r.OC)(e);return(0,d.jsx)(r.O_,{value:t,children:(0,d.jsx)(u,{className:e.className,children:(0,r.vT)(e.children)})},String(n))}},47751(e,n,t){t.d(n,{OC:()=>g,O_:()=>f,uc:()=>m,vT:()=>d});var s=t(96540),i=t(56347),r=t(205),a=t(57485),l=t(70679),o=t(31682),c=t(74848);function d(e){return s.Children.toArray(e).filter(e=>"\n"!==e)}function h(e){const{values:n,children:t}=e;return(0,s.useMemo)(()=>{const e=n??function(e){return s.Children.toArray(e).flatMap(e=>{if(!e)return[];if((0,s.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return[e];const n="string"==typeof e.type?e.type:e.type.name;throw new Error(`Docusaurus error: Bad <Tabs> child <${n}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.\nIf you do not want to pass on a "value" prop to the direct children of <Tabs>, you can also pass an explicit <Tabs values={...}> prop.`)}).map(({props:{value:e,label:n,attributes:t,default:s}})=>({value:e,label:n,attributes:t,default:s}))}(t);return function(e){const n=(0,o.XI)(e,(e,n)=>e.value===n.value);if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map(e=>`'${e.value}'`).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e},[n,t])}function p({value:e,tabValues:n}){return n.some(n=>n.value===e)}function u({queryString:e=!1,groupId:n}){const t=(0,i.W6)(),r=function({queryString:e=!1,groupId:n}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!n)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 n??null}({queryString:e,groupId:n});return[(0,a.aZ)(r),(0,s.useCallback)(e=>{if(!r)return;const n=new URLSearchParams(t.location.search);n.set(r,e),t.replace({...t.location,search:n.toString()})},[r,t])]}function g(e){const{defaultValue:n,queryString:t=!1,groupId:i}=e,a=h(e),[o,c]=(0,s.useState)(()=>function({defaultValue:e,tabValues:n}){if(0===n.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!p({value:e,tabValues:n}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${n.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}const t=n.find(e=>e.default)??n[0];if(!t)throw new Error("Unexpected error: 0 tabValues");return t.value}({defaultValue:n,tabValues:a})),[d,g]=u({queryString:t,groupId:i}),[_,m]=function({groupId:e}){const n=function(e){return e?`docusaurus.tab.${e}`:null}(e),[t,i]=(0,l.Dv)(n);return[t,(0,s.useCallback)(e=>{n&&i.set(e)},[n,i])]}({groupId:i}),f=(()=>{const e=d??_;return p({value:e,tabValues:a})?e:null})();(0,r.A)(()=>{f&&c(f)},[f]);return{selectedValue:o,selectValue:(0,s.useCallback)(e=>{if(!p({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);c(e),g(e),m(e)},[g,m,a]),tabValues:a,lazy:e.lazy??!1,block:e.block??!1}}const _=(0,s.createContext)(null);function m(){const e=s.useContext(_);if(!e)throw new Error("useTabsContext() must be used within a Tabs component");return e}function f(e){return(0,c.jsx)(_.Provider,{value:e.value,children:e.children})}},50395(e,n,t){const s=t.p+"assets/images/transitions-63465769291b01e7a678da41250ac206.png";t.d(n,["A",0,s])},28453(e,n,t){t.d(n,{R:()=>a,x:()=>l});var s=t(96540);const i={},r=s.createContext(i);function a(e){const n=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(r.Provider,{value:n},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.