1"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[15767],{15868:(e,n,r)=>{r.d(n,{A:()=>s});var t=r(65162),o=r(62540);function s({header:e,inline:n,updated:r,version:s}){return(0,o.jsx)(t.A,{text:`v${s}`,variant:r?"success":"info",className:e?"absolute right-0 top-1.5":n?"inline-block ml-1":"ml-2"})}},22491:(e,n,r)=>{r.d(n,{A:()=>l});r(63696);var t=r(11750),o=r(75373);const s={tabItem:"tabItem_wHwb"};var a=r(62540);function i({children:e,className:n,hidden:r}){return(0,a.jsx)("div",{role:"tabpanel",className:(0,t.A)(s.tabItem,n),hidden:r,children:e})}function l({children:e,className:n,value:r}){const{selectedValue:t,lazy:s}=(0,o.uc)(),l=r===t;return!l&&s?null:(0,a.jsx)(i,{className:n,hidden:!l,children:e})}},33161:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>u,contentTitle:()=>d,default:()=>f,frontMatter:()=>c,metadata:()=>t,toc:()=>h});const t=JSON.parse('{"id":"guides/codeowners","title":"Code owners","description":"Code owners enables companies to define individuals, teams, or groups that are responsible for code","source":"@site/docs/guides/codeowners.mdx","sourceDirName":"guides","slug":"/guides/codeowners","permalink":"/docs/guides/codeowners","draft":false,"unlisted":false,"editUrl":"https://github.com/moonrepo/moon/tree/master/website/docs/guides/codeowners.mdx","tags":[{"inline":true,"label":"code","permalink":"/docs/tags/code"},{"inline":true,"label":"owners","permalink":"/docs/tags/owners"},{"inline":true,"label":"codeowners","permalink":"/docs/tags/codeowners"}],"version":"current","frontMatter":{"title":"Code owners","toc_max_heading_level":6,"tags":["code","owners","codeowners"]},"sidebar":"guides","previous":{"title":"Code generation","permalink":"/docs/guides/codegen"},"next":{"title":"Daemon","permalink":"/docs/guides/daemon"}}');var o=r(62540),s=r(43023),a=r(49479),i=r(22491),l=r(15868);const c={title:"Code owners",toc_max_heading_level:6,tags:["code","owners","codeowners"]},d=void 0,u={},h=[{value:"Defining owners",id:"defining-owners",level:2},{value:"Project-level",id:"project-level",level:3},{value:"Workspace-level",id:"workspace-level",level:3},{value:"Generating <code>CODEOWNERS</code>",id:"generating-codeowners",level:2},{value:"FAQ",id:"faq",level:2},{value:"What providers or formats are supported?",id:"what-providers-or-formats-are-supported",level:3},{value:"Where does the <code>CODEOWNERS</code> file get created?",id:"where-does-the-codeowners-file-get-created",level:3},{value:"Why are owners defined in <code>moon.*</code> and not an alternative like <code>OWNERS</code>?",id:"why-are-owners-defined-in-moon-and-not-an-alternative-like-owners",level:3}];function p(e){const n={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(l.A,{version:"1.8.0",header:!0}),"\n",(0,o.jsx)(n.p,{children:"Code owners enables companies to define individuals, teams, or groups that are responsible for code\nin a repository. This is useful in ensuring that pull/merge requests are reviewed and approved by a\nspecific set of contributors, before the branch is merged into the base branch."}),"\n",(0,o.jsxs)(n.p,{children:["With that being said, moon ",(0,o.jsx)(n.em,{children:"does not"})," implement a custom code owners solution, and instead builds\nupon the popular ",(0,o.jsx)(n.code,{children:"CODEOWNERS"})," integration in VCS providers, like GitHub, GitLab, and Bitbucket."]}),"\n",(0,o.jsx)(n.h2,{id:"defining-owners",children:"Defining owners"}),"\n",(0,o.jsxs)(n.p,{children:["With moon, you ",(0,o.jsx)(n.em,{children:"do not"})," modify a ",(0,o.jsx)(n.code,{children:"CODEOWNERS"})," file directly. Instead you define owners ",(0,o.jsx)(n.em,{children:"per project"}),"\nwith ",(0,o.jsx)(n.a,{href:"../config/project",children:(0,o.jsx)(n.code,{children:"moon.*"})}),", or globally with ",(0,o.jsx)(n.a,{href:"../config/workspace",children:(0,o.jsx)(n.code,{children:".moon/workspace.*"})}),".\nThese owners are then aggregated and automatically\n",(0,o.jsxs)(n.a,{href:"#generating-codeowners",children:["synced to a ",(0,o.jsx)(n.code,{children:"CODEOWNERS"})," file"]}),"."]}),"\n",(0,o.jsx)(n.admonition,{type:"info",children:(0,o.jsx)(n.p,{children:"An owner is a user, team, or group unique to your VCS provider. Please refer to your provider's\ndocumentation for the correct format in which to define owners."})}),"\n",(0,o.jsx)(n.h3,{id:"project-level",children:"Project-level"}),"\n",(0,o.jsxs)(n.p,{children:["For projects, we support an ",(0,o.jsx)(n.a,{href:"../config/project#owners",children:(0,o.jsx)(n.code,{children:"owners"})})," setting in\n",(0,o.jsx)(n.a,{href:"../config/project",children:(0,o.jsx)(n.code,{children:"moon.*"})})," that accepts file patterns/paths and their owners (contributors\nrequired to review), as well as operational settings for minimum required approvals, custom groups,\nand more."]}),"\n",(0,o.jsx)(n.p,{children:"Paths configured here are relative from the project root, and will be prefixed with the project\nsource (path from workspace root to project root) when the file is synced."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:'title="packages/components/moon.yml"',children:"owners:\n requiredApprovals: 2\n paths:\n 'src/': ['@frontend', '@design-system']\n '*.config.js': ['@frontend-infra']\n '*.json': ['@frontend-infra']\n"})}),"\n",(0,o.jsx)(n.p,{children:"The configuration above would generate the following:"}),"\n",(0,o.jsxs)(a.A,{groupId:"codeowners",defaultValue:"github",values:[{label:"GitHub",value:"github"},{label:"GitLab",value:"gitlab"},{label:"Bitbucket",value:"bitbucket"}],children:[(0,o.jsx)(i.A,{value:"github",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-shell",metastring:'title=".github/CODEOWNERS"',children:"# components\n/packages/components/src/ @frontend @design-system\n/packages/components/*.config.js @frontend-infra\n/packages/components/*.json @frontend-infra\n"})})}),(0,o.jsx)(i.A,{value:"gitlab",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-shell",metastring:'title=".gitlab/CODEOWNERS"',children:"# components\n[components][2]\n/packages/components/src/ @frontend @design-system\n/packages/components/*.config.js @frontend-infra\n/packages/components/*.json @frontend-infra\n"})})}),(0,o.jsx)(i.A,{value:"bitbucket",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-shell",metastring:'title=".bitbucket/CODEOWNERS"',children:"# components\n/packages/components/src/ @frontend @design-system\n/packages/components/*.config.js @frontend-infra\n/packages/components/*.json @frontend-infra\n"})})})]}
1),"\n",(0,o.jsx)(n.h3,{id:"workspace-level",children:"Workspace-level"}),"\n",(0,o.jsxs)(n.p,{children:["Project scoped owners are great but sometimes you need to define owners for files that span across\nall projects, or files at any depth within the repository. With the\n",(0,o.jsx)(n.a,{href:"../config/workspace#globalpaths",children:(0,o.jsx)(n.code,{children:"codeowners.globalPaths"})})," setting in\n",(0,o.jsx)(n.a,{href:"../config/workspace",children:(0,o.jsx)(n.code,{children:".moon/workspace.*"})}),", you can do just that."]}),"\n",(0,o.jsx)(n.p,{children:"Paths configured here are used as-is, allowing for full control of what ownership is applied."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:'title=".moon/workspace.yml"',children:"codeowners:\n globalPaths:\n # All files\n '*': ['@admins']\n # Config folder at any depth\n 'config/': ['@app-platform']\n # GitHub folder at the root\n '/.github/': ['@infra']\n"})}),"\n",(0,o.jsx)(n.p,{children:"The configuration above would generate the following at the top of the file (is the same for all\nproviders):"}),"\n",(0,o.jsxs)(a.A,{groupId:"codeowners",defaultValue:"github",values:[{label:"GitHub",value:"github"},{label:"GitLab",value:"gitlab"},{label:"Bitbucket",value:"bitbucket"}],children:[(0,o.jsx)(i.A,{value:"github",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-shell",metastring:'title=".github/CODEOWNERS"',children:"# (workspace)\n* @admins\nconfig/ @app-platform\n/.github/ @infra\n"})})}),(0,o.jsx)(i.A,{value:"gitlab",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-shell",metastring:'title=".gitlab/CODEOWNERS"',children:"# (workspace)\n* @admins\nconfig/ @app-platform\n/.github/ @infra\n"})})}),(0,o.jsx)(i.A,{value:"bitbucket",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-shell",metastring:'title=".bitbucket/CODEOWNERS"',children:"# (workspace)\n* @admins\nconfig/ @app-platform\n/.github/ @infra\n"})})})]}),"\n",(0,o.jsxs)(n.h2,{id:"generating-codeowners",children:["Generating ",(0,o.jsx)(n.code,{children:"CODEOWNERS"})]}),"\n",(0,o.jsxs)(n.p,{children:["Code owners is an opt-in feature, and as such, the ",(0,o.jsx)(n.code,{children:"CODEOWNERS"})," file can be generated in a few ways.\nThe first is manually, with the ",(0,o.jsx)(n.a,{href:"../commands/sync/code-owners",children:(0,o.jsx)(n.code,{children:"moon sync codeowners"})})," command."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-shell",children:"$ moon sync codeowners\n"})}),"\n",(0,o.jsx)(n.p,{children:"While this works, it is a manual process, and can easily be forgotten, resulting in an out-of-date\nfile."}),"\n",(0,o.jsxs)(n.p,{children:["An alternative solution is the ",(0,o.jsx)(n.a,{href:"../config/workspace#sync",children:(0,o.jsx)(n.code,{children:"codeowners.sync"})})," setting in\n",(0,o.jsx)(n.a,{href:"../config/workspace#codeowners",children:(0,o.jsx)(n.code,{children:".moon/workspace.*"})}),", that when enabled, moon will automatically\ngenerate a ",(0,o.jsx)(n.code,{children:"CODEOWNERS"})," file when a ",(0,o.jsx)(n.a,{href:"../concepts/target",children:"target"})," is ran."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:'title=".moon/workspace.yml"',children:"codeowners:\n sync: true\n"})}),"\n",(0,o.jsxs)(n.blockquote,{children:["\n",(0,o.jsxs)(n.p,{children:["The format and location of the ",(0,o.jsx)(n.code,{children:"CODEOWNERS"})," file is based on the\n",(0,o.jsx)(n.a,{href:"../config/workspace#provider",children:(0,o.jsx)(n.code,{children:"vcs.provider"})})," setting."]}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"faq",children:"FAQ"}),"\n",(0,o.jsx)(n.h3,{id:"what-providers-or-formats-are-supported",children:"What providers or formats are supported?"}),"\n",(0,o.jsxs)(n.p,{children:["The following providers are supported, based on the ",(0,o.jsx)(n.a,{href:"../config/workspace#provider",children:(0,o.jsx)(n.code,{children:"vcs.provider"})}
1),"\nsetting."]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"https://support.atlassian.com/bitbucket-cloud/docs/set-up-and-use-code-owners/",children:"Bitbucket"})," (native\ncode owners, uses the same syntax as GitHub)"]}),"\n",(0,o.jsxs)(n.li,{children:["Bitbucket (legacy) \u2014 the ",(0,o.jsx)(n.code,{children:"bitbucket-legacy"})," provider, for the 3rd-party\n",(0,o.jsx)(n.a,{href:"https://marketplace.atlassian.com/apps/1218598/code-owners-for-bitbucket?tab=overview&hosting=cloud",children:"DevSensei / Code Owners for Bitbucket"}),"\napp, which uses a root ",(0,o.jsx)(n.code,{children:"CODEOWNERS"})," and the ",(0,o.jsx)(n.code,{children:"Check()"})," syntax"]}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners",children:"GitHub"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.gitlab.com/ee/user/project/codeowners/reference.html",children:"GitLab"})}),"\n",(0,o.jsx)(n.li,{children:"Other (very basic syntax)"}),"\n"]}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"bitbucket"})," provider now targets Bitbucket's native code owners (",(0,o.jsx)(n.code,{children:".bitbucket/CODEOWNERS"}),",\nGitHub-compatible syntax). If you were relying on the\n",(0,o.jsx)(n.a,{href:"https://marketplace.atlassian.com/apps/1218598/code-owners-for-bitbucket?tab=overview&hosting=cloud",children:"DevSensei / Code Owners for Bitbucket"}),"\napp (root ",(0,o.jsx)(n.code,{children:"CODEOWNERS"})," with the ",(0,o.jsx)(n.code,{children:"Check()"})," syntax), set ",(0,o.jsx)(n.code,{children:"vcs.provider"})," to ",(0,o.jsx)(n.code,{children:"bitbucket-legacy"})," to keep\nthe previous output."]})}),"\n",(0,o.jsxs)(n.h3,{id:"where-does-the-codeowners-file-get-created",children:["Where does the ",(0,o.jsx)(n.code,{children:"CODEOWNERS"})," file get created?"]}),"\n",(0,o.jsx)(n.p,{children:"The location of the file is dependent on the configured provider."}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["GitHub -> ",(0,o.jsx)(n.code,{children:".github/CODEOWNERS"})]}),"\n",(0,o.jsxs)(n.li,{children:["GitLab -> ",(0,o.jsx)(n.code,{children:".gitlab/CODEOWNERS"})]}),"\n",(0,o.jsxs)(n.li,{children:["Bitbucket -> ",(0,o.jsx)(n.code,{children:".bitbucket/CODEOWNERS"})]}),"\n",(0,o.jsxs)(n.li,{children:["Everything else (including ",(0,o.jsx)(n.code,{children:"bitbucket-legacy"}),") -> ",(0,o.jsx)(n.code,{children:"CODEOWNERS"})]}),"\n"]}),"\n",(0,o.jsxs)(n.h3,{id:"why-are-owners-defined-in-moon-and-not-an-alternative-like-owners",children:["Why are owners defined in ",(0,o.jsx)(n.code,{children:"moon.*"})," and not an alternative like ",(0,o.jsx)(n.code,{children:"OWNERS"}),"?"]}),"\n",(0,o.jsxs)(n.p,{children:["A very popular pattern for defining owners is through an ",(0,o.jsx)(n.code,{children:"OWNERS"})," file, which can appear in any\nfolder, at any depth, within the repository. All of these files are then aggregated into a single\n",(0,o.jsx)(n.code,{children:"CODEOWNERS"})," file."]}),"\n",(0,o.jsxs)(n.p,{children:["While this is useful for viewing ownership of a folder at a glance, it incurs a massive performance\nhit as we'd have to constantly glob the ",(0,o.jsx)(n.em,{children:"entire"})," repository to find all ",(0,o.jsx)(n.code,{children:"OWNERS"})," files. We found it\nbest to define owners in ",(0,o.jsx)(n.code,{children:"moon.*"})," instead for the following reasons:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"No performance hit, as we're already loading and parsing these config files."}),"\n",(0,o.jsx)(n.li,{children:"Co-locates owners with the rest of moon's configuration."}),"\n",(0,o.jsx)(n.li,{children:"Ownership is now a part of the project graph, enabling future features."}),"\n"]})]})}function f(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}},43023:(e,n,r)=>{r.d(n,{R:()=>a,x:()=>i});var t=r(63696);const o={},s=t.createContext(o);function a(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),t.createElement(s.Provider,{value:n},e.children)}},49479:(e,n,r)=>{r.d(n,{A:()=>p});r(63696);var t=r(11750),o=r(53237),s=r(75373),a=r(90766),i=r(86681);const l={tabList:"tabList_J5MA",tabItem:"tabItem_l0OV"};var c=r(62540);function d({className:e}){const{selectedValue:n,selectValue:r,tabValues:o,block:i}=(0,s.uc)(),d=[],{blockElementScrollPositionUntilNextRender:u}
1=(0,a.a_)(),h=e=>{const t=e.currentTarget,s=d.indexOf(t),a=o[s].value;a!==n&&(u(t),r(a))},p=e=>{let n=null;switch(e.key){case"Enter":h(e);break;case"ArrowRight":{const r=d.indexOf(e.currentTarget)+1;n=d[r]??d[0];break}case"ArrowLeft":{const r=d.indexOf(e.currentTarget)-1;n=d[r]??d[d.length-1];break}}n?.focus()};return(0,c.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.A)("tabs",{"tabs--block":i},e),children:o.map((({value:e,label:r,attributes:o})=>(0,c.jsx)("li",{role:"tab",tabIndex:n===e?0:-1,"aria-selected":n===e,ref:e=>{d.push(e)},onKeyDown:p,onClick:h,...o,className:(0,t.A)("tabs__item",l.tabItem,o?.className,{"tabs__item--active":n===e}),children:r??e},e)))})}function u({children:e}){return(0,c.jsx)("div",{className:"margin-top--md",children:e})}function h({className:e,children:n}){return(0,c.jsxs)("div",{className:(0,t.A)(o.G.tabs.container,"tabs-container",l.tabList),children:[(0,c.jsx)(d,{className:e}),(0,c.jsx)(u,{children:n})]})}function p(e){const n=(0,i.A)(),r=(0,s.OC)(e);return(0,c.jsx)(s.O_,{value:r,children:(0,c.jsx)(h,{className:e.className,children:(0,s.vT)(e.children)})},String(n))}},65162:(e,n,r)=>{r.d(n,{A:()=>i});var t=r(11750),o=r(74599),s=r(62540);const a={failure:"bg-red-100 text-red-900",info:"bg-pink-100 text-pink-900",success:"bg-green-100 text-green-900",warning:"bg-orange-100 text-orange-900"};function i({className:e,icon:n,text:r,variant:i}){return(0,s.jsxs)("span",{className:(0,t.A)("inline-flex items-center px-1 py-0.5 rounded text-xs font-bold uppercase",i?a[i]:"bg-gray-100 text-gray-800",e),children:[n&&(0,s.jsx)(o.A,{icon:n,className:"mr-1"}),r]})}},75373:(e,n,r)=>{r.d(n,{OC:()=>f,O_:()=>b,uc:()=>m,vT:()=>d});var t=r(63696),o=r(49519),s=r(14395),a=r(35043),i=r(44544),l=r(94243),c=r(62540);function d(e){return t.Children.toArray(e).filter((e=>"\n"!==e))}function u(e){const{values:n,children:r}=e;return(0,t.useMemo)((()=>{const e=n??function(e){return t.Children.toArray(e).flatMap((e=>{if(!e)return[];if((0,t.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:r,default:t}})=>({value:e,label:n,attributes:r,default:t})))}(r);return function(e){const n=(0,i.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,r])}function h({value:e,tabValues:n}){return n.some((n=>n.value===e))}function p({queryString:e=!1,groupId:n}){const r=(0,o.W6)(),s=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)(s),(0,t.useCallback)((e=>{if(!s)return;const n=new URLSearchParams(r.location.search);n.set(s,e),r.replace({...r.location,search:n.toString()})}),[s,r])]}function f(e){const{defaultValue:n,queryString:r=!1,groupId:o}=e,a=u(e),[i,c]=(0,t.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(!h({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 r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:a}))),[d,f]=p({queryString:r,groupId:o}),[g,m]=function({groupId:e}){const n=function(e){return e?`docusaurus.tab.${e}`:null}(e),[r,o]=(0,l.Dv)(n);return[r,(0,t.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:o}),b=(()=>{const e=d??g;return h({value:e,tabValues:a})?e:null})();(0,s.A)((()=>{b&&c(b)}),[b]);return{selectedValue:i,selectValue:(0,t.useCallback)((e=>{if(!h({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);c(e),f(e),m(e)}),[f,m,a]),tabValues:a,lazy:e.lazy??!1,block:e.block??!1}}const g=(0,t.createContext)(null);function m(){const e=t.useContext(g);if(!e)throw new Error("useTabsContext() must be used within a Tabs component");return e}function b(e){return(0,c.jsx)(g.Provider,{value:e.value,children: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.