From f05e5674cc7c2e217dc9531c8c56556733d2feb1 Mon Sep 17 00:00:00 2001 From: facebook-github-bot Date: Tue, 22 Oct 2024 13:05:10 +0000 Subject: [PATCH] Deploy website - based on 1f561f0900a21fc0c6225f28cda015f43edf4947 --- 404.html | 4 +- assets/js/1906a68b.625723d8.js | 1 - assets/js/1906a68b.f6bbe8eb.js | 1 + assets/js/413f2abb.2a3134f2.js | 1 + assets/js/413f2abb.a98743fb.js | 1 - assets/js/b4a56aa4.e796c4bd.js | 1 - assets/js/b4a56aa4.f86e56c3.js | 1 + ...5d8e4.b4e18fab.js => c4f5d8e4.25763f5c.js} | 4 +- ...E.txt => c4f5d8e4.25763f5c.js.LICENSE.txt} | 2 +- assets/js/main.5f3f48b2.js | 2 + ...CENSE.txt => main.5f3f48b2.js.LICENSE.txt} | 0 assets/js/main.f74a0b22.js | 2 - ...n.8c7addba.js => runtime~main.1357fbb7.js} | 2 +- .../index.html | 4 +- .../17/collaboration-with-spotify/index.html | 4 +- .../07/mobileatscale-london-talk/index.html | 4 +- .../06/23/first-opensourceversary/index.html | 4 +- blog/2016/08/30/curryon-rome-talk/index.html | 4 +- blog/2016/11/28/atscale16/index.html | 4 +- .../10/20/ocamlformat-released/index.html | 4 +- blog/archive/index.html | 4 +- blog/index.html | 4 +- docs/1.1.0/about-Infer/index.html | 4 +- docs/1.1.0/absint-framework/index.html | 4 +- docs/1.1.0/all-issue-types/index.html | 4 +- .../analyzing-apps-or-projects/index.html | 4 +- .../index.html | 4 +- docs/1.1.0/checker-biabduction/index.html | 4 +- docs/1.1.0/checker-bufferoverrun/index.html | 4 +- .../index.html | 4 +- .../checker-config-impact-analysis/index.html | 4 +- docs/1.1.0/checker-cost/index.html | 4 +- .../checker-dotnet-resource-leak/index.html | 4 +- docs/1.1.0/checker-eradicate/index.html | 4 +- .../checker-fragment-retains-view/index.html | 4 +- docs/1.1.0/checker-immutable-cast/index.html | 4 +- docs/1.1.0/checker-impurity/index.html | 4 +- .../index.html | 4 +- docs/1.1.0/checker-linters/index.html | 4 +- .../checker-litho-required-props/index.html | 4 +- docs/1.1.0/checker-liveness/index.html | 4 +- docs/1.1.0/checker-loop-hoisting/index.html | 4 +- docs/1.1.0/checker-printf-args/index.html | 4 +- docs/1.1.0/checker-pulse/index.html | 4 +- docs/1.1.0/checker-purity/index.html | 4 +- docs/1.1.0/checker-quandary/index.html | 4 +- docs/1.1.0/checker-racerd/index.html | 4 +- .../checker-resource-leak-lab/index.html | 4 +- docs/1.1.0/checker-self-in-block/index.html | 4 +- docs/1.1.0/checker-siof/index.html | 4 +- docs/1.1.0/checker-starvation/index.html | 4 +- docs/1.1.0/checker-topl/index.html | 4 +- docs/1.1.0/checker-uninit/index.html | 4 +- docs/1.1.0/getting-started/index.html | 4 +- docs/1.1.0/hello-world/index.html | 4 +- docs/1.1.0/infer-workflow/index.html | 4 +- docs/1.1.0/internal-API/index.html | 4 +- docs/1.1.0/man-infer-analyze/index.html | 4 +- docs/1.1.0/man-infer-capture/index.html | 4 +- docs/1.1.0/man-infer-compile/index.html | 4 +- docs/1.1.0/man-infer-debug/index.html | 4 +- docs/1.1.0/man-infer-explore/index.html | 4 +- docs/1.1.0/man-infer-help/index.html | 4 +- docs/1.1.0/man-infer-report/index.html | 4 +- docs/1.1.0/man-infer-reportdiff/index.html | 4 +- docs/1.1.0/man-infer-run/index.html | 4 +- docs/1.1.0/man-infer/index.html | 4 +- docs/1.1.0/man-pages/index.html | 4 +- .../index.html | 136 ++++++++-------- docs/1.1.0/steps-for-ci/index.html | 4 +- docs/1.1.0/support/index.html | 4 +- docs/1.1.0/versions/index.html | 4 +- docs/about-Infer/index.html | 4 +- docs/absint-framework/index.html | 4 +- docs/all-categories/index.html | 4 +- docs/all-checkers/index.html | 4 +- docs/all-issue-types/index.html | 4 +- docs/analyzing-apps-or-projects/index.html | 4 +- .../index.html | 4 +- docs/checker-biabduction/index.html | 4 +- docs/checker-bufferoverrun/index.html | 4 +- .../checker-config-impact-analysis/index.html | 4 +- docs/checker-cost/index.html | 4 +- docs/checker-datalog/index.html | 4 +- docs/checker-fragment-retains-view/index.html | 4 +- docs/checker-impurity/index.html | 4 +- .../index.html | 4 +- docs/checker-lineage/index.html | 4 +- docs/checker-litho-required-props/index.html | 4 +- docs/checker-liveness/index.html | 4 +- docs/checker-loop-hoisting/index.html | 4 +- .../index.html | 4 +- docs/checker-printf-args/index.html | 4 +- docs/checker-pulse/index.html | 4 +- docs/checker-purity/index.html | 4 +- docs/checker-quandary/index.html | 4 +- docs/checker-racerd/index.html | 4 +- docs/checker-resource-leak-lab/index.html | 4 +- docs/checker-scope-leakage/index.html | 4 +- docs/checker-self-in-block/index.html | 4 +- docs/checker-sil-validation/index.html | 4 +- docs/checker-siof/index.html | 4 +- docs/checker-starvation/index.html | 4 +- docs/checker-topl/index.html | 4 +- docs/getting-started/index.html | 4 +- docs/hello-world/index.html | 4 +- docs/infer-workflow/index.html | 4 +- docs/internal-API/index.html | 4 +- docs/man-infer-analyze/index.html | 4 +- docs/man-infer-capture/index.html | 4 +- docs/man-infer-compile/index.html | 4 +- docs/man-infer-debug/index.html | 4 +- docs/man-infer-explore/index.html | 4 +- docs/man-infer-help/index.html | 4 +- docs/man-infer-report/index.html | 4 +- docs/man-infer-reportdiff/index.html | 4 +- docs/man-infer-run/index.html | 4 +- docs/man-infer/index.html | 4 +- docs/man-pages/index.html | 4 +- docs/next/about-Infer/index.html | 4 +- docs/next/absint-framework/index.html | 4 +- docs/next/all-categories/index.html | 4 +- docs/next/all-checkers/index.html | 4 +- docs/next/all-issue-types/index.html | 4 +- .../analyzing-apps-or-projects/index.html | 4 +- .../index.html | 4 +- docs/next/checker-biabduction/index.html | 4 +- docs/next/checker-bufferoverrun/index.html | 4 +- .../checker-config-impact-analysis/index.html | 4 +- docs/next/checker-cost/index.html | 4 +- .../checker-fragment-retains-view/index.html | 4 +- docs/next/checker-impurity/index.html | 4 +- .../index.html | 4 +- docs/next/checker-lineage/index.html | 4 +- .../checker-litho-required-props/index.html | 4 +- docs/next/checker-liveness/index.html | 4 +- docs/next/checker-loop-hoisting/index.html | 4 +- .../index.html | 4 +- docs/next/checker-pulse/index.html | 4 +- docs/next/checker-purity/index.html | 4 +- docs/next/checker-racerd/index.html | 4 +- .../next/checker-resource-leak-lab/index.html | 4 +- docs/next/checker-scope-leakage/index.html | 4 +- docs/next/checker-self-in-block/index.html | 4 +- docs/next/checker-sil-validation/index.html | 4 +- docs/next/checker-siof/index.html | 4 +- docs/next/checker-starvation/index.html | 4 +- docs/next/checker-topl/index.html | 4 +- docs/next/getting-started/index.html | 4 +- docs/next/hello-world/index.html | 4 +- docs/next/infer-workflow/index.html | 4 +- docs/next/internal-API/index.html | 4 +- docs/next/man-infer-analyze/index.html | 4 +- docs/next/man-infer-capture/index.html | 4 +- docs/next/man-infer-compile/index.html | 4 +- docs/next/man-infer-debug/index.html | 4 +- docs/next/man-infer-explore/index.html | 4 +- docs/next/man-infer-help/index.html | 4 +- docs/next/man-infer-report/index.html | 4 +- docs/next/man-infer-reportdiff/index.html | 4 +- docs/next/man-infer-run/index.html | 4 +- docs/next/man-infer/index.html | 4 +- docs/next/man-pages/index.html | 4 +- .../index.html | 146 +++++++++--------- docs/next/steps-for-ci/index.html | 4 +- docs/next/support/index.html | 4 +- docs/next/suppressions/index.html | 4 +- docs/next/versions/index.html | 4 +- .../index.html | 146 +++++++++--------- docs/steps-for-ci/index.html | 4 +- docs/support/index.html | 4 +- docs/versions/index.html | 4 +- index.html | 4 +- search/index.html | 4 +- 174 files changed, 541 insertions(+), 541 deletions(-) delete mode 100644 assets/js/1906a68b.625723d8.js create mode 100644 assets/js/1906a68b.f6bbe8eb.js create mode 100644 assets/js/413f2abb.2a3134f2.js delete mode 100644 assets/js/413f2abb.a98743fb.js delete mode 100644 assets/js/b4a56aa4.e796c4bd.js create mode 100644 assets/js/b4a56aa4.f86e56c3.js rename assets/js/{c4f5d8e4.b4e18fab.js => c4f5d8e4.25763f5c.js} (94%) rename assets/js/{c4f5d8e4.b4e18fab.js.LICENSE.txt => c4f5d8e4.25763f5c.js.LICENSE.txt} (87%) create mode 100644 assets/js/main.5f3f48b2.js rename assets/js/{main.f74a0b22.js.LICENSE.txt => main.5f3f48b2.js.LICENSE.txt} (100%) delete mode 100644 assets/js/main.f74a0b22.js rename assets/js/{runtime~main.8c7addba.js => runtime~main.1357fbb7.js} (74%) diff --git a/404.html b/404.html index 384bf0bc9de..11ccb179106 100644 --- a/404.html +++ b/404.html @@ -13,8 +13,8 @@ - - + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

