PageSourceSearch

https://laradock.io/assets/js/5b21ac5a.7ff7d5ea.js

js laradock.io collected 2026-09-25 19:47:55 UTC 24,331 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunklaradock_documentation=globalThis.webpackChunklaradock_documentation||[]).push([[4347],{82980(e,n,r){r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>x,frontMatter:()=>i,metadata:()=>a,toc:()=>u});const a=JSON.parse('{"id":"services/monitoring/influxdb","title":"InfluxDB","description":"Run InfluxDB in Laradock for high-volume time-series metrics, events, and IoT/analytics data, and chart it with Grafana.","source":"@site/docs/services/monitoring/influxdb.md","sourceDirName":"services/monitoring","slug":"/services/influxdb","permalink":"/docs/services/influxdb","draft":false,"unlisted":false,"editUrl":"https://github.com/laradock/laradock/tree/master/DOCUMENTATION/docs/services/monitoring/influxdb.md","tags":[],"version":"current","frontMatter":{"slug":"/services/influxdb","title":"InfluxDB","description":"Run InfluxDB in Laradock for high-volume time-series metrics, events, and IoT/analytics data, and chart it with Grafana.","keywords":["laradock influxdb","influxdb docker","influxdb docker compose","time series database docker","influxdb grafana docker","influxdb 2 docker"]},"sidebar":"tutorialSidebar","previous":{"title":"Prometheus","permalink":"/docs/services/prometheus"},"next":{"title":"Logstash","permalink":"/docs/services/logstash"}}');var s=r(74848),t=r(28453),l=r(4865),o=r(19365);const i={slug:"/services/influxdb",title:"InfluxDB",description:"Run InfluxDB in Laradock for high-volume time-series metrics, events, and IoT/analytics data, and chart it with Grafana.",keywords:["laradock influxdb","influxdb docker","influxdb docker compose","time series database docker","influxdb grafana docker","influxdb 2 docker"]},c=void 0,d={},u=[{value:"What is InfluxDB?",id:"what-is-influxdb",level:2},{value:"Start InfluxDB",id:"start-influxdb",level:2},{value:"Stop InfluxDB",id:"stop-influxdb",level:2},{value:"Configuration",id:"configuration",level:2},{value:"Connect",id:"connect",level:2},{value:"Get an API token",id:"get-an-api-token",level:2},{value:"Buckets and retention",id:"buckets-and-retention",level:2},{value:"Backup and restore",id:"backup-and-restore",level:2},{value:"Start completely fresh (wipe all data)",id:"start-completely-fresh-wipe-all-data",level:2},{value:"Talk to this database from another Laradock project",id:"talk-to-this-database-from-another-laradock-project",level:2},{value:"Common issues",id:"common-issues",level:2}];function h(e){const n={a:"a",code:"code",h2:"h2",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"what-is-influxdb",children:"What is InfluxDB?"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://www.influxdata.com",children:"InfluxDB"})," is an open-source time-series database purpose-built for high-volume metrics, events, and IoT/analytics data. It's commonly paired with ",(0,s.jsx)(n.a,{href:"/docs/services/grafana",children:"Grafana"})," for dashboards. Laradock builds it (InfluxDB 2.x) as its own container from the official image."]}),"\n",(0,s.jsx)(n.h2,{id:"start-influxdb",children:"Start InfluxDB"}),"\n",(0,s.jsxs)(l.A,{groupId:"interface",children:[(0,s.jsx)(o.A,{value:"cli",label:"Laradock CLI",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"./laradock start influxdb\n"})})}),(0,s.jsx)(o.A,{value:"docker",label:"Docker Compose",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose up -d influxdb\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["Your organization, bucket, and admin user are created on first boot and kept between restarts. Name any other services alongside it to start them together, for example ",(0,s.jsx)(n.code,{children:"./laradock start influxdb workspace"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"stop-influxdb",children:"Stop InfluxDB"}),"\n",(0,s.jsxs)(n.p,{children:["Stopping just pauses the container; ",(0,s.jsx)(n.strong,{children:"your data is safe"})," (kept in the ",(0,s.jsx)(n.code,{children:"influxdb"})," volume):"]}),"\n",(0,s.jsxs)(l.A,{groupId:"interface",children:[(0,s.jsx)(o.A,{value:"cli",label:"Laradock CLI",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"./laradock stop influxdb\n"})})}),(0,s.jsx)(o.A,{value:"docker",label:"Docker Compose",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker 
1compose stop influxdb\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["To delete the container entirely (the data in the ",(0,s.jsx)(n.code,{children:"influxdb"})," volume is still untouched):"]}),"\n",(0,s.jsxs)(l.A,{groupId:"interface",children:[(0,s.jsx)(o.A,{value:"cli",label:"Laradock CLI",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"./laradock remove influxdb\n"})})}),(0,s.jsx)(o.A,{value:"docker",label:"Docker Compose",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose rm -sf influxdb\n"})})})]}),"\n",(0,s.jsx)(n.h2,{id:"configuration",children:"Configuration"}),"\n",(0,s.jsxs)(n.p,{children:["All settings live in ",(0,s.jsx)(n.code,{children:"influxdb/defaults.env"})," and can be overridden by adding the same line to your own ",(0,s.jsx)(n.code,{children:".env"}),":"]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Variable"}),(0,s.jsx)(n.th,{children:"Default"}),(0,s.jsx)(n.th,{children:"What it does"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"INFLUXDB_VERSION"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"2.7"})}),(0,s.jsxs)(n.td,{children:["Image version built via ",(0,s.jsx)(n.code,{children:"influxdb/Dockerfile"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"INFLUXDB_HOST_PORT"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"8086"})}),(0,s.jsxs)(n.td,{children:["Host-side port InfluxDB is published on (container port ",(0,s.jsx)(n.code,{children:"8086"}),")."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"INFLUXDB_INIT_USERNAME"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"laradock"})}),(0,s.jsx)(n.td,{children:"Admin username created on first boot."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"INFLUXDB_INIT_PASSWORD"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"secretpassword"})}),(0,s.jsx)(n.td,{children:"Password for that admin user."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"INFLUXDB_INIT_ORG"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"laradock"})}),(0,s.jsx)(n.td,{children:"Organization created on first boot."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"INFLUXDB_INIT_BUCKET"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"default"})}),(0,s.jsx)(n.td,{children:"Bucket (database) created on first boot."})]})]})]}),"\n",(0,s.jsxs)(n.p,{children:["These map directly to InfluxDB's own ",(0,s.jsx)(n.code,{children:"DOCKER_INFLUXDB_INIT_*"})," environment variables (set in ",(0,s.jsx)(n.code,{children:"influxdb/compose.yml"}),"), with ",(0,s.jsx)(n.code,{children:"DOCKER_INFLUXDB_INIT_MODE=setup"})," triggering the automatic first-run setup. Data itself persists in the ",(0,s.jsx)(n.code,{children:"influxdb"})," ",(0,s.jsx)(n.strong,{children:"named Docker volume"}),", mounted at ",(0,s.jsx)(n.code,{children:"/var/lib/influxdb2"})," inside the container, not a ",(0,s.jsx)(n.code,{children:"DATA_PATH_HOST"})," folder."]}),"\n",(0,s.jsx)(n.h2,{id:"connect",children:"Connect"}),"\n",(0,s.jsxs)(n.p,{children:["Open the UI and API at ",(0,s.jsx)(n.a,{href:"http://localhost:8086",children:"http://localhost:8086"}),"; check readiness with ",(0,s.jsx)(n.code,{children:"curl http://localhost:8086/health"}),". Log in with ",(0,s.jsx)(n.code,{children:"INFLUXDB_INIT_USERNAME"}),"/",(0,s.jsx)(n.code,{children:"INFLUXDB_INIT_PASSWORD"}),", org ",(0,s.jsx)(n.code,{children:"INFLUXDB_INIT_ORG"}),", bucket ",(0,s.jsx)(n.code,{children:"INFLUXDB_INIT_BUCKET"}),". From another container, use ",(0,s.jsx)(n.code,{children:"http://influxdb:8086"}),". The UI login is username/password, but the write and query ",(0,s.jsx)(n.strong,{children:"APIs"})," (and any client library, including Grafana's InfluxDB data source) need a token instead, see ",(0,s.jsx)(n.a,{href:"#get-an-api-token",children:"Get an API token"})," below."]}),"\n",(0,s.jsx)(n.h2,{id:"get-an-api-token",children:"Get an API token"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"influxdb/compose.yml"})," doesn't pin ",(0,s.jsx)(n.code,{children:"DOCKER_INFLUXDB_INIT_ADMIN_TOKEN"}),", so InfluxDB generates a random all-access token during first-run setup rather than a predictable one. The official image also writes a CLI config pointing at that token, so the ",(0,s.jsx)(n.code,{children:"influx"})," CLI works inside the container without any extra flags."]}),"\n",(0,s.jsx)(n.p,{children:"Open a terminal inside the container and list existing tokens:"}),"\n",(0,s.jsxs)(l.A,{groupId:"interface",children:[(0,s.jsx)(o.A,{value:"cli",label:"Laradock CLI",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"./laradock enter influxdb\n"})})}),(0,s.jsx)(o.A,{value:"docker",label:"Docker Compose",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker 
1compose exec influxdb bash\n"})})})]}),"\n",(0,s.jsx)(n.p,{children:"Then, inside the container:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"influx auth list\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Or from the UI: log in at ",(0,s.jsx)(n.a,{href:"http://localhost:8086",children:"http://localhost:8086"}),", then ",(0,s.jsx)(n.strong,{children:"Load Data > API Tokens"})," to view or copy one. Use the token in an ",(0,s.jsx)(n.code,{children:"Authorization: Token <token>"})," header on API requests, or paste it into Grafana's InfluxDB data source config."]}),"\n",(0,s.jsx)(n.p,{children:"To create a new, separate token instead of reusing the auto-generated one:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"influx auth create --org laradock --all-access\n"})}),"\n",(0,s.jsx)(n.h2,{id:"buckets-and-retention",children:"Buckets and retention"}),"\n",(0,s.jsxs)(n.p,{children:["A bucket is InfluxDB 2.x's unit of storage, roughly a database and a retention period combined. ",(0,s.jsx)(n.code,{children:"INFLUXDB_INIT_BUCKET"})," only creates one bucket on first boot; day-to-day you'll likely want more, each with its own retention."]}),"\n",(0,s.jsxs)(n.p,{children:["List existing buckets (run after ",(0,s.jsx)(n.code,{children:"./laradock enter influxdb"}),", same as above):"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"influx bucket list --org laradock\n"})}),"\n",(0,s.jsx)(n.p,{children:"Create a new bucket with, for example, 30 days of retention:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"influx bucket create --name metrics_30d --org laradock --retention 30d\n"})}),"\n",(0,s.jsx)(n.h2,{id:"backup-and-restore",children:"Backup and restore"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Back up"})," all organizations and buckets to a folder inside the container, then copy that folder to your host:"]}),"\n",(0,s.jsxs)(l.A,{groupId:"interface",children:[(0,s.jsx)(o.A,{value:"cli",label:"Laradock CLI",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"./laradock exec influxdb influx backup /tmp/influxdb-backup\n"})})}),(0,s.jsx)(o.A,{value:"docker",label:"Docker Compose",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose exec influxdb influx backup /tmp/influxdb-backup\n"})})})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'docker cp "$(docker compose ps -q influxdb)":/tmp/influxdb-backup ./influxdb-backup\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Restore"})," by copying a backup folder back in, then restoring from it:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'docker cp ./influxdb-backup "$(docker compose ps -q influxdb)":/tmp/influxdb-backup\n'})}),"\n",(0,s.jsxs)(l.A,{groupId:"interface",children:[(0,s.jsx)(o.A,{value:"cli",label:"Laradock CLI",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"./laradock exec influxdb influx restore /tmp/influxdb-backup\n"})})}),(0,s.jsx)(o.A,{value:"docker",label:"Docker Compose",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose exec influxdb influx restore /tmp/influxdb-backup\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["Restore flags and behavior have changed across InfluxDB releases, check the ",(0,s.jsx)(n.a,{href:"https://docs.influxdata.com/influxdb/v2/backup-restore/",children:"InfluxDB backup/restore docs"})," for options specific to your ",(0,s.jsx)(n.code,{children:"INFLUXDB_VERSION"}),". Keep the ",(0,s.jsx)(n.code,{children:"influxdb-backup"})," folder itself somewhere safe, it's the actual backup."]}),"\n",(0,s.jsx)(n.h2,{id:"start-completely-fresh-wipe-all-data",children:"Start completely fresh (wipe all data)"}),"\n",(0,s.jsxs)(n.p,{children:["To throw away every organization, bucket, and data point, and start InfluxDB from a clean, empty state (\u26a0\ufe0f this ",(0,s.jsx)(n.strong,{children:"permanently deletes"})," everything in the ",(0,s.jsx)(n.code,{children:"influxdb"})," volume, back up first if you need anything):"]}),"\n",(0,s.jsxs)(l.A,{groupId:"interface",children:[(0,s.jsx)(o.A,{value:"cli",label:"Laradock CLI",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'./laradock stop influxdb\n./laradock remove influxdb\n
1docker volume rm "${COMPOSE_PROJECT_NAME}_influxdb"\n./laradock start influxdb\n'})})}),(0,s.jsx)(o.A,{value:"docker",label:"Docker Compose",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'docker compose stop influxdb\ndocker compose rm -sf influxdb\ndocker volume rm "${COMPOSE_PROJECT_NAME}_influxdb"\ndocker compose up -d influxdb\n'})})})]}),"\n",(0,s.jsxs)(n.p,{children:["Unlike bind-mounted services, InfluxDB's storage lives in a ",(0,s.jsx)(n.strong,{children:"named Docker volume"}),", not a folder under ",(0,s.jsx)(n.code,{children:"DATA_PATH_HOST"}),", so wiping it means removing the volume itself. If you're unsure of the exact volume name on your machine (it's prefixed with your ",(0,s.jsx)(n.code,{children:"COMPOSE_PROJECT_NAME"}),"), list it first with ",(0,s.jsx)(n.code,{children:"docker volume ls | grep influxdb"}),". Deleting it and starting again re-runs first-boot setup: ",(0,s.jsx)(n.code,{children:"INFLUXDB_INIT_USERNAME"}),", ",(0,s.jsx)(n.code,{children:"INFLUXDB_INIT_PASSWORD"}),", ",(0,s.jsx)(n.code,{children:"INFLUXDB_INIT_ORG"}),", and ",(0,s.jsx)(n.code,{children:"INFLUXDB_INIT_BUCKET"})," all apply fresh, and a new admin token is generated, exactly like a brand-new install."]}),"\n",(0,s.jsx)(n.h2,{id:"talk-to-this-database-from-another-laradock-project",children:"Talk to this database from another Laradock project"}),"\n",(0,s.jsxs)(n.p,{children:["Each Laradock project is its own isolated Docker network by default, so a second project's containers can't reach this InfluxDB by container name out of the box. Easiest fix: the API port is already published (",(0,s.jsx)(n.code,{children:"INFLUXDB_HOST_PORT"}),"), so point the other project (or a shared Grafana) at your ",(0,s.jsx)(n.strong,{children:"host machine's"})," address instead of ",(0,s.jsx)(n.code,{children:"influxdb"}),", for example ",(0,s.jsx)(n.code,{children:"http://host.docker.internal:8086"})," (Docker Desktop). Make sure the two projects use different ",(0,s.jsx)(n.code,{children:"INFLUXDB_HOST_PORT"})," values if they're both running at once."]}),"\n",(0,s.jsx)(n.h2,{id:"common-issues",children:"Common issues"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Port already in use on your host."})," Change ",(0,s.jsx)(n.code,{children:"INFLUXDB_HOST_PORT"})," in ",(0,s.jsx)(n.code,{children:".env"})," and restart: ",(0,s.jsx)(n.code,{children:"./laradock restart influxdb"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsxs)(n.strong,{children:[(0,s.jsx)(n.code,{children:"INFLUXDB_INIT_*"})," changes don't take effect."]})," These only apply during the automatic first-run setup. If InfluxDB already initialized its volume, changing them afterward has no effect, you'd need to create a new user/org/bucket manually or ",(0,s.jsx)(n.a,{href:"#start-completely-fresh-wipe-all-data",children:"start completely fresh"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Default credentials in a shared environment."})," ",(0,s.jsx)(n.code,{children:"secretpassword"})," is a placeholder meant for local dev only, override ",(0,s.jsx)(n.code,{children:"INFLUXDB_INIT_PASSWORD"})," in ",(0,s.jsx)(n.code,{children:".env"})," before exposing this beyond your machine."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsxs)(n.strong,{children:["API requests return ",(0,s.jsx)(n.code,{children:"401 Unauthorized"}),"."]})," The UI login (username/password) doesn't work for the write/query API, you need a token, see ",(0,s.jsx)(n.a,{href:"#get-an-api-token",children:"Get an API token"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"App can't connect but the container is running."})," Confirm your app or Grafana data source uses ",(0,s.jsx)(n.code,{children:"influxdb"})," as the host, not ",(0,s.jsx)(n.code,{children:"localhost"}),", that only works from your host machine."]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsxs)(n.p,{children:["Want to chart this data with dashboards? See ",(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.a,{href:"/docs/services/grafana",children:"Grafana"})}),". Want PromQL-based metrics instead? See ",(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.a,{href:"/docs/services/prometheus",children:"Prometheus"})}),". New to Laradock? Start with ",(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.a,{href:"/docs/getting-started",children:"Getting Started"})}),"."]})]})}function x(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},19365(e,n,r){r.d(n,{A:()=>i});r(96540);var a=r(34164),s=r(47751);const t="tabItem_Ymn6";var l=r(74848);function o({children:e,className:n,hidden:r}){return(0,l.jsx)("div",{role:"tabpanel",className:(0,a.A)(t,n),hidden:r,children:e})}function i({children:e,className:n,value:r}){const{selectedValue:a,lazy:t}=(0,s.uc)(),i=r===a;return!i&&t?null:(0,l.jsx)(o,{className:n,hidden:!i,children:e})}},4865(e,n,r){r.d(n,{A:()=>f});r(96540);var a=r(34164),s=r(17559),t=r(47751),l=r(23104),o=r(92303);const i="tabList__CuJ",c="tabItem_LNqP";var d=r(74848);function u({className:e}){const{selectedValue:n,selectValue:r,tabValues:s,block:o}=(0,t.uc)(),i=[],{blockElementScrollPositionUntilNextRender:u}
1=(0,l.a_)(),h=e=>{const a=e.currentTarget,t=i.indexOf(a),l=s[t].value;l!==n&&(u(a),r(l))},x=e=>{let n=null;switch(e.key){case"Enter":h(e);break;case"ArrowRight":{const r=i.indexOf(e.currentTarget)+1;n=i[r]??i[0];break}case"ArrowLeft":{const r=i.indexOf(e.currentTarget)-1;n=i[r]??i[i.length-1];break}}n?.focus()};return(0,d.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,a.A)("tabs",{"tabs--block":o},e),children:s.map(({value:e,label:r,attributes:s})=>(0,d.jsx)("li",{role:"tab",tabIndex:n===e?0:-1,"aria-selected":n===e,ref:e=>{i.push(e)},onKeyDown:x,onClick:h,...s,className:(0,a.A)("tabs__item",c,s?.className,{"tabs__item--active":n===e}),children:r??e},e))})}function h({children:e}){return(0,d.jsx)("div",{className:"margin-top--md",children:e})}function x({className:e,children:n}){return(0,d.jsxs)("div",{className:(0,a.A)(s.G.tabs.container,"tabs-container",i),children:[(0,d.jsx)(u,{className:e}),(0,d.jsx)(h,{children:n})]})}function f(e){const n=(0,o.A)(),r=(0,t.OC)(e);return(0,d.jsx)(t.O_,{value:r,children:(0,d.jsx)(x,{className:e.className,children:(0,t.vT)(e.children)})},String(n))}},47751(e,n,r){r.d(n,{OC:()=>f,O_:()=>j,uc:()=>b,vT:()=>d});var a=r(96540),s=r(56347),t=r(205),l=r(57485),o=r(70679),i=r(31682),c=r(74848);function d(e){return a.Children.toArray(e).filter(e=>"\n"!==e)}function u(e){const{values:n,children:r}=e;return(0,a.useMemo)(()=>{const e=n??function(e){return a.Children.toArray(e).flatMap(e=>{if(!e)return[];if((0,a.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:a}})=>({value:e,label:n,attributes:r,default:a}))}(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 x({queryString:e=!1,groupId:n}){const r=(0,s.W6)(),t=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,l.aZ)(t),(0,a.useCallback)(e=>{if(!t)return;const n=new URLSearchParams(r.location.search);n.set(t,e),r.replace({...r.location,search:n.toString()})},[t,r])]}function f(e){const{defaultValue:n,queryString:r=!1,groupId:s}=e,l=u(e),[i,c]=(0,a.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:l})),[d,f]=x({queryString:r,groupId:s}),[p,b]=function({groupId:e}){const n=function(e){return e?`docusaurus.tab.${e}`:null}(e),[r,s]=(0,o.Dv)(n);return[r,(0,a.useCallback)(e=>{n&&s.set(e)},[n,s])]}({groupId:s}),j=(()=>{const e=d??p;return h({value:e,tabValues:l})?e:null})();(0,t.A)(()=>{j&&c(j)},[j]);return{selectedValue:i,selectValue:(0,a.useCallback)(e=>{if(!h({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);c(e),f(e),b(e)},[f,b,l]),tabValues:l,lazy:e.lazy??!1,block:e.block??!1}}const p=(0,a.createContext)(null);function b(){const e=a.useContext(p);if(!e)throw new Error("useTabsContext() must be used within a Tabs component");return e}function j(e){return(0,c.jsx)(p.Provider,{value:e.value,children:e.children})}},28453(e,n,r){r.d(n,{R:()=>l,x:()=>o});var a=r(96540);const s={},t=a.createContext(s);function l(e){const n=a.useContext(t);return a.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),a.createElement(t.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.