diff --git a/assets/js/1906a68b.625723d8.js b/assets/js/1906a68b.625723d8.js deleted file mode 100644 index 866340cf7e8..00000000000 --- a/assets/js/1906a68b.625723d8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9692],{3990:(e,n,o)=>{o.r(n),o.d(n,{Math:()=>l,assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var a=o(4848),t=o(8453);const s={id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction"},i=void 0,r={id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction",description:"- Separation logic",source:"@site/docs/02-separation-logic-and-biabduction.md",sourceDirName:".",slug:"/separation-logic-and-bi-abduction",permalink:"/docs/next/separation-logic-and-bi-abduction",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction"},sidebar:"docs",previous:{title:"About Infer",permalink:"/docs/next/about-Infer"},next:{title:"Building checkers with the Infer.AI framework",permalink:"/docs/next/absint-framework"}},c={},l=({code:e})=>{const n={img:"img",...(0,t.R)()};return(0,a.jsx)(n.img,{src:`https://math.now.sh?from=${encodeURIComponent(e)}&color=mediumslateblue`,style:{height:"100%",verticalAlign:"middle"}})},d=[{value:"Separation logic",id:"separation-logic",level:2},{value:"Bi-abduction",id:"bi-abduction",level:2},{value:"Technical papers",id:"technical-papers",level:2}];function h(e){const n={a:"a",em:"em",h2:"h2",hr:"hr",img:"img",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#separation-logic",children:"Separation logic"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#bi-abduction",children:"Bi-abduction"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#technical-papers",children:"Technical papers"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"separation-logic",children:"Separation logic"}),"\n",(0,a.jsx)(n.p,{children:"Separation logic is a novel kind of mathematical logic which facilitates\nreasoning about mutations to computer memory. It enables scalability by breaking\nreasoning into chunks corresponding to local operations on memory, and then\ncomposing the reasoning chunks together."}),"\n",(0,a.jsxs)(n.p,{children:["Separation logic is based on a logical connective ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"}),"\ncalled the ",(0,a.jsx)(n.em,{children:"separating conjunction"}),' and pronounced "and separately". Separation\nlogic formulae are interpreted over program allocated heaps. The logical formula\n',(0,a.jsx)(l,{code:"\\\\( A*B \\\\)"})," holds of a piece of program heap (a heaplet) when it\ncan be divided into two sub-heaplets described by ",(0,a.jsx)(l,{code:"\\\\(A\\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\(B\\\\)"}),". For example, the formula"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(x \\mapsto y * y \\mapsto x \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:['can be read "',(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," points to ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," and\nseparately ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," points to ",(0,a.jsx)(l,{code:"\\\\(x\\\\)"}),'". This\nformula describes precisely two allocated memory cells. The first cell is\nallocated at the address denoted by the pointer ',(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," and the\ncontent of this cell is the value of ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"}),". The second cell is\nallocated at the address denoted by the pointer ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," and the\ncontent of this second cell is the value of ",(0,a.jsx)(l,{code:"\\\\(x\\\\)"}),". Crucially,\nwe know that there are precisely two cells because ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"}),"\nstipulates that they are separated and therefore the cells are allocated in two\ndifferent parts of memory. In other words, ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"})," says that\n",(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," and ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," do not hold the same value\n(i.e., these pointers are not aliased). The heaplet partitioning defined by the\nformula above can be visualized like so:"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{src:o(8615).A+"",width:"473",height:"129"})}),"\n",(0,a.jsxs)(n.p,{children:["The important thing about the separating conjunction is the way that it fits\ntogether with mutation to computer memory; reasoning about program commands\ntends to work by updating ",(0,a.jsx)(l,{code:"\\\\(*\\\\)"}),"-conjuncts in-place, mimicking\nthe operational in-place update of RAM."]}),"\n",(0,a.jsxs)(n.p,{children:["Separation logic uses Hoare triples of the form\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace pre \\rbrace prog \\lbrace post \\rbrace \\\\)"})," where\n",(0,a.jsx)(l,{code:"\\\\(pre\\\\)"})," is the precondition, ",(0,a.jsx)(l,{code:"\\\\(prog\\\\)"})," a\nprogram part, and ",(0,a.jsx)(l,{code:"\\\\(post\\\\)"})," the postcondition. Triples are\nabstract specifications of the behavior of the program. For example, we could\ntake"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r \\mapsto open\\rbrace \\, closeResource(r)\\, \\lbrace r \\mapsto closed\\rbrace \\;\\;\\; (spec)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"as a specification for a method which closes a resource given to it as a\nparameter."}),"\n",(0,a.jsxs)(n.p,{children:["Now, suppose we have two resources ",(0,a.jsx)(l,{code:"\\\\( r\\_1 \\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\( r\\_2 \\\\)"}),", described by\n",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto open * r\\_2 \\mapsto open\\\\)"})," and we close the\nfirst of them. We think operationally in terms of updating the memory in place,\nleaving ",(0,a.jsx)(l,{code:"\\\\(r\\_2 \\mapsto open\\\\)"})," alone, as described by this triple:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r\\_1 \\mapsto open * r\\_2 \\mapsto open\\rbrace closeResource(r\\_1) \\lbrace r\\_1 \\mapsto closed * r\\_2 \\mapsto open \\rbrace \\;\\;\\; (use)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["What we have here is the that specification (spec) described how\n",(0,a.jsx)(l,{code:"\\\\(closeResource()\\\\)"})," works by mentioning only one piece of\nstate, what is sometimes called a small specification, and in (use) we use that\nspecification to update a larger precondition in place."]}),"\n",(0,a.jsx)(n.p,{children:"This is an instance of a general pattern. There is a rule that lets you go from\nsmaller to bigger specifications"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\frac{\\lbrace pre \\rbrace prog \\lbrace post \\rbrace}{\\lbrace pre * frame \\rbrace prog \\lbrace post * frame \\rbrace}\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"Our passage from (spec) to (use) is obtained by taking"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(pre\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto open\\\\)"})]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(post\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto closed \\\\)"}),",\nand"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(frame\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_2 \\mapsto open \\\\)"})]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["This rule is called the ",(0,a.jsx)(n.em,{children:"frame rule"})," of separation logic. It is named after the\nframe problem, a classic problem in artificial intelligence. Generally, the\n",(0,a.jsx)(l,{code:"\\\\(frame\\\\)"})," describes state that remains unchanged; the\nterminology comes from the analogy of a background scene in an animation as\nunchanging while the objects and characters within the scene change."]}),"\n",(0,a.jsx)(n.p,{children:"The frame rule is the key to the principle of local reasoning in separation\nlogic: reasoning and specifications should concentrate on the resources that a\nprogram accesses (the footprint), without mentioning what doesn't change."}),"\n",(0,a.jsx)(n.h2,{id:"bi-abduction",children:"Bi-abduction"}),"\n",(0,a.jsx)(n.p,{children:"Bi-abduction is a form of logical inference for separation logic which automates\nthe key ideas about local reasoning."}),"\n",(0,a.jsx)(n.p,{children:"Usually, logic works with validity or entailment statements like"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(A \\vdash B\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["which says that ",(0,a.jsx)(l,{code:"\\\\(A\\\\)"})," implies ",(0,a.jsx)(l,{code:"\\\\(B\\\\)"}),". Infer\nuses an extension of this inference question in an internal theorem prover while\nit runs over program statements. Infer's question"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(A * ?antiframe \\vdash B * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["is called ",(0,a.jsx)(n.em,{children:"bi-abduction"}),". The problem here is for the theorem prover to ",(0,a.jsx)("i",{children:"\ndiscover "})," a pair of frame and antiframe formulae that make the entailment\nstatement valid."]}),"\n",(0,a.jsx)(n.p,{children:"Global analyses of large programs are normally computationally intractable.\nHowever, bi-abduction breaks apart a large analysis of a large program into\nsmall independent analyses of its procedures. This gives Infer the ability to\nscale independently of the size of the analyzed code. Moreover, by breaking the\nanalysis into small independent parts, when the full program is analyzed again\nbecause of a code change the analysis results of the unchanged part of the code\ncan be reused, and only the code change needs to be re-analyzed. This process\nis called incremental analysis and it is very powerful when integrating a\nstatic analysis tool like Infer in a development environment."}),"\n",(0,a.jsxs)(n.p,{children:["In order to be able to decompose a global analysis into small independent\nanalyses, let's first consider how a function call is analyzed in separation\nlogic. Assume we have the following spec for a function\n",(0,a.jsx)(l,{code:"\\\\( f() \\\\)"}),":"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace pre\\_f \\rbrace \\;\\; f() \\;\\; \\lbrace post\\_f \\rbrace \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["and by analyzing the caller function, we compute that before the call of ",(0,a.jsx)(l,{code:"\\\\( f \\\\)"}),", the formula ",(0,a.jsx)(l,{code:"\\\\( CallingState \\\\)"}),"\nholds. Then to utilize the specification of ",(0,a.jsx)(l,{code:"\\\\( f \\\\)"})," the\nfollowing implication must hold:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( CallingState \\vdash pre\\_f \\;\\;\\;\\;\\;\\;\\;\\;\\;\\;\\;\\; (Function Call)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"Given that, bi-abduction is used at procedure call sites for two reasons: to\ndiscover missing state that is needed for the above implication to hold and\nallow the analysis to proceed (the antiframe) as well as state that the\nprocedure leaves unchanged (the frame)."}),"\n",(0,a.jsx)(n.p,{children:"To see how this works suppose we have some bare code"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(closeResource(r1); \\, closeResource(r2)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["but no overall specification; we are going to describe how to discover a\npre/post spec for it. Considering the first statement and the (spec) above, the\nhuman might say: if only we had ",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto open\\\\)"})," in the\nprecondition then we could proceed. Technically, we ask a bi-abduction question:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(emp * ?antiframe \\vdash r1 \\mapsto open * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["and we can fill this in easily by picking\n",(0,a.jsx)(l,{code:"\\\\(antiframe = r1 \\mapsto open\\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\(frame = emp\\\\)"}),", where ",(0,a.jsx)(l,{code:"emp"}),"\nmeans the empty state. The ",(0,a.jsx)(l,{code:"emp"})," is recording that at the start\nwe presume nothing. So we obtain the trivially true implication:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(emp * r1 \\mapsto open \\vdash r1 \\mapsto open * emp\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"which, by applying logical rules, can be re-written equivalently to:"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto open \\vdash r1 \\mapsto open\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["Notice that this satisfies the (Function Call) requirement to correctly make\nthe call. So let's add that information in the ",(0,a.jsx)(l,{code:"pre"}),", and while\nwe are at it, record the information in the ",(0,a.jsx)(l,{code:"post"})," of the first\nstatement that comes from ",(0,a.jsx)(l,{code:"\\\\(spec\\\\)"}),"."]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["Now, let's move to the second statement. Its precondition\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed\\\\)"})," in the partial symbolic execution trace\njust given does not have the information needed by\n",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"}),", so we can fill that in and continue by\nputting ",(0,a.jsx)(l,{code:"\\\\(r2 \\mapsto open\\\\)"})," in the ",(0,a.jsx)(l,{code:"pre"}),". While\nwe are at it, we can thread this assertion back to the beginning."]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open * r2 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto open\\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"This information on what to thread backwards can be obtained as the antiframe\npart of the bi-abduction question:"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed * ?antiframe \\vdash r2 \\mapsto open * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["where the solution picks\n",(0,a.jsx)(l,{code:"\\\\(antiframe = r2 \\mapsto open\\\\) and \\\\(frame = r1 \\mapsto closed\\\\)"}),".\nNote that the antiframe is precisely the information missing from the\nprecondition in order for ",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"})," to proceed. On\nthe other hand, the frame ",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed\\\\)"})," is the portion\nof state not changed by ",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"}),"; we can thread\nthat through to the overall postconditon (as justified by the frame rule),\ngiving us:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open * r2 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto open\\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto closed \\rbrace\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["Thus, we have obtained a ",(0,a.jsx)(l,{code:"pre"})," and ",(0,a.jsx)(l,{code:"post"})," for this\ncode by symbolically executing it, using bi-abduction to discover preconditions\n(abduction of antiframes) as well as untouched portions of memory (frames) as\nwe go along."]}),"\n",(0,a.jsx)(n.p,{children:"In general, bi-abduction provides a way to infer a pre/post specs from bare\ncode, as long as we know specs for the primitives at the base level of the code.\nThe human does not need to write preconditions and postconditions for all the\nprocedures, which is the key to having a high level of automation. This is the\nbasis for how Infer works, why it can scale, and how it can analyze code changes\nincrementally."}),"\n",(0,a.jsx)(n.p,{children:"Context: The logical terminology we have been using here comes from AI and\nphilosophy of science. Abductive inference was introduced by the philosopher\nCharles Peirce, and described as the mechanism underpinning hypothesis formation\n(or, guessing what might be true about the world), the most creative part of the\nscientific process. Abduction and the frame problem have both attracted\nsignificant attention in AI. Infer uses an automated form of abduction to\ngenerate preconditions describing the memory that a program touches (the\nantiframe part above), and frame inference to discover what isn't touched. Infer\nthen uses deductive reasoning to calculate a formula describing the effect of a\nprogram, starting from the preconditions. In a sense, Infer approaches automated\nreasoning about programs by mimicking what a human might do when trying to\nunderstand a program: it abduces what the program needs, and deduces conclusions\nof that. It is when the reasoning goes wrong that Infer reports a potential bug."}),"\n",(0,a.jsx)(n.p,{children:"This description is by necessity simplified compared to what Infer actually\ndoes. More technical information can be found in the following papers. The\ndescriptions in the papers are precise, but still simplified; there are many\nengineering decisions not recorded there. Finally, beyond the papers, you can\nread the source code if you wish!"}),"\n",(0,a.jsx)(n.h2,{id:"technical-papers",children:"Technical papers"}),"\n",(0,a.jsx)(n.p,{children:"The following papers contain some of the technical background on Infer and\ninformation on how it is used inside Facebook."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007%2F3-540-44802-0_1",children:"Local\nReasoning about Programs that Alter Data Structures."})," An early separation\nlogic paper which advanced ideas about local reasoning and the frame rule."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007/11804192_6",children:"Smallfoot:\nModular Automatic Assertion Checking with Separation Logic."})," First\nseparation logic verification tool, introduced frame inference"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007%2F11691372_19",children:"A Local Shape\nAnalysis Based on Separation Logic."})," Separation logic meets abstract\ninterpretation; calculating loop invariants via a fixed-point computation."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://dl.acm.org/citation.cfm?id=2049700",children:"Compositional Shape\nAnalysis by Means of Bi-Abduction."})," The bi-abduction paper."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"https://research.facebook.com/publications/moving-fast-with-software-verification/",children:"Moving\nFast with Software Verification."})," A paper about the way we use Infer at\nFacebook."]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},8615:(e,n,o)=>{o.d(n,{A:()=>a});const a=o.p+"assets/images/SepSplit-dca4e1fe63cb590718402c7c0c9ab7f8.jpg"},8453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>r});var a=o(6540);const t={},s=a.createContext(t);function i(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1906a68b.f6bbe8eb.js b/assets/js/1906a68b.f6bbe8eb.js new file mode 100644 index 00000000000..3155ecaec17 --- /dev/null +++ b/assets/js/1906a68b.f6bbe8eb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9692],{3990:(e,n,o)=>{o.r(n),o.d(n,{Math:()=>l,assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var a=o(4848),t=o(8453);const s={id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction"},i=void 0,r={id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction",description:"- Separation logic",source:"@site/docs/02-separation-logic-and-biabduction.md",sourceDirName:".",slug:"/separation-logic-and-bi-abduction",permalink:"/docs/next/separation-logic-and-bi-abduction",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction"},sidebar:"docs",previous:{title:"About Infer",permalink:"/docs/next/about-Infer"},next:{title:"Building checkers with the Infer.AI framework",permalink:"/docs/next/absint-framework"}},c={},l=({code:e})=>(0,a.jsx)("img",{src:`https://math.now.sh?from=${encodeURIComponent(e)}&color=mediumslateblue`,style:{height:"100%",verticalAlign:"middle"}}),d=[{value:"Separation logic",id:"separation-logic",level:2},{value:"Bi-abduction",id:"bi-abduction",level:2},{value:"Technical papers",id:"technical-papers",level:2}];function h(e){const n={a:"a",em:"em",h2:"h2",hr:"hr",img:"img",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#separation-logic",children:"Separation logic"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#bi-abduction",children:"Bi-abduction"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#technical-papers",children:"Technical papers"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"separation-logic",children:"Separation logic"}),"\n",(0,a.jsx)(n.p,{children:"Separation logic is a novel kind of mathematical logic which facilitates\nreasoning about mutations to computer memory. It enables scalability by breaking\nreasoning into chunks corresponding to local operations on memory, and then\ncomposing the reasoning chunks together."}),"\n",(0,a.jsxs)(n.p,{children:["Separation logic is based on a logical connective ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"}),"\ncalled the ",(0,a.jsx)(n.em,{children:"separating conjunction"}),' and pronounced "and separately". Separation\nlogic formulae are interpreted over program allocated heaps. The logical formula\n',(0,a.jsx)(l,{code:"\\\\( A*B \\\\)"})," holds of a piece of program heap (a heaplet) when it\ncan be divided into two sub-heaplets described by ",(0,a.jsx)(l,{code:"\\\\(A\\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\(B\\\\)"}),". For example, the formula"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(x \\mapsto y * y \\mapsto x \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:['can be read "',(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," points to ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," and\nseparately ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," points to ",(0,a.jsx)(l,{code:"\\\\(x\\\\)"}),'". This\nformula describes precisely two allocated memory cells. The first cell is\nallocated at the address denoted by the pointer ',(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," and the\ncontent of this cell is the value of ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"}),". The second cell is\nallocated at the address denoted by the pointer ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," and the\ncontent of this second cell is the value of ",(0,a.jsx)(l,{code:"\\\\(x\\\\)"}),". Crucially,\nwe know that there are precisely two cells because ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"}),"\nstipulates that they are separated and therefore the cells are allocated in two\ndifferent parts of memory. In other words, ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"})," says that\n",(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," and ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," do not hold the same value\n(i.e., these pointers are not aliased). The heaplet partitioning defined by the\nformula above can be visualized like so:"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{src:o(8615).A+"",width:"473",height:"129"})}),"\n",(0,a.jsxs)(n.p,{children:["The important thing about the separating conjunction is the way that it fits\ntogether with mutation to computer memory; reasoning about program commands\ntends to work by updating ",(0,a.jsx)(l,{code:"\\\\(*\\\\)"}),"-conjuncts in-place, mimicking\nthe operational in-place update of RAM."]}),"\n",(0,a.jsxs)(n.p,{children:["Separation logic uses Hoare triples of the form\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace pre \\rbrace prog \\lbrace post \\rbrace \\\\)"})," where\n",(0,a.jsx)(l,{code:"\\\\(pre\\\\)"})," is the precondition, ",(0,a.jsx)(l,{code:"\\\\(prog\\\\)"})," a\nprogram part, and ",(0,a.jsx)(l,{code:"\\\\(post\\\\)"})," the postcondition. Triples are\nabstract specifications of the behavior of the program. For example, we could\ntake"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r \\mapsto open\\rbrace \\, closeResource(r)\\, \\lbrace r \\mapsto closed\\rbrace \\;\\;\\; (spec)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"as a specification for a method which closes a resource given to it as a\nparameter."}),"\n",(0,a.jsxs)(n.p,{children:["Now, suppose we have two resources ",(0,a.jsx)(l,{code:"\\\\( r\\_1 \\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\( r\\_2 \\\\)"}),", described by\n",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto open * r\\_2 \\mapsto open\\\\)"})," and we close the\nfirst of them. We think operationally in terms of updating the memory in place,\nleaving ",(0,a.jsx)(l,{code:"\\\\(r\\_2 \\mapsto open\\\\)"})," alone, as described by this triple:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r\\_1 \\mapsto open * r\\_2 \\mapsto open\\rbrace closeResource(r\\_1) \\lbrace r\\_1 \\mapsto closed * r\\_2 \\mapsto open \\rbrace \\;\\;\\; (use)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["What we have here is the that specification (spec) described how\n",(0,a.jsx)(l,{code:"\\\\(closeResource()\\\\)"})," works by mentioning only one piece of\nstate, what is sometimes called a small specification, and in (use) we use that\nspecification to update a larger precondition in place."]}),"\n",(0,a.jsx)(n.p,{children:"This is an instance of a general pattern. There is a rule that lets you go from\nsmaller to bigger specifications"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\frac{\\lbrace pre \\rbrace prog \\lbrace post \\rbrace}{\\lbrace pre * frame \\rbrace prog \\lbrace post * frame \\rbrace}\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"Our passage from (spec) to (use) is obtained by taking"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(pre\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto open\\\\)"})]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(post\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto closed \\\\)"}),",\nand"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(frame\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_2 \\mapsto open \\\\)"})]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["This rule is called the ",(0,a.jsx)(n.em,{children:"frame rule"})," of separation logic. It is named after the\nframe problem, a classic problem in artificial intelligence. Generally, the\n",(0,a.jsx)(l,{code:"\\\\(frame\\\\)"})," describes state that remains unchanged; the\nterminology comes from the analogy of a background scene in an animation as\nunchanging while the objects and characters within the scene change."]}),"\n",(0,a.jsx)(n.p,{children:"The frame rule is the key to the principle of local reasoning in separation\nlogic: reasoning and specifications should concentrate on the resources that a\nprogram accesses (the footprint), without mentioning what doesn't change."}),"\n",(0,a.jsx)(n.h2,{id:"bi-abduction",children:"Bi-abduction"}),"\n",(0,a.jsx)(n.p,{children:"Bi-abduction is a form of logical inference for separation logic which automates\nthe key ideas about local reasoning."}),"\n",(0,a.jsx)(n.p,{children:"Usually, logic works with validity or entailment statements like"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(A \\vdash B\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["which says that ",(0,a.jsx)(l,{code:"\\\\(A\\\\)"})," implies ",(0,a.jsx)(l,{code:"\\\\(B\\\\)"}),". Infer\nuses an extension of this inference question in an internal theorem prover while\nit runs over program statements. Infer's question"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(A * ?antiframe \\vdash B * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["is called ",(0,a.jsx)(n.em,{children:"bi-abduction"}),". The problem here is for the theorem prover to ",(0,a.jsx)("i",{children:"\ndiscover "})," a pair of frame and antiframe formulae that make the entailment\nstatement valid."]}),"\n",(0,a.jsx)(n.p,{children:"Global analyses of large programs are normally computationally intractable.\nHowever, bi-abduction breaks apart a large analysis of a large program into\nsmall independent analyses of its procedures. This gives Infer the ability to\nscale independently of the size of the analyzed code. Moreover, by breaking the\nanalysis into small independent parts, when the full program is analyzed again\nbecause of a code change the analysis results of the unchanged part of the code\ncan be reused, and only the code change needs to be re-analyzed. This process\nis called incremental analysis and it is very powerful when integrating a\nstatic analysis tool like Infer in a development environment."}),"\n",(0,a.jsxs)(n.p,{children:["In order to be able to decompose a global analysis into small independent\nanalyses, let's first consider how a function call is analyzed in separation\nlogic. Assume we have the following spec for a function\n",(0,a.jsx)(l,{code:"\\\\( f() \\\\)"}),":"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace pre\\_f \\rbrace \\;\\; f() \\;\\; \\lbrace post\\_f \\rbrace \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["and by analyzing the caller function, we compute that before the call of ",(0,a.jsx)(l,{code:"\\\\( f \\\\)"}),", the formula ",(0,a.jsx)(l,{code:"\\\\( CallingState \\\\)"}),"\nholds. Then to utilize the specification of ",(0,a.jsx)(l,{code:"\\\\( f \\\\)"})," the\nfollowing implication must hold:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( CallingState \\vdash pre\\_f \\;\\;\\;\\;\\;\\;\\;\\;\\;\\;\\;\\; (Function Call)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"Given that, bi-abduction is used at procedure call sites for two reasons: to\ndiscover missing state that is needed for the above implication to hold and\nallow the analysis to proceed (the antiframe) as well as state that the\nprocedure leaves unchanged (the frame)."}),"\n",(0,a.jsx)(n.p,{children:"To see how this works suppose we have some bare code"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(closeResource(r1); \\, closeResource(r2)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["but no overall specification; we are going to describe how to discover a\npre/post spec for it. Considering the first statement and the (spec) above, the\nhuman might say: if only we had ",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto open\\\\)"})," in the\nprecondition then we could proceed. Technically, we ask a bi-abduction question:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(emp * ?antiframe \\vdash r1 \\mapsto open * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["and we can fill this in easily by picking\n",(0,a.jsx)(l,{code:"\\\\(antiframe = r1 \\mapsto open\\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\(frame = emp\\\\)"}),", where ",(0,a.jsx)(l,{code:"emp"}),"\nmeans the empty state. The ",(0,a.jsx)(l,{code:"emp"})," is recording that at the start\nwe presume nothing. So we obtain the trivially true implication:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(emp * r1 \\mapsto open \\vdash r1 \\mapsto open * emp\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"which, by applying logical rules, can be re-written equivalently to:"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto open \\vdash r1 \\mapsto open\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["Notice that this satisfies the (Function Call) requirement to correctly make\nthe call. So let's add that information in the ",(0,a.jsx)(l,{code:"pre"}),", and while\nwe are at it, record the information in the ",(0,a.jsx)(l,{code:"post"})," of the first\nstatement that comes from ",(0,a.jsx)(l,{code:"\\\\(spec\\\\)"}),"."]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["Now, let's move to the second statement. Its precondition\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed\\\\)"})," in the partial symbolic execution trace\njust given does not have the information needed by\n",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"}),", so we can fill that in and continue by\nputting ",(0,a.jsx)(l,{code:"\\\\(r2 \\mapsto open\\\\)"})," in the ",(0,a.jsx)(l,{code:"pre"}),". While\nwe are at it, we can thread this assertion back to the beginning."]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open * r2 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto open\\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"This information on what to thread backwards can be obtained as the antiframe\npart of the bi-abduction question:"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed * ?antiframe \\vdash r2 \\mapsto open * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["where the solution picks\n",(0,a.jsx)(l,{code:"\\\\(antiframe = r2 \\mapsto open\\\\) and \\\\(frame = r1 \\mapsto closed\\\\)"}),".\nNote that the antiframe is precisely the information missing from the\nprecondition in order for ",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"})," to proceed. On\nthe other hand, the frame ",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed\\\\)"})," is the portion\nof state not changed by ",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"}),"; we can thread\nthat through to the overall postconditon (as justified by the frame rule),\ngiving us:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open * r2 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto open\\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto closed \\rbrace\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["Thus, we have obtained a ",(0,a.jsx)(l,{code:"pre"})," and ",(0,a.jsx)(l,{code:"post"})," for this\ncode by symbolically executing it, using bi-abduction to discover preconditions\n(abduction of antiframes) as well as untouched portions of memory (frames) as\nwe go along."]}),"\n",(0,a.jsx)(n.p,{children:"In general, bi-abduction provides a way to infer a pre/post specs from bare\ncode, as long as we know specs for the primitives at the base level of the code.\nThe human does not need to write preconditions and postconditions for all the\nprocedures, which is the key to having a high level of automation. This is the\nbasis for how Infer works, why it can scale, and how it can analyze code changes\nincrementally."}),"\n",(0,a.jsx)(n.p,{children:"Context: The logical terminology we have been using here comes from AI and\nphilosophy of science. Abductive inference was introduced by the philosopher\nCharles Peirce, and described as the mechanism underpinning hypothesis formation\n(or, guessing what might be true about the world), the most creative part of the\nscientific process. Abduction and the frame problem have both attracted\nsignificant attention in AI. Infer uses an automated form of abduction to\ngenerate preconditions describing the memory that a program touches (the\nantiframe part above), and frame inference to discover what isn't touched. Infer\nthen uses deductive reasoning to calculate a formula describing the effect of a\nprogram, starting from the preconditions. In a sense, Infer approaches automated\nreasoning about programs by mimicking what a human might do when trying to\nunderstand a program: it abduces what the program needs, and deduces conclusions\nof that. It is when the reasoning goes wrong that Infer reports a potential bug."}),"\n",(0,a.jsx)(n.p,{children:"This description is by necessity simplified compared to what Infer actually\ndoes. More technical information can be found in the following papers. The\ndescriptions in the papers are precise, but still simplified; there are many\nengineering decisions not recorded there. Finally, beyond the papers, you can\nread the source code if you wish!"}),"\n",(0,a.jsx)(n.h2,{id:"technical-papers",children:"Technical papers"}),"\n",(0,a.jsx)(n.p,{children:"The following papers contain some of the technical background on Infer and\ninformation on how it is used inside Facebook."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007%2F3-540-44802-0_1",children:"Local\nReasoning about Programs that Alter Data Structures."})," An early separation\nlogic paper which advanced ideas about local reasoning and the frame rule."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007/11804192_6",children:"Smallfoot:\nModular Automatic Assertion Checking with Separation Logic."})," First\nseparation logic verification tool, introduced frame inference"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007%2F11691372_19",children:"A Local Shape\nAnalysis Based on Separation Logic."})," Separation logic meets abstract\ninterpretation; calculating loop invariants via a fixed-point computation."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://dl.acm.org/citation.cfm?id=2049700",children:"Compositional Shape\nAnalysis by Means of Bi-Abduction."})," The bi-abduction paper."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"https://research.facebook.com/publications/moving-fast-with-software-verification/",children:"Moving\nFast with Software Verification."})," A paper about the way we use Infer at\nFacebook."]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},8615:(e,n,o)=>{o.d(n,{A:()=>a});const a=o.p+"assets/images/SepSplit-dca4e1fe63cb590718402c7c0c9ab7f8.jpg"},8453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>r});var a=o(6540);const t={},s=a.createContext(t);function i(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/413f2abb.2a3134f2.js b/assets/js/413f2abb.2a3134f2.js new file mode 100644 index 00000000000..7831355765c --- /dev/null +++ b/assets/js/413f2abb.2a3134f2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[8886],{3950:(e,n,o)=>{o.r(n),o.d(n,{Math:()=>l,assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var a=o(4848),t=o(8453);const s={id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction"},i=void 0,r={id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction",description:"- Separation logic",source:"@site/versioned_docs/version-1.1.0/02-separation-logic-and-biabduction.md",sourceDirName:".",slug:"/separation-logic-and-bi-abduction",permalink:"/docs/1.1.0/separation-logic-and-bi-abduction",draft:!1,unlisted:!1,tags:[],version:"1.1.0",sidebarPosition:2,frontMatter:{id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction"},sidebar:"docs",previous:{title:"About Infer",permalink:"/docs/1.1.0/about-Infer"},next:{title:"Building checkers with the Infer.AI framework",permalink:"/docs/1.1.0/absint-framework"}},c={},l=({code:e})=>(0,a.jsx)("img",{src:`https://math.now.sh?from=${encodeURIComponent(e)}&color=mediumslateblue`,style:{height:"100%",verticalAlign:"middle"}}),d=[{value:"Separation logic",id:"separation-logic",level:2},{value:"Bi-abduction",id:"bi-abduction",level:2},{value:"Technical papers",id:"technical-papers",level:2}];function h(e){const n={a:"a",em:"em",h2:"h2",hr:"hr",img:"img",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#separation-logic",children:"Separation logic"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#bi-abduction",children:"Bi-abduction"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#technical-papers",children:"Technical papers"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"separation-logic",children:"Separation logic"}),"\n",(0,a.jsx)(n.p,{children:"Separation logic is a novel kind of mathematical logic which facilitates\nreasoning about mutations to computer memory. It enables scalability by breaking\nreasoning into chunks corresponding to local operations on memory, and then\ncomposing the reasoning chunks together."}),"\n",(0,a.jsxs)(n.p,{children:["Separation logic is based on a logical connective ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"}),"\ncalled the ",(0,a.jsx)(n.em,{children:"separating conjunction"}),' and pronounced "and separately". Separation\nlogic formulae are interpreted over program allocated heaps. The logical formula\n',(0,a.jsx)(l,{code:"\\\\( A*B \\\\)"})," holds of a piece of program heap (a heaplet) when it\ncan be divided into two sub-heaplets described by ",(0,a.jsx)(l,{code:"\\\\(A\\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\(B\\\\)"}),". For example, the formula"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(x \\mapsto y * y \\mapsto x \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:['can be read "',(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," points to ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," and\nseparately ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," points to ",(0,a.jsx)(l,{code:"\\\\(x\\\\)"}),'". This\nformula describes precisely two allocated memory cells. The first cell is\nallocated at the address denoted by the pointer ',(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," and the\ncontent of this cell is the value of ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"}),". The second cell is\nallocated at the address denoted by the pointer ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," and the\ncontent of this second cell is the value of ",(0,a.jsx)(l,{code:"\\\\(x\\\\)"}),". Crucially,\nwe know that there are precisely two cells because ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"}),"\nstipulates that they are separated and therefore the cells are allocated in two\ndifferent parts of memory. In other words, ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"})," says that\n",(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," and ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," do not hold the same value\n(i.e., these pointers are not aliased). The heaplet partitioning defined by the\nformula above can be visualized like so:"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{src:o(8615).A+"",width:"473",height:"129"})}),"\n",(0,a.jsxs)(n.p,{children:["The important thing about separating conjunction is the way that it fits\ntogether with mutation to computer memory; reasoning about program commands\ntends to work by updating ",(0,a.jsx)(l,{code:"\\\\(*\\\\)"}),"-conjuncts in-place, mimicking\nthe operational in-place update of RAM."]}),"\n",(0,a.jsxs)(n.p,{children:["Separation logic uses Hoare triples of the form\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace pre \\rbrace prog \\lbrace post \\rbrace \\\\)"})," where\n",(0,a.jsx)(l,{code:"\\\\(pre\\\\)"})," is the precondition, ",(0,a.jsx)(l,{code:"\\\\(prog\\\\)"})," a\nprogram part, and ",(0,a.jsx)(l,{code:"\\\\(post\\\\)"})," the postcondition. Triples are\nabstract specifications of the behavior of the program. For example, we could\ntake"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r \\mapsto open\\rbrace \\, closeResource(r)\\, \\lbrace r \\mapsto closed\\rbrace \\;\\;\\; (spec)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"as a specification for a method which closes a resource given to it as a\nparameter."}),"\n",(0,a.jsxs)(n.p,{children:["Now, suppose we have two resources ",(0,a.jsx)(l,{code:"\\\\( r\\_1 \\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\( r\\_2 \\\\)"}),", described by\n",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto open * r\\_2 \\mapsto open\\\\)"})," and we close the\nfirst of them. We think operationally in terms of updating the memory in place,\nleaving ",(0,a.jsx)(l,{code:"\\\\(r\\_2 \\mapsto open\\\\)"})," alone, as described by this triple:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r\\_1 \\mapsto open * r\\_2 \\mapsto open\\rbrace closeResource(r\\_1) \\lbrace r\\_1 \\mapsto closed * r\\_2 \\mapsto open \\rbrace \\;\\;\\; (use)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["What we have here is the that specification (spec) described how\n",(0,a.jsx)(l,{code:"\\\\(closeResource()\\\\)"})," works by mentioning only one piece of\nstate, what is sometimes called a small specification, and in (use) we use that\nspecification to update a larger precondition in place."]}),"\n",(0,a.jsx)(n.p,{children:"This is an instance of a general pattern. There is a rule that lets you go from\nsmaller to bigger specifications"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\frac{\\lbrace pre \\rbrace prog \\lbrace post \\rbrace}{\\lbrace pre * frame \\rbrace prog \\lbrace post * frame \\rbrace}\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"Our passage from (spec) to (use) is obtained by taking"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(pre\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto open\\\\)"})]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(post\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto closed \\\\)"}),",\nand"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(frame\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_2 \\mapsto open \\\\)"})]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["This rule is called the ",(0,a.jsx)(n.em,{children:"frame rule"})," of separation logic. It is named after the\nframe problem, a classic problem in artificial intelligence. Generally, the\n",(0,a.jsx)(l,{code:"\\\\(frame\\\\)"})," describes state that remains unchanged; the\nterminology comes from the analogy of a background scene in an animation as\nunchanging while the objects and characters within the scene change."]}),"\n",(0,a.jsx)(n.p,{children:"The frame rule is the key to the principle of local reasoning in separation\nlogic: reasoning and specifications should concentrate on the resources that a\nprogram accesses (the footprint), without mentioning what doesn't change."}),"\n",(0,a.jsx)(n.h2,{id:"bi-abduction",children:"Bi-abduction"}),"\n",(0,a.jsx)(n.p,{children:"Bi-abduction is a form of logical inference for separation logic which automates\nthe key ideas about local reasoning."}),"\n",(0,a.jsx)(n.p,{children:"Usually, logic works with validity or entailment statements like"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(A \\vdash B\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["which says that ",(0,a.jsx)(l,{code:"\\\\(A\\\\)"})," implies ",(0,a.jsx)(l,{code:"\\\\(B\\\\)"}),". Infer\nuses an extension of this inference question in an internal theorem prover while\nit runs over program statements. Infer's question"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(A * ?antiframe \\vdash B * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["is called ",(0,a.jsx)(n.em,{children:"bi-abduction"}),". The problem here is for the theorem prover to ",(0,a.jsx)("i",{children:"\ndiscover "})," a pair of frame and antiframe formulae that make the entailment\nstatement valid."]}),"\n",(0,a.jsx)(n.p,{children:"Global analyses of large programs are normally computational untractable.\nHowever, bi-abduction allows to break the large analysis of a large program in\nsmall independent analyses of its procedures. This gives Infer the ability to\nscale independently of the size of the analyzed code. Moreover, by breaking the\nanalysis in small independent parts, when the full program is analyzed again\nbecause of a code change the analysis results of the unchanged part of the code\ncan be reused and only the code change needs to be re-analyzed. This process is\ncalled incremental analysis and it is very powerful when integrating a static\nanalysis tool like infer in a development environment."}),"\n",(0,a.jsxs)(n.p,{children:["In order to be able to decompose a global analysis in small independent\nanalyses, let's first consider how a function call is analyzed in separation\nlogic. Assume we have the following spec for a function\n",(0,a.jsx)(l,{code:"\\\\( f() \\\\)"}),":"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace pre\\_f \\rbrace \\;\\; f() \\;\\; \\lbrace post\\_f \\rbrace \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["and by analyzing the caller function, we compute that before the call of\n",(0,a.jsx)(l,{code:"\\\\( f \\\\)"}),", the formula ",(0,a.jsx)(l,{code:"\\\\( CallingState \\\\)"}),"\nhold. Then to utilize the specification of ",(0,a.jsx)(l,{code:"\\\\( f \\\\)"})," the\nfollowing implication must holds:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( CallingState \\vdash pre\\_f \\;\\;\\;\\;\\;\\;\\;\\;\\;\\;\\;\\; (Function Call)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"Given that, bi-abduction is used at procedure call sites for two reasons: to\ndiscover missing state that is needed for the above implication to hold and\nallow the analysis to proceed (the antiframe) as well as state that the\nprocedure leaves unchanged (the frame)."}),"\n",(0,a.jsx)(n.p,{children:"To see how this works suppose we have some bare code"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(closeResource(r1); \\, closeResource(r2)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["but no overall specification; we are going to describe how to discover a\npre/post spec for it. Considering the first statement and the (spec) above, the\nhuman might say: if only we had ",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto open\\\\)"})," in the\nprecondition then we could proceed. Technically, we ask a bi-abduction question"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(emp * ?antiframe \\vdash r1 \\mapsto open * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["and we can fill this in easily by picking\n",(0,a.jsx)(l,{code:"\\\\(antiframe = r1 \\mapsto open\\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\(frame = emp\\\\)"}),", where emp means the empty state. The emp is\nrecording that at the start we presume nothing. So we obtain the trivially true\nimplication:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(emp * r1 \\mapsto open \\vdash r1 \\mapsto open * emp\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"which, by applying logical rules, can be re-written equivalently to:"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto open \\vdash r1 \\mapsto open\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"Notice that this satisfy the (Function Call) requirement to correctly make the\ncall. So let's add that information in the pre, and while we are at it record\nthe information in the post of the first statement that comes from (spec)."}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["Now, let's move to the second statement. Its precondition\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed\\\\)"})," in the partial symbolic execution trace\njust given does not have the information needed by\n",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"}),", so we can fill that in and continue by\nputting ",(0,a.jsx)(l,{code:"\\\\(r2 \\mapsto open\\\\)"})," in the pre. While we are at it we\ncan thread this assertion back to the beginning."]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open * r2 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto open\\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"This information on what to thread backwards can be obtained as the antiframe\npart of the bi-abduction question"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed * ?antiframe \\vdash r2 \\mapsto open * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["where the solution picks\n",(0,a.jsx)(l,{code:"\\\\(antiframe = r2 \\mapsto open\\\\) and \\\\(frame = r1 \\mapsto closed\\\\)"}),".\nNote that the antiframe is precisely the information missing from the\nprecondition in order for ",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"})," to proceed. On\nthe other hand, the frame ",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed\\\\)"})," is the portion\nof state not changed by ",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"}),"; we can thread\nthat through to the overall postconditon (as justified by the frame rule),\ngiving us"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open * r2 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto open\\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto closed \\rbrace\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"Thus, we have obtained a pre and post for this code by symbolically executing\nit, using bi-abduction to discover preconditions (abduction of antiframes) as\nwell as untouched portions of memory (frames) as we go along."}),"\n",(0,a.jsx)(n.p,{children:"In general, bi-abduction provides a way to infer a pre/post specs from bare\ncode, as long as we know specs for the primitives at the base level of the code.\nThe human does not need to write preconditions and postconditions for all the\nprocedures, which is the key to having a high level of automation. This is the\nbasis for how Infer works, why it can scale, and how it can analyze code changes\nincrementally."}),"\n",(0,a.jsx)(n.p,{children:"Context: The logical terminology we have been using here comes from AI and\nphilosophy of science. Abductive inference was introduced by the philosopher\nCharles Peirce, and described as the mechanism underpinning hypothesis formation\n(or, guessing what might be true about the world), the most creative part of the\nscientific process. Abduction and the frame problem have both attracted\nsignificant attention in AI. Infer uses an automated form of abduction to\ngenerate preconditions describing the memory that a program touches (the\nantiframe part above), and frame inference to discover what isn't touched. Infer\nthen uses deductive reasoning to calculate a formula describing the effect of a\nprogram, starting from the preconditions. In a sense, Infer approaches automated\nreasoning about programs by mimicking what a human might do when trying to\nunderstand a program: it abduces what the program needs, and deduces conclusions\nof that. It is when the reasoning goes wrong that Infer reports a potential bug."}),"\n",(0,a.jsx)(n.p,{children:"This description is by necessity simplified compared to what Infer actually\ndoes. More technical information can be found in the following papers. The\ndescriptions in the papers are precise, but still simplified; there are many\nengineering decisions not recorded there. Finally, beyond the papers, you can\nread the source code if you wish!"}),"\n",(0,a.jsx)(n.h2,{id:"technical-papers",children:"Technical papers"}),"\n",(0,a.jsx)(n.p,{children:"The following papers contain some of the technical background on Infer and\ninformation on how it is used inside Facebook."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007%2F3-540-44802-0_1",children:"Local\nReasoning about Programs that Alter Data Structures."})," An early separation\nlogic paper which advanced ideas about local reasoning and the frame rule."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007/11804192_6",children:"Smallfoot:\nModular Automatic Assertion Checking with Separation Logic."})," First\nseparation logic verification tool, introduced frame inference"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007%2F11691372_19",children:"A Local Shape\nAnalysis Based on Separation Logic."})," Separation logic meets abstract\ninterpretation; calculating loop invariants via a fixed-point computation."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://dl.acm.org/citation.cfm?id=2049700",children:"Compositional Shape\nAnalysis by Means of Bi-Abduction."})," The bi-abduction paper."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"https://research.facebook.com/publications/moving-fast-with-software-verification/",children:"Moving\nFast with Software Verification."})," A paper about the way we use Infer at\nFacebook."]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},8615:(e,n,o)=>{o.d(n,{A:()=>a});const a=o.p+"assets/images/SepSplit-dca4e1fe63cb590718402c7c0c9ab7f8.jpg"},8453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>r});var a=o(6540);const t={},s=a.createContext(t);function i(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/413f2abb.a98743fb.js b/assets/js/413f2abb.a98743fb.js deleted file mode 100644 index a1102be6004..00000000000 --- a/assets/js/413f2abb.a98743fb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[8886],{3950:(e,n,o)=>{o.r(n),o.d(n,{Math:()=>l,assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var a=o(4848),t=o(8453);const s={id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction"},i=void 0,r={id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction",description:"- Separation logic",source:"@site/versioned_docs/version-1.1.0/02-separation-logic-and-biabduction.md",sourceDirName:".",slug:"/separation-logic-and-bi-abduction",permalink:"/docs/1.1.0/separation-logic-and-bi-abduction",draft:!1,unlisted:!1,tags:[],version:"1.1.0",sidebarPosition:2,frontMatter:{id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction"},sidebar:"docs",previous:{title:"About Infer",permalink:"/docs/1.1.0/about-Infer"},next:{title:"Building checkers with the Infer.AI framework",permalink:"/docs/1.1.0/absint-framework"}},c={},l=({code:e})=>{const n={img:"img",...(0,t.R)()};return(0,a.jsx)(n.img,{src:`https://math.now.sh?from=${encodeURIComponent(e)}&color=mediumslateblue`,style:{height:"100%",verticalAlign:"middle"}})},d=[{value:"Separation logic",id:"separation-logic",level:2},{value:"Bi-abduction",id:"bi-abduction",level:2},{value:"Technical papers",id:"technical-papers",level:2}];function h(e){const n={a:"a",em:"em",h2:"h2",hr:"hr",img:"img",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#separation-logic",children:"Separation logic"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#bi-abduction",children:"Bi-abduction"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#technical-papers",children:"Technical papers"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"separation-logic",children:"Separation logic"}),"\n",(0,a.jsx)(n.p,{children:"Separation logic is a novel kind of mathematical logic which facilitates\nreasoning about mutations to computer memory. It enables scalability by breaking\nreasoning into chunks corresponding to local operations on memory, and then\ncomposing the reasoning chunks together."}),"\n",(0,a.jsxs)(n.p,{children:["Separation logic is based on a logical connective ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"}),"\ncalled the ",(0,a.jsx)(n.em,{children:"separating conjunction"}),' and pronounced "and separately". Separation\nlogic formulae are interpreted over program allocated heaps. The logical formula\n',(0,a.jsx)(l,{code:"\\\\( A*B \\\\)"})," holds of a piece of program heap (a heaplet) when it\ncan be divided into two sub-heaplets described by ",(0,a.jsx)(l,{code:"\\\\(A\\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\(B\\\\)"}),". For example, the formula"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(x \\mapsto y * y \\mapsto x \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:['can be read "',(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," points to ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," and\nseparately ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," points to ",(0,a.jsx)(l,{code:"\\\\(x\\\\)"}),'". This\nformula describes precisely two allocated memory cells. The first cell is\nallocated at the address denoted by the pointer ',(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," and the\ncontent of this cell is the value of ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"}),". The second cell is\nallocated at the address denoted by the pointer ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," and the\ncontent of this second cell is the value of ",(0,a.jsx)(l,{code:"\\\\(x\\\\)"}),". Crucially,\nwe know that there are precisely two cells because ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"}),"\nstipulates that they are separated and therefore the cells are allocated in two\ndifferent parts of memory. In other words, ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"})," says that\n",(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," and ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," do not hold the same value\n(i.e., these pointers are not aliased). The heaplet partitioning defined by the\nformula above can be visualized like so:"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{src:o(8615).A+"",width:"473",height:"129"})}),"\n",(0,a.jsxs)(n.p,{children:["The important thing about separating conjunction is the way that it fits\ntogether with mutation to computer memory; reasoning about program commands\ntends to work by updating ",(0,a.jsx)(l,{code:"\\\\(*\\\\)"}),"-conjuncts in-place, mimicking\nthe operational in-place update of RAM."]}),"\n",(0,a.jsxs)(n.p,{children:["Separation logic uses Hoare triples of the form\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace pre \\rbrace prog \\lbrace post \\rbrace \\\\)"})," where\n",(0,a.jsx)(l,{code:"\\\\(pre\\\\)"})," is the precondition, ",(0,a.jsx)(l,{code:"\\\\(prog\\\\)"})," a\nprogram part, and ",(0,a.jsx)(l,{code:"\\\\(post\\\\)"})," the postcondition. Triples are\nabstract specifications of the behavior of the program. For example, we could\ntake"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r \\mapsto open\\rbrace \\, closeResource(r)\\, \\lbrace r \\mapsto closed\\rbrace \\;\\;\\; (spec)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"as a specification for a method which closes a resource given to it as a\nparameter."}),"\n",(0,a.jsxs)(n.p,{children:["Now, suppose we have two resources ",(0,a.jsx)(l,{code:"\\\\( r\\_1 \\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\( r\\_2 \\\\)"}),", described by\n",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto open * r\\_2 \\mapsto open\\\\)"})," and we close the\nfirst of them. We think operationally in terms of updating the memory in place,\nleaving ",(0,a.jsx)(l,{code:"\\\\(r\\_2 \\mapsto open\\\\)"})," alone, as described by this triple:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r\\_1 \\mapsto open * r\\_2 \\mapsto open\\rbrace closeResource(r\\_1) \\lbrace r\\_1 \\mapsto closed * r\\_2 \\mapsto open \\rbrace \\;\\;\\; (use)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["What we have here is the that specification (spec) described how\n",(0,a.jsx)(l,{code:"\\\\(closeResource()\\\\)"})," works by mentioning only one piece of\nstate, what is sometimes called a small specification, and in (use) we use that\nspecification to update a larger precondition in place."]}),"\n",(0,a.jsx)(n.p,{children:"This is an instance of a general pattern. There is a rule that lets you go from\nsmaller to bigger specifications"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\frac{\\lbrace pre \\rbrace prog \\lbrace post \\rbrace}{\\lbrace pre * frame \\rbrace prog \\lbrace post * frame \\rbrace}\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"Our passage from (spec) to (use) is obtained by taking"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(pre\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto open\\\\)"})]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(post\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto closed \\\\)"}),",\nand"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(frame\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_2 \\mapsto open \\\\)"})]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["This rule is called the ",(0,a.jsx)(n.em,{children:"frame rule"})," of separation logic. It is named after the\nframe problem, a classic problem in artificial intelligence. Generally, the\n",(0,a.jsx)(l,{code:"\\\\(frame\\\\)"})," describes state that remains unchanged; the\nterminology comes from the analogy of a background scene in an animation as\nunchanging while the objects and characters within the scene change."]}),"\n",(0,a.jsx)(n.p,{children:"The frame rule is the key to the principle of local reasoning in separation\nlogic: reasoning and specifications should concentrate on the resources that a\nprogram accesses (the footprint), without mentioning what doesn't change."}),"\n",(0,a.jsx)(n.h2,{id:"bi-abduction",children:"Bi-abduction"}),"\n",(0,a.jsx)(n.p,{children:"Bi-abduction is a form of logical inference for separation logic which automates\nthe key ideas about local reasoning."}),"\n",(0,a.jsx)(n.p,{children:"Usually, logic works with validity or entailment statements like"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(A \\vdash B\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["which says that ",(0,a.jsx)(l,{code:"\\\\(A\\\\)"})," implies ",(0,a.jsx)(l,{code:"\\\\(B\\\\)"}),". Infer\nuses an extension of this inference question in an internal theorem prover while\nit runs over program statements. Infer's question"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(A * ?antiframe \\vdash B * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["is called ",(0,a.jsx)(n.em,{children:"bi-abduction"}),". The problem here is for the theorem prover to ",(0,a.jsx)("i",{children:"\ndiscover "})," a pair of frame and antiframe formulae that make the entailment\nstatement valid."]}),"\n",(0,a.jsx)(n.p,{children:"Global analyses of large programs are normally computational untractable.\nHowever, bi-abduction allows to break the large analysis of a large program in\nsmall independent analyses of its procedures. This gives Infer the ability to\nscale independently of the size of the analyzed code. Moreover, by breaking the\nanalysis in small independent parts, when the full program is analyzed again\nbecause of a code change the analysis results of the unchanged part of the code\ncan be reused and only the code change needs to be re-analyzed. This process is\ncalled incremental analysis and it is very powerful when integrating a static\nanalysis tool like infer in a development environment."}),"\n",(0,a.jsxs)(n.p,{children:["In order to be able to decompose a global analysis in small independent\nanalyses, let's first consider how a function call is analyzed in separation\nlogic. Assume we have the following spec for a function\n",(0,a.jsx)(l,{code:"\\\\( f() \\\\)"}),":"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace pre\\_f \\rbrace \\;\\; f() \\;\\; \\lbrace post\\_f \\rbrace \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["and by analyzing the caller function, we compute that before the call of\n",(0,a.jsx)(l,{code:"\\\\( f \\\\)"}),", the formula ",(0,a.jsx)(l,{code:"\\\\( CallingState \\\\)"}),"\nhold. Then to utilize the specification of ",(0,a.jsx)(l,{code:"\\\\( f \\\\)"})," the\nfollowing implication must holds:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( CallingState \\vdash pre\\_f \\;\\;\\;\\;\\;\\;\\;\\;\\;\\;\\;\\; (Function Call)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"Given that, bi-abduction is used at procedure call sites for two reasons: to\ndiscover missing state that is needed for the above implication to hold and\nallow the analysis to proceed (the antiframe) as well as state that the\nprocedure leaves unchanged (the frame)."}),"\n",(0,a.jsx)(n.p,{children:"To see how this works suppose we have some bare code"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(closeResource(r1); \\, closeResource(r2)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["but no overall specification; we are going to describe how to discover a\npre/post spec for it. Considering the first statement and the (spec) above, the\nhuman might say: if only we had ",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto open\\\\)"})," in the\nprecondition then we could proceed. Technically, we ask a bi-abduction question"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(emp * ?antiframe \\vdash r1 \\mapsto open * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["and we can fill this in easily by picking\n",(0,a.jsx)(l,{code:"\\\\(antiframe = r1 \\mapsto open\\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\(frame = emp\\\\)"}),", where emp means the empty state. The emp is\nrecording that at the start we presume nothing. So we obtain the trivially true\nimplication:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(emp * r1 \\mapsto open \\vdash r1 \\mapsto open * emp\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"which, by applying logical rules, can be re-written equivalently to:"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto open \\vdash r1 \\mapsto open\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"Notice that this satisfy the (Function Call) requirement to correctly make the\ncall. So let's add that information in the pre, and while we are at it record\nthe information in the post of the first statement that comes from (spec)."}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["Now, let's move to the second statement. Its precondition\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed\\\\)"})," in the partial symbolic execution trace\njust given does not have the information needed by\n",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"}),", so we can fill that in and continue by\nputting ",(0,a.jsx)(l,{code:"\\\\(r2 \\mapsto open\\\\)"})," in the pre. While we are at it we\ncan thread this assertion back to the beginning."]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open * r2 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto open\\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"This information on what to thread backwards can be obtained as the antiframe\npart of the bi-abduction question"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed * ?antiframe \\vdash r2 \\mapsto open * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["where the solution picks\n",(0,a.jsx)(l,{code:"\\\\(antiframe = r2 \\mapsto open\\\\) and \\\\(frame = r1 \\mapsto closed\\\\)"}),".\nNote that the antiframe is precisely the information missing from the\nprecondition in order for ",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"})," to proceed. On\nthe other hand, the frame ",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed\\\\)"})," is the portion\nof state not changed by ",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"}),"; we can thread\nthat through to the overall postconditon (as justified by the frame rule),\ngiving us"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open * r2 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto open\\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto closed \\rbrace\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"Thus, we have obtained a pre and post for this code by symbolically executing\nit, using bi-abduction to discover preconditions (abduction of antiframes) as\nwell as untouched portions of memory (frames) as we go along."}),"\n",(0,a.jsx)(n.p,{children:"In general, bi-abduction provides a way to infer a pre/post specs from bare\ncode, as long as we know specs for the primitives at the base level of the code.\nThe human does not need to write preconditions and postconditions for all the\nprocedures, which is the key to having a high level of automation. This is the\nbasis for how Infer works, why it can scale, and how it can analyze code changes\nincrementally."}),"\n",(0,a.jsx)(n.p,{children:"Context: The logical terminology we have been using here comes from AI and\nphilosophy of science. Abductive inference was introduced by the philosopher\nCharles Peirce, and described as the mechanism underpinning hypothesis formation\n(or, guessing what might be true about the world), the most creative part of the\nscientific process. Abduction and the frame problem have both attracted\nsignificant attention in AI. Infer uses an automated form of abduction to\ngenerate preconditions describing the memory that a program touches (the\nantiframe part above), and frame inference to discover what isn't touched. Infer\nthen uses deductive reasoning to calculate a formula describing the effect of a\nprogram, starting from the preconditions. In a sense, Infer approaches automated\nreasoning about programs by mimicking what a human might do when trying to\nunderstand a program: it abduces what the program needs, and deduces conclusions\nof that. It is when the reasoning goes wrong that Infer reports a potential bug."}),"\n",(0,a.jsx)(n.p,{children:"This description is by necessity simplified compared to what Infer actually\ndoes. More technical information can be found in the following papers. The\ndescriptions in the papers are precise, but still simplified; there are many\nengineering decisions not recorded there. Finally, beyond the papers, you can\nread the source code if you wish!"}),"\n",(0,a.jsx)(n.h2,{id:"technical-papers",children:"Technical papers"}),"\n",(0,a.jsx)(n.p,{children:"The following papers contain some of the technical background on Infer and\ninformation on how it is used inside Facebook."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007%2F3-540-44802-0_1",children:"Local\nReasoning about Programs that Alter Data Structures."})," An early separation\nlogic paper which advanced ideas about local reasoning and the frame rule."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007/11804192_6",children:"Smallfoot:\nModular Automatic Assertion Checking with Separation Logic."})," First\nseparation logic verification tool, introduced frame inference"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007%2F11691372_19",children:"A Local Shape\nAnalysis Based on Separation Logic."})," Separation logic meets abstract\ninterpretation; calculating loop invariants via a fixed-point computation."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://dl.acm.org/citation.cfm?id=2049700",children:"Compositional Shape\nAnalysis by Means of Bi-Abduction."})," The bi-abduction paper."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"https://research.facebook.com/publications/moving-fast-with-software-verification/",children:"Moving\nFast with Software Verification."})," A paper about the way we use Infer at\nFacebook."]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},8615:(e,n,o)=>{o.d(n,{A:()=>a});const a=o.p+"assets/images/SepSplit-dca4e1fe63cb590718402c7c0c9ab7f8.jpg"},8453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>r});var a=o(6540);const t={},s=a.createContext(t);function i(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b4a56aa4.e796c4bd.js b/assets/js/b4a56aa4.e796c4bd.js deleted file mode 100644 index 687733eae9a..00000000000 --- a/assets/js/b4a56aa4.e796c4bd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[6499],{3127:(e,n,o)=>{o.r(n),o.d(n,{Math:()=>l,assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var a=o(4848),t=o(8453);const s={id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction"},i=void 0,r={id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction",description:"- Separation logic",source:"@site/versioned_docs/version-1.2.0/02-separation-logic-and-biabduction.md",sourceDirName:".",slug:"/separation-logic-and-bi-abduction",permalink:"/docs/separation-logic-and-bi-abduction",draft:!1,unlisted:!1,tags:[],version:"1.2.0",sidebarPosition:2,frontMatter:{id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction"},sidebar:"docs",previous:{title:"About Infer",permalink:"/docs/about-Infer"},next:{title:"Building checkers with the Infer.AI framework",permalink:"/docs/absint-framework"}},c={},l=({code:e})=>{const n={img:"img",...(0,t.R)()};return(0,a.jsx)(n.img,{src:`https://math.now.sh?from=${encodeURIComponent(e)}&color=mediumslateblue`,style:{height:"100%",verticalAlign:"middle"}})},d=[{value:"Separation logic",id:"separation-logic",level:2},{value:"Bi-abduction",id:"bi-abduction",level:2},{value:"Technical papers",id:"technical-papers",level:2}];function h(e){const n={a:"a",em:"em",h2:"h2",hr:"hr",img:"img",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#separation-logic",children:"Separation logic"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#bi-abduction",children:"Bi-abduction"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#technical-papers",children:"Technical papers"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"separation-logic",children:"Separation logic"}),"\n",(0,a.jsx)(n.p,{children:"Separation logic is a novel kind of mathematical logic which facilitates\nreasoning about mutations to computer memory. It enables scalability by breaking\nreasoning into chunks corresponding to local operations on memory, and then\ncomposing the reasoning chunks together."}),"\n",(0,a.jsxs)(n.p,{children:["Separation logic is based on a logical connective ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"}),"\ncalled the ",(0,a.jsx)(n.em,{children:"separating conjunction"}),' and pronounced "and separately". Separation\nlogic formulae are interpreted over program allocated heaps. The logical formula\n',(0,a.jsx)(l,{code:"\\\\( A*B \\\\)"})," holds of a piece of program heap (a heaplet) when it\ncan be divided into two sub-heaplets described by ",(0,a.jsx)(l,{code:"\\\\(A\\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\(B\\\\)"}),". For example, the formula"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(x \\mapsto y * y \\mapsto x \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:['can be read "',(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," points to ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," and\nseparately ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," points to ",(0,a.jsx)(l,{code:"\\\\(x\\\\)"}),'". This\nformula describes precisely two allocated memory cells. The first cell is\nallocated at the address denoted by the pointer ',(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," and the\ncontent of this cell is the value of ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"}),". The second cell is\nallocated at the address denoted by the pointer ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," and the\ncontent of this second cell is the value of ",(0,a.jsx)(l,{code:"\\\\(x\\\\)"}),". Crucially,\nwe know that there are precisely two cells because ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"}),"\nstipulates that they are separated and therefore the cells are allocated in two\ndifferent parts of memory. In other words, ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"})," says that\n",(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," and ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," do not hold the same value\n(i.e., these pointers are not aliased). The heaplet partitioning defined by the\nformula above can be visualized like so:"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{src:o(8615).A+"",width:"473",height:"129"})}),"\n",(0,a.jsxs)(n.p,{children:["The important thing about the separating conjunction is the way that it fits\ntogether with mutation to computer memory; reasoning about program commands\ntends to work by updating ",(0,a.jsx)(l,{code:"\\\\(*\\\\)"}),"-conjuncts in-place, mimicking\nthe operational in-place update of RAM."]}),"\n",(0,a.jsxs)(n.p,{children:["Separation logic uses Hoare triples of the form\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace pre \\rbrace prog \\lbrace post \\rbrace \\\\)"})," where\n",(0,a.jsx)(l,{code:"\\\\(pre\\\\)"})," is the precondition, ",(0,a.jsx)(l,{code:"\\\\(prog\\\\)"})," a\nprogram part, and ",(0,a.jsx)(l,{code:"\\\\(post\\\\)"})," the postcondition. Triples are\nabstract specifications of the behavior of the program. For example, we could\ntake"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r \\mapsto open\\rbrace \\, closeResource(r)\\, \\lbrace r \\mapsto closed\\rbrace \\;\\;\\; (spec)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"as a specification for a method which closes a resource given to it as a\nparameter."}),"\n",(0,a.jsxs)(n.p,{children:["Now, suppose we have two resources ",(0,a.jsx)(l,{code:"\\\\( r\\_1 \\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\( r\\_2 \\\\)"}),", described by\n",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto open * r\\_2 \\mapsto open\\\\)"})," and we close the\nfirst of them. We think operationally in terms of updating the memory in place,\nleaving ",(0,a.jsx)(l,{code:"\\\\(r\\_2 \\mapsto open\\\\)"})," alone, as described by this triple:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r\\_1 \\mapsto open * r\\_2 \\mapsto open\\rbrace closeResource(r\\_1) \\lbrace r\\_1 \\mapsto closed * r\\_2 \\mapsto open \\rbrace \\;\\;\\; (use)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["What we have here is the that specification (spec) described how\n",(0,a.jsx)(l,{code:"\\\\(closeResource()\\\\)"})," works by mentioning only one piece of\nstate, what is sometimes called a small specification, and in (use) we use that\nspecification to update a larger precondition in place."]}),"\n",(0,a.jsx)(n.p,{children:"This is an instance of a general pattern. There is a rule that lets you go from\nsmaller to bigger specifications"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\frac{\\lbrace pre \\rbrace prog \\lbrace post \\rbrace}{\\lbrace pre * frame \\rbrace prog \\lbrace post * frame \\rbrace}\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"Our passage from (spec) to (use) is obtained by taking"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(pre\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto open\\\\)"})]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(post\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto closed \\\\)"}),",\nand"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(frame\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_2 \\mapsto open \\\\)"})]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["This rule is called the ",(0,a.jsx)(n.em,{children:"frame rule"})," of separation logic. It is named after the\nframe problem, a classic problem in artificial intelligence. Generally, the\n",(0,a.jsx)(l,{code:"\\\\(frame\\\\)"})," describes state that remains unchanged; the\nterminology comes from the analogy of a background scene in an animation as\nunchanging while the objects and characters within the scene change."]}),"\n",(0,a.jsx)(n.p,{children:"The frame rule is the key to the principle of local reasoning in separation\nlogic: reasoning and specifications should concentrate on the resources that a\nprogram accesses (the footprint), without mentioning what doesn't change."}),"\n",(0,a.jsx)(n.h2,{id:"bi-abduction",children:"Bi-abduction"}),"\n",(0,a.jsx)(n.p,{children:"Bi-abduction is a form of logical inference for separation logic which automates\nthe key ideas about local reasoning."}),"\n",(0,a.jsx)(n.p,{children:"Usually, logic works with validity or entailment statements like"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(A \\vdash B\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["which says that ",(0,a.jsx)(l,{code:"\\\\(A\\\\)"})," implies ",(0,a.jsx)(l,{code:"\\\\(B\\\\)"}),". Infer\nuses an extension of this inference question in an internal theorem prover while\nit runs over program statements. Infer's question"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(A * ?antiframe \\vdash B * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["is called ",(0,a.jsx)(n.em,{children:"bi-abduction"}),". The problem here is for the theorem prover to ",(0,a.jsx)("i",{children:"\ndiscover "})," a pair of frame and antiframe formulae that make the entailment\nstatement valid."]}),"\n",(0,a.jsx)(n.p,{children:"Global analyses of large programs are normally computationally intractable.\nHowever, bi-abduction breaks apart a large analysis of a large program into\nsmall independent analyses of its procedures. This gives Infer the ability to\nscale independently of the size of the analyzed code. Moreover, by breaking the\nanalysis into small independent parts, when the full program is analyzed again\nbecause of a code change the analysis results of the unchanged part of the code\ncan be reused, and only the code change needs to be re-analyzed. This process\nis called incremental analysis and it is very powerful when integrating a\nstatic analysis tool like Infer in a development environment."}),"\n",(0,a.jsxs)(n.p,{children:["In order to be able to decompose a global analysis into small independent\nanalyses, let's first consider how a function call is analyzed in separation\nlogic. Assume we have the following spec for a function\n",(0,a.jsx)(l,{code:"\\\\( f() \\\\)"}),":"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace pre\\_f \\rbrace \\;\\; f() \\;\\; \\lbrace post\\_f \\rbrace \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["and by analyzing the caller function, we compute that before the call of ",(0,a.jsx)(l,{code:"\\\\( f \\\\)"}),", the formula ",(0,a.jsx)(l,{code:"\\\\( CallingState \\\\)"}),"\nholds. Then to utilize the specification of ",(0,a.jsx)(l,{code:"\\\\( f \\\\)"})," the\nfollowing implication must hold:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( CallingState \\vdash pre\\_f \\;\\;\\;\\;\\;\\;\\;\\;\\;\\;\\;\\; (Function Call)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"Given that, bi-abduction is used at procedure call sites for two reasons: to\ndiscover missing state that is needed for the above implication to hold and\nallow the analysis to proceed (the antiframe) as well as state that the\nprocedure leaves unchanged (the frame)."}),"\n",(0,a.jsx)(n.p,{children:"To see how this works suppose we have some bare code"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(closeResource(r1); \\, closeResource(r2)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["but no overall specification; we are going to describe how to discover a\npre/post spec for it. Considering the first statement and the (spec) above, the\nhuman might say: if only we had ",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto open\\\\)"})," in the\nprecondition then we could proceed. Technically, we ask a bi-abduction question:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(emp * ?antiframe \\vdash r1 \\mapsto open * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["and we can fill this in easily by picking\n",(0,a.jsx)(l,{code:"\\\\(antiframe = r1 \\mapsto open\\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\(frame = emp\\\\)"}),", where ",(0,a.jsx)(l,{code:"emp"}),"\nmeans the empty state. The ",(0,a.jsx)(l,{code:"emp"})," is recording that at the start\nwe presume nothing. So we obtain the trivially true implication:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(emp * r1 \\mapsto open \\vdash r1 \\mapsto open * emp\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"which, by applying logical rules, can be re-written equivalently to:"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto open \\vdash r1 \\mapsto open\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["Notice that this satisfies the (Function Call) requirement to correctly make\nthe call. So let's add that information in the ",(0,a.jsx)(l,{code:"pre"}),", and while\nwe are at it, record the information in the ",(0,a.jsx)(l,{code:"post"})," of the first\nstatement that comes from ",(0,a.jsx)(l,{code:"\\\\(spec\\\\)"}),"."]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["Now, let's move to the second statement. Its precondition\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed\\\\)"})," in the partial symbolic execution trace\njust given does not have the information needed by\n",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"}),", so we can fill that in and continue by\nputting ",(0,a.jsx)(l,{code:"\\\\(r2 \\mapsto open\\\\)"})," in the ",(0,a.jsx)(l,{code:"pre"}),". While\nwe are at it, we can thread this assertion back to the beginning."]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open * r2 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto open\\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"This information on what to thread backwards can be obtained as the antiframe\npart of the bi-abduction question:"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed * ?antiframe \\vdash r2 \\mapsto open * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["where the solution picks\n",(0,a.jsx)(l,{code:"\\\\(antiframe = r2 \\mapsto open\\\\) and \\\\(frame = r1 \\mapsto closed\\\\)"}),".\nNote that the antiframe is precisely the information missing from the\nprecondition in order for ",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"})," to proceed. On\nthe other hand, the frame ",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed\\\\)"})," is the portion\nof state not changed by ",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"}),"; we can thread\nthat through to the overall postconditon (as justified by the frame rule),\ngiving us:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open * r2 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto open\\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto closed \\rbrace\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["Thus, we have obtained a ",(0,a.jsx)(l,{code:"pre"})," and ",(0,a.jsx)(l,{code:"post"})," for this\ncode by symbolically executing it, using bi-abduction to discover preconditions\n(abduction of antiframes) as well as untouched portions of memory (frames) as\nwe go along."]}),"\n",(0,a.jsx)(n.p,{children:"In general, bi-abduction provides a way to infer a pre/post specs from bare\ncode, as long as we know specs for the primitives at the base level of the code.\nThe human does not need to write preconditions and postconditions for all the\nprocedures, which is the key to having a high level of automation. This is the\nbasis for how Infer works, why it can scale, and how it can analyze code changes\nincrementally."}),"\n",(0,a.jsx)(n.p,{children:"Context: The logical terminology we have been using here comes from AI and\nphilosophy of science. Abductive inference was introduced by the philosopher\nCharles Peirce, and described as the mechanism underpinning hypothesis formation\n(or, guessing what might be true about the world), the most creative part of the\nscientific process. Abduction and the frame problem have both attracted\nsignificant attention in AI. Infer uses an automated form of abduction to\ngenerate preconditions describing the memory that a program touches (the\nantiframe part above), and frame inference to discover what isn't touched. Infer\nthen uses deductive reasoning to calculate a formula describing the effect of a\nprogram, starting from the preconditions. In a sense, Infer approaches automated\nreasoning about programs by mimicking what a human might do when trying to\nunderstand a program: it abduces what the program needs, and deduces conclusions\nof that. It is when the reasoning goes wrong that Infer reports a potential bug."}),"\n",(0,a.jsx)(n.p,{children:"This description is by necessity simplified compared to what Infer actually\ndoes. More technical information can be found in the following papers. The\ndescriptions in the papers are precise, but still simplified; there are many\nengineering decisions not recorded there. Finally, beyond the papers, you can\nread the source code if you wish!"}),"\n",(0,a.jsx)(n.h2,{id:"technical-papers",children:"Technical papers"}),"\n",(0,a.jsx)(n.p,{children:"The following papers contain some of the technical background on Infer and\ninformation on how it is used inside Facebook."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007%2F3-540-44802-0_1",children:"Local\nReasoning about Programs that Alter Data Structures."})," An early separation\nlogic paper which advanced ideas about local reasoning and the frame rule."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007/11804192_6",children:"Smallfoot:\nModular Automatic Assertion Checking with Separation Logic."})," First\nseparation logic verification tool, introduced frame inference"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007%2F11691372_19",children:"A Local Shape\nAnalysis Based on Separation Logic."})," Separation logic meets abstract\ninterpretation; calculating loop invariants via a fixed-point computation."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://dl.acm.org/citation.cfm?id=2049700",children:"Compositional Shape\nAnalysis by Means of Bi-Abduction."})," The bi-abduction paper."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"https://research.facebook.com/publications/moving-fast-with-software-verification/",children:"Moving\nFast with Software Verification."})," A paper about the way we use Infer at\nFacebook."]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},8615:(e,n,o)=>{o.d(n,{A:()=>a});const a=o.p+"assets/images/SepSplit-dca4e1fe63cb590718402c7c0c9ab7f8.jpg"},8453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>r});var a=o(6540);const t={},s=a.createContext(t);function i(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b4a56aa4.f86e56c3.js b/assets/js/b4a56aa4.f86e56c3.js new file mode 100644 index 00000000000..fc6589d8572 --- /dev/null +++ b/assets/js/b4a56aa4.f86e56c3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[6499],{3127:(e,n,o)=>{o.r(n),o.d(n,{Math:()=>l,assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var a=o(4848),t=o(8453);const s={id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction"},i=void 0,r={id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction",description:"- Separation logic",source:"@site/versioned_docs/version-1.2.0/02-separation-logic-and-biabduction.md",sourceDirName:".",slug:"/separation-logic-and-bi-abduction",permalink:"/docs/separation-logic-and-bi-abduction",draft:!1,unlisted:!1,tags:[],version:"1.2.0",sidebarPosition:2,frontMatter:{id:"separation-logic-and-bi-abduction",title:"Separation logic and bi-abduction"},sidebar:"docs",previous:{title:"About Infer",permalink:"/docs/about-Infer"},next:{title:"Building checkers with the Infer.AI framework",permalink:"/docs/absint-framework"}},c={},l=({code:e})=>(0,a.jsx)("img",{src:`https://math.now.sh?from=${encodeURIComponent(e)}&color=mediumslateblue`,style:{height:"100%",verticalAlign:"middle"}}),d=[{value:"Separation logic",id:"separation-logic",level:2},{value:"Bi-abduction",id:"bi-abduction",level:2},{value:"Technical papers",id:"technical-papers",level:2}];function h(e){const n={a:"a",em:"em",h2:"h2",hr:"hr",img:"img",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#separation-logic",children:"Separation logic"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#bi-abduction",children:"Bi-abduction"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"separation-logic-and-bi-abduction#technical-papers",children:"Technical papers"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"separation-logic",children:"Separation logic"}),"\n",(0,a.jsx)(n.p,{children:"Separation logic is a novel kind of mathematical logic which facilitates\nreasoning about mutations to computer memory. It enables scalability by breaking\nreasoning into chunks corresponding to local operations on memory, and then\ncomposing the reasoning chunks together."}),"\n",(0,a.jsxs)(n.p,{children:["Separation logic is based on a logical connective ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"}),"\ncalled the ",(0,a.jsx)(n.em,{children:"separating conjunction"}),' and pronounced "and separately". Separation\nlogic formulae are interpreted over program allocated heaps. The logical formula\n',(0,a.jsx)(l,{code:"\\\\( A*B \\\\)"})," holds of a piece of program heap (a heaplet) when it\ncan be divided into two sub-heaplets described by ",(0,a.jsx)(l,{code:"\\\\(A\\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\(B\\\\)"}),". For example, the formula"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(x \\mapsto y * y \\mapsto x \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:['can be read "',(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," points to ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," and\nseparately ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," points to ",(0,a.jsx)(l,{code:"\\\\(x\\\\)"}),'". This\nformula describes precisely two allocated memory cells. The first cell is\nallocated at the address denoted by the pointer ',(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," and the\ncontent of this cell is the value of ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"}),". The second cell is\nallocated at the address denoted by the pointer ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," and the\ncontent of this second cell is the value of ",(0,a.jsx)(l,{code:"\\\\(x\\\\)"}),". Crucially,\nwe know that there are precisely two cells because ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"}),"\nstipulates that they are separated and therefore the cells are allocated in two\ndifferent parts of memory. In other words, ",(0,a.jsx)(l,{code:"\\\\( * \\\\)"})," says that\n",(0,a.jsx)(l,{code:"\\\\(x\\\\)"})," and ",(0,a.jsx)(l,{code:"\\\\(y\\\\)"})," do not hold the same value\n(i.e., these pointers are not aliased). The heaplet partitioning defined by the\nformula above can be visualized like so:"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{src:o(8615).A+"",width:"473",height:"129"})}),"\n",(0,a.jsxs)(n.p,{children:["The important thing about the separating conjunction is the way that it fits\ntogether with mutation to computer memory; reasoning about program commands\ntends to work by updating ",(0,a.jsx)(l,{code:"\\\\(*\\\\)"}),"-conjuncts in-place, mimicking\nthe operational in-place update of RAM."]}),"\n",(0,a.jsxs)(n.p,{children:["Separation logic uses Hoare triples of the form\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace pre \\rbrace prog \\lbrace post \\rbrace \\\\)"})," where\n",(0,a.jsx)(l,{code:"\\\\(pre\\\\)"})," is the precondition, ",(0,a.jsx)(l,{code:"\\\\(prog\\\\)"})," a\nprogram part, and ",(0,a.jsx)(l,{code:"\\\\(post\\\\)"})," the postcondition. Triples are\nabstract specifications of the behavior of the program. For example, we could\ntake"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r \\mapsto open\\rbrace \\, closeResource(r)\\, \\lbrace r \\mapsto closed\\rbrace \\;\\;\\; (spec)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"as a specification for a method which closes a resource given to it as a\nparameter."}),"\n",(0,a.jsxs)(n.p,{children:["Now, suppose we have two resources ",(0,a.jsx)(l,{code:"\\\\( r\\_1 \\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\( r\\_2 \\\\)"}),", described by\n",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto open * r\\_2 \\mapsto open\\\\)"})," and we close the\nfirst of them. We think operationally in terms of updating the memory in place,\nleaving ",(0,a.jsx)(l,{code:"\\\\(r\\_2 \\mapsto open\\\\)"})," alone, as described by this triple:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r\\_1 \\mapsto open * r\\_2 \\mapsto open\\rbrace closeResource(r\\_1) \\lbrace r\\_1 \\mapsto closed * r\\_2 \\mapsto open \\rbrace \\;\\;\\; (use)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["What we have here is the that specification (spec) described how\n",(0,a.jsx)(l,{code:"\\\\(closeResource()\\\\)"})," works by mentioning only one piece of\nstate, what is sometimes called a small specification, and in (use) we use that\nspecification to update a larger precondition in place."]}),"\n",(0,a.jsx)(n.p,{children:"This is an instance of a general pattern. There is a rule that lets you go from\nsmaller to bigger specifications"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\frac{\\lbrace pre \\rbrace prog \\lbrace post \\rbrace}{\\lbrace pre * frame \\rbrace prog \\lbrace post * frame \\rbrace}\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"Our passage from (spec) to (use) is obtained by taking"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(pre\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto open\\\\)"})]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(post\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_1 \\mapsto closed \\\\)"}),",\nand"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(l,{code:"\\\\(frame\\\\)"})," to be ",(0,a.jsx)(l,{code:"\\\\(r\\_2 \\mapsto open \\\\)"})]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["This rule is called the ",(0,a.jsx)(n.em,{children:"frame rule"})," of separation logic. It is named after the\nframe problem, a classic problem in artificial intelligence. Generally, the\n",(0,a.jsx)(l,{code:"\\\\(frame\\\\)"})," describes state that remains unchanged; the\nterminology comes from the analogy of a background scene in an animation as\nunchanging while the objects and characters within the scene change."]}),"\n",(0,a.jsx)(n.p,{children:"The frame rule is the key to the principle of local reasoning in separation\nlogic: reasoning and specifications should concentrate on the resources that a\nprogram accesses (the footprint), without mentioning what doesn't change."}),"\n",(0,a.jsx)(n.h2,{id:"bi-abduction",children:"Bi-abduction"}),"\n",(0,a.jsx)(n.p,{children:"Bi-abduction is a form of logical inference for separation logic which automates\nthe key ideas about local reasoning."}),"\n",(0,a.jsx)(n.p,{children:"Usually, logic works with validity or entailment statements like"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(A \\vdash B\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["which says that ",(0,a.jsx)(l,{code:"\\\\(A\\\\)"})," implies ",(0,a.jsx)(l,{code:"\\\\(B\\\\)"}),". Infer\nuses an extension of this inference question in an internal theorem prover while\nit runs over program statements. Infer's question"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(A * ?antiframe \\vdash B * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["is called ",(0,a.jsx)(n.em,{children:"bi-abduction"}),". The problem here is for the theorem prover to ",(0,a.jsx)("i",{children:"\ndiscover "})," a pair of frame and antiframe formulae that make the entailment\nstatement valid."]}),"\n",(0,a.jsx)(n.p,{children:"Global analyses of large programs are normally computationally intractable.\nHowever, bi-abduction breaks apart a large analysis of a large program into\nsmall independent analyses of its procedures. This gives Infer the ability to\nscale independently of the size of the analyzed code. Moreover, by breaking the\nanalysis into small independent parts, when the full program is analyzed again\nbecause of a code change the analysis results of the unchanged part of the code\ncan be reused, and only the code change needs to be re-analyzed. This process\nis called incremental analysis and it is very powerful when integrating a\nstatic analysis tool like Infer in a development environment."}),"\n",(0,a.jsxs)(n.p,{children:["In order to be able to decompose a global analysis into small independent\nanalyses, let's first consider how a function call is analyzed in separation\nlogic. Assume we have the following spec for a function\n",(0,a.jsx)(l,{code:"\\\\( f() \\\\)"}),":"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace pre\\_f \\rbrace \\;\\; f() \\;\\; \\lbrace post\\_f \\rbrace \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["and by analyzing the caller function, we compute that before the call of ",(0,a.jsx)(l,{code:"\\\\( f \\\\)"}),", the formula ",(0,a.jsx)(l,{code:"\\\\( CallingState \\\\)"}),"\nholds. Then to utilize the specification of ",(0,a.jsx)(l,{code:"\\\\( f \\\\)"})," the\nfollowing implication must hold:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( CallingState \\vdash pre\\_f \\;\\;\\;\\;\\;\\;\\;\\;\\;\\;\\;\\; (Function Call)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"Given that, bi-abduction is used at procedure call sites for two reasons: to\ndiscover missing state that is needed for the above implication to hold and\nallow the analysis to proceed (the antiframe) as well as state that the\nprocedure leaves unchanged (the frame)."}),"\n",(0,a.jsx)(n.p,{children:"To see how this works suppose we have some bare code"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(closeResource(r1); \\, closeResource(r2)\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["but no overall specification; we are going to describe how to discover a\npre/post spec for it. Considering the first statement and the (spec) above, the\nhuman might say: if only we had ",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto open\\\\)"})," in the\nprecondition then we could proceed. Technically, we ask a bi-abduction question:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(emp * ?antiframe \\vdash r1 \\mapsto open * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["and we can fill this in easily by picking\n",(0,a.jsx)(l,{code:"\\\\(antiframe = r1 \\mapsto open\\\\)"})," and\n",(0,a.jsx)(l,{code:"\\\\(frame = emp\\\\)"}),", where ",(0,a.jsx)(l,{code:"emp"}),"\nmeans the empty state. The ",(0,a.jsx)(l,{code:"emp"})," is recording that at the start\nwe presume nothing. So we obtain the trivially true implication:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(emp * r1 \\mapsto open \\vdash r1 \\mapsto open * emp\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"which, by applying logical rules, can be re-written equivalently to:"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto open \\vdash r1 \\mapsto open\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["Notice that this satisfies the (Function Call) requirement to correctly make\nthe call. So let's add that information in the ",(0,a.jsx)(l,{code:"pre"}),", and while\nwe are at it, record the information in the ",(0,a.jsx)(l,{code:"post"})," of the first\nstatement that comes from ",(0,a.jsx)(l,{code:"\\\\(spec\\\\)"}),"."]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["Now, let's move to the second statement. Its precondition\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed\\\\)"})," in the partial symbolic execution trace\njust given does not have the information needed by\n",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"}),", so we can fill that in and continue by\nputting ",(0,a.jsx)(l,{code:"\\\\(r2 \\mapsto open\\\\)"})," in the ",(0,a.jsx)(l,{code:"pre"}),". While\nwe are at it, we can thread this assertion back to the beginning."]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open * r2 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto open\\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.p,{children:"This information on what to thread backwards can be obtained as the antiframe\npart of the bi-abduction question:"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed * ?antiframe \\vdash r2 \\mapsto open * ?frame\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["where the solution picks\n",(0,a.jsx)(l,{code:"\\\\(antiframe = r2 \\mapsto open\\\\) and \\\\(frame = r1 \\mapsto closed\\\\)"}),".\nNote that the antiframe is precisely the information missing from the\nprecondition in order for ",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"})," to proceed. On\nthe other hand, the frame ",(0,a.jsx)(l,{code:"\\\\(r1 \\mapsto closed\\\\)"})," is the portion\nof state not changed by ",(0,a.jsx)(l,{code:"\\\\(closeResource(r2)\\\\)"}),"; we can thread\nthat through to the overall postconditon (as justified by the frame rule),\ngiving us:"]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto open * r2 \\mapsto open \\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r1) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto open\\rbrace \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( closeResource(r2) \\\\)"}),"\n",(0,a.jsx)(l,{code:"\\\\( \\lbrace r1 \\mapsto closed * r2 \\mapsto closed \\rbrace\\\\)"}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsxs)(n.p,{children:["Thus, we have obtained a ",(0,a.jsx)(l,{code:"pre"})," and ",(0,a.jsx)(l,{code:"post"})," for this\ncode by symbolically executing it, using bi-abduction to discover preconditions\n(abduction of antiframes) as well as untouched portions of memory (frames) as\nwe go along."]}),"\n",(0,a.jsx)(n.p,{children:"In general, bi-abduction provides a way to infer a pre/post specs from bare\ncode, as long as we know specs for the primitives at the base level of the code.\nThe human does not need to write preconditions and postconditions for all the\nprocedures, which is the key to having a high level of automation. This is the\nbasis for how Infer works, why it can scale, and how it can analyze code changes\nincrementally."}),"\n",(0,a.jsx)(n.p,{children:"Context: The logical terminology we have been using here comes from AI and\nphilosophy of science. Abductive inference was introduced by the philosopher\nCharles Peirce, and described as the mechanism underpinning hypothesis formation\n(or, guessing what might be true about the world), the most creative part of the\nscientific process. Abduction and the frame problem have both attracted\nsignificant attention in AI. Infer uses an automated form of abduction to\ngenerate preconditions describing the memory that a program touches (the\nantiframe part above), and frame inference to discover what isn't touched. Infer\nthen uses deductive reasoning to calculate a formula describing the effect of a\nprogram, starting from the preconditions. In a sense, Infer approaches automated\nreasoning about programs by mimicking what a human might do when trying to\nunderstand a program: it abduces what the program needs, and deduces conclusions\nof that. It is when the reasoning goes wrong that Infer reports a potential bug."}),"\n",(0,a.jsx)(n.p,{children:"This description is by necessity simplified compared to what Infer actually\ndoes. More technical information can be found in the following papers. The\ndescriptions in the papers are precise, but still simplified; there are many\nengineering decisions not recorded there. Finally, beyond the papers, you can\nread the source code if you wish!"}),"\n",(0,a.jsx)(n.h2,{id:"technical-papers",children:"Technical papers"}),"\n",(0,a.jsx)(n.p,{children:"The following papers contain some of the technical background on Infer and\ninformation on how it is used inside Facebook."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007%2F3-540-44802-0_1",children:"Local\nReasoning about Programs that Alter Data Structures."})," An early separation\nlogic paper which advanced ideas about local reasoning and the frame rule."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007/11804192_6",children:"Smallfoot:\nModular Automatic Assertion Checking with Separation Logic."})," First\nseparation logic verification tool, introduced frame inference"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://link.springer.com/chapter/10.1007%2F11691372_19",children:"A Local Shape\nAnalysis Based on Separation Logic."})," Separation logic meets abstract\ninterpretation; calculating loop invariants via a fixed-point computation."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"http://dl.acm.org/citation.cfm?id=2049700",children:"Compositional Shape\nAnalysis by Means of Bi-Abduction."})," The bi-abduction paper."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)("a",{href:"https://research.facebook.com/publications/moving-fast-with-software-verification/",children:"Moving\nFast with Software Verification."})," A paper about the way we use Infer at\nFacebook."]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},8615:(e,n,o)=>{o.d(n,{A:()=>a});const a=o.p+"assets/images/SepSplit-dca4e1fe63cb590718402c7c0c9ab7f8.jpg"},8453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>r});var a=o(6540);const t={},s=a.createContext(t);function i(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c4f5d8e4.b4e18fab.js b/assets/js/c4f5d8e4.25763f5c.js similarity index 94% rename from assets/js/c4f5d8e4.b4e18fab.js rename to assets/js/c4f5d8e4.25763f5c.js index 029643b5d52..c4625dfe307 100644 --- a/assets/js/c4f5d8e4.b4e18fab.js +++ b/assets/js/c4f5d8e4.25763f5c.js @@ -1,2 +1,2 @@ -/*! For license information please see c4f5d8e4.b4e18fab.js.LICENSE.txt */ -(self.webpackChunk=self.webpackChunk||[]).push([[2634],{172:(e,t,o)=>{"use strict";o.r(t),o.d(t,{default:()=>w});var r=o(8774),a=o(6025),n=o(4586),i=o(1957),c=o(6942),s=o.n(c),l=o(6540);class d extends l.PureComponent{constructor(e){super(e),this.$=l.createRef(),this._=l.createRef()}render(){return l.createElement("span",{ref:this.$},l.createElement("a",{...this.props,ref:this._},this.props.children))}componentDidMount(){this.paint()}getSnapshotBeforeUpdate(){return this.reset(),null}componentDidUpdate(){this.paint()}componentWillUnmount(){this.reset()}paint(){const e=this.$.current.appendChild(document.createElement("span"));Promise.resolve().then(o.bind(o,9867)).then((({render:t})=>{null!=this._.current&&t(e.appendChild(this._.current),(function(t){try{e.parentNode.replaceChild(t,e)}catch(e){}}))}))}reset(){this.$.current.replaceChild(this._.current,this.$.current.lastChild)}}const h=d;var u=o(4848);function p(e){const t=(0,l.useRef)(null),o=(0,l.useRef)("undefined"!=typeof document?document.createElement("script"):null);return(0,l.useEffect)((()=>{t.current.appendChild(o.current)}),[]),(0,l.useEffect)((()=>{for(const t in e)e.hasOwnProperty(t)&&(o.current[t]=e[t])})),(0,u.jsx)("div",{ref:t})}const f={heroBanner:"heroBanner_UJJx",windows:"windows_virr",buttons:"buttons_pzbO",starCount:"starCount_rpSp",features:"features_keug",featureImage:"featureImage_yA8i",usingInfer:"usingInfer_a4la",whoUses:"whoUses_xgpa",whoUsesItems:"whoUsesItems_FZiH",poweredByImage:"poweredByImage_nWzf",poweredByItem:"poweredByItem_XE3g"},g=[{title:(0,u.jsx)(u.Fragment,{children:"Android and Java"}),description:(0,u.jsx)(u.Fragment,{children:"Infer checks for null pointer exceptions, resource leaks, annotation reachability, missing lock guards, and concurrency race conditions in Android and Java code."})},{title:(0,u.jsx)(u.Fragment,{children:"C, C++, and iOS/Objective-C"}),description:(0,u.jsx)(u.Fragment,{children:"Infer checks for null pointer dereferences, memory leaks, coding conventions and unavailable API\u2019s."})}],m=[{url:"https://www.adacore.com",image:"/img/who/adacore.png"},{url:"https://aws.amazon.com",image:"/img/who/aws.svg"},{url:"https://facebook.com",image:"/img/who/facebook.png"},{url:"https://freefem.org",image:"/img/who/freefem.png"},{url:"https://www.instagram.com",image:"/img/who/instagram.png"},{url:"https://www.microsoft.com",image:"/img/who/microsoft.png"},{url:"http://www.mozilla.com",image:"/img/who/mozilla.png"},{url:"https://www.oculus.com",image:"/img/who/oculus.png"},{url:"https://www.sonatype.com",image:"/img/who/sonatype.png"},{url:"/blog/2016/03/17/collaboration-with-spotify",image:"/img/who/spotify.png"},{url:"https://tangramflex.com",image:"/img/who/tangramflex.png"},{url:"https://www.uber.com",image:"/img/who/uber.svg"},{url:"https://www.whatsapp.com",image:"/img/who/whatsapp.svg"}],b=[{url:"https://www.mycode.ai",name:"CodeAI"},{url:"http://jd.com",name:"JD.com"},{url:"https://www.marksandspencer.com",name:"Marks and Spencer"},{url:"https://moneylover.me",name:"Money Lover"},{url:"https://www.netcetera.com",name:"Netcetera"},{url:"https://www.olacabs.com",name:"OLA"},{url:"https://www.sky.com",name:"Sky"},{url:"https://tile.com",name:"Tile"},{url:"https://vuo.org",name:"Vuo"},{url:"https://wolfssl.com",name:"wolfSSL"}];function v(){return(0,u.jsx)("div",{className:"container text--center margin-bottom--xl margin-top--lg",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col",children:[(0,u.jsx)("h2",{children:"Check it out in the intro video"}),(0,u.jsx)("div",{className:f.ytVideo,children:(0,u.jsx)("iframe",{width:"560",height:"315",src:"https://www.youtube.com/embed/swrmPTJAGqQ",title:"Explain Like I'm 5: Infer",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0})})]})})})}const w=function(){const e=(0,n.A)(),{siteConfig:t={}}=e;return(0,u.jsxs)(i.A,{title:"Infer Static Analyzer | Infer",description:`${t.tagline}`,children:[(0,u.jsx)("header",{className:s()("hero hero--primary",f.heroBanner),children:(0,u.jsxs)("div",{className:"container",children:[(0,u.jsx)("h1",{className:"hero__title",children:"A tool to detect bugs in Java and C/C++/Objective-C code before it ships"}),(0,u.jsx)("p",{className:"hero__subtitle",children:"Infer is a static analysis tool - if you give Infer some Java or C/C++/Objective-C code it produces a list of potential bugs. Anyone can use Infer to intercept critical bugs before they have shipped to users, and help prevent crashes or poor performance."}),(0,u.jsxs)("div",{className:f.buttons,children:[(0,u.jsx)("div",{className:"col col--2 margin-horiz--sm",children:(0,u.jsx)(r.A,{className:s()("button button--secondary button--lg",f.getStarted),to:(0,a.Ay)("docs/getting-started"),children:"Get Started"})}),(0,u.jsx)("div",{className:"col col--2 margin-horiz--sm",children:(0,u.jsx)(r.A,{className:s()("button button--secondary button--lg",f.getStarted),to:(0,a.Ay)("docs/about-Infer"),children:"Learn More"})})]}),(0,u.jsx)("div",{className:f.starCount,children:(0,u.jsx)(h,{href:"https://github.com/facebook/infer","data-icon":"octicon-star","data-size":"large","data-show-count":"true","aria-label":"Star facebook/infer on GitHub",children:"Star"})})]})}),(0,u.jsxs)("main",{children:[(0,u.jsx)(v,{}),g&&g.length&&(0,u.jsx)("section",{className:f.features,children:(0,u.jsx)("div",{className:"container",children:(0,u.jsx)("div",{className:"row",children:g.map(((e,t)=>{let{title:o,description:r}=e;return(0,u.jsxs)("div",{className:"col col--6",children:[(0,u.jsx)("h3",{children:o}),(0,u.jsx)("p",{children:r})]},t)}))})})}),(0,u.jsx)("section",{className:f.features,children:(0,u.jsx)("div",{className:"container",children:(0,u.jsxs)("div",{className:"row",children:[(0,u.jsxs)("div",{className:"col col--6",children:[(0,u.jsx)("h3",{children:"Infer in Action"}),(0,u.jsx)(p,{id:"asciicast-32101",src:"https://asciinema.org/a/32101.js","data-autoplay":"true","data-loop":"true","data-speed":"2",async:!0})]}),(0,u.jsxs)("div",{className:"col col--6",children:[(0,u.jsx)("h3",{children:"Try Infer"}),(0,u.jsx)("iframe",{className:f.windows,src:"https://codeboard.io/projects/11587?view=2.1-21.0-22.0"})]})]})})}),(0,u.jsx)("section",{className:f.usingInfer,children:(0,u.jsxs)("div",{className:"container",children:[(0,u.jsx)("h2",{children:"Using Infer"}),(0,u.jsxs)("p",{children:["Start with the ",(0,u.jsx)("a",{href:"/docs/getting-started",children:"Getting Started"})," ","guide and our other ",(0,u.jsx)("a",{href:"/docs/getting-started",children:"docs"})," to download and try Infer yourself. Infer is still evolving, and we want to continue to develop it in the open. We hope it will be useful for other projects, so please try it out or contribute to it, join the community and give us feedback!"]})]})}),(0,u.jsx)("section",{className:f.whoUses,id:"who-uses-infer",children:(0,u.jsxs)("div",{className:"container",children:[(0,u.jsx)("h2",{children:"Who Uses Infer?"}),(0,u.jsxs)("div",{style:{margin:"4rem 0"},children:[(0,u.jsx)("div",{className:"row",children:m.map(((e,t)=>{let{url:o,image:r}=e;return(0,u.jsx)("div",{className:"col col--2",children:(0,u.jsx)("div",{className:f.whoUsesItems,children:(0,u.jsx)("a",{href:o,children:(0,u.jsx)("img",{className:f.poweredByImage,src:r})})})},t)}))}),(0,u.jsx)("div",{className:"row",children:b.map(((e,t)=>{let{url:o,name:r}=e;return(0,u.jsx)("div",{className:"col col--2",children:(0,u.jsx)("div",{className:f.whoUsesItems,children:(0,u.jsx)("a",{href:o,children:(0,u.jsx)("h3",{className:f.poweredByItem,children:r})})})},t)}))})]}),(0,u.jsxs)("span",{children:["Does your project use Infer? Add it to this list with"," ",(0,u.jsx)("a",{href:"https://github.com/facebook/infer/edit/main/website/src/pages/index.js",children:"a pull request!"})]})]})})]})]})}},9867:(e,t,o)=>{"use strict";o.r(t),o.d(t,{render:()=>_});var r=window.document,a=window.Math,n=window.HTMLElement,i=window.XMLHttpRequest,c=function(e,t){for(var o=0,r=e.length;o'}}},download:{heights:{16:{width:16,path:''}}},eye:{heights:{16:{width:16,path:''}}},heart:{heights:{16:{width:16,path:''}}},"issue-opened":{heights:{16:{width:16,path:''}}},"mark-github":{heights:{16:{width:16,path:''}}},package:{heights:{16:{width:16,path:''}}},play:{heights:{16:{width:16,path:''}}},"repo-forked":{heights:{16:{width:16,path:''}}},"repo-template":{heights:{16:{width:16,path:''}}},star:{heights:{16:{width:16,path:''}}}},k=function(e,t){e=h(e).replace(/^octicon-/,""),d(y,e)||(e="mark-github");var o=t>=24&&24 in y[e].heights?24:16,r=y[e].heights[o];return'"},j={},C=function(e,t){var o=j[e]||(j[e]=[]);if(!(o.push(t)>1)){var r=function(e){var t;return function(){t||(t=1,e.apply(this,arguments))}}((function(){for(delete j[e];t=o.shift();)t.apply(null,arguments)}));if(f){var a=new i;m(a,"abort",r),m(a,"error",r),m(a,"load",(function(){var e;try{e=JSON.parse(this.responseText)}catch(t){return void r(t)}r(200!==this.status,e)})),a.open("GET",e),a.send()}else{var n=this||window;n._=function(e){n._=null,r(200!==e.meta.status,e.data)};var c=s(n.document)("script",{async:!0,src:e+(-1!==e.indexOf("?")?"&":"?")+"callback=_"}),l=function(){n._&&n._({meta:{}})};m(c,"load",l),m(c,"error",l),function(e,t,o){if(null!=e.readyState){var r="readystatechange",a=function(){if(t.test(e.readyState))return b(e,r,a),o.apply(this,arguments)};m(e,r,a)}}(c,/de|m/,l),n.document.getElementsByTagName("head")[0].appendChild(c)}}},A=function(e,t,o){var r=s(e.ownerDocument),a=e.appendChild(r("style",{type:"text/css"})),n="body{margin:0}a{text-decoration:none;outline:0}.widget{display:inline-block;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;font-size:0;line-height:0;white-space:nowrap}.btn,.social-count{position:relative;display:inline-block;display:inline-flex;height:14px;padding:2px 5px;font-size:11px;font-weight:600;line-height:14px;vertical-align:bottom;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-repeat:repeat-x;background-position:-1px -1px;background-size:110% 110%;border:1px solid}.btn{border-radius:.25em}.btn:not(:last-child){border-radius:.25em 0 0 .25em}.social-count{border-left:0;border-radius:0 .25em .25em 0}.widget-lg .btn,.widget-lg .social-count{height:16px;padding:5px 10px;font-size:12px;line-height:16px}.octicon{display:inline-block;vertical-align:text-top;fill:currentColor;overflow:visible}"+x(t["data-color-scheme"]);a.styleSheet?a.styleSheet.cssText=n:a.appendChild(e.ownerDocument.createTextNode(n));var i="large"===h(t["data-size"]),c=r("a",{className:"btn",href:t.href,rel:"noopener",target:"_blank",title:t.title||void 0,"aria-label":t["aria-label"]||void 0,innerHTML:k(t["data-icon"],i?16:14)+" "},[r("span",{},[t["data-text"]||""])]),l=e.appendChild(r("div",{className:"widget"+(i?" widget-lg":"")},[c])),d=c.hostname.replace(/\.$/,"");if(("."+d).substring(d.length-10)!=="."+u)return c.removeAttribute("href"),void o(l);var f=(" /"+c.pathname).split(/\/+/);if(((d===u||d==="gist."+u)&&"archive"===f[3]||d===u&&"releases"===f[3]&&("download"===f[4]||"latest"===f[4]&&"download"===f[5])||d==="codeload."+u)&&(c.target="_top"),"true"===h(t["data-show-count"])&&d===u&&"marketplace"!==f[1]&&"sponsors"!==f[1]&&"orgs"!==f[1]&&"users"!==f[1]&&"-"!==f[1]){var g,m;if(!f[2]&&f[1])m="followers",g="?tab=followers";else if(!f[3]&&f[2])m="stargazers_count",g="/stargazers";else if(f[4]||"subscription"!==f[3])if(f[4]||"fork"!==f[3]){if("issues"!==f[3])return void o(l);m="open_issues_count",g="/issues"}else m="forks_count",g="/forks";else m="subscribers_count",g="/watchers";var b=f[2]?"/repos/"+f[1]+"/"+f[2]:"/users/"+f[1];C.call(this,p+b,(function(e,t){if(!e){var a=t[m];l.appendChild(r("a",{className:"social-count",href:t.html_url+g,rel:"noopener",target:"_blank","aria-label":a+" "+m.replace(/_count$/,"").replace("_"," ").slice(0,a<2?-1:void 0)+" on GitHub"},[(""+a).replace(/\B(?=(\d{3})+(?!\d))/g,",")]))}o(l)}))}else o(l)},N=window.devicePixelRatio||1,I=function(e){return(N>1?a.ceil(a.round(e*N)/N*2)/2:a.ceil(e))||0},F=function(e,t){e.style.width=t[0]+"px",e.style.height=t[1]+"px"},_=function(e,t){if(null!=e&&null!=t)if(e.getAttribute&&(e=function(e){var t={href:e.href,title:e.title,"aria-label":e.getAttribute("aria-label")};return c(["icon","color-scheme","text","size","show-count"],(function(o){var r="data-"+o;t[r]=e.getAttribute(r)})),null==t["data-text"]&&(t["data-text"]=e.textContent||e.innerText),t}(e)),g){var o=l("span");A(o.attachShadow({mode:"closed"}),e,(function(){t(o)}))}else{var n=l("iframe",{src:"javascript:0",title:e.title||void 0,allowtransparency:!0,scrolling:"no",frameBorder:0});F(n,[0,0]),n.style.border="none";var i=function(){var o,c=n.contentWindow;try{o=c.document.body}catch(s){return void r.body.appendChild(n.parentNode.removeChild(n))}b(n,"load",i),A.call(c,o,e,(function(o){var r=function(e){var t=e.offsetWidth,o=e.offsetHeight;if(e.getBoundingClientRect){var r=e.getBoundingClientRect();t=a.max(t,I(r.width)),o=a.max(o,I(r.height))}return[t,o]}(o);n.parentNode.removeChild(n),function(e,t,o){var r=function(){return b(e,t,r),o.apply(this,arguments)};m(e,t,r)}(n,"load",(function(){F(n,r)})),n.src="https://unpkg.com/github-buttons@2.29.0/dist/buttons.html#"+(n.name=function(e,t,o,r){null==t&&(t="&"),null==o&&(o="="),null==r&&(r=window.encodeURIComponent);var a=[];for(var n in e){var i=e[n];null!=i&&a.push(r(n)+o+r(i))}return a.join(t)}(e)),t(n)}))};m(n,"load",i),r.body.appendChild(n)}}},6942:(e,t)=>{var o;!function(){"use strict";var r={}.hasOwnProperty;function a(){for(var e="",t=0;t{"use strict";o.r(t),o.d(t,{default:()=>w});var r=o(8774),a=o(6025),n=o(4586),i=o(1957),c=o(6942),s=o.n(c),l=o(6540);class d extends l.PureComponent{constructor(e){super(e),this.$=l.createRef(),this._=l.createRef()}render(){return l.createElement("span",{ref:this.$},l.createElement("a",{...this.props,ref:this._},this.props.children))}componentDidMount(){this.paint()}getSnapshotBeforeUpdate(){return this.reset(),null}componentDidUpdate(){this.paint()}componentWillUnmount(){this.reset()}paint(){const e=this.$.current.appendChild(document.createElement("span"));Promise.resolve().then(o.bind(o,9867)).then((({render:t})=>{null!=this._.current&&t(e.appendChild(this._.current),(function(t){try{e.parentNode.replaceChild(t,e)}catch(e){}}))}))}reset(){this.$.current.replaceChild(this._.current,this.$.current.lastChild)}}const h=d;var u=o(4848);function p(e){const t=(0,l.useRef)(null),o=(0,l.useRef)("undefined"!=typeof document?document.createElement("script"):null);return(0,l.useEffect)((()=>{t.current.appendChild(o.current)}),[]),(0,l.useEffect)((()=>{for(const t in e)e.hasOwnProperty(t)&&(o.current[t]=e[t])})),(0,u.jsx)("div",{ref:t})}const f={heroBanner:"heroBanner_UJJx",windows:"windows_virr",buttons:"buttons_pzbO",starCount:"starCount_rpSp",features:"features_keug",featureImage:"featureImage_yA8i",usingInfer:"usingInfer_a4la",whoUses:"whoUses_xgpa",whoUsesItems:"whoUsesItems_FZiH",poweredByImage:"poweredByImage_nWzf",poweredByItem:"poweredByItem_XE3g"},g=[{title:(0,u.jsx)(u.Fragment,{children:"Android and Java"}),description:(0,u.jsx)(u.Fragment,{children:"Infer checks for null pointer exceptions, resource leaks, annotation reachability, missing lock guards, and concurrency race conditions in Android and Java code."})},{title:(0,u.jsx)(u.Fragment,{children:"C, C++, and iOS/Objective-C"}),description:(0,u.jsx)(u.Fragment,{children:"Infer checks for null pointer dereferences, memory leaks, coding conventions and unavailable API\u2019s."})}],m=[{url:"https://www.adacore.com",image:"/img/who/adacore.png"},{url:"https://aws.amazon.com",image:"/img/who/aws.svg"},{url:"https://facebook.com",image:"/img/who/facebook.png"},{url:"https://freefem.org",image:"/img/who/freefem.png"},{url:"https://www.instagram.com",image:"/img/who/instagram.png"},{url:"https://www.microsoft.com",image:"/img/who/microsoft.png"},{url:"http://www.mozilla.com",image:"/img/who/mozilla.png"},{url:"https://www.oculus.com",image:"/img/who/oculus.png"},{url:"https://www.sonatype.com",image:"/img/who/sonatype.png"},{url:"/blog/2016/03/17/collaboration-with-spotify",image:"/img/who/spotify.png"},{url:"https://tangramflex.com",image:"/img/who/tangramflex.png"},{url:"https://www.uber.com",image:"/img/who/uber.svg"},{url:"https://www.whatsapp.com",image:"/img/who/whatsapp.svg"}],b=[{url:"https://www.mycode.ai",name:"CodeAI"},{url:"http://jd.com",name:"JD.com"},{url:"https://www.marksandspencer.com",name:"Marks and Spencer"},{url:"https://moneylover.me",name:"Money Lover"},{url:"https://www.netcetera.com",name:"Netcetera"},{url:"https://www.olacabs.com",name:"OLA"},{url:"https://www.sky.com",name:"Sky"},{url:"https://tile.com",name:"Tile"},{url:"https://vuo.org",name:"Vuo"},{url:"https://wolfssl.com",name:"wolfSSL"}];function v(){return(0,u.jsx)("div",{className:"container text--center margin-bottom--xl margin-top--lg",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col",children:[(0,u.jsx)("h2",{children:"Check it out in the intro video"}),(0,u.jsx)("div",{className:f.ytVideo,children:(0,u.jsx)("iframe",{width:"560",height:"315",src:"https://www.youtube.com/embed/swrmPTJAGqQ",title:"Explain Like I'm 5: Infer",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0})})]})})})}const w=function(){const e=(0,n.A)(),{siteConfig:t={}}=e;return(0,u.jsxs)(i.A,{title:"Infer Static Analyzer | Infer",description:`${t.tagline}`,children:[(0,u.jsx)("header",{className:s()("hero hero--primary",f.heroBanner),children:(0,u.jsxs)("div",{className:"container",children:[(0,u.jsx)("h1",{className:"hero__title",children:"A tool to detect bugs in Java and C/C++/Objective-C code before it ships"}),(0,u.jsx)("p",{className:"hero__subtitle",children:"Infer is a static analysis tool - if you give Infer some Java or C/C++/Objective-C code it produces a list of potential bugs. Anyone can use Infer to intercept critical bugs before they have shipped to users, and help prevent crashes or poor performance."}),(0,u.jsxs)("div",{className:f.buttons,children:[(0,u.jsx)("div",{className:"col col--2 margin-horiz--sm",children:(0,u.jsx)(r.A,{className:s()("button button--secondary button--lg",f.getStarted),to:(0,a.Ay)("docs/getting-started"),children:"Get Started"})}),(0,u.jsx)("div",{className:"col col--2 margin-horiz--sm",children:(0,u.jsx)(r.A,{className:s()("button button--secondary button--lg",f.getStarted),to:(0,a.Ay)("docs/about-Infer"),children:"Learn More"})})]}),(0,u.jsx)("div",{className:f.starCount,children:(0,u.jsx)(h,{href:"https://github.com/facebook/infer","data-icon":"octicon-star","data-size":"large","data-show-count":"true","aria-label":"Star facebook/infer on GitHub",children:"Star"})})]})}),(0,u.jsxs)("main",{children:[(0,u.jsx)(v,{}),g&&g.length&&(0,u.jsx)("section",{className:f.features,children:(0,u.jsx)("div",{className:"container",children:(0,u.jsx)("div",{className:"row",children:g.map(((e,t)=>{let{title:o,description:r}=e;return(0,u.jsxs)("div",{className:"col col--6",children:[(0,u.jsx)("h3",{children:o}),(0,u.jsx)("p",{children:r})]},t)}))})})}),(0,u.jsx)("section",{className:f.features,children:(0,u.jsx)("div",{className:"container",children:(0,u.jsxs)("div",{className:"row",children:[(0,u.jsxs)("div",{className:"col col--6",children:[(0,u.jsx)("h3",{children:"Infer in Action"}),(0,u.jsx)(p,{id:"asciicast-32101",src:"https://asciinema.org/a/32101.js","data-autoplay":"true","data-loop":"true","data-speed":"2",async:!0})]}),(0,u.jsxs)("div",{className:"col col--6",children:[(0,u.jsx)("h3",{children:"Try Infer"}),(0,u.jsx)("iframe",{className:f.windows,src:"https://codeboard.io/projects/11587?view=2.1-21.0-22.0"})]})]})})}),(0,u.jsx)("section",{className:f.usingInfer,children:(0,u.jsxs)("div",{className:"container",children:[(0,u.jsx)("h2",{children:"Using Infer"}),(0,u.jsxs)("p",{children:["Start with the ",(0,u.jsx)("a",{href:"/docs/getting-started",children:"Getting Started"})," ","guide and our other ",(0,u.jsx)("a",{href:"/docs/getting-started",children:"docs"})," to download and try Infer yourself. Infer is still evolving, and we want to continue to develop it in the open. We hope it will be useful for other projects, so please try it out or contribute to it, join the community and give us feedback!"]})]})}),(0,u.jsx)("section",{className:f.whoUses,id:"who-uses-infer",children:(0,u.jsxs)("div",{className:"container",children:[(0,u.jsx)("h2",{children:"Who Uses Infer?"}),(0,u.jsxs)("div",{style:{margin:"4rem 0"},children:[(0,u.jsx)("div",{className:"row",children:m.map(((e,t)=>{let{url:o,image:r}=e;return(0,u.jsx)("div",{className:"col col--2",children:(0,u.jsx)("div",{className:f.whoUsesItems,children:(0,u.jsx)("a",{href:o,children:(0,u.jsx)("img",{className:f.poweredByImage,src:r})})})},t)}))}),(0,u.jsx)("div",{className:"row",children:b.map(((e,t)=>{let{url:o,name:r}=e;return(0,u.jsx)("div",{className:"col col--2",children:(0,u.jsx)("div",{className:f.whoUsesItems,children:(0,u.jsx)("a",{href:o,children:(0,u.jsx)("h3",{className:f.poweredByItem,children:r})})})},t)}))})]}),(0,u.jsxs)("span",{children:["Does your project use Infer? Add it to this list with"," ",(0,u.jsx)("a",{href:"https://github.com/facebook/infer/edit/main/website/src/pages/index.js",children:"a pull request!"})]})]})})]})]})}},9867:(e,t,o)=>{"use strict";o.r(t),o.d(t,{render:()=>_});var r=window.document,a=window.Math,n=window.HTMLElement,i=window.XMLHttpRequest,c=function(e,t){for(var o=0,r=e.length;o'}}},download:{heights:{16:{width:16,path:''}}},eye:{heights:{16:{width:16,path:''}}},heart:{heights:{16:{width:16,path:''}}},"issue-opened":{heights:{16:{width:16,path:''}}},"mark-github":{heights:{16:{width:16,path:''}}},package:{heights:{16:{width:16,path:''}}},play:{heights:{16:{width:16,path:''}}},"repo-forked":{heights:{16:{width:16,path:''}}},"repo-template":{heights:{16:{width:16,path:''}}},star:{heights:{16:{width:16,path:''}}}},k=function(e,t){e=h(e).replace(/^octicon-/,""),d(y,e)||(e="mark-github");var o=t>=24&&24 in y[e].heights?24:16,r=y[e].heights[o];return'"},j={},C=function(e,t){var o=j[e]||(j[e]=[]);if(!(o.push(t)>1)){var r=function(e){var t;return function(){t||(t=1,e.apply(this,arguments))}}((function(){for(delete j[e];t=o.shift();)t.apply(null,arguments)}));if(f){var a=new i;m(a,"abort",r),m(a,"error",r),m(a,"load",(function(){var e;try{e=JSON.parse(this.responseText)}catch(t){return void r(t)}r(200!==this.status,e)})),a.open("GET",e),a.send()}else{var n=this||window;n._=function(e){n._=null,r(200!==e.meta.status,e.data)};var c=s(n.document)("script",{async:!0,src:e+(-1!==e.indexOf("?")?"&":"?")+"callback=_"}),l=function(){n._&&n._({meta:{}})};m(c,"load",l),m(c,"error",l),function(e,t,o){if(null!=e.readyState){var r="readystatechange",a=function(){if(t.test(e.readyState))return b(e,r,a),o.apply(this,arguments)};m(e,r,a)}}(c,/de|m/,l),n.document.getElementsByTagName("head")[0].appendChild(c)}}},A=function(e,t,o){var r=s(e.ownerDocument),a=e.appendChild(r("style",{type:"text/css"})),n="body{margin:0}a{text-decoration:none;outline:0}.widget{display:inline-block;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;font-size:0;line-height:0;white-space:nowrap}.btn,.social-count{position:relative;display:inline-block;display:inline-flex;height:14px;padding:2px 5px;font-size:11px;font-weight:600;line-height:14px;vertical-align:bottom;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-repeat:repeat-x;background-position:-1px -1px;background-size:110% 110%;border:1px solid}.btn{border-radius:.25em}.btn:not(:last-child){border-radius:.25em 0 0 .25em}.social-count{border-left:0;border-radius:0 .25em .25em 0}.widget-lg .btn,.widget-lg .social-count{height:16px;padding:5px 10px;font-size:12px;line-height:16px}.octicon{display:inline-block;vertical-align:text-top;fill:currentColor;overflow:visible}"+x(t["data-color-scheme"]);a.styleSheet?a.styleSheet.cssText=n:a.appendChild(e.ownerDocument.createTextNode(n));var i="large"===h(t["data-size"]),c=r("a",{className:"btn",href:t.href,rel:"noopener",target:"_blank",title:t.title||void 0,"aria-label":t["aria-label"]||void 0,innerHTML:k(t["data-icon"],i?16:14)+" "},[r("span",{},[t["data-text"]||""])]),l=e.appendChild(r("div",{className:"widget"+(i?" widget-lg":"")},[c])),d=c.hostname.replace(/\.$/,"");if(("."+d).substring(d.length-10)!=="."+u)return c.removeAttribute("href"),void o(l);var f=(" /"+c.pathname).split(/\/+/);if(((d===u||d==="gist."+u)&&"archive"===f[3]||d===u&&"releases"===f[3]&&("download"===f[4]||"latest"===f[4]&&"download"===f[5])||d==="codeload."+u)&&(c.target="_top"),"true"===h(t["data-show-count"])&&d===u&&"marketplace"!==f[1]&&"sponsors"!==f[1]&&"orgs"!==f[1]&&"users"!==f[1]&&"-"!==f[1]){var g,m;if(!f[2]&&f[1])m="followers",g="?tab=followers";else if(!f[3]&&f[2])m="stargazers_count",g="/stargazers";else if(f[4]||"subscription"!==f[3])if(f[4]||"fork"!==f[3]){if("issues"!==f[3])return void o(l);m="open_issues_count",g="/issues"}else m="forks_count",g="/forks";else m="subscribers_count",g="/watchers";var b=f[2]?"/repos/"+f[1]+"/"+f[2]:"/users/"+f[1];C.call(this,p+b,(function(e,t){if(!e){var a=t[m];l.appendChild(r("a",{className:"social-count",href:t.html_url+g,rel:"noopener",target:"_blank","aria-label":a+" "+m.replace(/_count$/,"").replace("_"," ").slice(0,a<2?-1:void 0)+" on GitHub"},[(""+a).replace(/\B(?=(\d{3})+(?!\d))/g,",")]))}o(l)}))}else o(l)},N=window.devicePixelRatio||1,I=function(e){return(N>1?a.ceil(a.round(e*N)/N*2)/2:a.ceil(e))||0},F=function(e,t){e.style.width=t[0]+"px",e.style.height=t[1]+"px"},_=function(e,t){if(null!=e&&null!=t)if(e.getAttribute&&(e=function(e){var t={href:e.href,title:e.title,"aria-label":e.getAttribute("aria-label")};return c(["icon","color-scheme","text","size","show-count"],(function(o){var r="data-"+o;t[r]=e.getAttribute(r)})),null==t["data-text"]&&(t["data-text"]=e.textContent||e.innerText),t}(e)),g){var o=l("span");A(o.attachShadow({mode:"closed"}),e,(function(){t(o)}))}else{var n=l("iframe",{src:"javascript:0",title:e.title||void 0,allowtransparency:!0,scrolling:"no",frameBorder:0});F(n,[0,0]),n.style.border="none",n.style.colorScheme="light";var i=function(){var o,c=n.contentWindow;try{o=c.document.body}catch(s){return void r.body.appendChild(n.parentNode.removeChild(n))}b(n,"load",i),A.call(c,o,e,(function(o){var r=function(e){var t=e.offsetWidth,o=e.offsetHeight;if(e.getBoundingClientRect){var r=e.getBoundingClientRect();t=a.max(t,I(r.width)),o=a.max(o,I(r.height))}return[t,o]}(o);n.parentNode.removeChild(n),function(e,t,o){var r=function(){return b(e,t,r),o.apply(this,arguments)};m(e,t,r)}(n,"load",(function(){F(n,r)})),n.src="https://unpkg.com/github-buttons@2.29.1/dist/buttons.html#"+(n.name=function(e,t,o,r){null==t&&(t="&"),null==o&&(o="="),null==r&&(r=window.encodeURIComponent);var a=[];for(var n in e){var i=e[n];null!=i&&a.push(r(n)+o+r(i))}return a.join(t)}(e)),t(n)}))};m(n,"load",i),r.body.appendChild(n)}}},6942:(e,t)=>{var o;!function(){"use strict";var r={}.hasOwnProperty;function a(){for(var e="",t=0;t{"use strict";n.d(t,{Bc:()=>g,E8:()=>Un,a1:()=>Bn});var r=n(6540);n(961);function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function l(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,a=[],i=!0,s=!1;try{for(n=n.call(e);!(i=(r=n.next()).done)&&(a.push(r.value),!t||a.length!==t);i=!0);}catch(e){s=!0,o=e}finally{try{i||null==n.return||n.return()}finally{if(s)throw o}}return a}}(e,t)||d(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function u(e){return function(e){if(Array.isArray(e))return f(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||d(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function d(e,t){if(e){if("string"==typeof e)return f(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?f(e,t):void 0}}function f(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);ne.length)&&(t=e.length);for(var n=0,r=new Array(t);ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function L(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function R(e){for(var t=1;t=3||2===n&&r>=4||1===n&&r>=10);function a(t,n,r){if(o&&void 0!==r){var a=r[0].__autocomplete_algoliaCredentials,i={"X-Algolia-Application-Id":a.appId,"X-Algolia-API-Key":a.apiKey};e.apply(void 0,[t].concat(P(n),[{headers:i}]))}else e.apply(void 0,[t].concat(P(n)))}return{init:function(t,n){e("init",{appId:t,apiKey:n})},setUserToken:function(t){e("setUserToken",t)},clickedObjectIDsAfterSearch:function(){for(var e=arguments.length,t=new Array(e),n=0;n0&&a("clickedObjectIDsAfterSearch",M(t),t[0].items)},clickedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),n=0;n0&&a("clickedObjectIDs",M(t),t[0].items)},clickedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r0&&e.apply(void 0,["clickedFilters"].concat(n))},convertedObjectIDsAfterSearch:function(){for(var e=arguments.length,t=new Array(e),n=0;n0&&a("convertedObjectIDsAfterSearch",M(t),t[0].items)},convertedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),n=0;n0&&a("convertedObjectIDs",M(t),t[0].items)},convertedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r0&&e.apply(void 0,["convertedFilters"].concat(n))},viewedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),n=0;n0&&t.reduce((function(e,t){var n=t.items,r=N(t,A);return[].concat(P(e),P(function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:20,n=[],r=0;r0&&e.apply(void 0,["viewedFilters"].concat(n))}}}function z(e){var t=e.items.reduce((function(e,t){var n;return e[t.__autocomplete_indexName]=(null!==(n=e[t.__autocomplete_indexName])&&void 0!==n?n:[]).concat(t),e}),{});return Object.keys(t).map((function(e){return{index:e,items:t[e],algoliaSource:["autocomplete"]}}))}function B(e){return e.objectID&&e.__autocomplete_indexName&&e.__autocomplete_queryID}function U(e){return U="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},U(e)}function $(e){return function(e){if(Array.isArray(e))return H(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return H(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?H(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function H(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&G({onItemsChange:r,items:n,insights:s,state:t}))}}),0);return{name:"aa.algoliaInsightsPlugin",subscribe:function(e){var t=e.setContext,n=e.onSelect,r=e.onActive;i("addAlgoliaAgent","insights-plugin"),t({algoliaInsightsPlugin:{__algoliaSearchParameters:{clickAnalytics:!0},insights:s}}),n((function(e){var t=e.item,n=e.state,r=e.event;B(t)&&o({state:n,event:r,insights:s,item:t,insightsEvents:[V({eventName:"Item Selected"},O({item:t,items:c.current}))]})})),r((function(e){var t=e.item,n=e.state,r=e.event;B(t)&&a({state:n,event:r,insights:s,item:t,insightsEvents:[V({eventName:"Item Active"},O({item:t,items:c.current}))]})}))},onStateChange:function(e){var t=e.state;l({state:t})},__autocomplete_pluginOptions:e}}function Z(e,t){var n=t;return{then:function(t,r){return Z(e.then(X(t,n,e),X(r,n,e)),n)},catch:function(t){return Z(e.catch(X(t,n,e)),n)},finally:function(t){return t&&n.onCancelList.push(t),Z(e.finally(X(t&&function(){return n.onCancelList=[],t()},n,e)),n)},cancel:function(){n.isCanceled=!0;var e=n.onCancelList;n.onCancelList=[],e.forEach((function(e){e()}))},isCanceled:function(){return!0===n.isCanceled}}}function Y(e){return Z(e,{isCanceled:!1,onCancelList:[]})}function X(e,t,n){return e?function(n){return t.isCanceled?n:e(n)}:n}function J(e,t,n,r){if(!n)return null;if(e<0&&(null===t||null!==r&&0===t))return n+e;var o=(null===t?-1:t)+e;return o<=-1||o>=n?null===r?null:0:o}function ee(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function te(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n0},reshape:function(e){return e.sources}},e),{},{id:null!==(n=e.id)&&void 0!==n?n:"autocomplete-".concat(k++),plugins:o,initialState:ge({activeItemId:null,query:"",completion:null,collections:[],isOpen:!1,status:"idle",context:{}},e.initialState),onStateChange:function(t){var n;null===(n=e.onStateChange)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onStateChange)||void 0===n?void 0:n.call(e,t)}))},onSubmit:function(t){var n;null===(n=e.onSubmit)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onSubmit)||void 0===n?void 0:n.call(e,t)}))},onReset:function(t){var n;null===(n=e.onReset)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onReset)||void 0===n?void 0:n.call(e,t)}))},getSources:function(n){return Promise.all([].concat(function(e){return function(e){if(Array.isArray(e))return he(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return he(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?he(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}(o.map((function(e){return e.getSources}))),[e.getSources]).filter(Boolean).map((function(e){return function(e,t){var n=[];return Promise.resolve(e(t)).then((function(e){return Promise.all(e.filter((function(e){return Boolean(e)})).map((function(e){if(e.sourceId,n.includes(e.sourceId))throw new Error("[Autocomplete] The `sourceId` ".concat(JSON.stringify(e.sourceId)," is not unique."));n.push(e.sourceId);var t={getItemInputValue:function(e){return e.state.query},getItemUrl:function(){},onSelect:function(e){(0,e.setIsOpen)(!1)},onActive:_,onResolve:_};Object.keys(t).forEach((function(e){t[e].__default=!0}));var r=te(te({},t),e);return Promise.resolve(r)})))}))}(e,n)}))).then((function(e){return v(e)})).then((function(e){return e.map((function(e){return ge(ge({},e),{},{onSelect:function(n){e.onSelect(n),t.forEach((function(e){var t;return null===(t=e.onSelect)||void 0===t?void 0:t.call(e,n)}))},onActive:function(n){e.onActive(n),t.forEach((function(e){var t;return null===(t=e.onActive)||void 0===t?void 0:t.call(e,n)}))},onResolve:function(n){e.onResolve(n),t.forEach((function(e){var t;return null===(t=e.onResolve)||void 0===t?void 0:t.call(e,n)}))}})}))}))},navigator:ge({navigate:function(e){var t=e.itemUrl;r.location.assign(t)},navigateNewTab:function(e){var t=e.itemUrl,n=r.open(t,"_blank","noopener");null==n||n.focus()},navigateNewWindow:function(e){var t=e.itemUrl;r.open(t,"_blank","noopener")}},e.navigator)})}function ve(e){return ve="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},ve(e)}function ke(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function we(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,Ie);ze&&o.environment.clearTimeout(ze);var l=c.setCollections,u=c.setIsOpen,d=c.setQuery,f=c.setActiveItemId,p=c.setStatus;if(d(a),f(o.defaultActiveItemId),!a&&!1===o.openOnFocus){var h,m=s.getState().collections.map((function(e){return Le(Le({},e),{},{items:[]})}));p("idle"),l(m),u(null!==(h=r.isOpen)&&void 0!==h?h:o.shouldPanelOpen({state:s.getState()}));var g=Y(Be(m).then((function(){return Promise.resolve()})));return s.pendingRequests.add(g)}p("loading"),ze=o.environment.setTimeout((function(){p("stalled")}),o.stallThreshold);var b=Y(Be(o.getSources(Le({query:a,refresh:i,state:s.getState()},c)).then((function(e){return Promise.all(e.map((function(e){return Promise.resolve(e.getItems(Le({query:a,refresh:i,state:s.getState()},c))).then((function(t){return function(e,t,n){if(o=e,Boolean(null==o?void 0:o.execute)){var r="algolia"===e.requesterId?Object.assign.apply(Object,[{}].concat(Ce(Object.keys(n.context).map((function(e){var t;return null===(t=n.context[e])||void 0===t?void 0:t.__algoliaSearchParameters}))))):{};return Ee(Ee({},e),{},{requests:e.queries.map((function(n){return{query:"algolia"===e.requesterId?Ee(Ee({},n),{},{params:Ee(Ee({},r),n.params)}):n,sourceId:t,transformResponse:e.transformResponse}}))})}var o;return{items:e,sourceId:t}}(t,e.sourceId,s.getState())}))}))).then(Te).then((function(t){return function(e,t,n){return t.map((function(t){var r,o=e.filter((function(e){return e.sourceId===t.sourceId})),a=o.map((function(e){return e.items})),i=o[0].transformResponse,s=i?i({results:r=a,hits:r.map((function(e){return e.hits})).filter(Boolean),facetHits:r.map((function(e){var t;return null===(t=e.facetHits)||void 0===t?void 0:t.map((function(e){return{label:e.value,count:e.count,_highlightResult:{label:{value:e.highlighted}}}}))})).filter(Boolean)}):a;return t.onResolve({source:t,results:a,items:s,state:n.getState()}),s.every(Boolean),'The `getItems` function from source "'.concat(t.sourceId,'" must return an array of items but returned ').concat(JSON.stringify(void 0),".\n\nDid you forget to return items?\n\nSee: https://www.algolia.com/doc/ui-libraries/autocomplete/core-concepts/sources/#param-getitems"),{source:t,items:s}}))}(t,e,s)})).then((function(e){return function(e){var t=e.props,n=e.state,r=e.collections.reduce((function(e,t){return we(we({},e),{},xe({},t.source.sourceId,we(we({},t.source),{},{getItems:function(){return v(t.items)}})))}),{}),o=t.plugins.reduce((function(e,t){return t.reshape?t.reshape(e):e}),{sourcesBySourceId:r,state:n}).sourcesBySourceId;return v(t.reshape({sourcesBySourceId:o,sources:Object.values(o),state:n})).filter(Boolean).map((function(e){return{source:e,items:e.getItems()}}))}({collections:e,props:o,state:s.getState()})}))})))).then((function(e){var n;p("idle"),l(e);var d=o.shouldPanelOpen({state:s.getState()});u(null!==(n=r.isOpen)&&void 0!==n?n:o.openOnFocus&&!a&&d||d);var f=oe(s.getState());if(null!==s.getState().activeItemId&&f){var h=f.item,m=f.itemInputValue,g=f.itemUrl,b=f.source;b.onActive(Le({event:t,item:h,itemInputValue:m,itemUrl:g,refresh:i,source:b,state:s.getState()},c))}})).finally((function(){p("idle"),ze&&o.environment.clearTimeout(ze)}));return s.pendingRequests.add(b)}function $e(e){return $e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},$e(e)}var He=["event","props","refresh","store"];function qe(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Ve(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function at(e){var t=e.props,n=e.refresh,r=e.store,o=ot(e,Ge),a=function(e,t){return void 0!==t?"".concat(e,"-").concat(t):e};return{getEnvironmentProps:function(e){var n=e.inputElement,o=e.formElement,a=e.panelElement;function i(e){!r.getState().isOpen&&r.pendingRequests.isEmpty()||e.target===n||!1===[o,a].some((function(t){return(n=t)===(r=e.target)||n.contains(r);var n,r}))&&(r.dispatch("blur",null),t.debug||r.pendingRequests.cancelAll())}return nt({onTouchStart:i,onMouseDown:i,onTouchMove:function(e){!1!==r.getState().isOpen&&n===t.environment.document.activeElement&&e.target!==n&&n.blur()}},ot(e,Qe))},getRootProps:function(e){return nt({role:"combobox","aria-expanded":r.getState().isOpen,"aria-haspopup":"listbox","aria-owns":r.getState().isOpen?"".concat(t.id,"-list"):void 0,"aria-labelledby":"".concat(t.id,"-label")},e)},getFormProps:function(e){return e.inputElement,nt({action:"",noValidate:!0,role:"search",onSubmit:function(a){var i;a.preventDefault(),t.onSubmit(nt({event:a,refresh:n,state:r.getState()},o)),r.dispatch("submit",null),null===(i=e.inputElement)||void 0===i||i.blur()},onReset:function(a){var i;a.preventDefault(),t.onReset(nt({event:a,refresh:n,state:r.getState()},o)),r.dispatch("reset",null),null===(i=e.inputElement)||void 0===i||i.focus()}},ot(e,Ze))},getLabelProps:function(e){var n=e||{},r=n.sourceIndex,o=ot(n,Xe);return nt({htmlFor:"".concat(a(t.id,r),"-input"),id:"".concat(a(t.id,r),"-label")},o)},getInputProps:function(e){var a;function i(e){(t.openOnFocus||Boolean(r.getState().query))&&Ue(nt({event:e,props:t,query:r.getState().completion||r.getState().query,refresh:n,store:r},o)),r.dispatch("focus",null)}var s=e||{},c=(s.inputElement,s.maxLength),l=void 0===c?512:c,u=ot(s,Ye),d=oe(r.getState()),f=function(e){return Boolean(e&&e.match(ae))}((null===(a=t.environment.navigator)||void 0===a?void 0:a.userAgent)||""),p=null!=d&&d.itemUrl&&!f?"go":"search";return nt({"aria-autocomplete":"both","aria-activedescendant":r.getState().isOpen&&null!==r.getState().activeItemId?"".concat(t.id,"-item-").concat(r.getState().activeItemId):void 0,"aria-controls":r.getState().isOpen?"".concat(t.id,"-list"):void 0,"aria-labelledby":"".concat(t.id,"-label"),value:r.getState().completion||r.getState().query,id:"".concat(t.id,"-input"),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",enterKeyHint:p,spellCheck:"false",autoFocus:t.autoFocus,placeholder:t.placeholder,maxLength:l,type:"search",onChange:function(e){Ue(nt({event:e,props:t,query:e.currentTarget.value.slice(0,l),refresh:n,store:r},o))},onKeyDown:function(e){!function(e){var t=e.event,n=e.props,r=e.refresh,o=e.store,a=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,He);if("ArrowUp"===t.key||"ArrowDown"===t.key){var i=function(){var e=n.environment.document.getElementById("".concat(n.id,"-item-").concat(o.getState().activeItemId));e&&(e.scrollIntoViewIfNeeded?e.scrollIntoViewIfNeeded(!1):e.scrollIntoView(!1))},s=function(){var e=oe(o.getState());if(null!==o.getState().activeItemId&&e){var n=e.item,i=e.itemInputValue,s=e.itemUrl,c=e.source;c.onActive(Ve({event:t,item:n,itemInputValue:i,itemUrl:s,refresh:r,source:c,state:o.getState()},a))}};t.preventDefault(),!1===o.getState().isOpen&&(n.openOnFocus||Boolean(o.getState().query))?Ue(Ve({event:t,props:n,query:o.getState().query,refresh:r,store:o},a)).then((function(){o.dispatch(t.key,{nextActiveItemId:n.defaultActiveItemId}),s(),setTimeout(i,0)})):(o.dispatch(t.key,{}),s(),i())}else if("Escape"===t.key)t.preventDefault(),o.dispatch(t.key,null),o.pendingRequests.cancelAll();else if("Tab"===t.key)o.dispatch("blur",null),o.pendingRequests.cancelAll();else if("Enter"===t.key){if(null===o.getState().activeItemId||o.getState().collections.every((function(e){return 0===e.items.length})))return void(n.debug||o.pendingRequests.cancelAll());t.preventDefault();var c=oe(o.getState()),l=c.item,u=c.itemInputValue,d=c.itemUrl,f=c.source;if(t.metaKey||t.ctrlKey)void 0!==d&&(f.onSelect(Ve({event:t,item:l,itemInputValue:u,itemUrl:d,refresh:r,source:f,state:o.getState()},a)),n.navigator.navigateNewTab({itemUrl:d,item:l,state:o.getState()}));else if(t.shiftKey)void 0!==d&&(f.onSelect(Ve({event:t,item:l,itemInputValue:u,itemUrl:d,refresh:r,source:f,state:o.getState()},a)),n.navigator.navigateNewWindow({itemUrl:d,item:l,state:o.getState()}));else if(t.altKey);else{if(void 0!==d)return f.onSelect(Ve({event:t,item:l,itemInputValue:u,itemUrl:d,refresh:r,source:f,state:o.getState()},a)),void n.navigator.navigate({itemUrl:d,item:l,state:o.getState()});Ue(Ve({event:t,nextState:{isOpen:!1},props:n,query:u,refresh:r,store:o},a)).then((function(){f.onSelect(Ve({event:t,item:l,itemInputValue:u,itemUrl:d,refresh:r,source:f,state:o.getState()},a))}))}}}(nt({event:e,props:t,refresh:n,store:r},o))},onFocus:i,onBlur:_,onClick:function(n){e.inputElement!==t.environment.document.activeElement||r.getState().isOpen||i(n)}},u)},getPanelProps:function(e){return nt({onMouseDown:function(e){e.preventDefault()},onMouseLeave:function(){r.dispatch("mouseleave",null)}},e)},getListProps:function(e){var n=e||{},r=n.sourceIndex,o=ot(n,Je);return nt({role:"listbox","aria-labelledby":"".concat(a(t.id,r),"-label"),id:"".concat(a(t.id,r),"-list")},o)},getItemProps:function(e){var i=e.item,s=e.source,c=e.sourceIndex,l=ot(e,et);return nt({id:"".concat(a(t.id,c),"-item-").concat(i.__autocomplete_id),role:"option","aria-selected":r.getState().activeItemId===i.__autocomplete_id,onMouseMove:function(e){if(i.__autocomplete_id!==r.getState().activeItemId){r.dispatch("mousemove",i.__autocomplete_id);var t=oe(r.getState());if(null!==r.getState().activeItemId&&t){var a=t.item,s=t.itemInputValue,c=t.itemUrl,l=t.source;l.onActive(nt({event:e,item:a,itemInputValue:s,itemUrl:c,refresh:n,source:l,state:r.getState()},o))}}},onMouseDown:function(e){e.preventDefault()},onClick:function(e){var a=s.getItemInputValue({item:i,state:r.getState()}),c=s.getItemUrl({item:i,state:r.getState()});(c?Promise.resolve():Ue(nt({event:e,nextState:{isOpen:!1},props:t,query:a,refresh:n,store:r},o))).then((function(){s.onSelect(nt({event:e,item:i,itemInputValue:a,itemUrl:c,refresh:n,source:s,state:r.getState()},o))}))}},l)}}}function it(e){return it="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},it(e)}function st(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function ct(e){for(var t=1;t0&&r.createElement("div",{className:"DocSearch-NoResults-Prefill-List"},r.createElement("p",{className:"DocSearch-Help"},l,":"),r.createElement("ul",null,m.slice(0,3).reduce((function(e,t){return[].concat(u(e),[r.createElement("li",{key:t},r.createElement("button",{className:"DocSearch-Prefill",key:t,type:"button",onClick:function(){o.setQuery(t.toLowerCase()+" "),o.refresh(),o.inputRef.current.focus()}},t))])}),[]))),o.getMissingResultsUrl&&r.createElement("p",{className:"DocSearch-Help"},"".concat(f," "),r.createElement("a",{href:o.getMissingResultsUrl({query:o.state.query}),target:"_blank",rel:"noopener noreferrer"},h)))}var Bt=["hit","attribute","tagName"];function Ut(e,t){return t.split(".").reduce((function(e,t){return null!=e&&e[t]?e[t]:null}),e)}function $t(e){var t=e.hit,n=e.attribute,o=e.tagName,i=void 0===o?"span":o,s=c(e,Bt);return(0,r.createElement)(i,a(a({},s),{},{dangerouslySetInnerHTML:{__html:Ut(t,"_snippetResult.".concat(n,".value"))||Ut(t,n)}}))}function Ht(e){return e.collection&&0!==e.collection.items.length?r.createElement("section",{className:"DocSearch-Hits"},r.createElement("div",{className:"DocSearch-Hit-source"},e.title),r.createElement("ul",e.getListProps(),e.collection.items.map((function(t,n){return r.createElement(qt,s({key:[e.title,t.objectID].join(":"),item:t,index:n},e))})))):null}function qt(e){var t=e.item,n=e.index,o=e.renderIcon,a=e.renderAction,i=e.getItemProps,c=e.onItemClick,u=e.collection,d=e.hitComponent,f=l(r.useState(!1),2),p=f[0],h=f[1],m=l(r.useState(!1),2),g=m[0],b=m[1],y=r.useRef(null),v=d;return r.createElement("li",s({className:["DocSearch-Hit",t.__docsearch_parent&&"DocSearch-Hit--Child",p&&"DocSearch-Hit--deleting",g&&"DocSearch-Hit--favoriting"].filter(Boolean).join(" "),onTransitionEnd:function(){y.current&&y.current()}},i({item:t,source:u.source,onClick:function(e){c(t,e)}})),r.createElement(v,{hit:t},r.createElement("div",{className:"DocSearch-Hit-Container"},o({item:t,index:n}),t.hierarchy[t.type]&&"lvl1"===t.type&&r.createElement("div",{className:"DocSearch-Hit-content-wrapper"},r.createElement($t,{className:"DocSearch-Hit-title",hit:t,attribute:"hierarchy.lvl1"}),t.content&&r.createElement($t,{className:"DocSearch-Hit-path",hit:t,attribute:"content"})),t.hierarchy[t.type]&&("lvl2"===t.type||"lvl3"===t.type||"lvl4"===t.type||"lvl5"===t.type||"lvl6"===t.type)&&r.createElement("div",{className:"DocSearch-Hit-content-wrapper"},r.createElement($t,{className:"DocSearch-Hit-title",hit:t,attribute:"hierarchy.".concat(t.type)}),r.createElement($t,{className:"DocSearch-Hit-path",hit:t,attribute:"hierarchy.lvl1"})),"content"===t.type&&r.createElement("div",{className:"DocSearch-Hit-content-wrapper"},r.createElement($t,{className:"DocSearch-Hit-title",hit:t,attribute:"content"}),r.createElement($t,{className:"DocSearch-Hit-path",hit:t,attribute:"hierarchy.lvl1"})),a({item:t,runDeleteTransition:function(e){h(!0),y.current=e},runFavoriteTransition:function(e){b(!0),y.current=e}}))))}function Vt(e,t,n){return e.reduce((function(e,r){var o=t(r);return e.hasOwnProperty(o)||(e[o]=[]),e[o].length<(n||5)&&e[o].push(r),e}),{})}function Wt(e){return e}function Kt(e){return 1===e.button||e.altKey||e.ctrlKey||e.metaKey||e.shiftKey}function Gt(){}var Qt=/(|<\/mark>)/g,Zt=RegExp(Qt.source);function Yt(e){var t,n,r=e;if(!r.__docsearch_parent&&!e._highlightResult)return e.hierarchy.lvl0;var o=r.__docsearch_parent?null===(t=r.__docsearch_parent)||void 0===t||null===(t=t._highlightResult)||void 0===t||null===(t=t.hierarchy)||void 0===t?void 0:t.lvl0:null===(n=e._highlightResult)||void 0===n||null===(n=n.hierarchy)||void 0===n?void 0:n.lvl0;return o?o.value&&Zt.test(o.value)?o.value.replace(Qt,""):o.value:e.hierarchy.lvl0}function Xt(e){return r.createElement("div",{className:"DocSearch-Dropdown-Container"},e.state.collections.map((function(t){if(0===t.items.length)return null;var n=Yt(t.items[0]);return r.createElement(Ht,s({},e,{key:t.source.sourceId,title:n,collection:t,renderIcon:function(e){var n,o=e.item,a=e.index;return r.createElement(r.Fragment,null,o.__docsearch_parent&&r.createElement("svg",{className:"DocSearch-Hit-Tree",viewBox:"0 0 24 54"},r.createElement("g",{stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"},o.__docsearch_parent!==(null===(n=t.items[a+1])||void 0===n?void 0:n.__docsearch_parent)?r.createElement("path",{d:"M8 6v21M20 27H8.3"}):r.createElement("path",{d:"M8 6v42M20 27H8.3"}))),r.createElement("div",{className:"DocSearch-Hit-icon"},r.createElement(Pt,{type:o.type})))},renderAction:function(){return r.createElement("div",{className:"DocSearch-Hit-action"},r.createElement(At,null))}}))})),e.resultsFooterComponent&&r.createElement("section",{className:"DocSearch-HitsFooter"},r.createElement(e.resultsFooterComponent,{state:e.state})))}var Jt=["translations"];function en(e){var t=e.translations,n=void 0===t?{}:t,o=c(e,Jt),a=n.recentSearchesTitle,i=void 0===a?"Recent":a,l=n.noRecentSearchesText,u=void 0===l?"No recent searches":l,d=n.saveRecentSearchButtonTitle,f=void 0===d?"Save this search":d,p=n.removeRecentSearchButtonTitle,h=void 0===p?"Remove this search from history":p,m=n.favoriteSearchesTitle,g=void 0===m?"Favorite":m,b=n.removeFavoriteSearchButtonTitle,y=void 0===b?"Remove this search from favorites":b;return"idle"===o.state.status&&!1===o.hasCollections?o.disableUserPersonalization?null:r.createElement("div",{className:"DocSearch-StartScreen"},r.createElement("p",{className:"DocSearch-Help"},u)):!1===o.hasCollections?null:r.createElement("div",{className:"DocSearch-Dropdown-Container"},r.createElement(Ht,s({},o,{title:i,collection:o.state.collections[0],renderIcon:function(){return r.createElement("div",{className:"DocSearch-Hit-icon"},r.createElement(Ct,null))},renderAction:function(e){var t=e.item,n=e.runFavoriteTransition,a=e.runDeleteTransition;return r.createElement(r.Fragment,null,r.createElement("div",{className:"DocSearch-Hit-action"},r.createElement("button",{className:"DocSearch-Hit-action-button",title:f,type:"submit",onClick:function(e){e.preventDefault(),e.stopPropagation(),n((function(){o.favoriteSearches.add(t),o.recentSearches.remove(t),o.refresh()}))}},r.createElement(Lt,null))),r.createElement("div",{className:"DocSearch-Hit-action"},r.createElement("button",{className:"DocSearch-Hit-action-button",title:h,type:"submit",onClick:function(e){e.preventDefault(),e.stopPropagation(),a((function(){o.recentSearches.remove(t),o.refresh()}))}},r.createElement(jt,null))))}})),r.createElement(Ht,s({},o,{title:g,collection:o.state.collections[1],renderIcon:function(){return r.createElement("div",{className:"DocSearch-Hit-icon"},r.createElement(Lt,null))},renderAction:function(e){var t=e.item,n=e.runDeleteTransition;return r.createElement("div",{className:"DocSearch-Hit-action"},r.createElement("button",{className:"DocSearch-Hit-action-button",title:y,type:"submit",onClick:function(e){e.preventDefault(),e.stopPropagation(),n((function(){o.favoriteSearches.remove(t),o.refresh()}))}},r.createElement(jt,null)))}})))}var tn=["translations"],nn=r.memo((function(e){var t=e.translations,n=void 0===t?{}:t,o=c(e,tn);if("error"===o.state.status)return r.createElement(Mt,{translations:null==n?void 0:n.errorScreen});var a=o.state.collections.some((function(e){return e.items.length>0}));return o.state.query?!1===a?r.createElement(zt,s({},o,{translations:null==n?void 0:n.noResultsScreen})):r.createElement(Xt,o):r.createElement(en,s({},o,{hasCollections:a,translations:null==n?void 0:n.startScreen}))}),(function(e,t){return"loading"===t.state.status||"stalled"===t.state.status})),rn=["translations"];function on(e){var t=e.translations,n=void 0===t?{}:t,o=c(e,rn),a=n.resetButtonTitle,i=void 0===a?"Clear the query":a,l=n.resetButtonAriaLabel,u=void 0===l?"Clear the query":l,d=n.cancelButtonText,f=void 0===d?"Cancel":d,p=n.cancelButtonAriaLabel,m=void 0===p?"Cancel":p,g=n.searchInputLabel,b=void 0===g?"Search":g,y=o.getFormProps({inputElement:o.inputRef.current}).onReset;return r.useEffect((function(){o.autoFocus&&o.inputRef.current&&o.inputRef.current.focus()}),[o.autoFocus,o.inputRef]),r.useEffect((function(){o.isFromSelection&&o.inputRef.current&&o.inputRef.current.select()}),[o.isFromSelection,o.inputRef]),r.createElement(r.Fragment,null,r.createElement("form",{className:"DocSearch-Form",onSubmit:function(e){e.preventDefault()},onReset:y},r.createElement("label",s({className:"DocSearch-MagnifierLabel"},o.getLabelProps()),r.createElement(h,null),r.createElement("span",{className:"DocSearch-VisuallyHiddenForAccessibility"},b)),r.createElement("div",{className:"DocSearch-LoadingIndicator"},r.createElement(Ot,null)),r.createElement("input",s({className:"DocSearch-Input",ref:o.inputRef},o.getInputProps({inputElement:o.inputRef.current,autoFocus:o.autoFocus,maxLength:64}))),r.createElement("button",{type:"reset",title:i,className:"DocSearch-Reset","aria-label":u,hidden:!o.state.query},r.createElement(jt,null))),r.createElement("button",{className:"DocSearch-Cancel",type:"reset","aria-label":m,onClick:o.onClose},f))}var an=["_highlightResult","_snippetResult"];function sn(e){var t=e.key,n=e.limit,r=void 0===n?5:n,o=function(e){return!1===function(){var e="__TEST_KEY__";try{return localStorage.setItem(e,""),localStorage.removeItem(e),!0}catch(e){return!1}}()?{setItem:function(){},getItem:function(){return[]}}:{setItem:function(t){return window.localStorage.setItem(e,JSON.stringify(t))},getItem:function(){var t=window.localStorage.getItem(e);return t?JSON.parse(t):[]}}}(t),a=o.getItem().slice(0,r);return{add:function(e){var t=e,n=(t._highlightResult,t._snippetResult,c(t,an)),i=a.findIndex((function(e){return e.objectID===n.objectID}));i>-1&&a.splice(i,1),a.unshift(n),a=a.slice(0,r),o.setItem(a)},remove:function(e){a=a.filter((function(t){return t.objectID!==e.objectID})),o.setItem(a)},getAll:function(){return a}}}function cn(e){const t=`algoliasearch-client-js-${e.key}`;let n;const r=()=>(void 0===n&&(n=e.localStorage||window.localStorage),n),o=()=>JSON.parse(r().getItem(t)||"{}"),a=e=>{r().setItem(t,JSON.stringify(e))};return{get:(t,n,r={miss:()=>Promise.resolve()})=>Promise.resolve().then((()=>{(()=>{const t=e.timeToLive?1e3*e.timeToLive:null,n=o(),r=Object.fromEntries(Object.entries(n).filter((([,e])=>void 0!==e.timestamp)));if(a(r),!t)return;const i=Object.fromEntries(Object.entries(r).filter((([,e])=>{const n=(new Date).getTime();return!(e.timestamp+tPromise.all([e?e.value:n(),void 0!==e]))).then((([e,t])=>Promise.all([e,t||r.miss(e)]))).then((([e])=>e)),set:(e,n)=>Promise.resolve().then((()=>{const a=o();return a[JSON.stringify(e)]={timestamp:(new Date).getTime(),value:n},r().setItem(t,JSON.stringify(a)),n})),delete:e=>Promise.resolve().then((()=>{const n=o();delete n[JSON.stringify(e)],r().setItem(t,JSON.stringify(n))})),clear:()=>Promise.resolve().then((()=>{r().removeItem(t)}))}}function ln(e){const t=[...e.caches],n=t.shift();return void 0===n?{get:(e,t,n={miss:()=>Promise.resolve()})=>t().then((e=>Promise.all([e,n.miss(e)]))).then((([e])=>e)),set:(e,t)=>Promise.resolve(t),delete:e=>Promise.resolve(),clear:()=>Promise.resolve()}:{get:(e,r,o={miss:()=>Promise.resolve()})=>n.get(e,r,o).catch((()=>ln({caches:t}).get(e,r,o))),set:(e,r)=>n.set(e,r).catch((()=>ln({caches:t}).set(e,r))),delete:e=>n.delete(e).catch((()=>ln({caches:t}).delete(e))),clear:()=>n.clear().catch((()=>ln({caches:t}).clear()))}}function un(e={serializable:!0}){let t={};return{get(n,r,o={miss:()=>Promise.resolve()}){const a=JSON.stringify(n);if(a in t)return Promise.resolve(e.serializable?JSON.parse(t[a]):t[a]);const i=r(),s=o&&o.miss||(()=>Promise.resolve());return i.then((e=>s(e))).then((()=>i))},set:(n,r)=>(t[JSON.stringify(n)]=e.serializable?JSON.stringify(r):r,Promise.resolve(r)),delete:e=>(delete t[JSON.stringify(e)],Promise.resolve()),clear:()=>(t={},Promise.resolve())}}function dn(e){let t=e.length-1;for(;t>0;t--){const n=Math.floor(Math.random()*(t+1)),r=e[t];e[t]=e[n],e[n]=r}return e}function fn(e,t){return t?(Object.keys(t).forEach((n=>{e[n]=t[n](e)})),e):e}function pn(e,...t){let n=0;return e.replace(/%s/g,(()=>encodeURIComponent(t[n++])))}const hn={WithinQueryParameters:0,WithinHeaders:1};function mn(e,t){const n=e||{},r=n.data||{};return Object.keys(n).forEach((e=>{-1===["timeout","headers","queryParameters","data","cacheable"].indexOf(e)&&(r[e]=n[e])})),{data:Object.entries(r).length>0?r:void 0,timeout:n.timeout||t,headers:n.headers||{},queryParameters:n.queryParameters||{},cacheable:n.cacheable}}const gn={Read:1,Write:2,Any:3};function bn(e,t=1){return{...e,status:t,lastUpdate:Date.now()}}function yn(e){return"string"==typeof e?{protocol:"https",url:e,accept:gn.Any}:{protocol:e.protocol||"https",url:e.url,accept:e.accept||gn.Any}}const vn="GET",kn="POST";function wn(e,t,n,r){const o=[],a=function(e,t){if(e.method===vn||void 0===e.data&&void 0===t.data)return;const n=Array.isArray(e.data)?e.data:{...e.data,...t.data};return JSON.stringify(n)}(n,r),i=function(e,t){const n={...e.headers,...t.headers},r={};return Object.keys(n).forEach((e=>{const t=n[e];r[e.toLowerCase()]=t})),r}(e,r),s=n.method,c=n.method!==vn?{}:{...n.data,...r.data},l={"x-algolia-agent":e.userAgent.value,...e.queryParameters,...c,...r.queryParameters};let u=0;const d=(t,c)=>{const f=t.pop();if(void 0===f)throw{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:En(o)};const p={data:a,headers:i,method:s,url:Sn(f,n.path,l),connectTimeout:c(u,e.timeouts.connect),responseTimeout:c(u,r.timeout)},h=e=>{const n={request:p,response:e,host:f,triesLeft:t.length};return o.push(n),n},m={onSuccess:e=>function(e){try{return JSON.parse(e.content)}catch(t){throw function(e,t){return{name:"DeserializationError",message:e,response:t}}(t.message,e)}}(e),onRetry(n){const r=h(n);return n.isTimedOut&&u++,Promise.all([e.logger.info("Retryable failure",On(r)),e.hostsCache.set(f,bn(f,n.isTimedOut?3:2))]).then((()=>d(t,c)))},onFail(e){throw h(e),function({content:e,status:t},n){let r=e;try{r=JSON.parse(e).message}catch(e){}return function(e,t,n){return{name:"ApiError",message:e,status:t,transporterStackTrace:n}}(r,t,n)}(e,En(o))}};return e.requester.send(p).then((e=>((e,t)=>(e=>{const t=e.status;return e.isTimedOut||(({isTimedOut:e,status:t})=>!e&&!~~t)(e)||2!=~~(t/100)&&4!=~~(t/100)})(e)?t.onRetry(e):(({status:e})=>2==~~(e/100))(e)?t.onSuccess(e):t.onFail(e))(e,m)))};return function(e,t){return Promise.all(t.map((t=>e.get(t,(()=>Promise.resolve(bn(t))))))).then((e=>{const n=e.filter((e=>function(e){return 1===e.status||Date.now()-e.lastUpdate>12e4}(e))),r=e.filter((e=>function(e){return 3===e.status&&Date.now()-e.lastUpdate<=12e4}(e))),o=[...n,...r];return{getTimeout:(e,t)=>(0===r.length&&0===e?1:r.length+3+e)*t,statelessHosts:o.length>0?o.map((e=>yn(e))):t}}))}(e.hostsCache,t).then((e=>d([...e.statelessHosts].reverse(),e.getTimeout)))}function xn(e){const t={value:`Algolia for JavaScript (${e})`,add(e){const n=`; ${e.segment}${void 0!==e.version?` (${e.version})`:""}`;return-1===t.value.indexOf(n)&&(t.value=`${t.value}${n}`),t}};return t}function Sn(e,t,n){const r=_n(n);let o=`${e.protocol}://${e.url}/${"/"===t.charAt(0)?t.substr(1):t}`;return r.length&&(o+=`?${r}`),o}function _n(e){return Object.keys(e).map((t=>{return pn("%s=%s",t,(n=e[t],"[object Object]"===Object.prototype.toString.call(n)||"[object Array]"===Object.prototype.toString.call(n)?JSON.stringify(e[t]):e[t]));var n})).join("&")}function En(e){return e.map((e=>On(e)))}function On(e){const t=e.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return{...e,request:{...e.request,headers:{...e.request.headers,...t}}}}const Cn=e=>{const t=e.appId,n=function(e,t,n){const r={"x-algolia-api-key":n,"x-algolia-application-id":t};return{headers:()=>e===hn.WithinHeaders?r:{},queryParameters:()=>e===hn.WithinQueryParameters?r:{}}}(void 0!==e.authMode?e.authMode:hn.WithinHeaders,t,e.apiKey),r=function(e){const{hostsCache:t,logger:n,requester:r,requestsCache:o,responsesCache:a,timeouts:i,userAgent:s,hosts:c,queryParameters:l,headers:u}=e,d={hostsCache:t,logger:n,requester:r,requestsCache:o,responsesCache:a,timeouts:i,userAgent:s,headers:u,queryParameters:l,hosts:c.map((e=>yn(e))),read(e,t){const n=mn(t,d.timeouts.read),r=()=>wn(d,d.hosts.filter((e=>!!(e.accept&gn.Read))),e,n);if(!0!==(void 0!==n.cacheable?n.cacheable:e.cacheable))return r();const o={request:e,mappedRequestOptions:n,transporter:{queryParameters:d.queryParameters,headers:d.headers}};return d.responsesCache.get(o,(()=>d.requestsCache.get(o,(()=>d.requestsCache.set(o,r()).then((e=>Promise.all([d.requestsCache.delete(o),e])),(e=>Promise.all([d.requestsCache.delete(o),Promise.reject(e)]))).then((([e,t])=>t))))),{miss:e=>d.responsesCache.set(o,e)})},write:(e,t)=>wn(d,d.hosts.filter((e=>!!(e.accept&gn.Write))),e,mn(t,d.timeouts.write))};return d}({hosts:[{url:`${t}-dsn.algolia.net`,accept:gn.Read},{url:`${t}.algolia.net`,accept:gn.Write}].concat(dn([{url:`${t}-1.algolianet.com`},{url:`${t}-2.algolianet.com`},{url:`${t}-3.algolianet.com`}])),...e,headers:{...n.headers(),"content-type":"application/x-www-form-urlencoded",...e.headers},queryParameters:{...n.queryParameters(),...e.queryParameters}}),o={transporter:r,appId:t,addAlgoliaAgent(e,t){r.userAgent.add({segment:e,version:t})},clearCache:()=>Promise.all([r.requestsCache.clear(),r.responsesCache.clear()]).then((()=>{}))};return fn(o,e.methods)},jn=e=>(t,n)=>t.method===vn?e.transporter.read(t,n):e.transporter.write(t,n),An=e=>(t,n={})=>fn({transporter:e.transporter,appId:e.appId,indexName:t},n.methods),Tn=e=>(t,n)=>{const r=t.map((e=>({...e,params:_n(e.params||{})})));return e.transporter.read({method:kn,path:"1/indexes/*/queries",data:{requests:r},cacheable:!0},n)},Pn=e=>(t,n)=>Promise.all(t.map((t=>{const{facetName:r,facetQuery:o,...a}=t.params;return An(e)(t.indexName,{methods:{searchForFacetValues:Ln}}).searchForFacetValues(r,o,{...n,...a})}))),In=e=>(t,n,r)=>e.transporter.read({method:kn,path:pn("1/answers/%s/prediction",e.indexName),data:{query:t,queryLanguages:n},cacheable:!0},r),Nn=e=>(t,n)=>e.transporter.read({method:kn,path:pn("1/indexes/%s/query",e.indexName),data:{query:t},cacheable:!0},n),Ln=e=>(t,n,r)=>e.transporter.read({method:kn,path:pn("1/indexes/%s/facets/%s/query",e.indexName,t),data:{facetQuery:n},cacheable:!0},r),Rn=1,Dn=2,Mn=3;function Fn(e,t,n){const r={appId:e,apiKey:t,timeouts:{connect:1,read:2,write:30},requester:{send:e=>new Promise((t=>{const n=new XMLHttpRequest;n.open(e.method,e.url,!0),Object.keys(e.headers).forEach((t=>n.setRequestHeader(t,e.headers[t])));const r=(e,r)=>setTimeout((()=>{n.abort(),t({status:0,content:r,isTimedOut:!0})}),1e3*e),o=r(e.connectTimeout,"Connection timeout");let a;n.onreadystatechange=()=>{n.readyState>n.OPENED&&void 0===a&&(clearTimeout(o),a=r(e.responseTimeout,"Socket timeout"))},n.onerror=()=>{0===n.status&&(clearTimeout(o),clearTimeout(a),t({content:n.responseText||"Network request failed",status:n.status,isTimedOut:!1}))},n.onload=()=>{clearTimeout(o),clearTimeout(a),t({content:n.responseText,status:n.status,isTimedOut:!1})},n.send(e.data)}))},logger:(o=Mn,{debug:(e,t)=>(Rn>=o&&console.debug(e,t),Promise.resolve()),info:(e,t)=>(Dn>=o&&console.info(e,t),Promise.resolve()),error:(e,t)=>(console.error(e,t),Promise.resolve())}),responsesCache:un(),requestsCache:un({serializable:!1}),hostsCache:ln({caches:[cn({key:`4.19.1-${e}`}),un()]}),userAgent:xn("4.19.1").add({segment:"Browser",version:"lite"}),authMode:hn.WithinQueryParameters};var o;return Cn({...r,...n,methods:{search:Tn,searchForFacetValues:Pn,multipleQueries:Tn,multipleSearchForFacetValues:Pn,customRequest:jn,initIndex:e=>t=>An(e)(t,{methods:{search:Nn,searchForFacetValues:Ln,findAnswers:In}})}})}Fn.version="4.19.1";var zn=["footer","searchBox"];function Bn(e){var t=e.appId,n=e.apiKey,o=e.indexName,i=e.placeholder,u=void 0===i?"Search docs":i,d=e.searchParameters,f=e.maxResultsPerGroup,p=e.onClose,h=void 0===p?Gt:p,m=e.transformItems,g=void 0===m?Wt:m,b=e.hitComponent,y=void 0===b?Et:b,v=e.resultsFooterComponent,k=void 0===v?function(){return null}:v,w=e.navigator,x=e.initialScrollY,S=void 0===x?0:x,_=e.transformSearchClient,E=void 0===_?Wt:_,O=e.disableUserPersonalization,C=void 0!==O&&O,j=e.initialQuery,A=void 0===j?"":j,T=e.translations,P=void 0===T?{}:T,I=e.getMissingResultsUrl,N=e.insights,L=void 0!==N&&N,R=P.footer,D=P.searchBox,M=c(P,zn),F=l(r.useState({query:"",collections:[],completion:null,context:{},isOpen:!1,activeItemId:null,status:"idle"}),2),z=F[0],B=F[1],U=r.useRef(null),$=r.useRef(null),H=r.useRef(null),q=r.useRef(null),V=r.useRef(null),W=r.useRef(10),K=r.useRef("undefined"!=typeof window?window.getSelection().toString().slice(0,64):"").current,G=r.useRef(A||K).current,Q=function(e,t,n){return r.useMemo((function(){var r=Fn(e,t);return r.addAlgoliaAgent("docsearch","3.6.2"),!1===/docsearch.js \(.*\)/.test(r.transporter.userAgent.value)&&r.addAlgoliaAgent("docsearch-react","3.6.2"),n(r)}),[e,t,n])}(t,n,E),Z=r.useRef(sn({key:"__DOCSEARCH_FAVORITE_SEARCHES__".concat(o),limit:10})).current,Y=r.useRef(sn({key:"__DOCSEARCH_RECENT_SEARCHES__".concat(o),limit:0===Z.getAll().length?7:4})).current,X=r.useCallback((function(e){if(!C){var t="content"===e.type?e.__docsearch_parent:e;t&&-1===Z.getAll().findIndex((function(e){return e.objectID===t.objectID}))&&Y.add(t)}}),[Z,Y,C]),J=r.useCallback((function(e){if(z.context.algoliaInsightsPlugin&&e.__autocomplete_id){var t=e,n={eventName:"Item Selected",index:t.__autocomplete_indexName,items:[t],positions:[e.__autocomplete_id],queryID:t.__autocomplete_queryID};z.context.algoliaInsightsPlugin.insights.clickedObjectIDsAfterSearch(n)}}),[z.context.algoliaInsightsPlugin]),ee=r.useMemo((function(){return wt({id:"docsearch",defaultActiveItemId:0,placeholder:u,openOnFocus:!0,initialState:{query:G,context:{searchSuggestions:[]}},insights:L,navigator:w,onStateChange:function(e){B(e.state)},getSources:function(e){var r=e.query,i=e.state,s=e.setContext,c=e.setStatus;if(!r)return C?[]:[{sourceId:"recentSearches",onSelect:function(e){var t=e.item,n=e.event;X(t),Kt(n)||h()},getItemUrl:function(e){return e.item.url},getItems:function(){return Y.getAll()}},{sourceId:"favoriteSearches",onSelect:function(e){var t=e.item,n=e.event;X(t),Kt(n)||h()},getItemUrl:function(e){return e.item.url},getItems:function(){return Z.getAll()}}];var l=Boolean(L);return Q.search([{query:r,indexName:o,params:a({attributesToRetrieve:["hierarchy.lvl0","hierarchy.lvl1","hierarchy.lvl2","hierarchy.lvl3","hierarchy.lvl4","hierarchy.lvl5","hierarchy.lvl6","content","type","url"],attributesToSnippet:["hierarchy.lvl1:".concat(W.current),"hierarchy.lvl2:".concat(W.current),"hierarchy.lvl3:".concat(W.current),"hierarchy.lvl4:".concat(W.current),"hierarchy.lvl5:".concat(W.current),"hierarchy.lvl6:".concat(W.current),"content:".concat(W.current)],snippetEllipsisText:"\u2026",highlightPreTag:"",highlightPostTag:"",hitsPerPage:20,clickAnalytics:l},d)}]).catch((function(e){throw"RetryError"===e.name&&c("error"),e})).then((function(e){var r=e.results[0],c=r.hits,u=r.nbHits,d=Vt(c,(function(e){return Yt(e)}),f);i.context.searchSuggestions.length0&&(re(),V.current&&V.current.focus())}),[G,re]),r.useEffect((function(){function e(){if($.current){var e=.01*window.innerHeight;$.current.style.setProperty("--docsearch-vh","".concat(e,"px"))}}return e(),window.addEventListener("resize",e),function(){window.removeEventListener("resize",e)}}),[]),r.createElement("div",s({ref:U},ne({"aria-expanded":!0}),{className:["DocSearch","DocSearch-Container","stalled"===z.status&&"DocSearch-Container--Stalled","error"===z.status&&"DocSearch-Container--Errored"].filter(Boolean).join(" "),role:"button",tabIndex:0,onMouseDown:function(e){e.target===e.currentTarget&&h()}}),r.createElement("div",{className:"DocSearch-Modal",ref:$},r.createElement("header",{className:"DocSearch-SearchBar",ref:H},r.createElement(on,s({},ee,{state:z,autoFocus:0===G.length,inputRef:V,isFromSelection:Boolean(G)&&G===K,translations:D,onClose:h}))),r.createElement("div",{className:"DocSearch-Dropdown",ref:q},r.createElement(nn,s({},ee,{indexName:o,state:z,hitComponent:y,resultsFooterComponent:k,disableUserPersonalization:C,recentSearches:Y,favoriteSearches:Z,inputRef:V,translations:M,getMissingResultsUrl:I,onItemClick:function(e,t){J(e),X(e),Kt(t)||h()}}))),r.createElement("footer",{className:"DocSearch-Footer"},r.createElement(_t,{translations:R}))))}function Un(e){var t=e.isOpen,n=e.onOpen,o=e.onClose,a=e.onInput,i=e.searchButtonRef;r.useEffect((function(){function e(e){var r;(27===e.keyCode&&t||"k"===(null===(r=e.key)||void 0===r?void 0:r.toLowerCase())&&(e.metaKey||e.ctrlKey)||!function(e){var t=e.target,n=t.tagName;return t.isContentEditable||"INPUT"===n||"SELECT"===n||"TEXTAREA"===n}(e)&&"/"===e.key&&!t)&&(e.preventDefault(),t?o():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||n()),i&&i.current===document.activeElement&&a&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&a(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[t,n,o,a,i])}},8328:(e,t,n)=>{"use strict";n.d(t,{A:()=>f});n(6540);var r=n(3259),o=n.n(r),a=n(4054);const i={"0058b4c6":[()=>n.e(849).then(n.t.bind(n,6164,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-175.json",6164],"00d3276d":[()=>n.e(4235).then(n.bind(n,5091)),"@site/blog/2016-06-23-first-opensourceversary.md",5091],"00e87d9a":[()=>n.e(7207).then(n.bind(n,5771)),"@site/versioned_docs/version-1.2.0/01-analyzing-apps-or-projects.md",5771],"0346afaa":[()=>n.e(5277).then(n.bind(n,5394)),"@site/versioned_docs/version-1.1.0/man-infer-debug.md",5394],"041e4035":[()=>n.e(8045).then(n.bind(n,4364)),"@site/docs/checker-starvation.md",4364],"04f8d6af":[()=>n.e(7378).then(n.bind(n,5226)),"@site/versioned_docs/version-1.1.0/checker-liveness.md",5226],"06d8773d":[()=>n.e(1998).then(n.bind(n,158)),"@site/docs/checker-litho-required-props.md",158],"0774da3f":[()=>n.e(7211).then(n.bind(n,5509)),"@site/versioned_docs/version-1.2.0/checker-printf-args.md",5509],"0c0efcaa":[()=>n.e(6950).then(n.bind(n,6966)),"@site/versioned_docs/version-1.1.0/checker-litho-required-props.md",6966],"0c78c462":[()=>n.e(9420).then(n.bind(n,9119)),"@site/versioned_docs/version-1.2.0/04-internal-API.md",9119],"0fe8a02a":[()=>n.e(9366).then(n.bind(n,5276)),"@site/docs/versions.md",5276],"136023f9":[()=>n.e(7331).then(n.bind(n,9579)),"@site/docs/01-suppressions.md",9579],"16fe8a4c":[()=>n.e(6107).then(n.bind(n,4840)),"@site/docs/00-getting-started.md",4840],"1772b9c1":[()=>n.e(3699).then(n.bind(n,5197)),"@site/versioned_docs/version-1.2.0/checker-scope-leakage.md",5197],17896441:[()=>Promise.all([n.e(1869),n.e(3962),n.e(8401)]).then(n.bind(n,575)),"@theme/DocItem",575],"18328e9e":[()=>n.e(9088).then(n.bind(n,2830)),"@site/docs/checker-purity.md",2830],"184ad633":[()=>n.e(7773).then(n.bind(n,500)),"@site/versioned_docs/version-1.1.0/checker-dotnet-resource-leak.md",500],"1906a68b":[()=>n.e(9692).then(n.bind(n,3990)),"@site/docs/02-separation-logic-and-biabduction.md",3990],"1a4e3797":[()=>Promise.all([n.e(1869),n.e(2138)]).then(n.bind(n,4604)),"@theme/SearchPage",4604],"1c7a9c9f":[()=>n.e(9978).then(n.bind(n,2192)),"@site/docs/checker-annotation-reachability.md",2192],"1d8647da":[()=>n.e(5632).then(n.bind(n,5708)),"@site/versioned_docs/version-1.1.0/checker-quandary.md",5708],"1dbe42a7":[()=>n.e(8973).then(n.bind(n,6158)),"@site/docs/01-man-pages.md",6158],"1df9637e":[()=>n.e(7314).then(n.bind(n,8866)),"@site/docs/checker-cost.md",8866],"1ed7bad6":[()=>n.e(7343).then(n.bind(n,3907)),"@site/versioned_docs/version-1.2.0/checker-parameter-not-null-checked.md",3907],"1fdfdeaa":[()=>n.e(9023).then(n.bind(n,651)),"@site/docs/checker-biabduction.md",651],21614072:[()=>n.e(2032).then(n.bind(n,4308)),"@site/docs/man-infer-run.md",4308],"21a9d6ed":[()=>n.e(1279).then(n.bind(n,278)),"@site/docs/man-infer-help.md",278],"223037ba":[()=>n.e(9383).then(n.bind(n,1483)),"@site/docs/all-categories.md",1483],"25a5a20c":[()=>n.e(6096).then(n.bind(n,5342)),"@site/docs/checker-bufferoverrun.md",5342],"293e08e8":[()=>n.e(6231).then(n.bind(n,4677)),"@site/blog/2017-10-20-ocamlformat-released.md?truncated=true",4677],33776668:[()=>n.e(1533).then(n.bind(n,3936)),"@site/versioned_docs/version-1.1.0/checker-config-checks-between-markers.md",3936],"3423820d":[()=>n.e(741).then(n.bind(n,5139)),"@site/blog/2017-10-20-ocamlformat-released.md",5139],"34fbd09a":[()=>n.e(468).then(n.bind(n,1155)),"@site/versioned_docs/version-1.1.0/checker-biabduction.md",1155],"36994c47":[()=>n.e(9858).then(n.t.bind(n,5516,19)),"@generated/docusaurus-plugin-content-blog/default/__plugin.json",5516],"37d3b766":[()=>n.e(8283).then(n.bind(n,6525)),"@site/versioned_docs/version-1.2.0/all-issue-types.md",6525],"38f5dda4":[()=>n.e(6230).then(n.bind(n,4714)),"@site/versioned_docs/version-1.2.0/man-infer-capture.md",4714],"3a27b2d9":[()=>n.e(4215).then(n.bind(n,2496)),"@site/versioned_docs/version-1.2.0/checker-racerd.md",2496],"3a3b1bdb":[()=>n.e(6227).then(n.bind(n,3613)),"@site/versioned_docs/version-1.2.0/checker-siof.md",3613],"3c055f5e":[()=>n.e(659).then(n.bind(n,9891)),"@site/docs/man-infer-capture.md",9891],"3c653e3b":[()=>n.e(3157).then(n.bind(n,1638)),"@site/versioned_docs/version-1.1.0/01-man-pages.md",1638],"3c741b47":[()=>n.e(5386).then(n.bind(n,1180)),"@site/versioned_docs/version-1.1.0/man-infer.md",1180],"3d9729af":[()=>n.e(8680).then(n.bind(n,9970)),"@site/versioned_docs/version-1.1.0/checker-topl.md",9970],"3eac2097":[()=>n.e(7877).then(n.bind(n,818)),"@site/docs/checker-liveness.md",818],"3eb0a99f":[()=>n.e(1926).then(n.bind(n,9288)),"@site/blog/2016-08-30-curryon-rome-talk.md?truncated=true",9288],"3f2a1ecb":[()=>n.e(8822).then(n.bind(n,4948)),"@site/versioned_docs/version-1.1.0/checker-starvation.md",4948],"413f2abb":[()=>n.e(8886).then(n.bind(n,3950)),"@site/versioned_docs/version-1.1.0/02-separation-logic-and-biabduction.md",3950],"420497a2":[()=>n.e(5360).then(n.bind(n,8492)),"@site/versioned_docs/version-1.1.0/checker-linters.md",8492],"45d37095":[()=>n.e(7586).then(n.bind(n,6598)),"@site/versioned_docs/version-1.1.0/checker-bufferoverrun.md",6598],"491a3217":[()=>n.e(4883).then(n.bind(n,3236)),"@site/blog/2016-11-28-atscale16.md?truncated=true",3236],"4b970726":[()=>n.e(7318).then(n.bind(n,3069)),"@site/versioned_docs/version-1.2.0/man-infer-run.md",3069],"4c2546f9":[()=>n.e(3526).then(n.bind(n,8034)),"@site/docs/man-infer-explore.md",8034],"4cccfac9":[()=>n.e(457).then(n.bind(n,1447)),"@site/versioned_docs/version-1.2.0/man-infer-debug.md",1447],"4dac5fec":[()=>n.e(1822).then(n.bind(n,8164)),"@site/docs/man-infer.md",8164],"4f53e586":[()=>n.e(8301).then(n.bind(n,7632)),"@site/versioned_docs/version-1.2.0/01-infer-workflow.md",7632],"4fb08289":[()=>n.e(9820).then(n.bind(n,6641)),"@site/versioned_docs/version-1.2.0/checker-loop-hoisting.md",6641],"509dc7bf":[()=>n.e(6241).then(n.bind(n,7115)),"@site/versioned_docs/version-1.1.0/checker-config-impact-analysis.md",7115],"556d04db":[()=>n.e(9677).then(n.bind(n,1128)),"@site/docs/checker-scope-leakage.md",1128],"5573af76":[()=>n.e(5041).then(n.bind(n,1808)),"@site/versioned_docs/version-1.2.0/all-checkers.md",1808],"56ebd09a":[()=>n.e(777).then(n.bind(n,2873)),"@site/docs/00-hello-world.md",2873],"57bcddd6":[()=>n.e(100).then(n.bind(n,7721)),"@site/versioned_docs/version-1.1.0/checker-eradicate.md",7721],"57dd985e":[()=>n.e(6166).then(n.bind(n,9129)),"@site/versioned_docs/version-1.2.0/checker-fragment-retains-view.md",9129],"58972da3":[()=>n.e(530).then(n.bind(n,4083)),"@site/versioned_docs/version-1.2.0/checker-pulse.md",4083],"58de4400":[()=>n.e(6689).then(n.bind(n,2012)),"@site/blog/2015-05-22-Infer-on-open-source-android-apps.md?truncated=true",2012],"5a5dcc21":[()=>n.e(3967).then(n.bind(n,3490)),"@site/docs/04-absint-framework.md",3490],"5acb8db5":[()=>n.e(8405).then(n.bind(n,2659)),"@site/versioned_docs/version-1.2.0/checker-starvation.md",2659],"5aef2ce6":[()=>n.e(700).then(n.bind(n,762)),"@site/versioned_docs/version-1.2.0/01-steps-for-ci.md",762],"5bb07cf5":[()=>n.e(4261).then(n.bind(n,3498)),"@site/docs/checker-lineage.md",3498],"5c708541":[()=>n.e(9026).then(n.bind(n,6881)),"@site/versioned_docs/version-1.2.0/checker-topl.md",6881],"5e95c892":[()=>n.e(9647).then(n.bind(n,7121)),"@theme/DocsRoot",7121],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,4784)),"@generated/docusaurus.config",4784],"5f403532":[()=>n.e(7197).then(n.bind(n,6719)),"@site/docs/01-steps-for-ci.md",6719],"6021085e":[()=>n.e(3548).then(n.bind(n,9738)),"@site/docs/man-infer-debug.md",9738],"61eca9d6":[()=>n.e(492).then(n.t.bind(n,1604,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-1-1-0-aa4.json",1604],"6297ff83":[()=>n.e(1652).then(n.bind(n,2164)),"@site/docs/man-infer-compile.md",2164],"637f8365":[()=>n.e(7417).then(n.bind(n,7792)),"@site/versioned_docs/version-1.2.0/checker-sil-validation.md",7792],"64cca8ef":[()=>n.e(7709).then(n.bind(n,2642)),"@site/versioned_docs/version-1.1.0/support.md",2642],"64f1f19c":[()=>n.e(6629).then(n.bind(n,2054)),"@site/versioned_docs/version-1.1.0/01-analyzing-apps-or-projects.md",2054],"65dc7644":[()=>n.e(2740).then(n.bind(n,4065)),"@site/versioned_docs/version-1.2.0/man-infer-help.md",4065],"671939c9":[()=>n.e(4728).then(n.bind(n,426)),"@site/versioned_docs/version-1.1.0/02-about-infer.md",426],"6d752ef5":[()=>n.e(2509).then(n.bind(n,1962)),"@site/versioned_docs/version-1.1.0/checker-cost.md",1962],"70793eb2":[()=>n.e(3730).then(n.bind(n,6298)),"@site/docs/04-internal-API.md",6298],"71a2656f":[()=>n.e(881).then(n.bind(n,7401)),"@site/versioned_docs/version-1.1.0/man-infer-analyze.md",7401],"76c96f4d":[()=>n.e(3212).then(n.bind(n,691)),"@site/versioned_docs/version-1.2.0/man-infer-explore.md",691],79263788:[()=>n.e(4865).then(n.bind(n,3474)),"@site/versioned_docs/version-1.1.0/04-internal-API.md",3474],"7a64ca81":[()=>n.e(1932).then(n.bind(n,251)),"@site/versioned_docs/version-1.2.0/versions.md",251],"7b1f0035":[()=>n.e(485).then(n.bind(n,6818)),"@site/docs/02-about-infer.md",6818],"7b6b5c72":[()=>n.e(3487).then(n.bind(n,4160)),"@site/versioned_docs/version-1.2.0/man-infer-analyze.md",4160],"7dd0d394":[()=>n.e(7930).then(n.bind(n,5692)),"@site/versioned_docs/version-1.2.0/checker-datalog.md",5692],"7efbfa7e":[()=>n.e(5680).then(n.bind(n,9952)),"@site/docs/man-infer-reportdiff.md",9952],"7f18f0db":[()=>n.e(7323).then(n.bind(n,5364)),"@site/versioned_docs/version-1.2.0/support.md",5364],"7f661f82":[()=>n.e(411).then(n.bind(n,7668)),"@site/versioned_docs/version-1.1.0/01-steps-for-ci.md",7668],"812c592f":[()=>n.e(4721).then(n.bind(n,4389)),"@site/versioned_docs/version-1.2.0/checker-annotation-reachability.md",4389],"814f3328":[()=>n.e(7472).then(n.t.bind(n,5513,19)),"~blog/default/blog-post-list-prop-default.json",5513],"81cc3644":[()=>n.e(5543).then(n.bind(n,7712)),"@site/versioned_docs/version-1.2.0/checker-resource-leak-lab.md",7712],"884bd1d2":[()=>n.e(946).then(n.bind(n,3456)),"@site/versioned_docs/version-1.2.0/man-infer-report.md",3456],"8919ea97":[()=>n.e(1158).then(n.bind(n,9581)),"@site/versioned_docs/version-1.1.0/checker-pulse.md",9581],"89b1f439":[()=>n.e(1759).then(n.bind(n,7747)),"@site/versioned_docs/version-1.2.0/checker-lineage.md",7747],"8a061d83":[()=>n.e(2996).then(n.bind(n,9508)),"@site/versioned_docs/version-1.1.0/checker-printf-args.md",9508],"8a838ea0":[()=>n.e(2883).then(n.bind(n,6209)),"@site/versioned_docs/version-1.2.0/01-man-pages.md",6209],"8db808e7":[()=>n.e(9749).then(n.bind(n,2613)),"@site/versioned_docs/version-1.1.0/01-infer-workflow.md",2613],"8fb47bcc":[()=>n.e(4478).then(n.bind(n,9967)),"@site/versioned_docs/version-1.2.0/checker-quandary.md",9967],"8fdeae25":[()=>n.e(9437).then(n.bind(n,930)),"@site/docs/checker-pulse.md",930],"9258f162":[()=>n.e(3426).then(n.bind(n,3982)),"@site/versioned_docs/version-1.1.0/checker-uninit.md",3982],"937dc5a6":[()=>n.e(4515).then(n.bind(n,6728)),"@site/docs/checker-parameter-not-null-checked.md",6728],"9702a600":[()=>n.e(9640).then(n.bind(n,9506)),"@site/blog/2016-04-07-mobileatscale-london-talk.md?truncated=true",9506],"99c7964b":[()=>n.e(8984).then(n.bind(n,3574)),"@site/docs/checker-siof.md",3574],"9d221b96":[()=>n.e(1444).then(n.bind(n,6441)),"@site/versioned_docs/version-1.1.0/checker-self-in-block.md",6441],"9d4bdb35":[()=>n.e(2708).then(n.bind(n,5025)),"@site/versioned_docs/version-1.1.0/checker-resource-leak-lab.md",5025],"9e4087bc":[()=>n.e(2711).then(n.bind(n,9331)),"@theme/BlogArchivePage",9331],a02168a2:[()=>n.e(2968).then(n.bind(n,8430)),"@site/versioned_docs/version-1.1.0/man-infer-help.md",8430],a177ae00:[()=>n.e(9401).then(n.bind(n,5360)),"@site/versioned_docs/version-1.2.0/all-categories.md",5360],a2bed8f0:[()=>n.e(4631).then(n.bind(n,9329)),"@site/docs/man-infer-analyze.md",9329],a33b6a74:[()=>n.e(1734).then(n.bind(n,452)),"@site/docs/checker-fragment-retains-view.md",452],a373fd77:[()=>n.e(553).then(n.bind(n,4902)),"@site/docs/checker-inefficient-keyset-iterator.md",4902],a3e198d1:[()=>n.e(7283).then(n.bind(n,6167)),"@site/versioned_docs/version-1.2.0/checker-impurity.md",6167],a5a260f1:[()=>n.e(1989).then(n.bind(n,7582)),"@site/blog/2016-04-07-mobileatscale-london-talk.md",7582],a67edc69:[()=>n.e(3838).then(n.bind(n,7126)),"@site/versioned_docs/version-1.2.0/00-hello-world.md",7126],a6aa9e1f:[()=>Promise.all([n.e(1869),n.e(3962),n.e(6238),n.e(7643)]).then(n.bind(n,2052)),"@theme/BlogListPage",2052],a7456010:[()=>n.e(1235).then(n.t.bind(n,8552,19)),"@generated/docusaurus-plugin-content-pages/default/__plugin.json",8552],a7bd4aaa:[()=>n.e(7098).then(n.bind(n,4532)),"@theme/DocVersionRoot",4532],a94703ab:[()=>Promise.all([n.e(1869),n.e(9048)]).then(n.bind(n,1377)),"@theme/DocRoot",1377],aa0b35eb:[()=>n.e(1010).then(n.bind(n,7916)),"@site/blog/2016-08-30-curryon-rome-talk.md",7916],aaa764ed:[()=>n.e(8108).then(n.bind(n,1563)),"@site/versioned_docs/version-1.2.0/checker-bufferoverrun.md",1563],aaff9110:[()=>n.e(6408).then(n.bind(n,2456)),"@site/versioned_docs/version-1.1.0/man-infer-reportdiff.md",2456],ab17452f:[()=>n.e(7419).then(n.bind(n,9018)),"@site/versioned_docs/version-1.1.0/man-infer-explore.md",9018],aba21aa0:[()=>n.e(5742).then(n.t.bind(n,7093,19)),"@generated/docusaurus-plugin-content-docs/default/__plugin.json",7093],abc9d724:[()=>n.e(1599).then(n.bind(n,1851)),"@site/versioned_docs/version-1.1.0/man-infer-capture.md",1851],ac4b567d:[()=>n.e(293).then(n.bind(n,2752)),"@site/versioned_docs/version-1.2.0/checker-self-in-block.md",2752],acaf655c:[()=>n.e(613).then(n.bind(n,8931)),"@site/versioned_docs/version-1.1.0/00-getting-started.md",8931],acb2d06a:[()=>n.e(7972).then(n.bind(n,549)),"@site/blog/2016-06-23-first-opensourceversary.md?truncated=true",549],acecf23e:[()=>n.e(1903).then(n.t.bind(n,1912,19)),"~blog/default/blogMetadata-default.json",1912],ae565638:[()=>n.e(2380).then(n.bind(n,3656)),"@site/versioned_docs/version-1.1.0/checker-impurity.md",3656],ae894706:[()=>n.e(2365).then(n.bind(n,5439)),"@site/versioned_docs/version-1.2.0/man-infer-reportdiff.md",5439],b05ccea0:[()=>n.e(46).then(n.bind(n,9649)),"@site/versioned_docs/version-1.2.0/checker-liveness.md",9649],b065408b:[()=>n.e(7632).then(n.bind(n,1787)),"@site/versioned_docs/version-1.1.0/man-infer-report.md",1787],b388a56e:[()=>n.e(6555).then(n.bind(n,5888)),"@site/versioned_docs/version-1.2.0/checker-config-impact-analysis.md",5888],b4a56aa4:[()=>n.e(6499).then(n.bind(n,3127)),"@site/versioned_docs/version-1.2.0/02-separation-logic-and-biabduction.md",3127],b7bf8e49:[()=>n.e(9034).then(n.bind(n,1173)),"@site/versioned_docs/version-1.2.0/man-infer.md",1173],b9f8aa82:[()=>n.e(1610).then(n.bind(n,6115)),"@site/docs/man-infer-report.md",6115],bab022f4:[()=>n.e(7560).then(n.bind(n,7197)),"@site/docs/01-infer-workflow.md",7197],bbdc39ec:[()=>n.e(1068).then(n.bind(n,5339)),"@site/docs/checker-sil-validation.md",5339],bc20efef:[()=>n.e(7436).then(n.bind(n,7671)),"@site/versioned_docs/version-1.2.0/checker-inefficient-keyset-iterator.md",7671],bc3f1a98:[()=>n.e(8112).then(n.bind(n,4460)),"@site/versioned_docs/version-1.1.0/man-infer-compile.md",4460],bd470307:[()=>n.e(4638).then(n.bind(n,4961)),"@site/docs/checker-self-in-block.md",4961],be77d225:[()=>n.e(1463).then(n.bind(n,8045)),"@site/versioned_docs/version-1.1.0/04-absint-framework.md",8045],bf1307fc:[()=>n.e(9525).then(n.t.bind(n,1413,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-next-d71.json",1413],bf6aacca:[()=>n.e(2212).then(n.bind(n,3508)),"@site/versioned_docs/version-1.1.0/all-issue-types.md",3508],bf769997:[()=>n.e(5118).then(n.bind(n,3473)),"@site/versioned_docs/version-1.2.0/man-infer-compile.md",3473],c141421f:[()=>n.e(957).then(n.t.bind(n,936,19)),"@generated/docusaurus-theme-search-algolia/default/__plugin.json",936],c15d9823:[()=>n.e(8146).then(n.t.bind(n,9328,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-bd9.json",9328],c222a988:[()=>n.e(9390).then(n.bind(n,6585)),"@site/docs/checker-resource-leak-lab.md",6585],c26add1d:[()=>n.e(8684).then(n.bind(n,2140)),"@site/versioned_docs/version-1.1.0/checker-fragment-retains-view.md",2140],c359af60:[()=>n.e(2316).then(n.bind(n,28)),"@site/docs/all-issue-types.md",28],c412bf64:[()=>n.e(4765).then(n.bind(n,1518)),"@site/blog/2016-03-17-collaboration-with-spotify.md",1518],c4f5d8e4:[()=>Promise.all([n.e(1869),n.e(2634)]).then(n.bind(n,172)),"@site/src/pages/index.js",172],c8131338:[()=>n.e(1439).then(n.bind(n,4782)),"@site/docs/01-analyzing-apps-or-projects.md",4782],c8a5dae5:[()=>n.e(5075).then(n.bind(n,6926)),"@site/versioned_docs/version-1.1.0/checker-siof.md",6926],ca86781b:[()=>n.e(7017).then(n.bind(n,6459)),"@site/docs/all-checkers.md",6459],ccc49370:[()=>Promise.all([n.e(1869),n.e(3962),n.e(6238),n.e(3249)]).then(n.bind(n,3858)),"@theme/BlogPostPage",3858],cd3b4295:[()=>n.e(2057).then(n.bind(n,357)),"@site/versioned_docs/version-1.2.0/checker-litho-required-props.md",357],cd83de9e:[()=>n.e(7698).then(n.bind(n,8275)),"@site/versioned_docs/version-1.1.0/checker-loop-hoisting.md",8275],cf554d4e:[()=>n.e(9095).then(n.bind(n,6975)),"@site/versioned_docs/version-1.2.0/00-getting-started.md",6975],d1458f14:[()=>n.e(9262).then(n.bind(n,8599)),"@site/versioned_docs/version-1.2.0/04-absint-framework.md",8599],d47ba782:[()=>n.e(2938).then(n.bind(n,4352)),"@site/blog/2015-05-22-Infer-on-open-source-android-apps.md",4352],d9e16301:[()=>n.e(1416).then(n.bind(n,1562)),"@site/docs/support.md",1562],da41ed28:[()=>n.e(6146).then(n.bind(n,4004)),"@site/versioned_docs/version-1.1.0/versions.md",4004],df12ff2a:[()=>n.e(7803).then(n.bind(n,8704)),"@site/docs/checker-impurity.md",8704],e0f83a1d:[()=>n.e(4341).then(n.bind(n,1038)),"@site/versioned_docs/version-1.1.0/00-hello-world.md",1038],e305a15c:[()=>n.e(9676).then(n.bind(n,396)),"@site/versioned_docs/version-1.1.0/man-infer-run.md",396],e436f9fb:[()=>n.e(1236).then(n.bind(n,1723)),"@site/docs/checker-loop-hoisting.md",1723],e44e3f47:[()=>n.e(2385).then(n.bind(n,5534)),"@site/versioned_docs/version-1.1.0/checker-inefficient-keyset-iterator.md",5534],e66621bc:[()=>n.e(8500).then(n.bind(n,5592)),"@site/versioned_docs/version-1.1.0/checker-annotation-reachability.md",5592],e6b9ef91:[()=>n.e(4569).then(n.bind(n,3702)),"@site/versioned_docs/version-1.1.0/checker-purity.md",3702],e9325e77:[()=>n.e(4982).then(n.bind(n,8058)),"@site/docs/checker-topl.md",8058],eb0c92c1:[()=>n.e(3716).then(n.bind(n,2764)),"@site/versioned_docs/version-1.1.0/checker-racerd.md",2764],f22cd6c1:[()=>n.e(6112).then(n.bind(n,9193)),"@site/versioned_docs/version-1.2.0/checker-cost.md",9193],f28ca027:[()=>n.e(7758).then(n.bind(n,3758)),"@site/versioned_docs/version-1.2.0/02-about-infer.md",3758],f28f39ea:[()=>n.e(1847).then(n.bind(n,7297)),"@site/versioned_docs/version-1.2.0/checker-purity.md",7297],f5ff54f0:[()=>n.e(6237).then(n.bind(n,2946)),"@site/blog/2016-03-17-collaboration-with-spotify.md?truncated=true",2946],f769b3fd:[()=>n.e(7906).then(n.bind(n,9491)),"@site/docs/checker-config-impact-analysis.md",9491],f8092feb:[()=>n.e(517).then(n.bind(n,6751)),"@site/versioned_docs/version-1.1.0/checker-immutable-cast.md",6751],f81c1134:[()=>n.e(8130).then(n.t.bind(n,7735,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-archive-f05.json",7735],fa38ac94:[()=>n.e(6510).then(n.bind(n,1572)),"@site/docs/checker-racerd.md",1572],fa9ab54d:[()=>n.e(6929).then(n.bind(n,776)),"@site/blog/2016-11-28-atscale16.md",776],fd7416f6:[()=>n.e(5073).then(n.bind(n,4942)),"@site/versioned_docs/version-1.2.0/checker-biabduction.md",4942]};var s=n(4848);function c(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,s.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,s.jsx)("p",{children:String(t)}),(0,s.jsx)("div",{children:(0,s.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,s.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,s.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,s.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,s.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var l=n(6921),u=n(3102);function d(e,t){if("*"===e)return o()({loading:c,loader:()=>n.e(2237).then(n.bind(n,2237)),modules:["@theme/NotFound"],webpack:()=>[2237],render(e,t){const n=e.default;return(0,s.jsx)(u.W,{value:{plugin:{name:"native",id:"default"}},children:(0,s.jsx)(n,{...t})})}});const r=a[`${e}-${t}`],d={},f=[],p=[],h=(0,l.A)(r);return Object.entries(h).forEach((e=>{let[t,n]=e;const r=i[n];r&&(d[t]=r[0],f.push(r[1]),p.push(r[2]))})),o().Map({loading:c,loader:d,modules:f,webpack:()=>p,render(t,n){const o=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let i=o;const s=n.split(".");s.slice(0,-1).forEach((e=>{i=i[e]})),i[s[s.length-1]]=a}));const a=o.__comp;delete o.__comp;const i=o.__context;delete o.__context;const c=o.__props;return delete o.__props,(0,s.jsx)(u.W,{value:i,children:(0,s.jsx)(a,{...o,...c,...n})})}})}const f=[{path:"/blog",component:d("/blog","6d5"),exact:!0},{path:"/blog/2015/05/22/Infer-on-open-source-android-apps",component:d("/blog/2015/05/22/Infer-on-open-source-android-apps","b97"),exact:!0},{path:"/blog/2016/03/17/collaboration-with-spotify",component:d("/blog/2016/03/17/collaboration-with-spotify","a0f"),exact:!0},{path:"/blog/2016/04/07/mobileatscale-london-talk",component:d("/blog/2016/04/07/mobileatscale-london-talk","b49"),exact:!0},{path:"/blog/2016/06/23/first-opensourceversary",component:d("/blog/2016/06/23/first-opensourceversary","7d3"),exact:!0},{path:"/blog/2016/08/30/curryon-rome-talk",component:d("/blog/2016/08/30/curryon-rome-talk","888"),exact:!0},{path:"/blog/2016/11/28/atscale16",component:d("/blog/2016/11/28/atscale16","d6e"),exact:!0},{path:"/blog/2017/10/20/ocamlformat-released",component:d("/blog/2017/10/20/ocamlformat-released","d21"),exact:!0},{path:"/blog/archive",component:d("/blog/archive","182"),exact:!0},{path:"/search",component:d("/search","5de"),exact:!0},{path:"/docs",component:d("/docs","e9a"),routes:[{path:"/docs/1.1.0",component:d("/docs/1.1.0","c00"),routes:[{path:"/docs/1.1.0",component:d("/docs/1.1.0","802"),routes:[{path:"/docs/1.1.0/about-Infer",component:d("/docs/1.1.0/about-Infer","3dd"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/absint-framework",component:d("/docs/1.1.0/absint-framework","985"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/all-issue-types",component:d("/docs/1.1.0/all-issue-types","aee"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/analyzing-apps-or-projects",component:d("/docs/1.1.0/analyzing-apps-or-projects","383"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-annotation-reachability",component:d("/docs/1.1.0/checker-annotation-reachability","513"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-biabduction",component:d("/docs/1.1.0/checker-biabduction","1fa"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-bufferoverrun",component:d("/docs/1.1.0/checker-bufferoverrun","3dc"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-config-checks-between-markers",component:d("/docs/1.1.0/checker-config-checks-between-markers","b46"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-config-impact-analysis",component:d("/docs/1.1.0/checker-config-impact-analysis","f54"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-cost",component:d("/docs/1.1.0/checker-cost","fac"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-dotnet-resource-leak",component:d("/docs/1.1.0/checker-dotnet-resource-leak","367"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-eradicate",component:d("/docs/1.1.0/checker-eradicate","e3d"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-fragment-retains-view",component:d("/docs/1.1.0/checker-fragment-retains-view","70b"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-immutable-cast",component:d("/docs/1.1.0/checker-immutable-cast","9e3"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-impurity",component:d("/docs/1.1.0/checker-impurity","6b0"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-inefficient-keyset-iterator",component:d("/docs/1.1.0/checker-inefficient-keyset-iterator","e07"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-linters",component:d("/docs/1.1.0/checker-linters","ec4"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-litho-required-props",component:d("/docs/1.1.0/checker-litho-required-props","bce"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-liveness",component:d("/docs/1.1.0/checker-liveness","a0e"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-loop-hoisting",component:d("/docs/1.1.0/checker-loop-hoisting","b79"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-printf-args",component:d("/docs/1.1.0/checker-printf-args","1e3"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-pulse",component:d("/docs/1.1.0/checker-pulse","873"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-purity",component:d("/docs/1.1.0/checker-purity","7e2"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-quandary",component:d("/docs/1.1.0/checker-quandary","5fe"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-racerd",component:d("/docs/1.1.0/checker-racerd","cf8"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-resource-leak-lab",component:d("/docs/1.1.0/checker-resource-leak-lab","eb6"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-self-in-block",component:d("/docs/1.1.0/checker-self-in-block","235"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-siof",component:d("/docs/1.1.0/checker-siof","282"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-starvation",component:d("/docs/1.1.0/checker-starvation","44d"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-topl",component:d("/docs/1.1.0/checker-topl","32e"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/checker-uninit",component:d("/docs/1.1.0/checker-uninit","9e1"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/getting-started",component:d("/docs/1.1.0/getting-started","92b"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/hello-world",component:d("/docs/1.1.0/hello-world","d51"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/infer-workflow",component:d("/docs/1.1.0/infer-workflow","9e4"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/internal-API",component:d("/docs/1.1.0/internal-API","c7f"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/man-infer",component:d("/docs/1.1.0/man-infer","783"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/man-infer-analyze",component:d("/docs/1.1.0/man-infer-analyze","106"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/man-infer-capture",component:d("/docs/1.1.0/man-infer-capture","3cf"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/man-infer-compile",component:d("/docs/1.1.0/man-infer-compile","187"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/man-infer-debug",component:d("/docs/1.1.0/man-infer-debug","961"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/man-infer-explore",component:d("/docs/1.1.0/man-infer-explore","3cd"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/man-infer-help",component:d("/docs/1.1.0/man-infer-help","806"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/man-infer-report",component:d("/docs/1.1.0/man-infer-report","c9f"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/man-infer-reportdiff",component:d("/docs/1.1.0/man-infer-reportdiff","b5f"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/man-infer-run",component:d("/docs/1.1.0/man-infer-run","4e3"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/man-pages",component:d("/docs/1.1.0/man-pages","9c5"),exact:!0},{path:"/docs/1.1.0/separation-logic-and-bi-abduction",component:d("/docs/1.1.0/separation-logic-and-bi-abduction","af7"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/steps-for-ci",component:d("/docs/1.1.0/steps-for-ci","03b"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/support",component:d("/docs/1.1.0/support","24c"),exact:!0},{path:"/docs/1.1.0/versions",component:d("/docs/1.1.0/versions","08e"),exact:!0,sidebar:"docs"}]}]},{path:"/docs/next",component:d("/docs/next","fa5"),routes:[{path:"/docs/next",component:d("/docs/next","9fe"),routes:[{path:"/docs/next/about-Infer",component:d("/docs/next/about-Infer","63b"),exact:!0,sidebar:"docs"},{path:"/docs/next/absint-framework",component:d("/docs/next/absint-framework","7ef"),exact:!0,sidebar:"docs"},{path:"/docs/next/all-categories",component:d("/docs/next/all-categories","4e2"),exact:!0,sidebar:"docs"},{path:"/docs/next/all-checkers",component:d("/docs/next/all-checkers","feb"),exact:!0,sidebar:"docs"},{path:"/docs/next/all-issue-types",component:d("/docs/next/all-issue-types","968"),exact:!0,sidebar:"docs"},{path:"/docs/next/analyzing-apps-or-projects",component:d("/docs/next/analyzing-apps-or-projects","376"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-annotation-reachability",component:d("/docs/next/checker-annotation-reachability","c69"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-biabduction",component:d("/docs/next/checker-biabduction","efb"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-bufferoverrun",component:d("/docs/next/checker-bufferoverrun","46a"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-config-impact-analysis",component:d("/docs/next/checker-config-impact-analysis","ae0"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-cost",component:d("/docs/next/checker-cost","bb9"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-fragment-retains-view",component:d("/docs/next/checker-fragment-retains-view","f97"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-impurity",component:d("/docs/next/checker-impurity","bb9"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-inefficient-keyset-iterator",component:d("/docs/next/checker-inefficient-keyset-iterator","9ca"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-lineage",component:d("/docs/next/checker-lineage","905"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-litho-required-props",component:d("/docs/next/checker-litho-required-props","4ac"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-liveness",component:d("/docs/next/checker-liveness","84e"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-loop-hoisting",component:d("/docs/next/checker-loop-hoisting","3b1"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-parameter-not-null-checked",component:d("/docs/next/checker-parameter-not-null-checked","017"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-pulse",component:d("/docs/next/checker-pulse","de3"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-purity",component:d("/docs/next/checker-purity","ed9"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-racerd",component:d("/docs/next/checker-racerd","e1b"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-resource-leak-lab",component:d("/docs/next/checker-resource-leak-lab","cf2"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-scope-leakage",component:d("/docs/next/checker-scope-leakage","512"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-self-in-block",component:d("/docs/next/checker-self-in-block","7cb"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-sil-validation",component:d("/docs/next/checker-sil-validation","419"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-siof",component:d("/docs/next/checker-siof","b0d"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-starvation",component:d("/docs/next/checker-starvation","609"),exact:!0,sidebar:"docs"},{path:"/docs/next/checker-topl",component:d("/docs/next/checker-topl","49b"),exact:!0,sidebar:"docs"},{path:"/docs/next/getting-started",component:d("/docs/next/getting-started","377"),exact:!0,sidebar:"docs"},{path:"/docs/next/hello-world",component:d("/docs/next/hello-world","9d2"),exact:!0,sidebar:"docs"},{path:"/docs/next/infer-workflow",component:d("/docs/next/infer-workflow","868"),exact:!0,sidebar:"docs"},{path:"/docs/next/internal-API",component:d("/docs/next/internal-API","c2a"),exact:!0,sidebar:"docs"},{path:"/docs/next/man-infer",component:d("/docs/next/man-infer","434"),exact:!0,sidebar:"docs"},{path:"/docs/next/man-infer-analyze",component:d("/docs/next/man-infer-analyze","587"),exact:!0,sidebar:"docs"},{path:"/docs/next/man-infer-capture",component:d("/docs/next/man-infer-capture","aec"),exact:!0,sidebar:"docs"},{path:"/docs/next/man-infer-compile",component:d("/docs/next/man-infer-compile","a31"),exact:!0,sidebar:"docs"},{path:"/docs/next/man-infer-debug",component:d("/docs/next/man-infer-debug","dc0"),exact:!0,sidebar:"docs"},{path:"/docs/next/man-infer-explore",component:d("/docs/next/man-infer-explore","8bf"),exact:!0,sidebar:"docs"},{path:"/docs/next/man-infer-help",component:d("/docs/next/man-infer-help","d28"),exact:!0,sidebar:"docs"},{path:"/docs/next/man-infer-report",component:d("/docs/next/man-infer-report","360"),exact:!0,sidebar:"docs"},{path:"/docs/next/man-infer-reportdiff",component:d("/docs/next/man-infer-reportdiff","cb4"),exact:!0,sidebar:"docs"},{path:"/docs/next/man-infer-run",component:d("/docs/next/man-infer-run","e8d"),exact:!0,sidebar:"docs"},{path:"/docs/next/man-pages",component:d("/docs/next/man-pages","88e"),exact:!0},{path:"/docs/next/separation-logic-and-bi-abduction",component:d("/docs/next/separation-logic-and-bi-abduction","f7f"),exact:!0,sidebar:"docs"},{path:"/docs/next/steps-for-ci",component:d("/docs/next/steps-for-ci","6b9"),exact:!0,sidebar:"docs"},{path:"/docs/next/support",component:d("/docs/next/support","8f6"),exact:!0},{path:"/docs/next/suppressions",component:d("/docs/next/suppressions","ace"),exact:!0,sidebar:"docs"},{path:"/docs/next/versions",component:d("/docs/next/versions","61e"),exact:!0,sidebar:"docs"}]}]},{path:"/docs",component:d("/docs","dd3"),routes:[{path:"/docs",component:d("/docs","a55"),routes:[{path:"/docs/about-Infer",component:d("/docs/about-Infer","088"),exact:!0,sidebar:"docs"},{path:"/docs/absint-framework",component:d("/docs/absint-framework","9ac"),exact:!0,sidebar:"docs"},{path:"/docs/all-categories",component:d("/docs/all-categories","a33"),exact:!0,sidebar:"docs"},{path:"/docs/all-checkers",component:d("/docs/all-checkers","964"),exact:!0,sidebar:"docs"},{path:"/docs/all-issue-types",component:d("/docs/all-issue-types","197"),exact:!0,sidebar:"docs"},{path:"/docs/analyzing-apps-or-projects",component:d("/docs/analyzing-apps-or-projects","2f0"),exact:!0,sidebar:"docs"},{path:"/docs/checker-annotation-reachability",component:d("/docs/checker-annotation-reachability","046"),exact:!0,sidebar:"docs"},{path:"/docs/checker-biabduction",component:d("/docs/checker-biabduction","897"),exact:!0,sidebar:"docs"},{path:"/docs/checker-bufferoverrun",component:d("/docs/checker-bufferoverrun","734"),exact:!0,sidebar:"docs"},{path:"/docs/checker-config-impact-analysis",component:d("/docs/checker-config-impact-analysis","292"),exact:!0,sidebar:"docs"},{path:"/docs/checker-cost",component:d("/docs/checker-cost","74e"),exact:!0,sidebar:"docs"},{path:"/docs/checker-datalog",component:d("/docs/checker-datalog","a6c"),exact:!0,sidebar:"docs"},{path:"/docs/checker-fragment-retains-view",component:d("/docs/checker-fragment-retains-view","c02"),exact:!0,sidebar:"docs"},{path:"/docs/checker-impurity",component:d("/docs/checker-impurity","59a"),exact:!0,sidebar:"docs"},{path:"/docs/checker-inefficient-keyset-iterator",component:d("/docs/checker-inefficient-keyset-iterator","b07"),exact:!0,sidebar:"docs"},{path:"/docs/checker-lineage",component:d("/docs/checker-lineage","ae0"),exact:!0,sidebar:"docs"},{path:"/docs/checker-litho-required-props",component:d("/docs/checker-litho-required-props","d82"),exact:!0,sidebar:"docs"},{path:"/docs/checker-liveness",component:d("/docs/checker-liveness","efa"),exact:!0,sidebar:"docs"},{path:"/docs/checker-loop-hoisting",component:d("/docs/checker-loop-hoisting","9c0"),exact:!0,sidebar:"docs"},{path:"/docs/checker-parameter-not-null-checked",component:d("/docs/checker-parameter-not-null-checked","5a6"),exact:!0,sidebar:"docs"},{path:"/docs/checker-printf-args",component:d("/docs/checker-printf-args","fa4"),exact:!0,sidebar:"docs"},{path:"/docs/checker-pulse",component:d("/docs/checker-pulse","b5d"),exact:!0,sidebar:"docs"},{path:"/docs/checker-purity",component:d("/docs/checker-purity","0e8"),exact:!0,sidebar:"docs"},{path:"/docs/checker-quandary",component:d("/docs/checker-quandary","2ce"),exact:!0,sidebar:"docs"},{path:"/docs/checker-racerd",component:d("/docs/checker-racerd","dfb"),exact:!0,sidebar:"docs"},{path:"/docs/checker-resource-leak-lab",component:d("/docs/checker-resource-leak-lab","563"),exact:!0,sidebar:"docs"},{path:"/docs/checker-scope-leakage",component:d("/docs/checker-scope-leakage","71c"),exact:!0,sidebar:"docs"},{path:"/docs/checker-self-in-block",component:d("/docs/checker-self-in-block","d76"),exact:!0,sidebar:"docs"},{path:"/docs/checker-sil-validation",component:d("/docs/checker-sil-validation","3d1"),exact:!0,sidebar:"docs"},{path:"/docs/checker-siof",component:d("/docs/checker-siof","f04"),exact:!0,sidebar:"docs"},{path:"/docs/checker-starvation",component:d("/docs/checker-starvation","f69"),exact:!0,sidebar:"docs"},{path:"/docs/checker-topl",component:d("/docs/checker-topl","66c"),exact:!0,sidebar:"docs"},{path:"/docs/getting-started",component:d("/docs/getting-started","9af"),exact:!0,sidebar:"docs"},{path:"/docs/hello-world",component:d("/docs/hello-world","1ff"),exact:!0,sidebar:"docs"},{path:"/docs/infer-workflow",component:d("/docs/infer-workflow","e29"),exact:!0,sidebar:"docs"},{path:"/docs/internal-API",component:d("/docs/internal-API","35b"),exact:!0,sidebar:"docs"},{path:"/docs/man-infer",component:d("/docs/man-infer","ca9"),exact:!0,sidebar:"docs"},{path:"/docs/man-infer-analyze",component:d("/docs/man-infer-analyze","c5c"),exact:!0,sidebar:"docs"},{path:"/docs/man-infer-capture",component:d("/docs/man-infer-capture","9f1"),exact:!0,sidebar:"docs"},{path:"/docs/man-infer-compile",component:d("/docs/man-infer-compile","e7e"),exact:!0,sidebar:"docs"},{path:"/docs/man-infer-debug",component:d("/docs/man-infer-debug","ace"),exact:!0,sidebar:"docs"},{path:"/docs/man-infer-explore",component:d("/docs/man-infer-explore","5bf"),exact:!0,sidebar:"docs"},{path:"/docs/man-infer-help",component:d("/docs/man-infer-help","453"),exact:!0,sidebar:"docs"},{path:"/docs/man-infer-report",component:d("/docs/man-infer-report","1e8"),exact:!0,sidebar:"docs"},{path:"/docs/man-infer-reportdiff",component:d("/docs/man-infer-reportdiff","7e2"),exact:!0,sidebar:"docs"},{path:"/docs/man-infer-run",component:d("/docs/man-infer-run","070"),exact:!0,sidebar:"docs"},{path:"/docs/man-pages",component:d("/docs/man-pages","381"),exact:!0},{path:"/docs/separation-logic-and-bi-abduction",component:d("/docs/separation-logic-and-bi-abduction","681"),exact:!0,sidebar:"docs"},{path:"/docs/steps-for-ci",component:d("/docs/steps-for-ci","175"),exact:!0,sidebar:"docs"},{path:"/docs/support",component:d("/docs/support","fa7"),exact:!0},{path:"/docs/versions",component:d("/docs/versions","fde"),exact:!0,sidebar:"docs"}]}]}]},{path:"/",component:d("/","2e1"),exact:!0},{path:"*",component:d("*")}]},6125:(e,t,n)=>{"use strict";n.d(t,{o:()=>a,x:()=>i});var r=n(6540),o=n(4848);const a=r.createContext(!1);function i(e){let{children:t}=e;const[n,i]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{i(!0)}),[]),(0,o.jsx)(a.Provider,{value:n,children:t})}},8536:(e,t,n)=>{"use strict";var r=n(6540),o=n(5338),a=n(545),i=n(4625),s=n(4784),c=n(8193);const l=[n(1911),n(119),n(6134),n(6294),n(1043)];var u=n(8328),d=n(6347),f=n(2831),p=n(4848);function h(e){let{children:t}=e;return(0,p.jsx)(p.Fragment,{children:t})}var m=n(5260),g=n(4586),b=n(6025),y=n(6342),v=n(5500),k=n(2131),w=n(4090),x=n(2967),S=n(440),_=n(1463);function E(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,g.A)(),r=(0,k.o)(),o=n[e].htmlLang,a=e=>e.replace("-","_");return(0,p.jsxs)(m.A,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,p.jsx)("meta",{property:"og:locale",content:a(o)}),Object.values(n).filter((e=>o!==e.htmlLang)).map((e=>(0,p.jsx)("meta",{property:"og:locale:alternate",content:a(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function O(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,g.A)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,g.A)(),{pathname:r}=(0,d.zy)();return e+(0,S.Ks)((0,b.Ay)(r),{trailingSlash:n,baseUrl:t})}(),o=t?`${n}${t}`:r;return(0,p.jsxs)(m.A,{children:[(0,p.jsx)("meta",{property:"og:url",content:o}),(0,p.jsx)("link",{rel:"canonical",href:o})]})}function C(){const{i18n:{currentLocale:e}}=(0,g.A)(),{metadata:t,image:n}=(0,y.p)();return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsxs)(m.A,{children:[(0,p.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,p.jsx)("body",{className:w.w})]}),n&&(0,p.jsx)(v.be,{image:n}),(0,p.jsx)(O,{}),(0,p.jsx)(E,{}),(0,p.jsx)(_.A,{tag:x.C,locale:e}),(0,p.jsx)(m.A,{children:t.map(((e,t)=>(0,p.jsx)("meta",{...e},t)))})]})}const j=new Map;var A=n(6125),T=n(6988),P=n(205);function I(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>o.forEach((e=>e?.()))}const N=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,P.A)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,o=t.hash===n.hash,a=t.search===n.search;if(r&&o&&!a)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),I("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function L(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,f.u)(u.A,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class R extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=c.A.canUseDOM?I("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=I("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),L(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,p.jsx)(N,{previousLocation:this.previousLocation,location:t,children:(0,p.jsx)(d.qh,{location:t,render:()=>e})})}}const D=R,M="__docusaurus-base-url-issue-banner-suggestion-container";function F(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '__docusaurus-base-url-issue-banner-container';\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{let{route:t}=e;return!0===t.exact})))return j.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return j.set(e.pathname,t),{...e,pathname:t}}((0,d.zy)());return(0,p.jsx)(D,{location:e,children:V})}function K(){return(0,p.jsx)($.A,{children:(0,p.jsx)(T.l,{children:(0,p.jsxs)(A.x,{children:[(0,p.jsxs)(h,{children:[(0,p.jsx)(U,{}),(0,p.jsx)(C,{}),(0,p.jsx)(B,{}),(0,p.jsx)(W,{})]}),(0,p.jsx)(q,{})]})})})}var G=n(4054);const Q=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const o=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;o?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var Z=n(6921);const Y=new Set,X=new Set,J=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ee={prefetch:e=>{if(!(e=>!J()&&!X.has(e)&&!Y.has(e))(e))return!1;Y.add(e);const t=(0,f.u)(u.A,e).flatMap((e=>{return t=e.route.path,Object.entries(G).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,Z.A)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Q(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!J()&&!X.has(e))(e)&&(X.add(e),L(e))},te=Object.freeze(ee);function ne(e){let{children:t}=e;return"hash"===s.default.future.experimental_router?(0,p.jsx)(i.I9,{children:t}):(0,p.jsx)(i.Kd,{children:t})}const re=Boolean(!0);if(c.A.canUseDOM){window.docusaurus=te;const e=document.getElementById("__docusaurus"),t=(0,p.jsx)(a.vd,{children:(0,p.jsx)(ne,{children:(0,p.jsx)(K,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},i=()=>{if(window.docusaurusRoot)window.docusaurusRoot.render(t);else if(re)window.docusaurusRoot=o.hydrateRoot(e,t,{onRecoverableError:n});else{const r=o.createRoot(e,{onRecoverableError:n});r.render(t),window.docusaurusRoot=r}};L(window.location.pathname).then((()=>{(0,r.startTransition)(i)}))}},6988:(e,t,n)=>{"use strict";n.d(t,{o:()=>d,l:()=>f});var r=n(6540),o=n(4784);const a=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":false,"path":"/docs/next","mainDocId":"getting-started","docs":[{"id":"about-Infer","path":"/docs/next/about-Infer","sidebar":"docs"},{"id":"absint-framework","path":"/docs/next/absint-framework","sidebar":"docs"},{"id":"all-categories","path":"/docs/next/all-categories","sidebar":"docs"},{"id":"all-checkers","path":"/docs/next/all-checkers","sidebar":"docs"},{"id":"all-issue-types","path":"/docs/next/all-issue-types","sidebar":"docs"},{"id":"analyzing-apps-or-projects","path":"/docs/next/analyzing-apps-or-projects","sidebar":"docs"},{"id":"checker-annotation-reachability","path":"/docs/next/checker-annotation-reachability","sidebar":"docs"},{"id":"checker-biabduction","path":"/docs/next/checker-biabduction","sidebar":"docs"},{"id":"checker-bufferoverrun","path":"/docs/next/checker-bufferoverrun","sidebar":"docs"},{"id":"checker-config-impact-analysis","path":"/docs/next/checker-config-impact-analysis","sidebar":"docs"},{"id":"checker-cost","path":"/docs/next/checker-cost","sidebar":"docs"},{"id":"checker-fragment-retains-view","path":"/docs/next/checker-fragment-retains-view","sidebar":"docs"},{"id":"checker-impurity","path":"/docs/next/checker-impurity","sidebar":"docs"},{"id":"checker-inefficient-keyset-iterator","path":"/docs/next/checker-inefficient-keyset-iterator","sidebar":"docs"},{"id":"checker-lineage","path":"/docs/next/checker-lineage","sidebar":"docs"},{"id":"checker-litho-required-props","path":"/docs/next/checker-litho-required-props","sidebar":"docs"},{"id":"checker-liveness","path":"/docs/next/checker-liveness","sidebar":"docs"},{"id":"checker-loop-hoisting","path":"/docs/next/checker-loop-hoisting","sidebar":"docs"},{"id":"checker-parameter-not-null-checked","path":"/docs/next/checker-parameter-not-null-checked","sidebar":"docs"},{"id":"checker-pulse","path":"/docs/next/checker-pulse","sidebar":"docs"},{"id":"checker-purity","path":"/docs/next/checker-purity","sidebar":"docs"},{"id":"checker-racerd","path":"/docs/next/checker-racerd","sidebar":"docs"},{"id":"checker-resource-leak-lab","path":"/docs/next/checker-resource-leak-lab","sidebar":"docs"},{"id":"checker-scope-leakage","path":"/docs/next/checker-scope-leakage","sidebar":"docs"},{"id":"checker-self-in-block","path":"/docs/next/checker-self-in-block","sidebar":"docs"},{"id":"checker-sil-validation","path":"/docs/next/checker-sil-validation","sidebar":"docs"},{"id":"checker-siof","path":"/docs/next/checker-siof","sidebar":"docs"},{"id":"checker-starvation","path":"/docs/next/checker-starvation","sidebar":"docs"},{"id":"checker-topl","path":"/docs/next/checker-topl","sidebar":"docs"},{"id":"getting-started","path":"/docs/next/getting-started","sidebar":"docs"},{"id":"hello-world","path":"/docs/next/hello-world","sidebar":"docs"},{"id":"infer-workflow","path":"/docs/next/infer-workflow","sidebar":"docs"},{"id":"internal-API","path":"/docs/next/internal-API","sidebar":"docs"},{"id":"man-infer","path":"/docs/next/man-infer","sidebar":"docs"},{"id":"man-infer-analyze","path":"/docs/next/man-infer-analyze","sidebar":"docs"},{"id":"man-infer-capture","path":"/docs/next/man-infer-capture","sidebar":"docs"},{"id":"man-infer-compile","path":"/docs/next/man-infer-compile","sidebar":"docs"},{"id":"man-infer-debug","path":"/docs/next/man-infer-debug","sidebar":"docs"},{"id":"man-infer-explore","path":"/docs/next/man-infer-explore","sidebar":"docs"},{"id":"man-infer-help","path":"/docs/next/man-infer-help","sidebar":"docs"},{"id":"man-infer-report","path":"/docs/next/man-infer-report","sidebar":"docs"},{"id":"man-infer-reportdiff","path":"/docs/next/man-infer-reportdiff","sidebar":"docs"},{"id":"man-infer-run","path":"/docs/next/man-infer-run","sidebar":"docs"},{"id":"man-pages","path":"/docs/next/man-pages"},{"id":"separation-logic-and-bi-abduction","path":"/docs/next/separation-logic-and-bi-abduction","sidebar":"docs"},{"id":"steps-for-ci","path":"/docs/next/steps-for-ci","sidebar":"docs"},{"id":"support","path":"/docs/next/support"},{"id":"suppressions","path":"/docs/next/suppressions","sidebar":"docs"},{"id":"versions","path":"/docs/next/versions","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/next/getting-started","label":"getting-started"}}}},{"name":"1.2.0","label":"1.2.0","isLast":true,"path":"/docs","mainDocId":"getting-started","docs":[{"id":"about-Infer","path":"/docs/about-Infer","sidebar":"docs"},{"id":"absint-framework","path":"/docs/absint-framework","sidebar":"docs"},{"id":"all-categories","path":"/docs/all-categories","sidebar":"docs"},{"id":"all-checkers","path":"/docs/all-checkers","sidebar":"docs"},{"id":"all-issue-types","path":"/docs/all-issue-types","sidebar":"docs"},{"id":"analyzing-apps-or-projects","path":"/docs/analyzing-apps-or-projects","sidebar":"docs"},{"id":"checker-annotation-reachability","path":"/docs/checker-annotation-reachability","sidebar":"docs"},{"id":"checker-biabduction","path":"/docs/checker-biabduction","sidebar":"docs"},{"id":"checker-bufferoverrun","path":"/docs/checker-bufferoverrun","sidebar":"docs"},{"id":"checker-config-impact-analysis","path":"/docs/checker-config-impact-analysis","sidebar":"docs"},{"id":"checker-cost","path":"/docs/checker-cost","sidebar":"docs"},{"id":"checker-datalog","path":"/docs/checker-datalog","sidebar":"docs"},{"id":"checker-fragment-retains-view","path":"/docs/checker-fragment-retains-view","sidebar":"docs"},{"id":"checker-impurity","path":"/docs/checker-impurity","sidebar":"docs"},{"id":"checker-inefficient-keyset-iterator","path":"/docs/checker-inefficient-keyset-iterator","sidebar":"docs"},{"id":"checker-lineage","path":"/docs/checker-lineage","sidebar":"docs"},{"id":"checker-litho-required-props","path":"/docs/checker-litho-required-props","sidebar":"docs"},{"id":"checker-liveness","path":"/docs/checker-liveness","sidebar":"docs"},{"id":"checker-loop-hoisting","path":"/docs/checker-loop-hoisting","sidebar":"docs"},{"id":"checker-parameter-not-null-checked","path":"/docs/checker-parameter-not-null-checked","sidebar":"docs"},{"id":"checker-printf-args","path":"/docs/checker-printf-args","sidebar":"docs"},{"id":"checker-pulse","path":"/docs/checker-pulse","sidebar":"docs"},{"id":"checker-purity","path":"/docs/checker-purity","sidebar":"docs"},{"id":"checker-quandary","path":"/docs/checker-quandary","sidebar":"docs"},{"id":"checker-racerd","path":"/docs/checker-racerd","sidebar":"docs"},{"id":"checker-resource-leak-lab","path":"/docs/checker-resource-leak-lab","sidebar":"docs"},{"id":"checker-scope-leakage","path":"/docs/checker-scope-leakage","sidebar":"docs"},{"id":"checker-self-in-block","path":"/docs/checker-self-in-block","sidebar":"docs"},{"id":"checker-sil-validation","path":"/docs/checker-sil-validation","sidebar":"docs"},{"id":"checker-siof","path":"/docs/checker-siof","sidebar":"docs"},{"id":"checker-starvation","path":"/docs/checker-starvation","sidebar":"docs"},{"id":"checker-topl","path":"/docs/checker-topl","sidebar":"docs"},{"id":"getting-started","path":"/docs/getting-started","sidebar":"docs"},{"id":"hello-world","path":"/docs/hello-world","sidebar":"docs"},{"id":"infer-workflow","path":"/docs/infer-workflow","sidebar":"docs"},{"id":"internal-API","path":"/docs/internal-API","sidebar":"docs"},{"id":"man-infer","path":"/docs/man-infer","sidebar":"docs"},{"id":"man-infer-analyze","path":"/docs/man-infer-analyze","sidebar":"docs"},{"id":"man-infer-capture","path":"/docs/man-infer-capture","sidebar":"docs"},{"id":"man-infer-compile","path":"/docs/man-infer-compile","sidebar":"docs"},{"id":"man-infer-debug","path":"/docs/man-infer-debug","sidebar":"docs"},{"id":"man-infer-explore","path":"/docs/man-infer-explore","sidebar":"docs"},{"id":"man-infer-help","path":"/docs/man-infer-help","sidebar":"docs"},{"id":"man-infer-report","path":"/docs/man-infer-report","sidebar":"docs"},{"id":"man-infer-reportdiff","path":"/docs/man-infer-reportdiff","sidebar":"docs"},{"id":"man-infer-run","path":"/docs/man-infer-run","sidebar":"docs"},{"id":"man-pages","path":"/docs/man-pages"},{"id":"separation-logic-and-bi-abduction","path":"/docs/separation-logic-and-bi-abduction","sidebar":"docs"},{"id":"steps-for-ci","path":"/docs/steps-for-ci","sidebar":"docs"},{"id":"support","path":"/docs/support"},{"id":"versions","path":"/docs/versions","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/getting-started","label":"getting-started"}}}},{"name":"1.1.0","label":"1.1.0","isLast":false,"path":"/docs/1.1.0","mainDocId":"getting-started","docs":[{"id":"about-Infer","path":"/docs/1.1.0/about-Infer","sidebar":"docs"},{"id":"absint-framework","path":"/docs/1.1.0/absint-framework","sidebar":"docs"},{"id":"all-issue-types","path":"/docs/1.1.0/all-issue-types","sidebar":"docs"},{"id":"analyzing-apps-or-projects","path":"/docs/1.1.0/analyzing-apps-or-projects","sidebar":"docs"},{"id":"checker-annotation-reachability","path":"/docs/1.1.0/checker-annotation-reachability","sidebar":"docs"},{"id":"checker-biabduction","path":"/docs/1.1.0/checker-biabduction","sidebar":"docs"},{"id":"checker-bufferoverrun","path":"/docs/1.1.0/checker-bufferoverrun","sidebar":"docs"},{"id":"checker-config-checks-between-markers","path":"/docs/1.1.0/checker-config-checks-between-markers","sidebar":"docs"},{"id":"checker-config-impact-analysis","path":"/docs/1.1.0/checker-config-impact-analysis","sidebar":"docs"},{"id":"checker-cost","path":"/docs/1.1.0/checker-cost","sidebar":"docs"},{"id":"checker-dotnet-resource-leak","path":"/docs/1.1.0/checker-dotnet-resource-leak","sidebar":"docs"},{"id":"checker-eradicate","path":"/docs/1.1.0/checker-eradicate","sidebar":"docs"},{"id":"checker-fragment-retains-view","path":"/docs/1.1.0/checker-fragment-retains-view","sidebar":"docs"},{"id":"checker-immutable-cast","path":"/docs/1.1.0/checker-immutable-cast","sidebar":"docs"},{"id":"checker-impurity","path":"/docs/1.1.0/checker-impurity","sidebar":"docs"},{"id":"checker-inefficient-keyset-iterator","path":"/docs/1.1.0/checker-inefficient-keyset-iterator","sidebar":"docs"},{"id":"checker-linters","path":"/docs/1.1.0/checker-linters","sidebar":"docs"},{"id":"checker-litho-required-props","path":"/docs/1.1.0/checker-litho-required-props","sidebar":"docs"},{"id":"checker-liveness","path":"/docs/1.1.0/checker-liveness","sidebar":"docs"},{"id":"checker-loop-hoisting","path":"/docs/1.1.0/checker-loop-hoisting","sidebar":"docs"},{"id":"checker-printf-args","path":"/docs/1.1.0/checker-printf-args","sidebar":"docs"},{"id":"checker-pulse","path":"/docs/1.1.0/checker-pulse","sidebar":"docs"},{"id":"checker-purity","path":"/docs/1.1.0/checker-purity","sidebar":"docs"},{"id":"checker-quandary","path":"/docs/1.1.0/checker-quandary","sidebar":"docs"},{"id":"checker-racerd","path":"/docs/1.1.0/checker-racerd","sidebar":"docs"},{"id":"checker-resource-leak-lab","path":"/docs/1.1.0/checker-resource-leak-lab","sidebar":"docs"},{"id":"checker-self-in-block","path":"/docs/1.1.0/checker-self-in-block","sidebar":"docs"},{"id":"checker-siof","path":"/docs/1.1.0/checker-siof","sidebar":"docs"},{"id":"checker-starvation","path":"/docs/1.1.0/checker-starvation","sidebar":"docs"},{"id":"checker-topl","path":"/docs/1.1.0/checker-topl","sidebar":"docs"},{"id":"checker-uninit","path":"/docs/1.1.0/checker-uninit","sidebar":"docs"},{"id":"getting-started","path":"/docs/1.1.0/getting-started","sidebar":"docs"},{"id":"hello-world","path":"/docs/1.1.0/hello-world","sidebar":"docs"},{"id":"infer-workflow","path":"/docs/1.1.0/infer-workflow","sidebar":"docs"},{"id":"internal-API","path":"/docs/1.1.0/internal-API","sidebar":"docs"},{"id":"man-infer","path":"/docs/1.1.0/man-infer","sidebar":"docs"},{"id":"man-infer-analyze","path":"/docs/1.1.0/man-infer-analyze","sidebar":"docs"},{"id":"man-infer-capture","path":"/docs/1.1.0/man-infer-capture","sidebar":"docs"},{"id":"man-infer-compile","path":"/docs/1.1.0/man-infer-compile","sidebar":"docs"},{"id":"man-infer-debug","path":"/docs/1.1.0/man-infer-debug","sidebar":"docs"},{"id":"man-infer-explore","path":"/docs/1.1.0/man-infer-explore","sidebar":"docs"},{"id":"man-infer-help","path":"/docs/1.1.0/man-infer-help","sidebar":"docs"},{"id":"man-infer-report","path":"/docs/1.1.0/man-infer-report","sidebar":"docs"},{"id":"man-infer-reportdiff","path":"/docs/1.1.0/man-infer-reportdiff","sidebar":"docs"},{"id":"man-infer-run","path":"/docs/1.1.0/man-infer-run","sidebar":"docs"},{"id":"man-pages","path":"/docs/1.1.0/man-pages"},{"id":"separation-logic-and-bi-abduction","path":"/docs/1.1.0/separation-logic-and-bi-abduction","sidebar":"docs"},{"id":"steps-for-ci","path":"/docs/1.1.0/steps-for-ci","sidebar":"docs"},{"id":"support","path":"/docs/1.1.0/support"},{"id":"versions","path":"/docs/1.1.0/versions","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/1.1.0/getting-started","label":"getting-started"}}}}],"breadcrumbs":true}},"docusaurus-plugin-google-gtag":{"default":{"trackingID":["G-6T8Z3855RZ"],"anonymizeIP":true,"id":"default"}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var s=n(2654);const c=JSON.parse('{"docusaurusVersion":"3.5.2","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.5.2"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.5.2"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.5.2"},"docusaurus-plugin-google-gtag":{"type":"package","name":"@docusaurus/plugin-google-gtag","version":"3.5.2"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.5.2"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.5.2"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"3.5.2"}}}');var l=n(4848);const u={siteConfig:o.default,siteMetadata:c,globalData:a,i18n:i,codeTranslations:s},d=r.createContext(u);function f(e){let{children:t}=e;return(0,l.jsx)(d.Provider,{value:u,children:t})}},7489:(e,t,n)=>{"use strict";n.d(t,{A:()=>m});var r=n(6540),o=n(8193),a=n(5260),i=n(440),s=n(1957),c=n(3102),l=n(4848);function u(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,l.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,l.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,l.jsx)(d,{error:t})]})}function d(e){let{error:t}=e;const n=(0,i.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,l.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function f(e){let{children:t}=e;return(0,l.jsx)(c.W,{value:{plugin:{name:"docusaurus-core-error-boundary",id:"default"}},children:t})}function p(e){let{error:t,tryAgain:n}=e;return(0,l.jsx)(f,{children:(0,l.jsxs)(m,{fallback:()=>(0,l.jsx)(u,{error:t,tryAgain:n}),children:[(0,l.jsx)(a.A,{children:(0,l.jsx)("title",{children:"Page Error"})}),(0,l.jsx)(s.A,{children:(0,l.jsx)(u,{error:t,tryAgain:n})})]})})}const h=e=>(0,l.jsx)(p,{...e});class m extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.A.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??h)(e)}return e??null}}},8193:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,o={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5260:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});n(6540);var r=n(545),o=n(4848);function a(e){return(0,o.jsx)(r.mg,{...e})}},8774:(e,t,n)=>{"use strict";n.d(t,{A:()=>p});var r=n(6540),o=n(4625),a=n(440),i=n(4586),s=n(6654),c=n(8193),l=n(3427),u=n(6025),d=n(4848);function f(e,t){let{isNavLink:n,to:f,href:p,activeClassName:h,isActive:m,"data-noBrokenLinkCheck":g,autoAddBaseUrl:b=!0,...y}=e;const{siteConfig:v}=(0,i.A)(),{trailingSlash:k,baseUrl:w}=v,x=v.future.experimental_router,{withBaseUrl:S}=(0,u.hH)(),_=(0,l.A)(),E=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>E.current));const O=f||p;const C=(0,s.A)(O),j=O?.replace("pathname://","");let A=void 0!==j?(T=j,b&&(e=>e.startsWith("/"))(T)?S(T):T):void 0;var T;"hash"===x&&A?.startsWith("./")&&(A=A?.slice(1)),A&&C&&(A=(0,a.Ks)(A,{trailingSlash:k,baseUrl:w}));const P=(0,r.useRef)(!1),I=n?o.k2:o.N_,N=c.A.canUseIntersectionObserver,L=(0,r.useRef)(),R=()=>{P.current||null==A||(window.docusaurus.preload(A),P.current=!0)};(0,r.useEffect)((()=>(!N&&C&&c.A.canUseDOM&&null!=A&&window.docusaurus.prefetch(A),()=>{N&&L.current&&L.current.disconnect()})),[L,A,N,C]);const D=A?.startsWith("#")??!1,M=!y.target||"_self"===y.target,F=!A||!C||!M||D&&"hash"!==x;g||!D&&F||_.collectLink(A),y.id&&_.collectAnchor(y.id);const z={};return F?(0,d.jsx)("a",{ref:E,href:A,...O&&!C&&{target:"_blank",rel:"noopener noreferrer"},...y,...z}):(0,d.jsx)(I,{...y,onMouseEnter:R,onTouchStart:R,innerRef:e=>{E.current=e,N&&e&&C&&(L.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(L.current.unobserve(e),L.current.disconnect(),null!=A&&window.docusaurus.prefetch(A))}))})),L.current.observe(e))},to:A,...n&&{isActive:m,activeClassName:h},...z})}const p=r.forwardRef(f)},1312:(e,t,n)=>{"use strict";n.d(t,{A:()=>l,T:()=>c});var r=n(6540),o=n(4848);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var i=n(2654);function s(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[t??n]??n??t}function c(e,t){let{message:n,id:r}=e;return a(s({message:n,id:r}),t)}function l(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const i=s({message:t,id:n});return(0,o.jsx)(o.Fragment,{children:a(i,r)})}},7065:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});const r="default"},6654:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!r(e)}n.d(t,{A:()=>o,z:()=>r})},6025:(e,t,n)=>{"use strict";n.d(t,{Ay:()=>s,hH:()=>i});var r=n(6540),o=n(4586),a=n(6654);function i(){const{siteConfig:e}=(0,o.A)(),{baseUrl:t,url:n}=e,i=e.future.experimental_router,s=(0,r.useCallback)(((e,r)=>function(e){let{siteUrl:t,baseUrl:n,url:r,options:{forcePrependBaseUrl:o=!1,absolute:i=!1}={},router:s}=e;if(!r||r.startsWith("#")||(0,a.z)(r))return r;if("hash"===s)return r.startsWith("/")?`.${r}`:`./${r}`;if(o)return n+r.replace(/^\//,"");if(r===n.replace(/\/$/,""))return n;const c=r.startsWith(n)?r:n+r.replace(/^\//,"");return i?t+c:c}({siteUrl:n,baseUrl:t,url:e,options:r,router:i})),[n,t,i]);return{withBaseUrl:s}}function s(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},3427:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});var r=n(6540);n(4848);const o=r.createContext({collectAnchor:()=>{},collectLink:()=>{}}),a=()=>(0,r.useContext)(o);function i(){return a()}},4586:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(6540),o=n(6988);function a(){return(0,r.useContext)(o.o)}},2303:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(6540),o=n(6125);function a(){return(0,r.useContext)(o.o)}},205:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540);const o=n(8193).A.canUseDOM?r.useLayoutEffect:r.useEffect},6803:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(6540),o=n(3102);function a(){const e=r.useContext(o.o);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}},6921:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function o(e){const t={};return function e(n,o){Object.entries(n).forEach((n=>{let[a,i]=n;const s=o?`${o}.${a}`:a;r(i)?e(i,s):t[s]=i}))}(e),t}},3102:(e,t,n)=>{"use strict";n.d(t,{W:()=>i,o:()=>a});var r=n(6540),o=n(4848);const a=r.createContext(null);function i(e){let{children:t,value:n}=e;const i=r.useContext(a),s=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:i,value:n})),[i,n]);return(0,o.jsx)(a.Provider,{value:s,children:t})}},3886:(e,t,n)=>{"use strict";n.d(t,{VQ:()=>g,XK:()=>v,g1:()=>y});var r=n(6540),o=n(4070),a=n(7065),i=n(6342),s=n(679),c=n(9532),l=n(4848);const u=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,s.Wf)(u(e),{persistence:t}).set(n)},read:(e,t)=>(0,s.Wf)(u(e),{persistence:t}).get(),clear:(e,t)=>{(0,s.Wf)(u(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const p=r.createContext(null);function h(){const e=(0,o.Gy)(),t=(0,i.p)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[a,s]=(0,r.useState)((()=>f(n)));(0,r.useEffect)((()=>{s(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function o(e){const t=d.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(d.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,o(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[a,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d.save(e,t,n),s((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function m(e){let{children:t}=e;const n=h();return(0,l.jsx)(p.Provider,{value:n,children:t})}function g(e){let{children:t}=e;return(0,l.jsx)(m,{children:t})}function b(){const e=(0,r.useContext)(p);if(!e)throw new c.dV("DocsPreferredVersionContextProvider");return e}function y(e){void 0===e&&(e=a.W);const t=(0,o.ht)(e),[n,i]=b(),{preferredVersionName:s}=n[e];return{preferredVersion:t.versions.find((e=>e.name===s))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}function v(){const e=(0,o.Gy)(),[t]=b();function n(n){const r=e[n],{preferredVersionName:o}=t[n];return r.versions.find((e=>e.name===o))??null}const r=Object.keys(e);return Object.fromEntries(r.map((e=>[e,n(e)])))}},2565:(e,t,n)=>{"use strict";n.d(t,{k:()=>a,v:()=>i});var r=n(4070),o=n(3886);function a(e,t){return`docs-${e}-${t}`}function i(){const e=(0,r.Gy)(),t=(0,r.gk)(),n=(0,o.XK)();return[...Object.keys(e).map((function(r){const o=t?.activePlugin.pluginId===r?t.activeVersion:void 0,i=n[r],s=e[r].versions.find((e=>e.isLast));return a(r,(o??i??s).name)}))]}},609:(e,t,n)=>{"use strict";n.d(t,{V:()=>c,t:()=>l});var r=n(6540),o=n(9532),a=n(4848);const i=Symbol("EmptyContext"),s=r.createContext(i);function c(e){let{children:t,name:n,items:o}=e;const i=(0,r.useMemo)((()=>n&&o?{name:n,items:o}:null),[n,o]);return(0,a.jsx)(s.Provider,{value:i,children:t})}function l(){const e=(0,r.useContext)(s);if(e===i)throw new o.dV("DocsSidebarProvider");return e}},6972:(e,t,n)=>{"use strict";n.d(t,{B5:()=>S,Nr:()=>f,OF:()=>v,QB:()=>x,Vd:()=>k,Y:()=>b,fW:()=>w,w8:()=>m});var r=n(6540),o=n(6347),a=n(2831),i=n(4070),s=n(9169),c=n(1682),l=n(3886),u=n(3025),d=n(609);function f(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=f(t);if(e)return e}}(e):void 0:e.href}const p=(e,t)=>void 0!==e&&(0,s.ys)(e,t),h=(e,t)=>e.some((e=>m(e,t)));function m(e,t){return"link"===e.type?p(e.href,t):"category"===e.type&&(p(e.href,t)||h(e.items,t))}function g(e,t){switch(e.type){case"category":return m(e,t)||e.items.some((e=>g(e,t)));case"link":return!e.unlisted||m(e,t);default:return!0}}function b(e,t){return(0,r.useMemo)((()=>e.filter((e=>g(e,t)))),[e,t])}function y(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const o=[];return function e(t){for(const a of t)if("category"===a.type&&((0,s.ys)(a.href,n)||e(a.items))||"link"===a.type&&(0,s.ys)(a.href,n)){return r&&"category"!==a.type||o.unshift(a),!0}return!1}(t),o}function v(){const e=(0,d.t)(),{pathname:t}=(0,o.zy)(),n=(0,i.vT)()?.pluginData.breadcrumbs;return!1!==n&&e?y({sidebarItems:e.items,pathname:t}):null}function k(e){const{activeVersion:t}=(0,i.zK)(e),{preferredVersion:n}=(0,l.g1)(e),o=(0,i.r7)(e);return(0,r.useMemo)((()=>(0,c.sb)([t,n,o].filter(Boolean))),[t,n,o])}function w(e,t){const n=k(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function x(e,t){const n=k(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,c.sb)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function S(e){let{route:t}=e;const n=(0,o.zy)(),r=(0,u.r)(),i=t.routes,s=i.find((e=>(0,o.B6)(n.pathname,e)));if(!s)return null;const c=s.sidebar,l=c?r.docsSidebars[c]:void 0;return{docElement:(0,a.v)(i),sidebarName:c,sidebarItems:l}}},3025:(e,t,n)=>{"use strict";n.d(t,{n:()=>s,r:()=>c});var r=n(6540),o=n(9532),a=n(4848);const i=r.createContext(null);function s(e){let{children:t,version:n}=e;return(0,a.jsx)(i.Provider,{value:n,children:t})}function c(){const e=(0,r.useContext)(i);if(null===e)throw new o.dV("DocsVersionProvider");return e}},4070:(e,t,n)=>{"use strict";n.d(t,{zK:()=>b,vT:()=>p,gk:()=>h,Gy:()=>d,HW:()=>y,ht:()=>f,r7:()=>g,jh:()=>m});var r=n(6347),o=n(4586),a=n(7065);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,o.A)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const s=e=>e.versions.find((e=>e.isLast));function c(e,t){return[...e.versions].sort(((e,t)=>e.path===t.path?0:e.path.includes(t.path)?-1:t.path.includes(e.path)?1:0)).find((e=>!!(0,r.B6)(t,{path:e.path,exact:!1,strict:!1})))}function l(e,t){const n=c(e,t),o=n?.docs.find((e=>!!(0,r.B6)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:o,alternateDocVersions:o?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(o.id):{}}}const u={},d=()=>i("docusaurus-plugin-content-docs")??u,f=e=>{try{return function(e,t,n){void 0===t&&(t=a.W),void 0===n&&(n={});const r=i(e),o=r?.[t];if(!o&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return o}("docusaurus-plugin-content-docs",e,{failfast:!0})}catch(t){throw new Error("You are using a feature of the Docusaurus docs plugin, but this plugin does not seem to be enabled"+("Default"===e?"":` (pluginId=${e}`),{cause:t})}};function p(e){void 0===e&&(e={});const t=d(),{pathname:n}=(0,r.zy)();return function(e,t,n){void 0===n&&(n={});const o=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.B6)(t,{path:n.path,exact:!1,strict:!1})})),a=o?{pluginId:o[0],pluginData:o[1]}:void 0;if(!a&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return a}(t,n,e)}function h(e){void 0===e&&(e={});const t=p(e),{pathname:n}=(0,r.zy)();if(!t)return;return{activePlugin:t,activeVersion:c(t.pluginData,n)}}function m(e){return f(e).versions}function g(e){const t=f(e);return s(t)}function b(e){const t=f(e),{pathname:n}=(0,r.zy)();return l(t,n)}function y(e){const t=f(e),{pathname:n}=(0,r.zy)();return function(e,t){const n=s(e);return{latestDocSuggestion:l(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},1911:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={onRouteDidUpdate(e){let{location:t,previousLocation:n}=e;!n||t.pathname===n.pathname&&t.search===n.search&&t.hash===n.hash||setTimeout((()=>{window.gtag("set","page_path",t.pathname+t.search+t.hash),window.gtag("event","page_view")}))}}},6294:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(5947),o=n.n(r);o().configure({showSpinner:!1});const a={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{o().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){o().done()}}},6134:(e,t,n)=>{"use strict";var r=n(1765),o=n(4784);!function(e){const{themeConfig:{prism:t}}=o.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(9700),n(1900)(`./prism-${e}`)})),delete globalThis.Prism}(r.My)},1107:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});n(6540);var r=n(4164),o=n(1312),a=n(6342),i=n(8774),s=n(3427);const c={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var l=n(4848);function u(e){let{as:t,id:n,...u}=e;const d=(0,s.A)(),{navbar:{hideOnScroll:f}}=(0,a.p)();if("h1"===t||!n)return(0,l.jsx)(t,{...u,id:void 0});d.collectAnchor(n);const p=(0,o.T)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return(0,l.jsxs)(t,{...u,className:(0,r.A)("anchor",f?c.anchorWithHideOnScrollNavbar:c.anchorWithStickyNavbar,u.className),id:n,children:[u.children,(0,l.jsx)(i.A,{className:"hash-link",to:`#${n}`,"aria-label":p,title:p,children:"\u200b"})]})}},3186:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});n(6540);const r={iconExternalLink:"iconExternalLink_nPIU"};var o=n(4848);function a(e){let{width:t=13.5,height:n=13.5}=e;return(0,o.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink,children:(0,o.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},1957:(e,t,n)=>{"use strict";n.d(t,{A:()=>Ot});var r=n(6540),o=n(4164),a=n(7489),i=n(5500),s=n(6347),c=n(1312),l=n(5062),u=n(4848);const d="__docusaurus_skipToContent_fallback";function f(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function p(){const e=(0,r.useRef)(null),{action:t}=(0,s.W6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&f(t)}),[]);return(0,l.$)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&f(e.current)})),{containerRef:e,onClick:n}}const h=(0,c.T)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function m(e){const t=e.children??h,{containerRef:n,onClick:r}=p();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":h,children:(0,u.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var g=n(7559),b=n(4090);const y={skipToContent:"skipToContent_fXgn"};function v(){return(0,u.jsx)(m,{className:y.skipToContent})}var k=n(6342),w=n(5041);function x(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:o=1.2,className:a,...i}=e;return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...i,children:(0,u.jsx)("g",{stroke:r,strokeWidth:o,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const S={closeButton:"closeButton_CVFx"};function _(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,c.T)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,o.A)("clean-btn close",S.closeButton,e.className),children:(0,u.jsx)(x,{width:14,height:14,strokeWidth:3.1})})}const E={content:"content_knG7"};function O(e){const{announcementBar:t}=(0,k.p)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,o.A)(E.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const C={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function j(){const{announcementBar:e}=(0,k.p)(),{isActive:t,close:n}=(0,w.M)();if(!t)return null;const{backgroundColor:r,textColor:o,isCloseable:a}=e;return(0,u.jsxs)("div",{className:C.announcementBar,style:{backgroundColor:r,color:o},role:"banner",children:[a&&(0,u.jsx)("div",{className:C.announcementBarPlaceholder}),(0,u.jsx)(O,{className:C.announcementBarContent}),a&&(0,u.jsx)(_,{onClick:n,className:C.announcementBarClose})]})}var A=n(2069),T=n(3104);var P=n(9532),I=n(5600);const N=r.createContext(null);function L(e){let{children:t}=e;const n=function(){const e=(0,A.M)(),t=(0,I.YL)(),[n,o]=(0,r.useState)(!1),a=null!==t.component,i=(0,P.ZC)(a);return(0,r.useEffect)((()=>{a&&!i&&o(!0)}),[a,i]),(0,r.useEffect)((()=>{a?e.shown||o(!0):o(!1)}),[e.shown,a]),(0,r.useMemo)((()=>[n,o]),[n])}();return(0,u.jsx)(N.Provider,{value:n,children:t})}function R(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function D(){const e=(0,r.useContext)(N);if(!e)throw new P.dV("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,o=(0,r.useCallback)((()=>n(!1)),[n]),a=(0,I.YL)();return(0,r.useMemo)((()=>({shown:t,hide:o,content:R(a)})),[o,a,t])}function M(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:a}=D();return(0,u.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,u.jsxs)("div",{className:(0,o.A)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":a}),children:[(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var F=n(5293),z=n(2303);function B(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function U(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const $={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function H(e){let{className:t,buttonClassName:n,value:r,onChange:a}=e;const i=(0,z.A)(),s=(0,c.T)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,c.T)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,c.T)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,u.jsx)("div",{className:(0,o.A)($.toggle,t),children:(0,u.jsxs)("button",{className:(0,o.A)("clean-btn",$.toggleButton,!i&&$.toggleButtonDisabled,n),type:"button",onClick:()=>a("dark"===r?"light":"dark"),disabled:!i,title:s,"aria-label":s,"aria-live":"polite",children:[(0,u.jsx)(B,{className:(0,o.A)($.toggleIcon,$.lightToggleIcon)}),(0,u.jsx)(U,{className:(0,o.A)($.toggleIcon,$.darkToggleIcon)})]})})}const q=r.memo(H),V={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function W(e){let{className:t}=e;const n=(0,k.p)().navbar.style,r=(0,k.p)().colorMode.disableSwitch,{colorMode:o,setColorMode:a}=(0,F.G)();return r?null:(0,u.jsx)(q,{className:t,buttonClassName:"dark"===n?V.darkNavbarColorModeToggle:void 0,value:o,onChange:a})}var K=n(3465);function G(){return(0,u.jsx)(K.A,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function Q(){const e=(0,A.M)();return(0,u.jsx)("button",{type:"button","aria-label":(0,c.T)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(x,{color:"var(--ifm-color-emphasis-600)"})})}function Z(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(G,{}),(0,u.jsx)(W,{className:"margin-right--md"}),(0,u.jsx)(Q,{})]})}var Y=n(8774),X=n(6025),J=n(6654),ee=n(1252),te=n(3186);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:o,label:a,html:i,isDropdownLink:s,prependBaseUrlToHref:c,...l}=e;const d=(0,X.Ay)(r),f=(0,X.Ay)(t),p=(0,X.Ay)(o,{forcePrependBaseUrl:!0}),h=a&&o&&!(0,J.A)(o),m=i?{dangerouslySetInnerHTML:{__html:i}}:{children:(0,u.jsxs)(u.Fragment,{children:[a,h&&(0,u.jsx)(te.A,{...s&&{width:12,height:12}})]})};return o?(0,u.jsx)(Y.A,{href:c?p:o,...l,...m}):(0,u.jsx)(Y.A,{to:d,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?(0,ee.G)(n,t.pathname):t.pathname.startsWith(f)},...l,...m})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const a=(0,u.jsx)(ne,{className:(0,o.A)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,u.jsx)("li",{children:a}):a}function oe(e){let{className:t,isDropdownItem:n,...r}=e;return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(ne,{className:(0,o.A)("menu__link",t),...r})})}function ae(e){let{mobile:t=!1,position:n,...r}=e;const o=t?oe:re;return(0,u.jsx)(o,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ie=n(1422),se=n(9169),ce=n(4586);const le="dropdownNavbarItemMobile_S0Fm";function ue(e,t){return e.some((e=>function(e,t){return!!(0,se.ys)(e.to,t)||!!(0,ee.G)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function de(e){let{items:t,position:n,className:a,onClick:i,...s}=e;const c=(0,r.useRef)(null),[l,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{c.current&&!c.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[c]),(0,u.jsxs)("div",{ref:c,className:(0,o.A)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":l}),children:[(0,u.jsx)(ne,{"aria-haspopup":"true","aria-expanded":l,role:"button",href:s.to?void 0:"#",className:(0,o.A)("navbar__link",a),...s,onClick:s.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!l))},children:s.children??s.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(Fe,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function fe(e){let{items:t,className:n,position:a,onClick:i,...c}=e;const l=function(){const{siteConfig:{baseUrl:e}}=(0,ce.A)(),{pathname:t}=(0,s.zy)();return t.replace(e,"/")}(),d=ue(t,l),{collapsed:f,toggleCollapsed:p,setCollapsed:h}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&h(!d)}),[l,d,h]),(0,u.jsxs)("li",{className:(0,o.A)("menu__list-item",{"menu__list-item--collapsed":f}),children:[(0,u.jsx)(ne,{role:"button",className:(0,o.A)(le,"menu__link menu__link--sublist menu__link--sublist-caret",n),...c,onClick:e=>{e.preventDefault(),p()},children:c.children??c.label}),(0,u.jsx)(ie.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:f,children:t.map(((e,t)=>(0,r.createElement)(Fe,{mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active",...e,key:t})))})]})}function pe(e){let{mobile:t=!1,...n}=e;const r=t?fe:de;return(0,u.jsx)(r,{...n})}var he=n(2131);function me(e){let{width:t=20,height:n=20,...r}=e;return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const ge="iconLanguage_nlXk";var be=n(961),ye=n(3219),ve=n(5260),ke=n(4255),we=n(1062),xe=n(2967),Se=n(2565);function _e(){return[`language:${(0,ce.A)().i18n.currentLocale}`,function(){const e=(0,Se.v)();return[xe.C,...e]}().map((e=>`docusaurus_tag:${e}`))]}const Ee={button:{buttonText:(0,c.T)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),buttonAriaLabel:(0,c.T)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"})},modal:{searchBox:{resetButtonTitle:(0,c.T)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),resetButtonAriaLabel:(0,c.T)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),cancelButtonText:(0,c.T)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"}),cancelButtonAriaLabel:(0,c.T)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"})},startScreen:{recentSearchesTitle:(0,c.T)({id:"theme.SearchModal.startScreen.recentSearchesTitle",message:"Recent",description:"The title for recent searches"}),noRecentSearchesText:(0,c.T)({id:"theme.SearchModal.startScreen.noRecentSearchesText",message:"No recent searches",description:"The text when no recent searches"}),saveRecentSearchButtonTitle:(0,c.T)({id:"theme.SearchModal.startScreen.saveRecentSearchButtonTitle",message:"Save this search",description:"The label for save recent search button"}),removeRecentSearchButtonTitle:(0,c.T)({id:"theme.SearchModal.startScreen.removeRecentSearchButtonTitle",message:"Remove this search from history",description:"The label for remove recent search button"}),favoriteSearchesTitle:(0,c.T)({id:"theme.SearchModal.startScreen.favoriteSearchesTitle",message:"Favorite",description:"The title for favorite searches"}),removeFavoriteSearchButtonTitle:(0,c.T)({id:"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle",message:"Remove this search from favorites",description:"The label for remove favorite search button"})},errorScreen:{titleText:(0,c.T)({id:"theme.SearchModal.errorScreen.titleText",message:"Unable to fetch results",description:"The title for error screen of search modal"}),helpText:(0,c.T)({id:"theme.SearchModal.errorScreen.helpText",message:"You might want to check your network connection.",description:"The help text for error screen of search modal"})},footer:{selectText:(0,c.T)({id:"theme.SearchModal.footer.selectText",message:"to select",description:"The explanatory text of the action for the enter key"}),selectKeyAriaLabel:(0,c.T)({id:"theme.SearchModal.footer.selectKeyAriaLabel",message:"Enter key",description:"The ARIA label for the Enter key button that makes the selection"}),navigateText:(0,c.T)({id:"theme.SearchModal.footer.navigateText",message:"to navigate",description:"The explanatory text of the action for the Arrow up and Arrow down key"}),navigateUpKeyAriaLabel:(0,c.T)({id:"theme.SearchModal.footer.navigateUpKeyAriaLabel",message:"Arrow up",description:"The ARIA label for the Arrow up key button that makes the navigation"}),navigateDownKeyAriaLabel:(0,c.T)({id:"theme.SearchModal.footer.navigateDownKeyAriaLabel",message:"Arrow down",description:"The ARIA label for the Arrow down key button that makes the navigation"}),closeText:(0,c.T)({id:"theme.SearchModal.footer.closeText",message:"to close",description:"The explanatory text of the action for Escape key"}),closeKeyAriaLabel:(0,c.T)({id:"theme.SearchModal.footer.closeKeyAriaLabel",message:"Escape key",description:"The ARIA label for the Escape key button that close the modal"}),searchByText:(0,c.T)({id:"theme.SearchModal.footer.searchByText",message:"Search by",description:"The text explain that the search is making by Algolia"})},noResultsScreen:{noResultsText:(0,c.T)({id:"theme.SearchModal.noResultsScreen.noResultsText",message:"No results for",description:"The text explains that there are no results for the following search"}),suggestedQueryText:(0,c.T)({id:"theme.SearchModal.noResultsScreen.suggestedQueryText",message:"Try searching for",description:"The text for the suggested query when no results are found for the following search"}),reportMissingResultsText:(0,c.T)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsText",message:"Believe this query should return results?",description:"The text for the question where the user thinks there are missing results"}),reportMissingResultsLinkText:(0,c.T)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText",message:"Let us know.",description:"The text for the link to report missing results"})}},placeholder:(0,c.T)({id:"theme.SearchModal.placeholder",message:"Search docs",description:"The placeholder of the input of the DocSearch pop-up modal"})};let Oe=null;function Ce(e){let{hit:t,children:n}=e;return(0,u.jsx)(Y.A,{to:t.url,children:n})}function je(e){let{state:t,onClose:n}=e;const r=(0,ke.w)();return(0,u.jsx)(Y.A,{to:r(t.query),onClick:n,children:(0,u.jsx)(c.A,{id:"theme.SearchBar.seeAll",values:{count:t.context.nbHits},children:"See all {count} results"})})}function Ae(e){let{contextualSearch:t,externalUrlRegex:o,...a}=e;const{siteMetadata:i}=(0,ce.A)(),c=(0,we.C)(),l=_e(),d=a.searchParameters?.facetFilters??[],f=t?function(e,t){const n=e=>"string"==typeof e?[e]:e;return[...n(e),...n(t)]}(l,d):d,p={...a.searchParameters,facetFilters:f},h=(0,s.W6)(),m=(0,r.useRef)(null),g=(0,r.useRef)(null),[b,y]=(0,r.useState)(!1),[v,k]=(0,r.useState)(void 0),w=(0,r.useCallback)((()=>Oe?Promise.resolve():Promise.all([n.e(8158).then(n.bind(n,8158)),Promise.all([n.e(1869),n.e(8913)]).then(n.bind(n,8913)),Promise.all([n.e(1869),n.e(416)]).then(n.bind(n,416))]).then((e=>{let[{DocSearchModal:t}]=e;Oe=t}))),[]),x=(0,r.useCallback)((()=>{if(!m.current){const e=document.createElement("div");m.current=e,document.body.insertBefore(e,document.body.firstChild)}}),[]),S=(0,r.useCallback)((()=>{x(),w().then((()=>y(!0)))}),[w,x]),_=(0,r.useCallback)((()=>{y(!1),g.current?.focus()}),[]),E=(0,r.useCallback)((e=>{"f"===e.key&&(e.metaKey||e.ctrlKey)||(e.preventDefault(),k(e.key),S())}),[S]),O=(0,r.useRef)({navigate(e){let{itemUrl:t}=e;(0,ee.G)(o,t)?window.location.href=t:h.push(t)}}).current,C=(0,r.useRef)((e=>a.transformItems?a.transformItems(e):e.map((e=>({...e,url:c(e.url)}))))).current,j=(0,r.useMemo)((()=>e=>(0,u.jsx)(je,{...e,onClose:_})),[_]),A=(0,r.useCallback)((e=>(e.addAlgoliaAgent("docusaurus",i.docusaurusVersion),e)),[i.docusaurusVersion]);return(0,ye.E8)({isOpen:b,onOpen:S,onClose:_,onInput:E,searchButtonRef:g}),(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(ve.A,{children:(0,u.jsx)("link",{rel:"preconnect",href:`https://${a.appId}-dsn.algolia.net`,crossOrigin:"anonymous"})}),(0,u.jsx)(ye.Bc,{onTouchStart:w,onFocus:w,onMouseOver:w,onClick:S,ref:g,translations:Ee.button}),b&&Oe&&m.current&&(0,be.createPortal)((0,u.jsx)(Oe,{onClose:_,initialScrollY:window.scrollY,initialQuery:v,navigator:O,transformItems:C,hitComponent:Ce,transformSearchClient:A,...a.searchPagePath&&{resultsFooterComponent:j},...a,searchParameters:p,placeholder:Ee.placeholder,translations:Ee.modal}),m.current)]})}function Te(){const{siteConfig:e}=(0,ce.A)();return(0,u.jsx)(Ae,{...e.themeConfig.algolia})}const Pe={navbarSearchContainer:"navbarSearchContainer_Bca1"};function Ie(e){let{children:t,className:n}=e;return(0,u.jsx)("div",{className:(0,o.A)(n,Pe.navbarSearchContainer),children:t})}var Ne=n(4070),Le=n(6972);var Re=n(3886);function De(e,t){return t.alternateDocVersions[e.name]??function(e){return e.docs.find((t=>t.id===e.mainDocId))}(e)}const Me={default:ae,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:o="",...a}=e;const{i18n:{currentLocale:i,locales:l,localeConfigs:d}}=(0,ce.A)(),f=(0,he.o)(),{search:p,hash:h}=(0,s.zy)(),m=[...n,...l.map((e=>{const n=`${`pathname://${f.createUrl({locale:e,fullyQualified:!1})}`}${p}${h}${o}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...r],g=t?(0,c.T)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return(0,u.jsx)(pe,{...a,mobile:t,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(me,{className:ge}),g]}),items:m})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,u.jsx)(Ie,{className:n,children:(0,u.jsx)(Te,{})})},dropdown:pe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:a=!1}=e;const i=a?"li":"div";return(0,u.jsx)(i,{className:(0,o.A)({navbar__item:!r&&!a,"menu__list-item":r},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:a}=(0,Ne.zK)(r),i=(0,Le.QB)(t,r),s=a?.path===i?.path;return null===i||i.unlisted&&!s?null:(0,u.jsx)(ae,{exact:!0,...o,isActive:()=>s||!!a?.sidebar&&a.sidebar===i.sidebar,label:n??i.id,to:i.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:a}=(0,Ne.zK)(r),i=(0,Le.fW)(t,r).link;if(!i)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,u.jsx)(ae,{exact:!0,...o,isActive:()=>a?.sidebar===t,label:n??i.label,to:i.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...o}=e;const a=(0,Le.Vd)(r)[0],i=t??a.label,s=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(a).path;return(0,u.jsx)(ae,{...o,label:i,to:s})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:o,dropdownItemsAfter:a,...i}=e;const{search:l,hash:d}=(0,s.zy)(),f=(0,Ne.zK)(n),p=(0,Ne.jh)(n),{savePreferredVersionName:h}=(0,Re.g1)(n),m=[...o,...p.map((function(e){const t=De(e,f);return{label:e.label,to:`${t.path}${l}${d}`,isActive:()=>e===f.activeVersion,onClick:()=>h(e.name)}})),...a],g=(0,Le.Vd)(n)[0],b=t&&m.length>1?(0,c.T)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):g.label,y=t&&m.length>1?void 0:De(g,f).path;return m.length<=1?(0,u.jsx)(ae,{...i,mobile:t,label:b,to:y,isActive:r?()=>!1:void 0}):(0,u.jsx)(pe,{...i,mobile:t,label:b,to:y,items:m,isActive:r?()=>!1:void 0})}};function Fe(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Me[r];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,u.jsx)(o,{...n})}function ze(){const e=(0,A.M)(),t=(0,k.p)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(Fe,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Be(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(c.A,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function Ue(){const e=0===(0,k.p)().navbar.items.length,t=D();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(Be,{onClick:()=>t.hide()}),t.content]})}function $e(){const e=(0,A.M)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,u.jsx)(M,{header:(0,u.jsx)(Z,{}),primaryMenu:(0,u.jsx)(ze,{}),secondaryMenu:(0,u.jsx)(Ue,{})}):null}const He={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function qe(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,o.A)("navbar-sidebar__backdrop",e.className)})}function Ve(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:a}}=(0,k.p)(),i=(0,A.M)(),{navbarRef:s,isNavbarVisible:d}=function(e){const[t,n]=(0,r.useState)(e),o=(0,r.useRef)(!1),a=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(a.current=e.getBoundingClientRect().height)}),[]);return(0,T.Mq)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=s?n(!1):i+l{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return o.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:s,"aria-label":(0,c.T)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,o.A)("navbar","navbar--fixed-top",n&&[He.navbarHideable,!d&&He.navbarHidden],{"navbar--dark":"dark"===a,"navbar--primary":"primary"===a,"navbar-sidebar--show":i.shown}),children:[t,(0,u.jsx)(qe,{onClick:i.toggle}),(0,u.jsx)($e,{})]})}var We=n(440);const Ke={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};function Ge(e){return(0,u.jsx)("button",{type:"button",...e,children:(0,u.jsx)(c.A,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function Qe(e){let{error:t}=e;const n=(0,We.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,u.jsx)("p",{className:Ke.errorBoundaryError,children:n})}class Ze extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const Ye="right";function Xe(e){let{width:t=30,height:n=30,className:r,...o}=e;return(0,u.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...o,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function Je(){const{toggle:e,shown:t}=(0,A.M)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,c.T)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(Xe,{})})}const et={colorModeToggle:"colorModeToggle_DEke"};function tt(e){let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(Ze,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(Fe,{...e})},t)))})}function nt(e){let{left:t,right:n}=e;return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:"navbar__items",children:t}),(0,u.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function rt(){const e=(0,A.M)(),t=(0,k.p)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??Ye)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return(0,u.jsx)(nt,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(Je,{}),(0,u.jsx)(G,{}),(0,u.jsx)(tt,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(tt,{items:r}),(0,u.jsx)(W,{className:et.colorModeToggle}),!o&&(0,u.jsx)(Ie,{children:(0,u.jsx)(Te,{})})]})})}function ot(){return(0,u.jsx)(Ve,{children:(0,u.jsx)(rt,{})})}function at(e){let{item:t}=e;const{to:n,href:r,label:o,prependBaseUrlToHref:a,...i}=t,s=(0,X.Ay)(n),c=(0,X.Ay)(r,{forcePrependBaseUrl:!0});return(0,u.jsxs)(Y.A,{className:"footer__link-item",...r?{href:a?c:r}:{to:s},...i,children:[o,r&&!(0,J.A)(r)&&(0,u.jsx)(te.A,{})]})}function it(e){let{item:t}=e;return t.html?(0,u.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(at,{item:t})},t.href??t.to)}function st(e){let{column:t}=e;return(0,u.jsxs)("div",{className:"col footer__col",children:[(0,u.jsx)("div",{className:"footer__title",children:t.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,u.jsx)(it,{item:e},t)))})]})}function ct(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(st,{column:e},t)))})}function lt(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function ut(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(at,{item:t})}function dt(e){let{links:t}=e;return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,u.jsxs)(r.Fragment,{children:[(0,u.jsx)(ut,{item:e}),t.length!==n+1&&(0,u.jsx)(lt,{})]},n)))})})}function ft(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(ct,{columns:t}):(0,u.jsx)(dt,{links:t})}var pt=n(1122);const ht="footerLogoLink_BH7S";function mt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.hH)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,u.jsx)(pt.A,{className:(0,o.A)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function gt(e){let{logo:t}=e;return t.href?(0,u.jsx)(Y.A,{href:t.href,className:ht,target:t.target,children:(0,u.jsx)(mt,{logo:t})}):(0,u.jsx)(mt,{logo:t})}function bt(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function yt(e){let{style:t,links:n,logo:r,copyright:a}=e;return(0,u.jsx)("footer",{className:(0,o.A)("footer",{"footer--dark":"dark"===t}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[n,(r||a)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:r}),a]})]})})}function vt(){const{footer:e}=(0,k.p)();if(!e)return null;const{copyright:t,links:n,logo:r,style:o}=e;return(0,u.jsx)(yt,{style:o,links:n&&n.length>0&&(0,u.jsx)(ft,{links:n}),logo:r&&(0,u.jsx)(gt,{logo:r}),copyright:t&&(0,u.jsx)(bt,{copyright:t})})}const kt=r.memo(vt),wt=(0,P.fM)([F.a,w.o,T.Tv,Re.VQ,i.Jx,function(e){let{children:t}=e;return(0,u.jsx)(I.y_,{children:(0,u.jsx)(A.e,{children:(0,u.jsx)(L,{children:t})})})}]);function xt(e){let{children:t}=e;return(0,u.jsx)(wt,{children:t})}var St=n(1107);function _t(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(St.A,{as:"h1",className:"hero__title",children:(0,u.jsx)(c.A,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(Ge,{onClick:n,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(Qe,{error:t})})]})})})}const Et={mainWrapper:"mainWrapper_z2l0"};function Ot(e){const{children:t,noFooter:n,wrapperClassName:r,title:s,description:c}=e;return(0,b.J)(),(0,u.jsxs)(xt,{children:[(0,u.jsx)(i.be,{title:s,description:c}),(0,u.jsx)(v,{}),(0,u.jsx)(j,{}),(0,u.jsx)(ot,{}),(0,u.jsx)("div",{id:d,className:(0,o.A)(g.G.wrapper.main,Et.mainWrapper,r),children:(0,u.jsx)(a.A,{fallback:e=>(0,u.jsx)(_t,{...e}),children:t})}),!n&&(0,u.jsx)(kt,{})]})}},3465:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});n(6540);var r=n(8774),o=n(6025),a=n(4586),i=n(6342),s=n(1122),c=n(4848);function l(e){let{logo:t,alt:n,imageClassName:r}=e;const a={light:(0,o.Ay)(t.src),dark:(0,o.Ay)(t.srcDark||t.src)},i=(0,c.jsx)(s.A,{className:t.className,sources:a,height:t.height,width:t.width,alt:n,style:t.style});return r?(0,c.jsx)("div",{className:r,children:i}):i}function u(e){const{siteConfig:{title:t}}=(0,a.A)(),{navbar:{title:n,logo:s}}=(0,i.p)(),{imageClassName:u,titleClassName:d,...f}=e,p=(0,o.Ay)(s?.href||"/"),h=n?"":t,m=s?.alt??h;return(0,c.jsxs)(r.A,{to:p,...f,...s?.target&&{target:s.target},children:[s&&(0,c.jsx)(l,{logo:s,alt:m,imageClassName:u}),null!=n&&(0,c.jsx)("b",{className:d,children:n})]})}},1463:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});n(6540);var r=n(5260),o=n(4848);function a(e){let{locale:t,version:n,tag:a}=e;const i=t;return(0,o.jsxs)(r.A,{children:[t&&(0,o.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,o.jsx)("meta",{name:"docusaurus_version",content:n}),a&&(0,o.jsx)("meta",{name:"docusaurus_tag",content:a}),i&&(0,o.jsx)("meta",{name:"docsearch:language",content:i}),n&&(0,o.jsx)("meta",{name:"docsearch:version",content:n}),a&&(0,o.jsx)("meta",{name:"docsearch:docusaurus_tag",content:a})]})}},1122:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});var r=n(6540),o=n(4164),a=n(2303),i=n(5293);const s={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var c=n(4848);function l(e){let{className:t,children:n}=e;const l=(0,a.A)(),{colorMode:u}=(0,i.G)();return(0,c.jsx)(c.Fragment,{children:(l?"dark"===u?["dark"]:["light"]:["light","dark"]).map((e=>{const a=n({theme:e,className:(0,o.A)(t,s.themedComponent,s[`themedComponent--${e}`])});return(0,c.jsx)(r.Fragment,{children:a},e)}))})}function u(e){const{sources:t,className:n,alt:r,...o}=e;return(0,c.jsx)(l,{className:n,children:e=>{let{theme:n,className:a}=e;return(0,c.jsx)("img",{src:t[n],alt:r,className:a,...o})}})}},1422:(e,t,n)=>{"use strict";n.d(t,{N:()=>b,u:()=>l});var r=n(6540),o=n(8193),a=n(205),i=n(3109),s=n(4848);const c="ease-in-out";function l(e){let{initialState:t}=e;const[n,o]=(0,r.useState)(t??!1),a=(0,r.useCallback)((()=>{o((e=>!e))}),[]);return{collapsed:n,setCollapsed:o,toggleCollapsed:a}}const u={display:"none",overflow:"hidden",height:"0px"},d={display:"block",overflow:"visible",height:"auto"};function f(e,t){const n=t?u:d;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function p(e){let{collapsibleRef:t,collapsed:n,animation:o}=e;const a=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=o?.duration??function(e){if((0,i.O)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${o?.easing??c}`,height:`${t}px`}}function s(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!a.current)return f(e,n),void(a.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,o])}function h(e){if(!o.A.canUseDOM)return e?u:d}function m(e){let{as:t="div",collapsed:n,children:o,animation:a,onCollapseTransitionEnd:i,className:c,disableSSRStyle:l}=e;const u=(0,r.useRef)(null);return p({collapsibleRef:u,collapsed:n,animation:a}),(0,s.jsx)(t,{ref:u,style:l?void 0:h(n),onTransitionEnd:e=>{"height"===e.propertyName&&(f(u.current,n),i?.(n))},className:c,children:o})}function g(e){let{collapsed:t,...n}=e;const[o,i]=(0,r.useState)(!t),[c,l]=(0,r.useState)(t);return(0,a.A)((()=>{t||i(!0)}),[t]),(0,a.A)((()=>{o&&l(t)}),[o,t]),o?(0,s.jsx)(m,{...n,collapsed:c}):null}function b(e){let{lazy:t,...n}=e;const r=t?g:m;return(0,s.jsx)(r,{...n})}},5041:(e,t,n)=>{"use strict";n.d(t,{M:()=>m,o:()=>h});var r=n(6540),o=n(2303),a=n(679),i=n(9532),s=n(6342),c=n(4848);const l=(0,a.Wf)("docusaurus.announcement.dismiss"),u=(0,a.Wf)("docusaurus.announcement.id"),d=()=>"true"===l.get(),f=e=>l.set(String(e)),p=r.createContext(null);function h(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,s.p)(),t=(0,o.A)(),[n,a]=(0,r.useState)((()=>!!t&&d()));(0,r.useEffect)((()=>{a(d())}),[]);const i=(0,r.useCallback)((()=>{f(!0),a(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&f(!1),!r&&d()||a(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return(0,c.jsx)(p.Provider,{value:n,children:t})}function m(){const e=(0,r.useContext)(p);if(!e)throw new i.dV("AnnouncementBarProvider");return e}},5293:(e,t,n)=>{"use strict";n.d(t,{G:()=>b,a:()=>g});var r=n(6540),o=n(8193),a=n(9532),i=n(679),s=n(6342),c=n(4848);const l=r.createContext(void 0),u="theme",d=(0,i.Wf)(u),f={light:"light",dark:"dark"},p=e=>e===f.dark?f.dark:f.light,h=e=>o.A.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e),m=e=>{d.set(p(e))};function g(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.p)(),[o,a]=(0,r.useState)(h(e));(0,r.useEffect)((()=>{t&&d.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:o=!0}=r;t?(a(t),o&&m(t)):(a(n?window.matchMedia("(prefers-color-scheme: dark)").matches?f.dark:f.light:e),d.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",p(o))}),[o]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=d.get();null!==t&&i(p(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const c=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||c.current?c.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:o,setColorMode:i,get isDarkTheme(){return o===f.dark},setLightTheme(){i(f.light)},setDarkTheme(){i(f.dark)}})),[o,i])}();return(0,c.jsx)(l.Provider,{value:n,children:t})}function b(){const e=(0,r.useContext)(l);if(null==e)throw new a.dV("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},2069:(e,t,n)=>{"use strict";n.d(t,{M:()=>p,e:()=>f});var r=n(6540),o=n(5600),a=n(4581),i=n(7485),s=n(6342),c=n(9532),l=n(4848);const u=r.createContext(void 0);function d(){const e=function(){const e=(0,o.YL)(),{items:t}=(0,s.p)().navbar;return 0===t.length&&!e.component}(),t=(0,a.l)(),n=!e&&"mobile"===t,[c,l]=(0,r.useState)(!1);(0,i.$Z)((()=>{if(c)return l(!1),!1}));const u=(0,r.useCallback)((()=>{l((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&l(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:c})),[e,n,u,c])}function f(e){let{children:t}=e;const n=d();return(0,l.jsx)(u.Provider,{value:n,children:t})}function p(){const e=r.useContext(u);if(void 0===e)throw new c.dV("NavbarMobileSidebarProvider");return e}},5600:(e,t,n)=>{"use strict";n.d(t,{GX:()=>l,YL:()=>c,y_:()=>s});var r=n(6540),o=n(9532),a=n(4848);const i=r.createContext(null);function s(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return(0,a.jsx)(i.Provider,{value:n,children:t})}function c(){const e=(0,r.useContext)(i);if(!e)throw new o.dV("NavbarSecondaryMenuContentProvider");return e[0]}function l(e){let{component:t,props:n}=e;const a=(0,r.useContext)(i);if(!a)throw new o.dV("NavbarSecondaryMenuContentProvider");const[,s]=a,c=(0,o.Be)(n);return(0,r.useEffect)((()=>{s({component:t,props:c})}),[s,t,c]),(0,r.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},4090:(e,t,n)=>{"use strict";n.d(t,{w:()=>o,J:()=>a});var r=n(6540);const o="navigation-with-keyboard";function a(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(o),"mousedown"===e.type&&document.body.classList.remove(o)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(o),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},4255:(e,t,n)=>{"use strict";n.d(t,{b:()=>s,w:()=>c});var r=n(6540),o=n(4586),a=n(7485);const i="q";function s(){return(0,a.l)(i)}function c(){const{siteConfig:{baseUrl:e,themeConfig:t}}=(0,o.A)(),{algolia:{searchPagePath:n}}=t;return(0,r.useCallback)((t=>`${e}${n}?${i}=${encodeURIComponent(t)}`),[e,n])}},4581:(e,t,n)=>{"use strict";n.d(t,{l:()=>s});var r=n(6540),o=n(8193);const a={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function s(e){let{desktopBreakpoint:t=i}=void 0===e?{}:e;const[n,s]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){s(function(e){if(!o.A.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?a.desktop:a.mobile}(t))}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[t]),n}},7559:(e,t,n)=>{"use strict";n.d(t,{G:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",blogAuthorsListPage:"blog-authors-list-page",blogAuthorsPostsPage:"blog-authors-posts-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",draftBanner:"theme-draft-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{blogFooterTagsRow:"theme-blog-footer-tags-row",blogFooterEditMetaRow:"theme-blog-footer-edit-meta-row"},pages:{pageFooterEditMetaRow:"theme-pages-footer-edit-meta-row"}}},3109:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{O:()=>r})},481:(e,t,n)=>{"use strict";n.d(t,{s:()=>o});var r=n(4586);function o(e){const{siteConfig:t}=(0,r.A)(),{title:n,titleDelimiter:o}=t;return e?.trim().length?`${e.trim()} ${o} ${n}`:n}},7485:(e,t,n)=>{"use strict";n.d(t,{$Z:()=>i,l:()=>c});var r=n(6540),o=n(6347),a=n(9532);function i(e){!function(e){const t=(0,o.W6)(),n=(0,a._q)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function s(e){const t=(0,o.W6)();return(0,r.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}function c(e){const t=function(e){return s((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}(e)??"",n=function(e){const t=(0,o.W6)();return(0,r.useCallback)(((n,r)=>{const o=new URLSearchParams(t.location.search);n?o.set(e,n):o.delete(e),(r?.push?t.push:t.replace)({search:o.toString()})}),[e,t])}(e);return[t,n]}},1682:(e,t,n)=>{"use strict";function r(e){return Array.from(new Set(e))}function o(e,t){const n={};let r=0;for(const o of e){const e=t(o,r);n[e]??=[],n[e].push(o),r+=1}return n}n.d(t,{$z:()=>o,sb:()=>r})},5500:(e,t,n)=>{"use strict";n.d(t,{Jx:()=>p,be:()=>u,e3:()=>f});var r=n(6540),o=n(4164),a=n(5260),i=n(6803),s=n(6025),c=n(481),l=n(4848);function u(e){let{title:t,description:n,keywords:r,image:o,children:i}=e;const u=(0,c.s)(t),{withBaseUrl:d}=(0,s.hH)(),f=o?d(o,{absolute:!0}):void 0;return(0,l.jsxs)(a.A,{children:[t&&(0,l.jsx)("title",{children:u}),t&&(0,l.jsx)("meta",{property:"og:title",content:u}),n&&(0,l.jsx)("meta",{name:"description",content:n}),n&&(0,l.jsx)("meta",{property:"og:description",content:n}),r&&(0,l.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),f&&(0,l.jsx)("meta",{property:"og:image",content:f}),f&&(0,l.jsx)("meta",{name:"twitter:image",content:f}),i]})}const d=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=r.useContext(d),s=(0,o.A)(i,t);return(0,l.jsxs)(d.Provider,{value:s,children:[(0,l.jsx)(a.A,{children:(0,l.jsx)("html",{className:s})}),n]})}function p(e){let{children:t}=e;const n=(0,i.A)(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const a=`plugin-id-${n.plugin.id}`;return(0,l.jsx)(f,{className:(0,o.A)(r,a),children:t})}},9532:(e,t,n)=>{"use strict";n.d(t,{Be:()=>l,ZC:()=>s,_q:()=>i,dV:()=>c,fM:()=>u});var r=n(6540),o=n(205),a=n(4848);function i(e){const t=(0,r.useRef)(e);return(0,o.A)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function s(e){const t=(0,r.useRef)();return(0,o.A)((()=>{t.current=e})),t.current}class c extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function l(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return(0,a.jsx)(a.Fragment,{children:e.reduceRight(((e,t)=>(0,a.jsx)(t,{children:e})),n)})}}},1252:(e,t,n)=>{"use strict";function r(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}n.d(t,{G:()=>r})},9169:(e,t,n)=>{"use strict";n.d(t,{Dt:()=>s,ys:()=>i});var r=n(6540),o=n(8328),a=n(4586);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,a.A)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function o(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(o).flatMap((e=>e.routes??[])))}(n)}({routes:o.A,baseUrl:e})),[e])}},3104:(e,t,n)=>{"use strict";n.d(t,{Mq:()=>f,Tv:()=>l,gk:()=>p});var r=n(6540),o=n(8193),a=n(2303),i=(n(205),n(9532)),s=n(4848);const c=r.createContext(void 0);function l(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,s.jsx)(c.Provider,{value:n,children:t})}function u(){const e=(0,r.useContext)(c);if(null==e)throw new i.dV("ScrollControllerProvider");return e}const d=()=>o.A.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function f(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=u(),o=(0,r.useRef)(d()),a=(0,i._q)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=d();a(e,o.current),o.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[a,n,...t])}function p(){const e=(0,r.useRef)(null),t=(0,a.A)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const o=document.documentElement.scrollTop;(n&&o>e||!n&&ot&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},2967:(e,t,n)=>{"use strict";n.d(t,{C:()=>r});const r="default"},679:(e,t,n)=>{"use strict";n.d(t,{Wf:()=>l});n(6540);const r=JSON.parse('{"N":"localStorage","M":""}'),o=r.N;function a(e){let{key:t,oldValue:n,newValue:r,storage:o}=e;if(n===r)return;const a=document.createEvent("StorageEvent");a.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,o),window.dispatchEvent(a)}function i(e){if(void 0===e&&(e=o),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,s||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),s=!0),null}var t}let s=!1;const c={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function l(e,t){const n=`${e}${r.M}`;if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(n);const o=i(t?.persistence);return null===o?c:{get:()=>{try{return o.getItem(n)}catch(e){return console.error(`Docusaurus storage error, can't get key=${n}`,e),null}},set:e=>{try{const t=o.getItem(n);o.setItem(n,e),a({key:n,oldValue:t,newValue:e,storage:o})}catch(t){console.error(`Docusaurus storage error, can't set ${n}=${e}`,t)}},del:()=>{try{const e=o.getItem(n);o.removeItem(n),a({key:n,oldValue:e,newValue:null,storage:o})}catch(e){console.error(`Docusaurus storage error, can't delete key=${n}`,e)}},listen:e=>{try{const t=t=>{t.storageArea===o&&t.key===n&&e(t)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)}catch(t){return console.error(`Docusaurus storage error, can't listen for changes of key=${n}`,t),()=>{}}}}}},2131:(e,t,n)=>{"use strict";n.d(t,{o:()=>i});var r=n(4586),o=n(6347),a=n(440);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:s}}=(0,r.A)(),{pathname:c}=(0,o.zy)(),l=(0,a.Ks)(c,{trailingSlash:n,baseUrl:e}),u=s===i?e:e.replace(`/${s}/`,"/"),d=l.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===i?`${u}`:`${u}${e}/`}(n)}${d}`}}}},5062:(e,t,n)=>{"use strict";n.d(t,{$:()=>i});var r=n(6540),o=n(6347),a=n(9532);function i(e){const t=(0,o.zy)(),n=(0,a.ZC)(t),i=(0,a._q)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6342:(e,t,n)=>{"use strict";n.d(t,{p:()=>o});var r=n(4586);function o(){return(0,r.A)().siteConfig.themeConfig}},8126:(e,t,n)=>{"use strict";n.d(t,{c:()=>o});var r=n(4586);function o(){const{siteConfig:{themeConfig:e}}=(0,r.A)();return e}},1062:(e,t,n)=>{"use strict";n.d(t,{C:()=>s});var r=n(6540),o=n(1252),a=n(6025),i=n(8126);function s(){const{withBaseUrl:e}=(0,a.hH)(),{algolia:{externalUrlRegex:t,replaceSearchResultPathname:n}}=(0,i.c)();return(0,r.useCallback)((r=>{const a=new URL(r);if((0,o.G)(t,a.href))return r;const i=`${a.pathname+a.hash}`;return e(function(e,t){return t?e.replaceAll(new RegExp(t.from,"g"),t.to):e}(i,n))}),[e,t,n])}},2983:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addTrailingSlash=o,t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[i]=e.split(/[#?]/),s="/"===i||i===r?i:(c=i,l=n,l?o(c):a(c));var c,l;return e.replace(i,s)},t.addLeadingSlash=function(e){return(0,r.addPrefix)(e,"/")},t.removeTrailingSlash=a;const r=n(2566);function o(e){return e.endsWith("/")?e:`${e}/`}function a(e){return(0,r.removeSuffix)(e,"/")}},253:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=function e(t){if(t.cause)return[t,...e(t.cause)];return[t]}},440:(e,t,n)=>{"use strict";t.rA=t.Ks=t.LU=void 0;const r=n(1635);t.LU="__blog-post-container";var o=n(2983);Object.defineProperty(t,"Ks",{enumerable:!0,get:function(){return r.__importDefault(o).default}});var a=n(2566);var i=n(253);Object.defineProperty(t,"rA",{enumerable:!0,get:function(){return i.getErrorCausalChain}})},2566:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addPrefix=function(e,t){return e.startsWith(t)?e:`${t}${e}`},t.removeSuffix=function(e,t){if(""===t)return e;return e.endsWith(t)?e.slice(0,-t.length):e},t.addSuffix=function(e,t){return e.endsWith(t)?e:`${e}${t}`},t.removePrefix=function(e,t){return e.startsWith(t)?e.slice(t.length):e}},1513:(e,t,n)=>{"use strict";n.d(t,{zR:()=>k,TM:()=>O,yJ:()=>p,sC:()=>j,AO:()=>f});var r=n(8168);function o(e){return"/"===e.charAt(0)}function a(e,t){for(var n=t,r=n+1,o=e.length;r=0;f--){var p=i[f];"."===p?a(i,f):".."===p?(a(i,f),d++):d&&(a(i,f),d--)}if(!l)for(;d--;d)i.unshift("..");!l||""===i[0]||i[0]&&o(i[0])||i.unshift("");var h=i.join("/");return n&&"/"!==h.substr(-1)&&(h+="/"),h};var s=n(1561);function c(e){return"/"===e.charAt(0)?e:"/"+e}function l(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function f(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function p(e,t,n,o){var a;"string"==typeof e?(a=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substr(o),t=t.substr(0,o));var a=t.indexOf("?");return-1!==a&&(n=t.substr(a),t=t.substr(0,a)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),a.state=t):(void 0===(a=(0,r.A)({},e)).pathname&&(a.pathname=""),a.search?"?"!==a.search.charAt(0)&&(a.search="?"+a.search):a.search="",a.hash?"#"!==a.hash.charAt(0)&&(a.hash="#"+a.hash):a.hash="",void 0!==t&&void 0===a.state&&(a.state=t));try{a.pathname=decodeURI(a.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+a.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(a.key=n),o?a.pathname?"/"!==a.pathname.charAt(0)&&(a.pathname=i(a.pathname,o.pathname)):a.pathname=o.pathname:a.pathname||(a.pathname="/"),a}function h(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var a="function"==typeof e?e(t,n):e;"string"==typeof a?"function"==typeof r?r(a,o):o(!0):o(!1!==a)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,o):n.push(o),d({action:r,location:o,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",o=p(e,t,m(),k.location);u.confirmTransitionTo(o,r,n,(function(e){e&&(k.entries[k.index]=o,d({action:r,location:o}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=k.index+e;return t>=0&&t{"use strict";var r=n(4363),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},a={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function c(e){return r.isMemo(e)?i:s[e.$$typeof]||o}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=i;var l=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,h=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(h){var o=p(n);o&&o!==h&&e(t,o,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var s=c(t),m=c(n),g=0;g{"use strict";e.exports=function(e,t,n,r,o,a,i,s){if(!e){var c;if(void 0===t)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[n,r,o,a,i,s],u=0;(c=new Error(t.replace(/%s/g,(function(){return l[u++]})))).name="Invariant Violation"}throw c.framesToPop=1,c}}},4634:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},119:(e,t,n)=>{"use strict";n.r(t)},1043:(e,t,n)=>{"use strict";n.r(t)},5947:function(e,t,n){var r,o;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function o(e,t,n){return en?n:e}function a(e){return 100*(-1+e)}function i(e,t,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+a(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+a(e)+"%,0)"}:{"margin-left":a(e)+"%"}).transition="all "+t+"ms "+n,o}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=o(e,r.minimum,1),n.status=1===e?null:e;var a=n.render(!t),l=a.querySelector(r.barSelector),u=r.speed,d=r.easing;return a.offsetWidth,s((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),c(l,i(e,u,d)),1===e?(c(a,{transition:"none",opacity:1}),a.offsetWidth,setTimeout((function(){c(a,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*o(Math.random()*t,.1,.95)),t=o(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var o,i=t.querySelector(r.barSelector),s=e?"-100":a(n.status||0),l=document.querySelector(r.parent);return c(i,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),r.showSpinner||(o=t.querySelector(r.spinnerSelector))&&p(o),l!=document.body&&u(l,"nprogress-custom-parent"),l.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&p(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),c=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,o=e.length,a=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((r=e[o]+a)in n)return r;return t}function o(e){return e=n(e),t[e]||(t[e]=r(e))}function a(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,r,o=arguments;if(2==o.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&a(e,n,r);else a(e,o[1],o[2])}}();function l(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=f(e),r=n+t;l(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);l(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function f(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(o="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=o)},6976:()=>{!function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n=/(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,r={pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[r,{pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z]\w*(?=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source),lookbehind:!0,inside:r.inside},{pattern:RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source+n+/[A-Z]\w*\b/.source),lookbehind:!0,inside:r.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\b[A-Z][A-Z_\d]+\b/}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":r,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp(/(\bimport\s+)/.source+n+/(?:[A-Z]\w*|\*)(?=\s*;)/.source),lookbehind:!0,inside:{namespace:r.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp(/(\bimport\s+static\s+)/.source+n+/(?:\w+|\*)(?=\s*;)/.source),lookbehind:!0,alias:"static",inside:{namespace:r.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(//g,(function(){return t.source}))),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism)},9700:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,o,a){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(o,(function(e){if("function"==typeof a&&!a(e))return e;for(var o,s=i.length;-1!==n.code.indexOf(o=t(r,s));)++s;return i[s]=e,o})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var o=0,a=Object.keys(n.tokenStack);!function i(s){for(var c=0;c=a.length);c++){var l=s[c];if("string"==typeof l||l.content&&"string"==typeof l.content){var u=a[o],d=n.tokenStack[u],f="string"==typeof l?l:l.content,p=t(r,u),h=f.indexOf(p);if(h>-1){++o;var m=f.substring(0,h),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=f.substring(h+p.length),y=[];m&&y.push.apply(y,i([m])),y.push(g),b&&y.push.apply(y,i([b])),"string"==typeof l?s.splice.apply(s,[c,1].concat(y)):l.content=y}}else l.content&&i(l.content)}return s}(n.tokens)}}}})}(Prism)},1900:(e,t,n)=>{var r={"./prism-java":6976};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=1900},2694:(e,t,n)=>{"use strict";var r=n(6925);function o(){}function a(){}a.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,a,i){if(i!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:o};return n.PropTypes=n,n}},5556:(e,t,n)=>{e.exports=n(2694)()},6925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},2551:(e,t,n)=>{"use strict";var r=n(6540),o=n(9982);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n